Mercurial > repos > mingchen0919 > aurora_star
comparison vakata-jstree-3.3.5/src/jstree.contextmenu.js @ 0:25602263cff0 draft default tip
planemo upload commit 841d8b22bf9f1aaed6bfe8344b60617f45b275b2-dirty
author | mingchen0919 |
---|---|
date | Sun, 30 Dec 2018 13:11:48 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:25602263cff0 |
---|---|
1 /** | |
2 * ### Contextmenu plugin | |
3 * | |
4 * Shows a context menu when a node is right-clicked. | |
5 */ | |
6 /*globals jQuery, define, exports, require, document */ | |
7 (function (factory) { | |
8 "use strict"; | |
9 if (typeof define === 'function' && define.amd) { | |
10 define('jstree.contextmenu', ['jquery','jstree'], factory); | |
11 } | |
12 else if(typeof exports === 'object') { | |
13 factory(require('jquery'), require('jstree')); | |
14 } | |
15 else { | |
16 factory(jQuery, jQuery.jstree); | |
17 } | |
18 }(function ($, jstree, undefined) { | |
19 "use strict"; | |
20 | |
21 if($.jstree.plugins.contextmenu) { return; } | |
22 | |
23 /** | |
24 * stores all defaults for the contextmenu plugin | |
25 * @name $.jstree.defaults.contextmenu | |
26 * @plugin contextmenu | |
27 */ | |
28 $.jstree.defaults.contextmenu = { | |
29 /** | |
30 * a boolean indicating if the node should be selected when the context menu is invoked on it. Defaults to `true`. | |
31 * @name $.jstree.defaults.contextmenu.select_node | |
32 * @plugin contextmenu | |
33 */ | |
34 select_node : true, | |
35 /** | |
36 * a boolean indicating if the menu should be shown aligned with the node. Defaults to `true`, otherwise the mouse coordinates are used. | |
37 * @name $.jstree.defaults.contextmenu.show_at_node | |
38 * @plugin contextmenu | |
39 */ | |
40 show_at_node : true, | |
41 /** | |
42 * an object of actions, or a function that accepts a node and a callback function and calls the callback function with an object of actions available for that node (you can also return the items too). | |
43 * | |
44 * Each action consists of a key (a unique name) and a value which is an object with the following properties (only label and action are required). Once a menu item is activated the `action` function will be invoked with an object containing the following keys: item - the contextmenu item definition as seen below, reference - the DOM node that was used (the tree node), element - the contextmenu DOM element, position - an object with x/y properties indicating the position of the menu. | |
45 * | |
46 * * `separator_before` - a boolean indicating if there should be a separator before this item | |
47 * * `separator_after` - a boolean indicating if there should be a separator after this item | |
48 * * `_disabled` - a boolean indicating if this action should be disabled | |
49 * * `label` - a string - the name of the action (could be a function returning a string) | |
50 * * `title` - a string - an optional tooltip for the item | |
51 * * `action` - a function to be executed if this item is chosen, the function will receive | |
52 * * `icon` - a string, can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class | |
53 * * `shortcut` - keyCode which will trigger the action if the menu is open (for example `113` for rename, which equals F2) | |
54 * * `shortcut_label` - shortcut label (like for example `F2` for rename) | |
55 * * `submenu` - an object with the same structure as $.jstree.defaults.contextmenu.items which can be used to create a submenu - each key will be rendered as a separate option in a submenu that will appear once the current item is hovered | |
56 * | |
57 * @name $.jstree.defaults.contextmenu.items | |
58 * @plugin contextmenu | |
59 */ | |
60 items : function (o, cb) { // Could be an object directly | |
61 return { | |
62 "create" : { | |
63 "separator_before" : false, | |
64 "separator_after" : true, | |
65 "_disabled" : false, //(this.check("create_node", data.reference, {}, "last")), | |
66 "label" : "Create", | |
67 "action" : function (data) { | |
68 var inst = $.jstree.reference(data.reference), | |
69 obj = inst.get_node(data.reference); | |
70 inst.create_node(obj, {}, "last", function (new_node) { | |
71 try { | |
72 inst.edit(new_node); | |
73 } catch (ex) { | |
74 setTimeout(function () { inst.edit(new_node); },0); | |
75 } | |
76 }); | |
77 } | |
78 }, | |
79 "rename" : { | |
80 "separator_before" : false, | |
81 "separator_after" : false, | |
82 "_disabled" : false, //(this.check("rename_node", data.reference, this.get_parent(data.reference), "")), | |
83 "label" : "Rename", | |
84 /*! | |
85 "shortcut" : 113, | |
86 "shortcut_label" : 'F2', | |
87 "icon" : "glyphicon glyphicon-leaf", | |
88 */ | |
89 "action" : function (data) { | |
90 var inst = $.jstree.reference(data.reference), | |
91 obj = inst.get_node(data.reference); | |
92 inst.edit(obj); | |
93 } | |
94 }, | |
95 "remove" : { | |
96 "separator_before" : false, | |
97 "icon" : false, | |
98 "separator_after" : false, | |
99 "_disabled" : false, //(this.check("delete_node", data.reference, this.get_parent(data.reference), "")), | |
100 "label" : "Delete", | |
101 "action" : function (data) { | |
102 var inst = $.jstree.reference(data.reference), | |
103 obj = inst.get_node(data.reference); | |
104 if(inst.is_selected(obj)) { | |
105 inst.delete_node(inst.get_selected()); | |
106 } | |
107 else { | |
108 inst.delete_node(obj); | |
109 } | |
110 } | |
111 }, | |
112 "ccp" : { | |
113 "separator_before" : true, | |
114 "icon" : false, | |
115 "separator_after" : false, | |
116 "label" : "Edit", | |
117 "action" : false, | |
118 "submenu" : { | |
119 "cut" : { | |
120 "separator_before" : false, | |
121 "separator_after" : false, | |
122 "label" : "Cut", | |
123 "action" : function (data) { | |
124 var inst = $.jstree.reference(data.reference), | |
125 obj = inst.get_node(data.reference); | |
126 if(inst.is_selected(obj)) { | |
127 inst.cut(inst.get_top_selected()); | |
128 } | |
129 else { | |
130 inst.cut(obj); | |
131 } | |
132 } | |
133 }, | |
134 "copy" : { | |
135 "separator_before" : false, | |
136 "icon" : false, | |
137 "separator_after" : false, | |
138 "label" : "Copy", | |
139 "action" : function (data) { | |
140 var inst = $.jstree.reference(data.reference), | |
141 obj = inst.get_node(data.reference); | |
142 if(inst.is_selected(obj)) { | |
143 inst.copy(inst.get_top_selected()); | |
144 } | |
145 else { | |
146 inst.copy(obj); | |
147 } | |
148 } | |
149 }, | |
150 "paste" : { | |
151 "separator_before" : false, | |
152 "icon" : false, | |
153 "_disabled" : function (data) { | |
154 return !$.jstree.reference(data.reference).can_paste(); | |
155 }, | |
156 "separator_after" : false, | |
157 "label" : "Paste", | |
158 "action" : function (data) { | |
159 var inst = $.jstree.reference(data.reference), | |
160 obj = inst.get_node(data.reference); | |
161 inst.paste(obj); | |
162 } | |
163 } | |
164 } | |
165 } | |
166 }; | |
167 } | |
168 }; | |
169 | |
170 $.jstree.plugins.contextmenu = function (options, parent) { | |
171 this.bind = function () { | |
172 parent.bind.call(this); | |
173 | |
174 var last_ts = 0, cto = null, ex, ey; | |
175 this.element | |
176 .on("init.jstree loading.jstree ready.jstree", $.proxy(function () { | |
177 this.get_container_ul().addClass('jstree-contextmenu'); | |
178 }, this)) | |
179 .on("contextmenu.jstree", ".jstree-anchor", $.proxy(function (e, data) { | |
180 if (e.target.tagName.toLowerCase() === 'input') { | |
181 return; | |
182 } | |
183 e.preventDefault(); | |
184 last_ts = e.ctrlKey ? +new Date() : 0; | |
185 if(data || cto) { | |
186 last_ts = (+new Date()) + 10000; | |
187 } | |
188 if(cto) { | |
189 clearTimeout(cto); | |
190 } | |
191 if(!this.is_loading(e.currentTarget)) { | |
192 this.show_contextmenu(e.currentTarget, e.pageX, e.pageY, e); | |
193 } | |
194 }, this)) | |
195 .on("click.jstree", ".jstree-anchor", $.proxy(function (e) { | |
196 if(this._data.contextmenu.visible && (!last_ts || (+new Date()) - last_ts > 250)) { // work around safari & macOS ctrl+click | |
197 $.vakata.context.hide(); | |
198 } | |
199 last_ts = 0; | |
200 }, this)) | |
201 .on("touchstart.jstree", ".jstree-anchor", function (e) { | |
202 if(!e.originalEvent || !e.originalEvent.changedTouches || !e.originalEvent.changedTouches[0]) { | |
203 return; | |
204 } | |
205 ex = e.originalEvent.changedTouches[0].clientX; | |
206 ey = e.originalEvent.changedTouches[0].clientY; | |
207 cto = setTimeout(function () { | |
208 $(e.currentTarget).trigger('contextmenu', true); | |
209 }, 750); | |
210 }) | |
211 .on('touchmove.vakata.jstree', function (e) { | |
212 if(cto && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0] && (Math.abs(ex - e.originalEvent.changedTouches[0].clientX) > 10 || Math.abs(ey - e.originalEvent.changedTouches[0].clientY) > 10)) { | |
213 clearTimeout(cto); | |
214 $.vakata.context.hide(); | |
215 } | |
216 }) | |
217 .on('touchend.vakata.jstree', function (e) { | |
218 if(cto) { | |
219 clearTimeout(cto); | |
220 } | |
221 }); | |
222 | |
223 /*! | |
224 if(!('oncontextmenu' in document.body) && ('ontouchstart' in document.body)) { | |
225 var el = null, tm = null; | |
226 this.element | |
227 .on("touchstart", ".jstree-anchor", function (e) { | |
228 el = e.currentTarget; | |
229 tm = +new Date(); | |
230 $(document).one("touchend", function (e) { | |
231 e.target = document.elementFromPoint(e.originalEvent.targetTouches[0].pageX - window.pageXOffset, e.originalEvent.targetTouches[0].pageY - window.pageYOffset); | |
232 e.currentTarget = e.target; | |
233 tm = ((+(new Date())) - tm); | |
234 if(e.target === el && tm > 600 && tm < 1000) { | |
235 e.preventDefault(); | |
236 $(el).trigger('contextmenu', e); | |
237 } | |
238 el = null; | |
239 tm = null; | |
240 }); | |
241 }); | |
242 } | |
243 */ | |
244 $(document).on("context_hide.vakata.jstree", $.proxy(function (e, data) { | |
245 this._data.contextmenu.visible = false; | |
246 $(data.reference).removeClass('jstree-context'); | |
247 }, this)); | |
248 }; | |
249 this.teardown = function () { | |
250 if(this._data.contextmenu.visible) { | |
251 $.vakata.context.hide(); | |
252 } | |
253 parent.teardown.call(this); | |
254 }; | |
255 | |
256 /** | |
257 * prepare and show the context menu for a node | |
258 * @name show_contextmenu(obj [, x, y]) | |
259 * @param {mixed} obj the node | |
260 * @param {Number} x the x-coordinate relative to the document to show the menu at | |
261 * @param {Number} y the y-coordinate relative to the document to show the menu at | |
262 * @param {Object} e the event if available that triggered the contextmenu | |
263 * @plugin contextmenu | |
264 * @trigger show_contextmenu.jstree | |
265 */ | |
266 this.show_contextmenu = function (obj, x, y, e) { | |
267 obj = this.get_node(obj); | |
268 if(!obj || obj.id === $.jstree.root) { return false; } | |
269 var s = this.settings.contextmenu, | |
270 d = this.get_node(obj, true), | |
271 a = d.children(".jstree-anchor"), | |
272 o = false, | |
273 i = false; | |
274 if(s.show_at_node || x === undefined || y === undefined) { | |
275 o = a.offset(); | |
276 x = o.left; | |
277 y = o.top + this._data.core.li_height; | |
278 } | |
279 if(this.settings.contextmenu.select_node && !this.is_selected(obj)) { | |
280 this.activate_node(obj, e); | |
281 } | |
282 | |
283 i = s.items; | |
284 if($.isFunction(i)) { | |
285 i = i.call(this, obj, $.proxy(function (i) { | |
286 this._show_contextmenu(obj, x, y, i); | |
287 }, this)); | |
288 } | |
289 if($.isPlainObject(i)) { | |
290 this._show_contextmenu(obj, x, y, i); | |
291 } | |
292 }; | |
293 /** | |
294 * show the prepared context menu for a node | |
295 * @name _show_contextmenu(obj, x, y, i) | |
296 * @param {mixed} obj the node | |
297 * @param {Number} x the x-coordinate relative to the document to show the menu at | |
298 * @param {Number} y the y-coordinate relative to the document to show the menu at | |
299 * @param {Number} i the object of items to show | |
300 * @plugin contextmenu | |
301 * @trigger show_contextmenu.jstree | |
302 * @private | |
303 */ | |
304 this._show_contextmenu = function (obj, x, y, i) { | |
305 var d = this.get_node(obj, true), | |
306 a = d.children(".jstree-anchor"); | |
307 $(document).one("context_show.vakata.jstree", $.proxy(function (e, data) { | |
308 var cls = 'jstree-contextmenu jstree-' + this.get_theme() + '-contextmenu'; | |
309 $(data.element).addClass(cls); | |
310 a.addClass('jstree-context'); | |
311 }, this)); | |
312 this._data.contextmenu.visible = true; | |
313 $.vakata.context.show(a, { 'x' : x, 'y' : y }, i); | |
314 /** | |
315 * triggered when the contextmenu is shown for a node | |
316 * @event | |
317 * @name show_contextmenu.jstree | |
318 * @param {Object} node the node | |
319 * @param {Number} x the x-coordinate of the menu relative to the document | |
320 * @param {Number} y the y-coordinate of the menu relative to the document | |
321 * @plugin contextmenu | |
322 */ | |
323 this.trigger('show_contextmenu', { "node" : obj, "x" : x, "y" : y }); | |
324 }; | |
325 }; | |
326 | |
327 // contextmenu helper | |
328 (function ($) { | |
329 var right_to_left = false, | |
330 vakata_context = { | |
331 element : false, | |
332 reference : false, | |
333 position_x : 0, | |
334 position_y : 0, | |
335 items : [], | |
336 html : "", | |
337 is_visible : false | |
338 }; | |
339 | |
340 $.vakata.context = { | |
341 settings : { | |
342 hide_onmouseleave : 0, | |
343 icons : true | |
344 }, | |
345 _trigger : function (event_name) { | |
346 $(document).triggerHandler("context_" + event_name + ".vakata", { | |
347 "reference" : vakata_context.reference, | |
348 "element" : vakata_context.element, | |
349 "position" : { | |
350 "x" : vakata_context.position_x, | |
351 "y" : vakata_context.position_y | |
352 } | |
353 }); | |
354 }, | |
355 _execute : function (i) { | |
356 i = vakata_context.items[i]; | |
357 return i && (!i._disabled || ($.isFunction(i._disabled) && !i._disabled({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }))) && i.action ? i.action.call(null, { | |
358 "item" : i, | |
359 "reference" : vakata_context.reference, | |
360 "element" : vakata_context.element, | |
361 "position" : { | |
362 "x" : vakata_context.position_x, | |
363 "y" : vakata_context.position_y | |
364 } | |
365 }) : false; | |
366 }, | |
367 _parse : function (o, is_callback) { | |
368 if(!o) { return false; } | |
369 if(!is_callback) { | |
370 vakata_context.html = ""; | |
371 vakata_context.items = []; | |
372 } | |
373 var str = "", | |
374 sep = false, | |
375 tmp; | |
376 | |
377 if(is_callback) { str += "<"+"ul>"; } | |
378 $.each(o, function (i, val) { | |
379 if(!val) { return true; } | |
380 vakata_context.items.push(val); | |
381 if(!sep && val.separator_before) { | |
382 str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + "> <"+"/a><"+"/li>"; | |
383 } | |
384 sep = false; | |
385 str += "<"+"li class='" + (val._class || "") + (val._disabled === true || ($.isFunction(val._disabled) && val._disabled({ "item" : val, "reference" : vakata_context.reference, "element" : vakata_context.element })) ? " vakata-contextmenu-disabled " : "") + "' "+(val.shortcut?" data-shortcut='"+val.shortcut+"' ":'')+">"; | |
386 str += "<"+"a href='#' rel='" + (vakata_context.items.length - 1) + "' " + (val.title ? "title='" + val.title + "'" : "") + ">"; | |
387 if($.vakata.context.settings.icons) { | |
388 str += "<"+"i "; | |
389 if(val.icon) { | |
390 if(val.icon.indexOf("/") !== -1 || val.icon.indexOf(".") !== -1) { str += " style='background:url(\"" + val.icon + "\") center center no-repeat' "; } | |
391 else { str += " class='" + val.icon + "' "; } | |
392 } | |
393 str += "><"+"/i><"+"span class='vakata-contextmenu-sep'> <"+"/span>"; | |
394 } | |
395 str += ($.isFunction(val.label) ? val.label({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }) : val.label) + (val.shortcut?' <span class="vakata-contextmenu-shortcut vakata-contextmenu-shortcut-'+val.shortcut+'">'+ (val.shortcut_label || '') +'</span>':'') + "<"+"/a>"; | |
396 if(val.submenu) { | |
397 tmp = $.vakata.context._parse(val.submenu, true); | |
398 if(tmp) { str += tmp; } | |
399 } | |
400 str += "<"+"/li>"; | |
401 if(val.separator_after) { | |
402 str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + "> <"+"/a><"+"/li>"; | |
403 sep = true; | |
404 } | |
405 }); | |
406 str = str.replace(/<li class\='vakata-context-separator'\><\/li\>$/,""); | |
407 if(is_callback) { str += "</ul>"; } | |
408 /** | |
409 * triggered on the document when the contextmenu is parsed (HTML is built) | |
410 * @event | |
411 * @plugin contextmenu | |
412 * @name context_parse.vakata | |
413 * @param {jQuery} reference the element that was right clicked | |
414 * @param {jQuery} element the DOM element of the menu itself | |
415 * @param {Object} position the x & y coordinates of the menu | |
416 */ | |
417 if(!is_callback) { vakata_context.html = str; $.vakata.context._trigger("parse"); } | |
418 return str.length > 10 ? str : false; | |
419 }, | |
420 _show_submenu : function (o) { | |
421 o = $(o); | |
422 if(!o.length || !o.children("ul").length) { return; } | |
423 var e = o.children("ul"), | |
424 xl = o.offset().left, | |
425 x = xl + o.outerWidth(), | |
426 y = o.offset().top, | |
427 w = e.width(), | |
428 h = e.height(), | |
429 dw = $(window).width() + $(window).scrollLeft(), | |
430 dh = $(window).height() + $(window).scrollTop(); | |
431 // може да се спести е една проверка - дали няма някой от класовете вече нагоре | |
432 if(right_to_left) { | |
433 o[x - (w + 10 + o.outerWidth()) < 0 ? "addClass" : "removeClass"]("vakata-context-left"); | |
434 } | |
435 else { | |
436 o[x + w > dw && xl > dw - x ? "addClass" : "removeClass"]("vakata-context-right"); | |
437 } | |
438 if(y + h + 10 > dh) { | |
439 e.css("bottom","-1px"); | |
440 } | |
441 | |
442 //if does not fit - stick it to the side | |
443 if (o.hasClass('vakata-context-right')) { | |
444 if (xl < w) { | |
445 e.css("margin-right", xl - w); | |
446 } | |
447 } else { | |
448 if (dw - x < w) { | |
449 e.css("margin-left", dw - x - w); | |
450 } | |
451 } | |
452 | |
453 e.show(); | |
454 }, | |
455 show : function (reference, position, data) { | |
456 var o, e, x, y, w, h, dw, dh, cond = true; | |
457 if(vakata_context.element && vakata_context.element.length) { | |
458 vakata_context.element.width(''); | |
459 } | |
460 switch(cond) { | |
461 case (!position && !reference): | |
462 return false; | |
463 case (!!position && !!reference): | |
464 vakata_context.reference = reference; | |
465 vakata_context.position_x = position.x; | |
466 vakata_context.position_y = position.y; | |
467 break; | |
468 case (!position && !!reference): | |
469 vakata_context.reference = reference; | |
470 o = reference.offset(); | |
471 vakata_context.position_x = o.left + reference.outerHeight(); | |
472 vakata_context.position_y = o.top; | |
473 break; | |
474 case (!!position && !reference): | |
475 vakata_context.position_x = position.x; | |
476 vakata_context.position_y = position.y; | |
477 break; | |
478 } | |
479 if(!!reference && !data && $(reference).data('vakata_contextmenu')) { | |
480 data = $(reference).data('vakata_contextmenu'); | |
481 } | |
482 if($.vakata.context._parse(data)) { | |
483 vakata_context.element.html(vakata_context.html); | |
484 } | |
485 if(vakata_context.items.length) { | |
486 vakata_context.element.appendTo("body"); | |
487 e = vakata_context.element; | |
488 x = vakata_context.position_x; | |
489 y = vakata_context.position_y; | |
490 w = e.width(); | |
491 h = e.height(); | |
492 dw = $(window).width() + $(window).scrollLeft(); | |
493 dh = $(window).height() + $(window).scrollTop(); | |
494 if(right_to_left) { | |
495 x -= (e.outerWidth() - $(reference).outerWidth()); | |
496 if(x < $(window).scrollLeft() + 20) { | |
497 x = $(window).scrollLeft() + 20; | |
498 } | |
499 } | |
500 if(x + w + 20 > dw) { | |
501 x = dw - (w + 20); | |
502 } | |
503 if(y + h + 20 > dh) { | |
504 y = dh - (h + 20); | |
505 } | |
506 | |
507 vakata_context.element | |
508 .css({ "left" : x, "top" : y }) | |
509 .show() | |
510 .find('a').first().focus().parent().addClass("vakata-context-hover"); | |
511 vakata_context.is_visible = true; | |
512 /** | |
513 * triggered on the document when the contextmenu is shown | |
514 * @event | |
515 * @plugin contextmenu | |
516 * @name context_show.vakata | |
517 * @param {jQuery} reference the element that was right clicked | |
518 * @param {jQuery} element the DOM element of the menu itself | |
519 * @param {Object} position the x & y coordinates of the menu | |
520 */ | |
521 $.vakata.context._trigger("show"); | |
522 } | |
523 }, | |
524 hide : function () { | |
525 if(vakata_context.is_visible) { | |
526 vakata_context.element.hide().find("ul").hide().end().find(':focus').blur().end().detach(); | |
527 vakata_context.is_visible = false; | |
528 /** | |
529 * triggered on the document when the contextmenu is hidden | |
530 * @event | |
531 * @plugin contextmenu | |
532 * @name context_hide.vakata | |
533 * @param {jQuery} reference the element that was right clicked | |
534 * @param {jQuery} element the DOM element of the menu itself | |
535 * @param {Object} position the x & y coordinates of the menu | |
536 */ | |
537 $.vakata.context._trigger("hide"); | |
538 } | |
539 } | |
540 }; | |
541 $(function () { | |
542 right_to_left = $("body").css("direction") === "rtl"; | |
543 var to = false; | |
544 | |
545 vakata_context.element = $("<ul class='vakata-context'></ul>"); | |
546 vakata_context.element | |
547 .on("mouseenter", "li", function (e) { | |
548 e.stopImmediatePropagation(); | |
549 | |
550 if($.contains(this, e.relatedTarget)) { | |
551 // премахнато заради delegate mouseleave по-долу | |
552 // $(this).find(".vakata-context-hover").removeClass("vakata-context-hover"); | |
553 return; | |
554 } | |
555 | |
556 if(to) { clearTimeout(to); } | |
557 vakata_context.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(); | |
558 | |
559 $(this) | |
560 .siblings().find("ul").hide().end().end() | |
561 .parentsUntil(".vakata-context", "li").addBack().addClass("vakata-context-hover"); | |
562 $.vakata.context._show_submenu(this); | |
563 }) | |
564 // тестово - дали не натоварва? | |
565 .on("mouseleave", "li", function (e) { | |
566 if($.contains(this, e.relatedTarget)) { return; } | |
567 $(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover"); | |
568 }) | |
569 .on("mouseleave", function (e) { | |
570 $(this).find(".vakata-context-hover").removeClass("vakata-context-hover"); | |
571 if($.vakata.context.settings.hide_onmouseleave) { | |
572 to = setTimeout( | |
573 (function (t) { | |
574 return function () { $.vakata.context.hide(); }; | |
575 }(this)), $.vakata.context.settings.hide_onmouseleave); | |
576 } | |
577 }) | |
578 .on("click", "a", function (e) { | |
579 e.preventDefault(); | |
580 //}) | |
581 //.on("mouseup", "a", function (e) { | |
582 if(!$(this).blur().parent().hasClass("vakata-context-disabled") && $.vakata.context._execute($(this).attr("rel")) !== false) { | |
583 $.vakata.context.hide(); | |
584 } | |
585 }) | |
586 .on('keydown', 'a', function (e) { | |
587 var o = null; | |
588 switch(e.which) { | |
589 case 13: | |
590 case 32: | |
591 e.type = "click"; | |
592 e.preventDefault(); | |
593 $(e.currentTarget).trigger(e); | |
594 break; | |
595 case 37: | |
596 if(vakata_context.is_visible) { | |
597 vakata_context.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children('a').focus(); | |
598 e.stopImmediatePropagation(); | |
599 e.preventDefault(); | |
600 } | |
601 break; | |
602 case 38: | |
603 if(vakata_context.is_visible) { | |
604 o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first(); | |
605 if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last(); } | |
606 o.addClass("vakata-context-hover").children('a').focus(); | |
607 e.stopImmediatePropagation(); | |
608 e.preventDefault(); | |
609 } | |
610 break; | |
611 case 39: | |
612 if(vakata_context.is_visible) { | |
613 vakata_context.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children('a').focus(); | |
614 e.stopImmediatePropagation(); | |
615 e.preventDefault(); | |
616 } | |
617 break; | |
618 case 40: | |
619 if(vakata_context.is_visible) { | |
620 o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first(); | |
621 if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first(); } | |
622 o.addClass("vakata-context-hover").children('a').focus(); | |
623 e.stopImmediatePropagation(); | |
624 e.preventDefault(); | |
625 } | |
626 break; | |
627 case 27: | |
628 $.vakata.context.hide(); | |
629 e.preventDefault(); | |
630 break; | |
631 default: | |
632 //console.log(e.which); | |
633 break; | |
634 } | |
635 }) | |
636 .on('keydown', function (e) { | |
637 e.preventDefault(); | |
638 var a = vakata_context.element.find('.vakata-contextmenu-shortcut-' + e.which).parent(); | |
639 if(a.parent().not('.vakata-context-disabled')) { | |
640 a.click(); | |
641 } | |
642 }); | |
643 | |
644 $(document) | |
645 .on("mousedown.vakata.jstree", function (e) { | |
646 if(vakata_context.is_visible && vakata_context.element[0] !== e.target && !$.contains(vakata_context.element[0], e.target)) { | |
647 $.vakata.context.hide(); | |
648 } | |
649 }) | |
650 .on("context_show.vakata.jstree", function (e, data) { | |
651 vakata_context.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"); | |
652 if(right_to_left) { | |
653 vakata_context.element.addClass("vakata-context-rtl").css("direction", "rtl"); | |
654 } | |
655 // also apply a RTL class? | |
656 vakata_context.element.find("ul").hide().end(); | |
657 }); | |
658 }); | |
659 }($)); | |
660 // $.jstree.defaults.plugins.push("contextmenu"); | |
661 })); |