context menu

by Graham Fairweather

HTML

<div id="info">
    <div>Hold CTRL for original context menu</div>
</div>
<input id="input1" contenteditable class="customContext customTextContext" type="text"></input>
<input id="input2" contenteditable class="customContext customTextContext" type="datetime"></input>
<input id="input3" contenteditable class="customContext customTextContext" type="number"></input>
<input id="input4" contenteditable class="customContext customOtherContext" type="color"></input>

CSS

#info {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 230px;
    height: auto;
    border-style: solid;
    border-radius: 5px;
    border-width: 1px;
    box-shadow: 10px 10px 5px #888888;
    padding: 20px;
    background-color: #F3F3F3;
}
.menu {
    position: fixed;
    width: 180px;
    height: auto;
    border-style: solid;
    border-radius: 5px;
    border-width: 1px;
    box-shadow: 10px 10px 5px #888888;
    background-color: #F3F3F3;
    visibility: hidden;
}
.menutitle {
    text-align: center;
    font-weight: bold;
    color: white;
    background-color: black;
}
.menuitem {
    text-indent: 10px;
}
.menuitem:hover {
    cursor: pointer;
    width: 100%;
    height: auto;
    background-color: blue;
}
.fadein, .fadeout {
    overflow: hidden;
    /* This container should not have padding, borders, etc. */
}
.fadein {
    visibility: visible;
    opacity: 1;
    -webkit-transition: opacity 2s linear;
    -moz-transition: opacity 2s linear;
    transition: opacity 2s linear;
}
.fadeout {
    visibility: hidden;
    opacity: 0;
    -webkit-transition: visibility 0s 2s, opacity 2s linear;
    -moz-transition: visibility 0s 2s, opacity 2s linear;
    transition: visibility 0s 2s, opacity 2s linear;
}
.fadein > div, .fadeout > div {
    /* Put any padding, border, min-height, etc. here. */
}
.fadeout > div {
    margin-top: -10000px;
    -webkit-transition: margin-top 0s 2s;
    -moz-transition: margin-top 0s 2s;
    transition: margin-top 0s 2s;
}

JavaScript

/*jslint sub: true, maxerr: 50, indent: 4, browser: true */
/*global */

(function () {
    "use strict";

    var customTextContexts = document.getElementsByClassName("customTextContext"),
        info = document.getElementById("info"),
        inputTextContextMenu,
        inputOtherContextMenu;

    function hideMenus() {
        var menus = document.getElementsByClassName("menu");

        Array.prototype.forEach.call(menus, function (menu) {
            menu.style.visibility = "hidden";
        });
    }

    function toggleMenu(element) {
        var menus = document.getElementsByClassName("menu");

        Array.prototype.forEach.call(menus, function (menu) {
            if (menu.style.visibility === "visible") {
                menu.style.visibility = "hidden";
            } else if (element === menu) {
                menu.style.visibility = "visible";
            }
        });
    }

    function fadeout(element) {
        if (element.className.indexOf("fadein") !== -1) {
            element.className = element.className.replace("fadein", "fadeout");
        } else if (element.className.indexOf("fadeout") === -1) {
            element.className += "  fadeout";
        }
    }

    setTimeout(function () {
        fadeout(info);
    }, 3000);

    function context(evt) {
        var position;

        if (evt.target.className.indexOf("customContext ") !== -1) {
            if (!evt.ctrlKey) {
                evt.preventDefault();
                position = evt.target.getBoundingClientRect();
                
                if (evt.target.className.indexOf("customTextContext") !== -1) {
                    inputTextContextMenu.style.top = position.bottom + "px";
                    inputTextContextMenu.style.left = position.left + "px";
                    toggleMenu(inputTextContextMenu);
                } else if (evt.target.className.indexOf("customOtherContext") !== -1) {
                    inputOtherContextMenu.style.top = position.bottom + "px";
 ...