%PDF- %PDF-
Direktori : /home/tjamichg/intranet.tjamich.gob.mx/intranet/common/vendors/jstree/src/ |
Current File : /home/tjamichg/intranet.tjamich.gob.mx/intranet/common/vendors/jstree/src/jstree.dnd.js |
/** * ### Drag'n'drop plugin * * Enables dragging and dropping of nodes in the tree, resulting in a move or copy operations. */ /*globals jQuery, define, exports, require, document */ (function (factory) { "use strict"; if (typeof define === 'function' && define.amd) { define('jstree.dnd', ['jquery','jstree'], factory); } else if(typeof exports === 'object') { factory(require('jquery'), require('jstree')); } else { factory(jQuery, jQuery.jstree); } }(function ($, jstree, undefined) { "use strict"; if($.jstree.plugins.dnd) { return; } /** * stores all defaults for the drag'n'drop plugin * @name $.jstree.defaults.dnd * @plugin dnd */ $.jstree.defaults.dnd = { /** * a boolean indicating if a copy should be possible while dragging (by pressint the meta key or Ctrl). Defaults to `true`. * @name $.jstree.defaults.dnd.copy * @plugin dnd */ copy : true, /** * a number indicating how long a node should remain hovered while dragging to be opened. Defaults to `500`. * @name $.jstree.defaults.dnd.open_timeout * @plugin dnd */ open_timeout : 500, /** * a function invoked each time a node is about to be dragged, invoked in the tree's scope and receives the nodes about to be dragged as an argument (array) - return `false` to prevent dragging * @name $.jstree.defaults.dnd.is_draggable * @plugin dnd */ is_draggable : true, /** * a boolean indicating if checks should constantly be made while the user is dragging the node (as opposed to checking only on drop), default is `true` * @name $.jstree.defaults.dnd.check_while_dragging * @plugin dnd */ check_while_dragging : true, /** * a boolean indicating if nodes from this tree should only be copied with dnd (as opposed to moved), default is `false` * @name $.jstree.defaults.dnd.always_copy * @plugin dnd */ always_copy : false }; // TODO: now check works by checking for each node individually, how about max_children, unique, etc? // TODO: drop somewhere else - maybe demo only? $.jstree.plugins.dnd = function (options, parent) { this.bind = function () { parent.bind.call(this); this.element .on('mousedown.jstree touchstart.jstree', '.jstree-anchor', $.proxy(function (e) { var obj = this.get_node(e.target), mlt = this.is_selected(obj) ? this.get_selected().length : 1; if(obj && obj.id && obj.id !== "#" && (e.which === 1 || e.type === "touchstart") && (this.settings.dnd.is_draggable === true || ($.isFunction(this.settings.dnd.is_draggable) && this.settings.dnd.is_draggable.call(this, (mlt > 1 ? this.get_selected(true) : [obj])))) ) { this.element.trigger('mousedown.jstree'); return $.vakata.dnd.start(e, { 'jstree' : true, 'origin' : this, 'obj' : this.get_node(obj,true), 'nodes' : mlt > 1 ? this.get_selected() : [obj.id] }, '<div id="jstree-dnd" class="jstree-' + this.get_theme() + '"><i class="jstree-icon jstree-er"></i>' + (mlt > 1 ? mlt + ' ' + this.get_string('nodes') : this.get_text(e.currentTarget, true)) + '<ins class="jstree-copy" style="display:none;">+</ins></div>'); } }, this)); }; }; $(function() { // bind only once for all instances var lastmv = false, laster = false, opento = false, marker = $('<div id="jstree-marker"> </div>').hide().appendTo('body'); $(document) .bind('dnd_start.vakata', function (e, data) { lastmv = false; }) .bind('dnd_move.vakata', function (e, data) { if(opento) { clearTimeout(opento); } if(!data.data.jstree) { return; } // if we are hovering the marker image do nothing (can happen on "inside" drags) if(data.event.target.id && data.event.target.id === 'jstree-marker') { return; } var ins = $.jstree.reference(data.event.target), ref = false, off = false, rel = false, l, t, h, p, i, o, ok, t1, t2, op, ps, pr; // if we are over an instance if(ins && ins._data && ins._data.dnd) { marker.attr('class', 'jstree-' + ins.get_theme()); data.helper .children().attr('class', 'jstree-' + ins.get_theme()) .find('.jstree-copy:eq(0)')[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'show' : 'hide' ](); // if are hovering the container itself add a new root node if( (data.event.target === ins.element[0] || data.event.target === ins.get_container_ul()[0]) && ins.get_container_ul().children().length === 0) { ok = true; for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) { ok = ok && ins.check( (data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey)) ) ? "copy_node" : "move_node"), (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), '#', 'last', { 'dnd' : true, 'ref' : ins.get_node('#'), 'pos' : 'i', 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }); if(!ok) { break; } } if(ok) { lastmv = { 'ins' : ins, 'par' : '#', 'pos' : 'last' }; marker.hide(); data.helper.find('.jstree-icon:eq(0)').removeClass('jstree-er').addClass('jstree-ok'); return; } } else { // if we are hovering a tree node ref = $(data.event.target).closest('.jstree-anchor'); if(ref && ref.length && ref.parent().is('.jstree-closed, .jstree-open, .jstree-leaf')) { off = ref.offset(); rel = data.event.pageY - off.top; h = ref.height(); if(rel < h / 3) { o = ['b', 'i', 'a']; } else if(rel > h - h / 3) { o = ['a', 'i', 'b']; } else { o = rel > h / 2 ? ['i', 'a', 'b'] : ['i', 'b', 'a']; } $.each(o, function (j, v) { switch(v) { case 'b': l = off.left - 6; t = off.top - 5; p = ins.get_parent(ref); i = ref.parent().index(); break; case 'i': l = off.left - 2; t = off.top - 5 + h / 2 + 1; p = ins.get_node(ref.parent()).id; i = 0; break; case 'a': l = off.left - 6; t = off.top - 5 + h; p = ins.get_parent(ref); i = ref.parent().index() + 1; break; } /*! // TODO: moving inside, but the node is not yet loaded? // the check will work anyway, as when moving the node will be loaded first and checked again if(v === 'i' && !ins.is_loaded(p)) { } */ ok = true; for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) { op = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? "copy_node" : "move_node"; ps = i; if(op === "move_node" && v === 'a' && (data.data.origin && data.data.origin === ins) && p === ins.get_parent(data.data.nodes[t1])) { pr = ins.get_node(p); if(ps > $.inArray(data.data.nodes[t1], pr.children)) { ps -= 1; } } ok = ok && ( (ins && ins.settings && ins.settings.dnd && ins.settings.dnd.check_while_dragging === false) || ins.check(op, (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), p, ps, { 'dnd' : true, 'ref' : ins.get_node(ref.parent()), 'pos' : v, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }) ); if(!ok) { if(ins && ins.last_error) { laster = ins.last_error(); } break; } } if(ok) { if(v === 'i' && ref.parent().is('.jstree-closed') && ins.settings.dnd.open_timeout) { opento = setTimeout((function (x, z) { return function () { x.open_node(z); }; }(ins, ref)), ins.settings.dnd.open_timeout); } lastmv = { 'ins' : ins, 'par' : p, 'pos' : i }; marker.css({ 'left' : l + 'px', 'top' : t + 'px' }).show(); data.helper.find('.jstree-icon:eq(0)').removeClass('jstree-er').addClass('jstree-ok'); laster = {}; o = true; return false; } }); if(o === true) { return; } } } } lastmv = false; data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er'); marker.hide(); }) .bind('dnd_scroll.vakata', function (e, data) { if(!data.data.jstree) { return; } marker.hide(); lastmv = false; data.helper.find('.jstree-icon:eq(0)').removeClass('jstree-ok').addClass('jstree-er'); }) .bind('dnd_stop.vakata', function (e, data) { if(opento) { clearTimeout(opento); } if(!data.data.jstree) { return; } marker.hide(); var i, j, nodes = []; if(lastmv) { for(i = 0, j = data.data.nodes.length; i < j; i++) { nodes[i] = data.data.origin ? data.data.origin.get_node(data.data.nodes[i]) : data.data.nodes[i]; if(data.data.origin) { nodes[i].instance = data.data.origin; } } lastmv.ins[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'copy_node' : 'move_node' ](nodes, lastmv.par, lastmv.pos); } else { i = $(data.event.target).closest('.jstree'); if(i.length && laster && laster.error && laster.error === 'check') { i = i.jstree(true); if(i) { i.settings.core.error.call(this, laster); } } } }) .bind('keyup keydown', function (e, data) { data = $.vakata.dnd._get(); if(data.data && data.data.jstree) { data.helper.find('.jstree-copy:eq(0)')[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (e.metaKey || e.ctrlKey))) ? 'show' : 'hide' ](); } }); }); // helpers (function ($) { // private variable var vakata_dnd = { element : false, is_down : false, is_drag : false, helper : false, helper_w: 0, data : false, init_x : 0, init_y : 0, scroll_l: 0, scroll_t: 0, scroll_e: false, scroll_i: false }; $.vakata.dnd = { settings : { scroll_speed : 10, scroll_proximity : 20, helper_left : 5, helper_top : 10, threshold : 5 }, _trigger : function (event_name, e) { var data = $.vakata.dnd._get(); data.event = e; $(document).triggerHandler("dnd_" + event_name + ".vakata", data); }, _get : function () { return { "data" : vakata_dnd.data, "element" : vakata_dnd.element, "helper" : vakata_dnd.helper }; }, _clean : function () { if(vakata_dnd.helper) { vakata_dnd.helper.remove(); } if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; } vakata_dnd = { element : false, is_down : false, is_drag : false, helper : false, helper_w: 0, data : false, init_x : 0, init_y : 0, scroll_l: 0, scroll_t: 0, scroll_e: false, scroll_i: false }; $(document).off("mousemove touchmove", $.vakata.dnd.drag); $(document).off("mouseup touchend", $.vakata.dnd.stop); }, _scroll : function (init_only) { if(!vakata_dnd.scroll_e || (!vakata_dnd.scroll_l && !vakata_dnd.scroll_t)) { if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; } return false; } if(!vakata_dnd.scroll_i) { vakata_dnd.scroll_i = setInterval($.vakata.dnd._scroll, 100); return false; } if(init_only === true) { return false; } var i = vakata_dnd.scroll_e.scrollTop(), j = vakata_dnd.scroll_e.scrollLeft(); vakata_dnd.scroll_e.scrollTop(i + vakata_dnd.scroll_t * $.vakata.dnd.settings.scroll_speed); vakata_dnd.scroll_e.scrollLeft(j + vakata_dnd.scroll_l * $.vakata.dnd.settings.scroll_speed); if(i !== vakata_dnd.scroll_e.scrollTop() || j !== vakata_dnd.scroll_e.scrollLeft()) { /** * triggered on the document when a drag causes an element to scroll * @event * @plugin dnd * @name dnd_scroll.vakata * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start * @param {DOM} element the DOM element being dragged * @param {jQuery} helper the helper shown next to the mouse * @param {jQuery} event the element that is scrolling */ $.vakata.dnd._trigger("scroll", vakata_dnd.scroll_e); } }, start : function (e, data, html) { if(e.type === "touchstart" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { e.pageX = e.originalEvent.changedTouches[0].pageX; e.pageY = e.originalEvent.changedTouches[0].pageY; e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); } if(vakata_dnd.is_drag) { $.vakata.dnd.stop({}); } try { e.currentTarget.unselectable = "on"; e.currentTarget.onselectstart = function() { return false; }; if(e.currentTarget.style) { e.currentTarget.style.MozUserSelect = "none"; } } catch(ignore) { } vakata_dnd.init_x = e.pageX; vakata_dnd.init_y = e.pageY; vakata_dnd.data = data; vakata_dnd.is_down = true; vakata_dnd.element = e.currentTarget; if(html !== false) { vakata_dnd.helper = $("<div id='vakata-dnd'></div>").html(html).css({ "display" : "block", "margin" : "0", "padding" : "0", "position" : "absolute", "top" : "-2000px", "lineHeight" : "16px", "zIndex" : "10000" }); } $(document).bind("mousemove touchmove", $.vakata.dnd.drag); $(document).bind("mouseup touchend", $.vakata.dnd.stop); return false; }, drag : function (e) { if(e.type === "touchmove" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { e.pageX = e.originalEvent.changedTouches[0].pageX; e.pageY = e.originalEvent.changedTouches[0].pageY; e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); } if(!vakata_dnd.is_down) { return; } if(!vakata_dnd.is_drag) { if( Math.abs(e.pageX - vakata_dnd.init_x) > $.vakata.dnd.settings.threshold || Math.abs(e.pageY - vakata_dnd.init_y) > $.vakata.dnd.settings.threshold ) { if(vakata_dnd.helper) { vakata_dnd.helper.appendTo("body"); vakata_dnd.helper_w = vakata_dnd.helper.outerWidth(); } vakata_dnd.is_drag = true; /** * triggered on the document when a drag starts * @event * @plugin dnd * @name dnd_start.vakata * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start * @param {DOM} element the DOM element being dragged * @param {jQuery} helper the helper shown next to the mouse * @param {Object} event the event that caused the start (probably mousemove) */ $.vakata.dnd._trigger("start", e); } else { return; } } var d = false, w = false, dh = false, wh = false, dw = false, ww = false, dt = false, dl = false, ht = false, hl = false; vakata_dnd.scroll_t = 0; vakata_dnd.scroll_l = 0; vakata_dnd.scroll_e = false; $($(e.target).parentsUntil("body").addBack().get().reverse()) .filter(function () { return (/^auto|scroll$/).test($(this).css("overflow")) && (this.scrollHeight > this.offsetHeight || this.scrollWidth > this.offsetWidth); }) .each(function () { var t = $(this), o = t.offset(); if(this.scrollHeight > this.offsetHeight) { if(o.top + t.height() - e.pageY < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; } if(e.pageY - o.top < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; } } if(this.scrollWidth > this.offsetWidth) { if(o.left + t.width() - e.pageX < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; } if(e.pageX - o.left < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; } } if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) { vakata_dnd.scroll_e = $(this); return false; } }); if(!vakata_dnd.scroll_e) { d = $(document); w = $(window); dh = d.height(); wh = w.height(); dw = d.width(); ww = w.width(); dt = d.scrollTop(); dl = d.scrollLeft(); if(dh > wh && e.pageY - dt < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; } if(dh > wh && wh - (e.pageY - dt) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; } if(dw > ww && e.pageX - dl < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; } if(dw > ww && ww - (e.pageX - dl) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; } if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) { vakata_dnd.scroll_e = d; } } if(vakata_dnd.scroll_e) { $.vakata.dnd._scroll(true); } if(vakata_dnd.helper) { ht = parseInt(e.pageY + $.vakata.dnd.settings.helper_top, 10); hl = parseInt(e.pageX + $.vakata.dnd.settings.helper_left, 10); if(dh && ht + 25 > dh) { ht = dh - 50; } if(dw && hl + vakata_dnd.helper_w > dw) { hl = dw - (vakata_dnd.helper_w + 2); } vakata_dnd.helper.css({ left : hl + "px", top : ht + "px" }); } /** * triggered on the document when a drag is in progress * @event * @plugin dnd * @name dnd_move.vakata * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start * @param {DOM} element the DOM element being dragged * @param {jQuery} helper the helper shown next to the mouse * @param {Object} event the event that caused this to trigger (most likely mousemove) */ $.vakata.dnd._trigger("move", e); }, stop : function (e) { if(e.type === "touchend" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { e.pageX = e.originalEvent.changedTouches[0].pageX; e.pageY = e.originalEvent.changedTouches[0].pageY; e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); } if(vakata_dnd.is_drag) { /** * triggered on the document when a drag stops (the dragged element is dropped) * @event * @plugin dnd * @name dnd_stop.vakata * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start * @param {DOM} element the DOM element being dragged * @param {jQuery} helper the helper shown next to the mouse * @param {Object} event the event that caused the stop */ $.vakata.dnd._trigger("stop", e); } $.vakata.dnd._clean(); } }; }(jQuery)); // include the dnd plugin by default // $.jstree.defaults.plugins.push("dnd"); }));