UNPKG

atheos-ide

Version:

Web-based IDE framework

241 lines (201 loc) 6.81 kB
//////////////////////////////////////////////////////////////////////////////80 // Context Menu Init //////////////////////////////////////////////////////////////////////////////80 // Copyright (c) Atheos & Liam Siira (Atheos.io), distributed as-is and without // warranty under the MIT License. See [root]/LICENSE.md for more. // This information must remain intact. //////////////////////////////////////////////////////////////////////////////80 // Authors: Codiad Team, @Fluidbyte, Atheos Team, @hlsiira //////////////////////////////////////////////////////////////////////////////80 // Notes: // The context menu should become an object stored within the filemanager, and // constructed based on the fules specified therein. The OBJ is created, and then // added to by each plugin based on it's requirements. The OBJ could even be // cached. // - Liam Siira //////////////////////////////////////////////////////////////////////////////80 (function(global) { 'use strict'; var self = null; var menu = null; var atheos = global.atheos, carbon = global.carbon; carbon.subscribe('system.loadMinor', () => atheos.contextmenu.init()); atheos.contextmenu = { contextMenu: {}, baseMenu: '', init: function() { self = this; menu = oX('#contextmenu'); self.baseMenu = menu.html(); var checkAnchor = function(node) { node = oX(node); ////////////////////////////////////////////////////////////////// // This tagname business is due to the logical but annoying way // event delegation is handled. I keep trying to avoid organizing // the css in a better way for the file manager, and this is the // result. ////////////////////////////////////////////////////////////////// var tagName = node.el.tagName; if (tagName === 'UL') { return false; } else if (tagName !== 'A') { if (tagName === 'LI') { node = node.find('a'); } else { node = oX(node.parent()); } } return node; }; // Initialize node listener oX('#file-manager').on('contextmenu', function(e) { // Context Menu e.preventDefault(); menu.html(self.baseMenu); var active = oX('#file-manager a.context-menu-active'); if (active) { active.removeClass('context-menu-active'); } self.adjust(checkAnchor(e.target)); self.show(e); }); oX('#editor-top-bar').on('contextmenu', function(e) { // Context Menu e.preventDefault(); self.topBarMenu(checkAnchor(e.target)); self.show(e); }); }, //////////////////////////////////////////////////////////////////////80 // Show Context Menu //////////////////////////////////////////////////////////////////////80 show: function(e, node) { // Show menu var top = e.pageY; var windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; if (top > windowHeight - menu.height()) { top -= menu.height(); } if (top < 10) { top = 10; } var max = windowHeight - top - 10; menu.css({ 'top': top + 'px', 'left': e.pageX + 'px', 'max-height': max + 'px', 'display': 'block' }); self.keepOpen(); }, //////////////////////////////////////////////////////////////////////80 // Show Context Menu //////////////////////////////////////////////////////////////////////80 adjust: function(node) { if (!node) { return; } var path = node.attr('data-path'), type = node.attr('data-type'), name = node.find('span').html(); node.addClass('context-menu-active'); var menu = oX('#contextmenu'); var children = null; switch (type) { case 'directory': children = menu.findAll('.directory-only, .non-root'); children.forEach((child) => child.show()); children = menu.findAll('.file-only, .root-only'); children.forEach((child) => child.hide()); break; case 'file': children = menu.findAll('.directory-only, .root-only'); children.forEach((child) => child.hide()); children = menu.findAll('.file-only, .non-root'); children.forEach((child) => child.show()); break; case 'root': children = menu.findAll('.directory-only, .root-only'); children.forEach((child) => child.show()); children = menu.findAll('.file-only, .non-root'); children.forEach((child) => child.hide()); break; } children = menu.findAll('.no-external'); if (atheos.common.isAbsPath(oX('#file-manager a[data-type="root"]').attr('data-path'))) { children.forEach((child) => child.hide()); } else { children.forEach((child) => child.show()); } menu.attr({ 'data-path': path, 'data-type': type, 'data-name': name }); // Show faded 'paste' if nothing in clipboard if (atheos.filemanager.clipboard === '') { oX('#contextmenu i.fa-paste').parent().hide(); } else { oX('#contextmenu i.fa-paste').parent().show(); } /* Notify listeners. */ carbon.publish('contextmenu.show', { menu: menu, name: name, node: node, path: path, type: type }); // Hide on click menu.on('click', function() { self.hide(); }); }, keepOpen: function() { var hideContextMenu; menu.on('mouseout', function() { hideContextMenu = setTimeout(function() { self.hide(); }, 500); }); menu.on('mouseover', function() { if (hideContextMenu) { clearTimeout(hideContextMenu); } }); }, topBarMenu: function(node) { if (!node) { return; } node = node.parent('li'); var path = node.attr('data-path'), type = node.attr('data-type'), name = node.find('span').html(), active = node.hasClass('active'); var html = '<a class="directory-only" onclick="atheos.active.reload(oX(\'#contextmenu\').attr(\'data-path\'), ' + active +');" style="display: block;"><i class="fas fa-sync-alt"></i>Reload</a>'; menu.attr({ 'data-path': path, 'data-type': type, 'data-name': name }); menu.html(html); }, //////////////////////////////////////////////////////////////////////80 // Hide Context Menu //////////////////////////////////////////////////////////////////////80 hide: function() { menu.hide(); menu.off('*'); var active = oX('#file-manager a.context-menu-active'); if (active) { active.removeClass('context-menu-active'); } carbon.publish('contextmenu.hide', { menu: menu, name: menu.attr('data-name'), path: menu.attr('data-path'), type: menu.attr('data-type') }); }, }; })(this);