1/*! 2 * jquery.fancytree.menu.js 3 * 4 * Enable jQuery UI Menu as context menu for tree nodes. 5 * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/) 6 * 7 * @see http://api.jqueryui.com/menu/ 8 * 9 * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de) 10 * 11 * Released under the MIT license 12 * https://github.com/mar10/fancytree/wiki/LicenseInfo 13 * 14 * @version 2.38.3 15 * @date 2023-02-01T20:52:50Z 16 */ 17 18(function (factory) { 19 if (typeof define === "function" && define.amd) { 20 // AMD. Register as an anonymous module. 21 define(["jquery", "./jquery.fancytree"], factory); 22 } else if (typeof module === "object" && module.exports) { 23 // Node/CommonJS 24 require("./jquery.fancytree"); 25 module.exports = factory(require("jquery")); 26 } else { 27 // Browser globals 28 factory(jQuery); 29 } 30})(function ($) { 31 "use strict"; 32 33 $.ui.fancytree.registerExtension({ 34 name: "menu", 35 version: "2.38.3", 36 // Default options for this extension. 37 options: { 38 enable: true, 39 selector: null, // 40 position: {}, // 41 // Events: 42 create: $.noop, // 43 beforeOpen: $.noop, // 44 open: $.noop, // 45 focus: $.noop, // 46 select: $.noop, // 47 close: $.noop, // 48 }, 49 // Override virtual methods for this extension. 50 // `this` : is this extension object 51 // `this._base` : the Fancytree instance 52 // `this._super`: the virtual function that was overridden (member of prev. extension or Fancytree) 53 treeInit: function (ctx) { 54 var opts = ctx.options, 55 tree = ctx.tree; 56 57 this._superApply(arguments); 58 59 // Prepare an object that will be passed with menu events 60 tree.ext.menu.data = { 61 tree: tree, 62 node: null, 63 $menu: null, 64 menuId: null, 65 }; 66 67 // tree.$container[0].oncontextmenu = function() {return false;}; 68 // Replace the standard browser context menu with out own 69 tree.$container.on( 70 "contextmenu", 71 "span.fancytree-node", 72 function (event) { 73 var node = $.ui.fancytree.getNode(event), 74 ctx = { 75 node: node, 76 tree: node.tree, 77 originalEvent: event, 78 options: tree.options, 79 }; 80 tree.ext.menu._openMenu(ctx); 81 return false; 82 } 83 ); 84 85 // Use jquery.ui.menu 86 $(opts.menu.selector) 87 .menu({ 88 create: function (event, ui) { 89 tree.ext.menu.data.$menu = $(this).menu("widget"); 90 var data = $.extend({}, tree.ext.menu.data); 91 opts.menu.create.call(tree, event, data); 92 }, 93 focus: function (event, ui) { 94 var data = $.extend({}, tree.ext.menu.data, { 95 menuItem: ui.item, 96 menuId: ui.item.find(">a").attr("href"), 97 }); 98 opts.menu.focus.call(tree, event, data); 99 }, 100 select: function (event, ui) { 101 var data = $.extend({}, tree.ext.menu.data, { 102 menuItem: ui.item, 103 menuId: ui.item.find(">a").attr("href"), 104 }); 105 if ( 106 opts.menu.select.call(tree, event, data) !== false 107 ) { 108 tree.ext.menu._closeMenu(ctx); 109 } 110 }, 111 }) 112 .hide(); 113 }, 114 treeDestroy: function (ctx) { 115 this._superApply(arguments); 116 }, 117 _openMenu: function (ctx) { 118 var data, 119 tree = ctx.tree, 120 opts = ctx.options, 121 $menu = $(opts.menu.selector); 122 123 tree.ext.menu.data.node = ctx.node; 124 data = $.extend({}, tree.ext.menu.data); 125 126 if ( 127 opts.menu.beforeOpen.call(tree, ctx.originalEvent, data) === 128 false 129 ) { 130 return; 131 } 132 133 $(document) 134 .on("keydown.fancytree", function (event) { 135 if (event.which === $.ui.keyCode.ESCAPE) { 136 tree.ext.menu._closeMenu(ctx); 137 } 138 }) 139 .on("mousedown.fancytree", function (event) { 140 // Close menu when clicked outside menu 141 if ($(event.target).closest(".ui-menu-item").length === 0) { 142 tree.ext.menu._closeMenu(ctx); 143 } 144 }); 145 // $menu.position($.extend({my: "left top", at: "left bottom", of: event}, opts.menu.position)); 146 $menu 147 .css("position", "absolute") 148 .show() 149 .position({ 150 my: "left top", 151 at: "right top", 152 of: ctx.originalEvent, 153 collision: "fit", 154 }) 155 .focus(); 156 157 opts.menu.open.call(tree, ctx.originalEvent, data); 158 }, 159 _closeMenu: function (ctx) { 160 var $menu, 161 tree = ctx.tree, 162 opts = ctx.options, 163 data = $.extend({}, tree.ext.menu.data); 164 if (opts.menu.close.call(tree, ctx.originalEvent, data) === false) { 165 return; 166 } 167 $menu = $(opts.menu.selector); 168 $(document).off("keydown.fancytree, mousedown.fancytree"); 169 $menu.hide(); 170 tree.ext.menu.data.node = null; 171 }, 172 // , 173 // nodeClick: function(ctx) { 174 // var event = ctx.originalEvent; 175 // if(event.which === 2 || (event.which === 1 && event.ctrlKey)){ 176 // event.preventDefault(); 177 // ctx.tree.ext.menu._openMenu(ctx); 178 // return false; 179 // } 180 // this._superApply(arguments); 181 // } 182 }); 183 // Value returned by `require('jquery.fancytree..')` 184 return $.ui.fancytree; 185}); // End of closure 186