Skip to content

Instantly share code, notes, and snippets.

@rkeVader
Last active March 12, 2019 12:34
Show Gist options
  • Save rkeVader/4e719e7ad9ff0ca1974321834dd35e66 to your computer and use it in GitHub Desktop.
Save rkeVader/4e719e7ad9ff0ca1974321834dd35e66 to your computer and use it in GitHub Desktop.
function /* CLASS */ context_menu_system() {
if (context_menu_system.instance !== null) {
throw "You should only instantiate one context_menu_system!";
}
context_menu_system.instance = this;
this.menuPosition;
this.menuPositionX;
this.menuPositionY;
this.menuWidth;
this.menuHeight;
this.windowWidth;
this.windowHeight;
this.clickCoords;
this.clickCoordsX;
this.clickCoordsY;
this.init();
} /* CLASS context_menu_system */
context_menu_system.instance = null;
context_menu_system.getInstance = function() {
return context_menu_system.instance;
} // static context_menu_system getInstance
context_menu_system.taskItemClassName = 'contextmenuitem';
context_menu_system.activeClassName = "context-menu--active";
context_menu_system.prototype.init = function() {
this.__contextListener();
this.__clickListener();
this.__keyupListener();
this.__resizeListener();
var contextmenuitems = document.getElementsByClassName('contextmenuitem');
for (var i = 0; i < contextmenuitems.length; i++) {
var contextmenuitem = contextmenuitems[i];
if (contextmenuitem.getAttribute('contextmenu'))
this.__contextMenuListener(contextmenuitem);
}
} // context_menu_system->init
context_menu_system.prototype.__contextListener = function() {
document.addEventListener('contextmenu', function(e) { e.preventDefault(); });
} // context_menu_system->__contextListener
context_menu_system.prototype.__clickListener = function() {
var _this = this;
document.addEventListener('click', function(e) {
var button = e.which || e.button;
if (button === 1)
_this.__hideContextMenu();
});
} // context_menu_system->__clickListener
context_menu_system.prototype.__keyupListener = function() {
var _this = this;
window.onkeyup = function(e) {
if ( e.keyCode === 27 ) {
_this.__hideContextMenu();
}
}
} // context_menu_system->__keyupListener
context_menu_system.prototype.__resizeListener = function() {
var _this = this;
window.onresize = function(e) {
_this.__hideContextMenu();
};
} // context_menu_system->__resizeListener
context_menu_system.prototype.__contextMenuListener = function(el) {
var _this = this;
el.addEventListener('contextmenu', function(e) {
e.preventDefault();
if (_this.__clickInsideElement(e, context_menu_system.taskItemClassName)) {
var el = e.srcElement || e.target;
_this.__showContextMenu(el);
_this.__positionMenu(e, el);
} else {
_this.__hideContextMenu();
}
});
} // context_menu_system->__contextMenuListener
context_menu_system.prototype.__showContextMenu = function(el) {
this.__hideAllContextMenus();
document.getElementById(el.getAttribute('contextmenu')).classList.add(context_menu_system.activeClassName);
} // context_menu_system->__showContextMenu
context_menu_system.prototype.__hideContextMenu = function() {
this.__hideAllContextMenus();
} // context_menu_system->__hideContextMenu
context_menu_system.prototype.__hideAllContextMenus = function() {
var menus = document.getElementsByClassName('context-menu');
for (var i = 0; i < menus.length; i++) {
var menu = menus[i];
menu.classList.remove(context_menu_system.activeClassName);
}
} // context_menu_system->__hideContextMenu
context_menu_system.prototype.__clickInsideElement = function( e, className ) {
var el = e.srcElement || e.target;
if ( el.classList.contains(className) ) {
return el;
} else {
while ( el = el.parentNode ) {
if ( el.classList && el.classList.contains(className) ) {
return el;
}
}
}
return false;
} // context_menu_system->__clickInsideElement
context_menu_system.prototype.__positionMenu = function(e, el) {
clickCoords = this.__getPosition(e);
clickCoordsX = clickCoords.x;
clickCoordsY = clickCoords.y;
var menu = document.getElementById(el.getAttribute('contextmenu'));
menuWidth = menu.offsetWidth + 4;
menuHeight = menu.offsetHeight + 4;
windowWidth = window.innerWidth;
windowHeight = window.innerHeight;
if ( (windowWidth - clickCoordsX) < menuWidth ) {
menu.style.left = windowWidth - menuWidth + "px";
} else {
menu.style.left = clickCoordsX + "px";
}
if ( (windowHeight - clickCoordsY) < menuHeight ) {
menu.style.top = windowHeight - menuHeight + "px";
} else {
menu.style.top = clickCoordsY + "px";
}
} // context_menu_system->__positionMenu
context_menu_system.prototype.__getPosition = function(e) {
var posx = 0;
var posy = 0;
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
} else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
return {
x: posx,
y: posy
}
} // context_menu_system->__getPosition
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment