Mercurial > repos > mingchen0919 > aurora_star
comparison vakata-jstree-3.3.5/src/jstree.dnd.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 * ### Drag'n'drop plugin | |
3 * | |
4 * Enables dragging and dropping of nodes in the tree, resulting in a move or copy operations. | |
5 */ | |
6 /*globals jQuery, define, exports, require, document */ | |
7 (function (factory) { | |
8 "use strict"; | |
9 if (typeof define === 'function' && define.amd) { | |
10 define('jstree.dnd', ['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.dnd) { return; } | |
22 | |
23 /** | |
24 * stores all defaults for the drag'n'drop plugin | |
25 * @name $.jstree.defaults.dnd | |
26 * @plugin dnd | |
27 */ | |
28 $.jstree.defaults.dnd = { | |
29 /** | |
30 * a boolean indicating if a copy should be possible while dragging (by pressint the meta key or Ctrl). Defaults to `true`. | |
31 * @name $.jstree.defaults.dnd.copy | |
32 * @plugin dnd | |
33 */ | |
34 copy : true, | |
35 /** | |
36 * a number indicating how long a node should remain hovered while dragging to be opened. Defaults to `500`. | |
37 * @name $.jstree.defaults.dnd.open_timeout | |
38 * @plugin dnd | |
39 */ | |
40 open_timeout : 500, | |
41 /** | |
42 * 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) and the event that started the drag - return `false` to prevent dragging | |
43 * @name $.jstree.defaults.dnd.is_draggable | |
44 * @plugin dnd | |
45 */ | |
46 is_draggable : true, | |
47 /** | |
48 * 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` | |
49 * @name $.jstree.defaults.dnd.check_while_dragging | |
50 * @plugin dnd | |
51 */ | |
52 check_while_dragging : true, | |
53 /** | |
54 * a boolean indicating if nodes from this tree should only be copied with dnd (as opposed to moved), default is `false` | |
55 * @name $.jstree.defaults.dnd.always_copy | |
56 * @plugin dnd | |
57 */ | |
58 always_copy : false, | |
59 /** | |
60 * when dropping a node "inside", this setting indicates the position the node should go to - it can be an integer or a string: "first" (same as 0) or "last", default is `0` | |
61 * @name $.jstree.defaults.dnd.inside_pos | |
62 * @plugin dnd | |
63 */ | |
64 inside_pos : 0, | |
65 /** | |
66 * when starting the drag on a node that is selected this setting controls if all selected nodes are dragged or only the single node, default is `true`, which means all selected nodes are dragged when the drag is started on a selected node | |
67 * @name $.jstree.defaults.dnd.drag_selection | |
68 * @plugin dnd | |
69 */ | |
70 drag_selection : true, | |
71 /** | |
72 * controls whether dnd works on touch devices. If left as boolean true dnd will work the same as in desktop browsers, which in some cases may impair scrolling. If set to boolean false dnd will not work on touch devices. There is a special third option - string "selected" which means only selected nodes can be dragged on touch devices. | |
73 * @name $.jstree.defaults.dnd.touch | |
74 * @plugin dnd | |
75 */ | |
76 touch : true, | |
77 /** | |
78 * controls whether items can be dropped anywhere on the node, not just on the anchor, by default only the node anchor is a valid drop target. Works best with the wholerow plugin. If enabled on mobile depending on the interface it might be hard for the user to cancel the drop, since the whole tree container will be a valid drop target. | |
79 * @name $.jstree.defaults.dnd.large_drop_target | |
80 * @plugin dnd | |
81 */ | |
82 large_drop_target : false, | |
83 /** | |
84 * controls whether a drag can be initiated from any part of the node and not just the text/icon part, works best with the wholerow plugin. Keep in mind it can cause problems with tree scrolling on mobile depending on the interface - in that case set the touch option to "selected". | |
85 * @name $.jstree.defaults.dnd.large_drag_target | |
86 * @plugin dnd | |
87 */ | |
88 large_drag_target : false, | |
89 /** | |
90 * controls whether use HTML5 dnd api instead of classical. That will allow better integration of dnd events with other HTML5 controls. | |
91 * @reference http://caniuse.com/#feat=dragndrop | |
92 * @name $.jstree.defaults.dnd.use_html5 | |
93 * @plugin dnd | |
94 */ | |
95 use_html5: false | |
96 }; | |
97 var drg, elm; | |
98 // TODO: now check works by checking for each node individually, how about max_children, unique, etc? | |
99 $.jstree.plugins.dnd = function (options, parent) { | |
100 this.init = function (el, options) { | |
101 parent.init.call(this, el, options); | |
102 this.settings.dnd.use_html5 = this.settings.dnd.use_html5 && ('draggable' in document.createElement('span')); | |
103 }; | |
104 this.bind = function () { | |
105 parent.bind.call(this); | |
106 | |
107 this.element | |
108 .on(this.settings.dnd.use_html5 ? 'dragstart.jstree' : 'mousedown.jstree touchstart.jstree', this.settings.dnd.large_drag_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) { | |
109 if(this.settings.dnd.large_drag_target && $(e.target).closest('.jstree-node')[0] !== e.currentTarget) { | |
110 return true; | |
111 } | |
112 if(e.type === "touchstart" && (!this.settings.dnd.touch || (this.settings.dnd.touch === 'selected' && !$(e.currentTarget).closest('.jstree-node').children('.jstree-anchor').hasClass('jstree-clicked')))) { | |
113 return true; | |
114 } | |
115 var obj = this.get_node(e.target), | |
116 mlt = this.is_selected(obj) && this.settings.dnd.drag_selection ? this.get_top_selected().length : 1, | |
117 txt = (mlt > 1 ? mlt + ' ' + this.get_string('nodes') : this.get_text(e.currentTarget)); | |
118 if(this.settings.core.force_text) { | |
119 txt = $.vakata.html.escape(txt); | |
120 } | |
121 if(obj && obj.id && obj.id !== $.jstree.root && (e.which === 1 || e.type === "touchstart" || e.type === "dragstart") && | |
122 (this.settings.dnd.is_draggable === true || ($.isFunction(this.settings.dnd.is_draggable) && this.settings.dnd.is_draggable.call(this, (mlt > 1 ? this.get_top_selected(true) : [obj]), e))) | |
123 ) { | |
124 drg = { 'jstree' : true, 'origin' : this, 'obj' : this.get_node(obj,true), 'nodes' : mlt > 1 ? this.get_top_selected() : [obj.id] }; | |
125 elm = e.currentTarget; | |
126 if (this.settings.dnd.use_html5) { | |
127 $.vakata.dnd._trigger('start', e, { 'helper': $(), 'element': elm, 'data': drg }); | |
128 } else { | |
129 this.element.trigger('mousedown.jstree'); | |
130 return $.vakata.dnd.start(e, drg, '<div id="jstree-dnd" class="jstree-' + this.get_theme() + ' jstree-' + this.get_theme() + '-' + this.get_theme_variant() + ' ' + ( this.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ) + '"><i class="jstree-icon jstree-er"></i>' + txt + '<ins class="jstree-copy" style="display:none;">+</ins></div>'); | |
131 } | |
132 } | |
133 }, this)); | |
134 if (this.settings.dnd.use_html5) { | |
135 this.element | |
136 .on('dragover.jstree', function (e) { | |
137 e.preventDefault(); | |
138 $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); | |
139 return false; | |
140 }) | |
141 //.on('dragenter.jstree', this.settings.dnd.large_drop_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) { | |
142 // e.preventDefault(); | |
143 // $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); | |
144 // return false; | |
145 // }, this)) | |
146 .on('drop.jstree', $.proxy(function (e) { | |
147 e.preventDefault(); | |
148 $.vakata.dnd._trigger('stop', e, { 'helper': $(), 'element': elm, 'data': drg }); | |
149 return false; | |
150 }, this)); | |
151 } | |
152 }; | |
153 this.redraw_node = function(obj, deep, callback, force_render) { | |
154 obj = parent.redraw_node.apply(this, arguments); | |
155 if (obj && this.settings.dnd.use_html5) { | |
156 if (this.settings.dnd.large_drag_target) { | |
157 obj.setAttribute('draggable', true); | |
158 } else { | |
159 var i, j, tmp = null; | |
160 for(i = 0, j = obj.childNodes.length; i < j; i++) { | |
161 if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { | |
162 tmp = obj.childNodes[i]; | |
163 break; | |
164 } | |
165 } | |
166 if(tmp) { | |
167 tmp.setAttribute('draggable', true); | |
168 } | |
169 } | |
170 } | |
171 return obj; | |
172 }; | |
173 }; | |
174 | |
175 $(function() { | |
176 // bind only once for all instances | |
177 var lastmv = false, | |
178 laster = false, | |
179 lastev = false, | |
180 opento = false, | |
181 marker = $('<div id="jstree-marker"> </div>').hide(); //.appendTo('body'); | |
182 | |
183 $(document) | |
184 .on('dnd_start.vakata.jstree', function (e, data) { | |
185 lastmv = false; | |
186 lastev = false; | |
187 if(!data || !data.data || !data.data.jstree) { return; } | |
188 marker.appendTo('body'); //.show(); | |
189 }) | |
190 .on('dnd_move.vakata.jstree', function (e, data) { | |
191 var isDifferentNode = data.event.target !== lastev.target; | |
192 if(opento) { | |
193 if (!data.event || data.event.type !== 'dragover' || isDifferentNode) { | |
194 clearTimeout(opento); | |
195 } | |
196 } | |
197 if(!data || !data.data || !data.data.jstree) { return; } | |
198 | |
199 // if we are hovering the marker image do nothing (can happen on "inside" drags) | |
200 if(data.event.target.id && data.event.target.id === 'jstree-marker') { | |
201 return; | |
202 } | |
203 lastev = data.event; | |
204 | |
205 var ins = $.jstree.reference(data.event.target), | |
206 ref = false, | |
207 off = false, | |
208 rel = false, | |
209 tmp, l, t, h, p, i, o, ok, t1, t2, op, ps, pr, ip, tm, is_copy, pn; | |
210 // if we are over an instance | |
211 if(ins && ins._data && ins._data.dnd) { | |
212 marker.attr('class', 'jstree-' + ins.get_theme() + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' )); | |
213 is_copy = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))); | |
214 data.helper | |
215 .children().attr('class', 'jstree-' + ins.get_theme() + ' jstree-' + ins.get_theme() + '-' + ins.get_theme_variant() + ' ' + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' )) | |
216 .find('.jstree-copy').first()[ is_copy ? 'show' : 'hide' ](); | |
217 | |
218 // if are hovering the container itself add a new root node | |
219 //console.log(data.event); | |
220 if( (data.event.target === ins.element[0] || data.event.target === ins.get_container_ul()[0]) && ins.get_container_ul().children().length === 0) { | |
221 ok = true; | |
222 for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) { | |
223 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]), $.jstree.root, 'last', { 'dnd' : true, 'ref' : ins.get_node($.jstree.root), 'pos' : 'i', 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }); | |
224 if(!ok) { break; } | |
225 } | |
226 if(ok) { | |
227 lastmv = { 'ins' : ins, 'par' : $.jstree.root, 'pos' : 'last' }; | |
228 marker.hide(); | |
229 data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok'); | |
230 if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { | |
231 data.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move'; | |
232 } | |
233 return; | |
234 } | |
235 } | |
236 else { | |
237 // if we are hovering a tree node | |
238 ref = ins.settings.dnd.large_drop_target ? $(data.event.target).closest('.jstree-node').children('.jstree-anchor') : $(data.event.target).closest('.jstree-anchor'); | |
239 if(ref && ref.length && ref.parent().is('.jstree-closed, .jstree-open, .jstree-leaf')) { | |
240 off = ref.offset(); | |
241 rel = (data.event.pageY !== undefined ? data.event.pageY : data.event.originalEvent.pageY) - off.top; | |
242 h = ref.outerHeight(); | |
243 if(rel < h / 3) { | |
244 o = ['b', 'i', 'a']; | |
245 } | |
246 else if(rel > h - h / 3) { | |
247 o = ['a', 'i', 'b']; | |
248 } | |
249 else { | |
250 o = rel > h / 2 ? ['i', 'a', 'b'] : ['i', 'b', 'a']; | |
251 } | |
252 $.each(o, function (j, v) { | |
253 switch(v) { | |
254 case 'b': | |
255 l = off.left - 6; | |
256 t = off.top; | |
257 p = ins.get_parent(ref); | |
258 i = ref.parent().index(); | |
259 break; | |
260 case 'i': | |
261 ip = ins.settings.dnd.inside_pos; | |
262 tm = ins.get_node(ref.parent()); | |
263 l = off.left - 2; | |
264 t = off.top + h / 2 + 1; | |
265 p = tm.id; | |
266 i = ip === 'first' ? 0 : (ip === 'last' ? tm.children.length : Math.min(ip, tm.children.length)); | |
267 break; | |
268 case 'a': | |
269 l = off.left - 6; | |
270 t = off.top + h; | |
271 p = ins.get_parent(ref); | |
272 i = ref.parent().index() + 1; | |
273 break; | |
274 } | |
275 ok = true; | |
276 for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) { | |
277 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"; | |
278 ps = i; | |
279 if(op === "move_node" && v === 'a' && (data.data.origin && data.data.origin === ins) && p === ins.get_parent(data.data.nodes[t1])) { | |
280 pr = ins.get_node(p); | |
281 if(ps > $.inArray(data.data.nodes[t1], pr.children)) { | |
282 ps -= 1; | |
283 } | |
284 } | |
285 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, 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }) ); | |
286 if(!ok) { | |
287 if(ins && ins.last_error) { laster = ins.last_error(); } | |
288 break; | |
289 } | |
290 } | |
291 if(v === 'i' && ref.parent().is('.jstree-closed') && ins.settings.dnd.open_timeout) { | |
292 if (!data.event || data.event.type !== 'dragover' || isDifferentNode) { | |
293 if (opento) { clearTimeout(opento); } | |
294 opento = setTimeout((function (x, z) { return function () { x.open_node(z); }; }(ins, ref)), ins.settings.dnd.open_timeout); | |
295 } | |
296 } | |
297 if(ok) { | |
298 pn = ins.get_node(p, true); | |
299 if (!pn.hasClass('.jstree-dnd-parent')) { | |
300 $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); | |
301 pn.addClass('jstree-dnd-parent'); | |
302 } | |
303 lastmv = { 'ins' : ins, 'par' : p, 'pos' : v === 'i' && ip === 'last' && i === 0 && !ins.is_loaded(tm) ? 'last' : i }; | |
304 marker.css({ 'left' : l + 'px', 'top' : t + 'px' }).show(); | |
305 data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok'); | |
306 if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { | |
307 data.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move'; | |
308 } | |
309 laster = {}; | |
310 o = true; | |
311 return false; | |
312 } | |
313 }); | |
314 if(o === true) { return; } | |
315 } | |
316 } | |
317 } | |
318 $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); | |
319 lastmv = false; | |
320 data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er'); | |
321 if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { | |
322 data.event.originalEvent.dataTransfer.dropEffect = 'none'; | |
323 } | |
324 marker.hide(); | |
325 }) | |
326 .on('dnd_scroll.vakata.jstree', function (e, data) { | |
327 if(!data || !data.data || !data.data.jstree) { return; } | |
328 marker.hide(); | |
329 lastmv = false; | |
330 lastev = false; | |
331 data.helper.find('.jstree-icon').first().removeClass('jstree-ok').addClass('jstree-er'); | |
332 }) | |
333 .on('dnd_stop.vakata.jstree', function (e, data) { | |
334 $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); | |
335 if(opento) { clearTimeout(opento); } | |
336 if(!data || !data.data || !data.data.jstree) { return; } | |
337 marker.hide().detach(); | |
338 var i, j, nodes = []; | |
339 if(lastmv) { | |
340 for(i = 0, j = data.data.nodes.length; i < j; i++) { | |
341 nodes[i] = data.data.origin ? data.data.origin.get_node(data.data.nodes[i]) : data.data.nodes[i]; | |
342 } | |
343 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, false, false, false, data.data.origin); | |
344 } | |
345 else { | |
346 i = $(data.event.target).closest('.jstree'); | |
347 if(i.length && laster && laster.error && laster.error === 'check') { | |
348 i = i.jstree(true); | |
349 if(i) { | |
350 i.settings.core.error.call(this, laster); | |
351 } | |
352 } | |
353 } | |
354 lastev = false; | |
355 lastmv = false; | |
356 }) | |
357 .on('keyup.jstree keydown.jstree', function (e, data) { | |
358 data = $.vakata.dnd._get(); | |
359 if(data && data.data && data.data.jstree) { | |
360 if (e.type === "keyup" && e.which === 27) { | |
361 if (opento) { clearTimeout(opento); } | |
362 lastmv = false; | |
363 laster = false; | |
364 lastev = false; | |
365 opento = false; | |
366 marker.hide().detach(); | |
367 $.vakata.dnd._clean(); | |
368 } else { | |
369 data.helper.find('.jstree-copy').first()[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (e.metaKey || e.ctrlKey))) ? 'show' : 'hide' ](); | |
370 if(lastev) { | |
371 lastev.metaKey = e.metaKey; | |
372 lastev.ctrlKey = e.ctrlKey; | |
373 $.vakata.dnd._trigger('move', lastev); | |
374 } | |
375 } | |
376 } | |
377 }); | |
378 }); | |
379 | |
380 // helpers | |
381 (function ($) { | |
382 $.vakata.html = { | |
383 div : $('<div />'), | |
384 escape : function (str) { | |
385 return $.vakata.html.div.text(str).html(); | |
386 }, | |
387 strip : function (str) { | |
388 return $.vakata.html.div.empty().append($.parseHTML(str)).text(); | |
389 } | |
390 }; | |
391 // private variable | |
392 var vakata_dnd = { | |
393 element : false, | |
394 target : false, | |
395 is_down : false, | |
396 is_drag : false, | |
397 helper : false, | |
398 helper_w: 0, | |
399 data : false, | |
400 init_x : 0, | |
401 init_y : 0, | |
402 scroll_l: 0, | |
403 scroll_t: 0, | |
404 scroll_e: false, | |
405 scroll_i: false, | |
406 is_touch: false | |
407 }; | |
408 $.vakata.dnd = { | |
409 settings : { | |
410 scroll_speed : 10, | |
411 scroll_proximity : 20, | |
412 helper_left : 5, | |
413 helper_top : 10, | |
414 threshold : 5, | |
415 threshold_touch : 10 | |
416 }, | |
417 _trigger : function (event_name, e, data) { | |
418 if (data === undefined) { | |
419 data = $.vakata.dnd._get(); | |
420 } | |
421 data.event = e; | |
422 $(document).triggerHandler("dnd_" + event_name + ".vakata", data); | |
423 }, | |
424 _get : function () { | |
425 return { | |
426 "data" : vakata_dnd.data, | |
427 "element" : vakata_dnd.element, | |
428 "helper" : vakata_dnd.helper | |
429 }; | |
430 }, | |
431 _clean : function () { | |
432 if(vakata_dnd.helper) { vakata_dnd.helper.remove(); } | |
433 if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; } | |
434 vakata_dnd = { | |
435 element : false, | |
436 target : false, | |
437 is_down : false, | |
438 is_drag : false, | |
439 helper : false, | |
440 helper_w: 0, | |
441 data : false, | |
442 init_x : 0, | |
443 init_y : 0, | |
444 scroll_l: 0, | |
445 scroll_t: 0, | |
446 scroll_e: false, | |
447 scroll_i: false, | |
448 is_touch: false | |
449 }; | |
450 $(document).off("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag); | |
451 $(document).off("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop); | |
452 }, | |
453 _scroll : function (init_only) { | |
454 if(!vakata_dnd.scroll_e || (!vakata_dnd.scroll_l && !vakata_dnd.scroll_t)) { | |
455 if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; } | |
456 return false; | |
457 } | |
458 if(!vakata_dnd.scroll_i) { | |
459 vakata_dnd.scroll_i = setInterval($.vakata.dnd._scroll, 100); | |
460 return false; | |
461 } | |
462 if(init_only === true) { return false; } | |
463 | |
464 var i = vakata_dnd.scroll_e.scrollTop(), | |
465 j = vakata_dnd.scroll_e.scrollLeft(); | |
466 vakata_dnd.scroll_e.scrollTop(i + vakata_dnd.scroll_t * $.vakata.dnd.settings.scroll_speed); | |
467 vakata_dnd.scroll_e.scrollLeft(j + vakata_dnd.scroll_l * $.vakata.dnd.settings.scroll_speed); | |
468 if(i !== vakata_dnd.scroll_e.scrollTop() || j !== vakata_dnd.scroll_e.scrollLeft()) { | |
469 /** | |
470 * triggered on the document when a drag causes an element to scroll | |
471 * @event | |
472 * @plugin dnd | |
473 * @name dnd_scroll.vakata | |
474 * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start | |
475 * @param {DOM} element the DOM element being dragged | |
476 * @param {jQuery} helper the helper shown next to the mouse | |
477 * @param {jQuery} event the element that is scrolling | |
478 */ | |
479 $.vakata.dnd._trigger("scroll", vakata_dnd.scroll_e); | |
480 } | |
481 }, | |
482 start : function (e, data, html) { | |
483 if(e.type === "touchstart" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { | |
484 e.pageX = e.originalEvent.changedTouches[0].pageX; | |
485 e.pageY = e.originalEvent.changedTouches[0].pageY; | |
486 e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); | |
487 } | |
488 if(vakata_dnd.is_drag) { $.vakata.dnd.stop({}); } | |
489 try { | |
490 e.currentTarget.unselectable = "on"; | |
491 e.currentTarget.onselectstart = function() { return false; }; | |
492 if(e.currentTarget.style) { | |
493 e.currentTarget.style.touchAction = "none"; | |
494 e.currentTarget.style.msTouchAction = "none"; | |
495 e.currentTarget.style.MozUserSelect = "none"; | |
496 } | |
497 } catch(ignore) { } | |
498 vakata_dnd.init_x = e.pageX; | |
499 vakata_dnd.init_y = e.pageY; | |
500 vakata_dnd.data = data; | |
501 vakata_dnd.is_down = true; | |
502 vakata_dnd.element = e.currentTarget; | |
503 vakata_dnd.target = e.target; | |
504 vakata_dnd.is_touch = e.type === "touchstart"; | |
505 if(html !== false) { | |
506 vakata_dnd.helper = $("<div id='vakata-dnd'></div>").html(html).css({ | |
507 "display" : "block", | |
508 "margin" : "0", | |
509 "padding" : "0", | |
510 "position" : "absolute", | |
511 "top" : "-2000px", | |
512 "lineHeight" : "16px", | |
513 "zIndex" : "10000" | |
514 }); | |
515 } | |
516 $(document).on("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag); | |
517 $(document).on("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop); | |
518 return false; | |
519 }, | |
520 drag : function (e) { | |
521 if(e.type === "touchmove" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { | |
522 e.pageX = e.originalEvent.changedTouches[0].pageX; | |
523 e.pageY = e.originalEvent.changedTouches[0].pageY; | |
524 e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); | |
525 } | |
526 if(!vakata_dnd.is_down) { return; } | |
527 if(!vakata_dnd.is_drag) { | |
528 if( | |
529 Math.abs(e.pageX - vakata_dnd.init_x) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) || | |
530 Math.abs(e.pageY - vakata_dnd.init_y) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) | |
531 ) { | |
532 if(vakata_dnd.helper) { | |
533 vakata_dnd.helper.appendTo("body"); | |
534 vakata_dnd.helper_w = vakata_dnd.helper.outerWidth(); | |
535 } | |
536 vakata_dnd.is_drag = true; | |
537 $(vakata_dnd.target).one('click.vakata', false); | |
538 /** | |
539 * triggered on the document when a drag starts | |
540 * @event | |
541 * @plugin dnd | |
542 * @name dnd_start.vakata | |
543 * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start | |
544 * @param {DOM} element the DOM element being dragged | |
545 * @param {jQuery} helper the helper shown next to the mouse | |
546 * @param {Object} event the event that caused the start (probably mousemove) | |
547 */ | |
548 $.vakata.dnd._trigger("start", e); | |
549 } | |
550 else { return; } | |
551 } | |
552 | |
553 var d = false, w = false, | |
554 dh = false, wh = false, | |
555 dw = false, ww = false, | |
556 dt = false, dl = false, | |
557 ht = false, hl = false; | |
558 | |
559 vakata_dnd.scroll_t = 0; | |
560 vakata_dnd.scroll_l = 0; | |
561 vakata_dnd.scroll_e = false; | |
562 $($(e.target).parentsUntil("body").addBack().get().reverse()) | |
563 .filter(function () { | |
564 return (/^auto|scroll$/).test($(this).css("overflow")) && | |
565 (this.scrollHeight > this.offsetHeight || this.scrollWidth > this.offsetWidth); | |
566 }) | |
567 .each(function () { | |
568 var t = $(this), o = t.offset(); | |
569 if(this.scrollHeight > this.offsetHeight) { | |
570 if(o.top + t.height() - e.pageY < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; } | |
571 if(e.pageY - o.top < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; } | |
572 } | |
573 if(this.scrollWidth > this.offsetWidth) { | |
574 if(o.left + t.width() - e.pageX < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; } | |
575 if(e.pageX - o.left < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; } | |
576 } | |
577 if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) { | |
578 vakata_dnd.scroll_e = $(this); | |
579 return false; | |
580 } | |
581 }); | |
582 | |
583 if(!vakata_dnd.scroll_e) { | |
584 d = $(document); w = $(window); | |
585 dh = d.height(); wh = w.height(); | |
586 dw = d.width(); ww = w.width(); | |
587 dt = d.scrollTop(); dl = d.scrollLeft(); | |
588 if(dh > wh && e.pageY - dt < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; } | |
589 if(dh > wh && wh - (e.pageY - dt) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; } | |
590 if(dw > ww && e.pageX - dl < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; } | |
591 if(dw > ww && ww - (e.pageX - dl) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; } | |
592 if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) { | |
593 vakata_dnd.scroll_e = d; | |
594 } | |
595 } | |
596 if(vakata_dnd.scroll_e) { $.vakata.dnd._scroll(true); } | |
597 | |
598 if(vakata_dnd.helper) { | |
599 ht = parseInt(e.pageY + $.vakata.dnd.settings.helper_top, 10); | |
600 hl = parseInt(e.pageX + $.vakata.dnd.settings.helper_left, 10); | |
601 if(dh && ht + 25 > dh) { ht = dh - 50; } | |
602 if(dw && hl + vakata_dnd.helper_w > dw) { hl = dw - (vakata_dnd.helper_w + 2); } | |
603 vakata_dnd.helper.css({ | |
604 left : hl + "px", | |
605 top : ht + "px" | |
606 }); | |
607 } | |
608 /** | |
609 * triggered on the document when a drag is in progress | |
610 * @event | |
611 * @plugin dnd | |
612 * @name dnd_move.vakata | |
613 * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start | |
614 * @param {DOM} element the DOM element being dragged | |
615 * @param {jQuery} helper the helper shown next to the mouse | |
616 * @param {Object} event the event that caused this to trigger (most likely mousemove) | |
617 */ | |
618 $.vakata.dnd._trigger("move", e); | |
619 return false; | |
620 }, | |
621 stop : function (e) { | |
622 if(e.type === "touchend" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { | |
623 e.pageX = e.originalEvent.changedTouches[0].pageX; | |
624 e.pageY = e.originalEvent.changedTouches[0].pageY; | |
625 e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); | |
626 } | |
627 if(vakata_dnd.is_drag) { | |
628 /** | |
629 * triggered on the document when a drag stops (the dragged element is dropped) | |
630 * @event | |
631 * @plugin dnd | |
632 * @name dnd_stop.vakata | |
633 * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start | |
634 * @param {DOM} element the DOM element being dragged | |
635 * @param {jQuery} helper the helper shown next to the mouse | |
636 * @param {Object} event the event that caused the stop | |
637 */ | |
638 if (e.target !== vakata_dnd.target) { | |
639 $(vakata_dnd.target).off('click.vakata'); | |
640 } | |
641 $.vakata.dnd._trigger("stop", e); | |
642 } | |
643 else { | |
644 if(e.type === "touchend" && e.target === vakata_dnd.target) { | |
645 var to = setTimeout(function () { $(e.target).click(); }, 100); | |
646 $(e.target).one('click', function() { if(to) { clearTimeout(to); } }); | |
647 } | |
648 } | |
649 $.vakata.dnd._clean(); | |
650 return false; | |
651 } | |
652 }; | |
653 }($)); | |
654 | |
655 // include the dnd plugin by default | |
656 // $.jstree.defaults.plugins.push("dnd"); | |
657 })); |