jstree-rails-4 3.2.1 → 3.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c1e9d439c433e0e91591181a28c2d1566af266d5
4
- data.tar.gz: 01462dc6cff505dfe2d6b9d0b45680a1fc044ee9
3
+ metadata.gz: 0e38671e9e216082caf625aaf59c40a125492ad2
4
+ data.tar.gz: 4d33d52ed69182d6b87b42615c5cc8bfdc0eb004
5
5
  SHA512:
6
- metadata.gz: 06b491753a2641a14febe0fbc791394d4afe40b067e9009488e3a0ad1a6659eae1a3a6454930f44739ee0c0d82d8f5d78711a8b87bd7e4788cd070d46e91abb3
7
- data.tar.gz: 3b04097c8b81b31cb62175437bbdc2196423211c2daacd38612252544de7b0090aaf17a8a6427f68f259fd03ce8dbf3dbd9a2df9e5808740de617c84dbd6785d
6
+ metadata.gz: 9b6acdb78d4c4b24575a8efbeebdfdffc45f66d6641e83ff0301589e3eb9244dd57b873433a06ff0dcca07a572d3a908b24030ed5239f4c8c7567c9c889d8eb4
7
+ data.tar.gz: e2544fd84ca1b7831edcd31a956276a2a9cee12bce5386c5df86f5f67c1a22083a70c99f134ded69a9dd069602d22c6161e9776870c97deefda2be2af84635dd
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jstree-rails-4 (3.1.1)
4
+ jstree-rails-4 (3.3.3)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
@@ -46,9 +46,9 @@ GEM
46
46
  erubis (2.7.0)
47
47
  globalid (0.3.6)
48
48
  activesupport (>= 4.1.0)
49
- httpclient (2.6.0.1)
49
+ httpclient (2.8.3)
50
50
  i18n (0.7.0)
51
- json (1.8.3)
51
+ json (1.8.6)
52
52
  loofah (2.0.2)
53
53
  nokogiri (>= 1.5.9)
54
54
  mail (2.6.3)
@@ -101,11 +101,12 @@ PLATFORMS
101
101
  ruby
102
102
 
103
103
  DEPENDENCIES
104
- bundler (~> 1.0)
105
- httpclient (~> 2.2)
104
+ bundler (~> 1.14)
105
+ httpclient (~> 2.8)
106
+ json (~> 1.8.6)
106
107
  jstree-rails-4!
107
- rails (>= 3.0)
108
- thor (~> 0.14)
108
+ rails (>= 4.0)
109
+ thor (~> 0.19)
109
110
 
110
111
  BUNDLED WITH
111
- 1.10.6
112
+ 1.14.0
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015 kesha-antonov
3
+ Copyright (c) 2015 Innokentii Antonov
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
-
data/README.md CHANGED
@@ -4,9 +4,9 @@
4
4
 
5
5
  The `jstree-rails-4` gem integrates the `jsTree` jQuery plugin with the Rails asset pipeline.
6
6
 
7
- GemVersion: 3.2.1
7
+ GemVersion: 3.3.3
8
8
 
9
- jsTree Version: 3.2.1
9
+ jsTree Version: 3.3.3
10
10
 
11
11
  ## Usage
12
12
 
@@ -49,4 +49,3 @@ Use command line:
49
49
  ## License
50
50
 
51
51
  jsTree-Rails-4 is released under the [MIT License](http://www.opensource.org/licenses/MIT).
52
-
@@ -15,8 +15,9 @@ Gem::Specification.new do |s|
15
15
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
16
  s.require_paths = ["lib"]
17
17
 
18
- s.add_development_dependency "thor", "~> 0.14"
19
- s.add_development_dependency "bundler", "~> 1.0"
20
- s.add_development_dependency "rails", ">= 3.0"
21
- s.add_development_dependency "httpclient", "~> 2.2"
18
+ s.add_development_dependency "json", "~> 1.8.6"
19
+ s.add_development_dependency "thor", "~> 0.19"
20
+ s.add_development_dependency "bundler", "~> 1.14"
21
+ s.add_development_dependency "rails", ">= 4.0"
22
+ s.add_development_dependency "httpclient", "~> 2.8"
22
23
  end
@@ -1,5 +1,5 @@
1
1
  module JSTree
2
2
  module Rails
3
- VERSION = '3.2.1'
3
+ VERSION = '3.3.3'
4
4
  end
5
5
  end
@@ -13,7 +13,7 @@
13
13
  }(function ($, undefined) {
14
14
  "use strict";
15
15
  /*!
16
- * jsTree 3.2.1
16
+ * jsTree 3.3.3
17
17
  * http://jstree.com/
18
18
  *
19
19
  * Copyright (c) 2014 Ivan Bozhanov (http://vakata.com)
@@ -23,8 +23,9 @@
23
23
  */
24
24
  /*!
25
25
  * if using jslint please allow for the jQuery global and use following options:
26
- * jslint: browser: true, ass: true, bitwise: true, continue: true, nomen: true, plusplus: true, regexp: true, unparam: true, todo: true, white: true
26
+ * jslint: loopfunc: true, browser: true, ass: true, bitwise: true, continue: true, nomen: true, plusplus: true, regexp: true, unparam: true, todo: true, white: true
27
27
  */
28
+ /*jshint -W083 */
28
29
 
29
30
  // prevent another load? maybe there is a better way?
30
31
  if($.jstree) {
@@ -42,25 +43,7 @@
42
43
  ccp_inst = false,
43
44
  themes_loaded = [],
44
45
  src = $('script:last').attr('src'),
45
- document = window.document, // local variable is always faster to access then a global
46
- _node = document.createElement('LI'), _temp1, _temp2;
47
-
48
- _node.setAttribute('role', 'treeitem');
49
- _temp1 = document.createElement('I');
50
- _temp1.className = 'jstree-icon jstree-ocl';
51
- _temp1.setAttribute('role', 'presentation');
52
- _node.appendChild(_temp1);
53
- _temp1 = document.createElement('A');
54
- _temp1.className = 'jstree-anchor';
55
- _temp1.setAttribute('href','#');
56
- _temp1.setAttribute('tabindex','-1');
57
- _temp2 = document.createElement('I');
58
- _temp2.className = 'jstree-icon jstree-themeicon';
59
- _temp2.setAttribute('role', 'presentation');
60
- _temp1.appendChild(_temp2);
61
- _node.appendChild(_temp1);
62
- _temp1 = _temp2 = null;
63
-
46
+ document = window.document; // local variable is always faster to access then a global
64
47
 
65
48
  /**
66
49
  * holds all jstree related functions and variables, including the actual class and methods to create, access and manipulate instances.
@@ -71,7 +54,7 @@
71
54
  * specifies the jstree version in use
72
55
  * @name $.jstree.version
73
56
  */
74
- version : '3.2.1',
57
+ version : '3.3.3',
75
58
  /**
76
59
  * holds all the default options used when creating new instances
77
60
  * @name $.jstree.defaults
@@ -92,6 +75,7 @@
92
75
  idregex : /[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g,
93
76
  root : '#'
94
77
  };
78
+
95
79
  /**
96
80
  * creates a jstree instance
97
81
  * @name $.jstree.create(el [, options])
@@ -138,7 +122,8 @@
138
122
  themes : {
139
123
  name : false,
140
124
  dots : false,
141
- icons : false
125
+ icons : false,
126
+ ellipsis : false
142
127
  },
143
128
  selected : [],
144
129
  last_error : {},
@@ -260,7 +245,7 @@
260
245
  * @name $(':jstree')
261
246
  * @return {jQuery}
262
247
  */
263
- $.expr[':'].jstree = $.expr.createPseudo(function(search) {
248
+ $.expr.pseudos.jstree = $.expr.createPseudo(function(search) {
264
249
  return function(a) {
265
250
  return $(a).hasClass('jstree') &&
266
251
  $(a).data('jstree') !== undefined;
@@ -309,7 +294,8 @@
309
294
  * 'children' : [ { 'text' : 'Child 1' }, 'Child 2']
310
295
  * }
311
296
  * ]
312
- * });
297
+ * }
298
+ * });
313
299
  *
314
300
  * // function
315
301
  * $('#tree').jstree({
@@ -407,6 +393,11 @@
407
393
  * @name $.jstree.defaults.core.themes.icons
408
394
  */
409
395
  icons : true,
396
+ /**
397
+ * a boolean indicating if node ellipsis should be shown - this only works with a fixed with on the container
398
+ * @name $.jstree.defaults.core.themes.ellipsis
399
+ */
400
+ ellipsis : false,
410
401
  /**
411
402
  * a boolean indicating if the tree background is striped
412
403
  * @name $.jstree.defaults.core.themes.stripes
@@ -525,6 +516,7 @@
525
516
  this.element.html("<"+"ul class='jstree-container-ul jstree-children' role='group'><"+"li id='j"+this._id+"_loading' class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='tree-item'><i class='jstree-icon jstree-ocl'></i><"+"a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>" + this.get_string("Loading ...") + "</a></li></ul>");
526
517
  this.element.attr('aria-activedescendant','j' + this._id + '_loading');
527
518
  this._data.core.li_height = this.get_container_ul().children("li").first().height() || 24;
519
+ this._data.core.node = this._create_prototype_node();
528
520
  /**
529
521
  * triggered after the loading text is shown and before loading starts
530
522
  * @event
@@ -549,6 +541,29 @@
549
541
  if(!keep_html) { this.element.empty(); }
550
542
  this.teardown();
551
543
  },
544
+ /**
545
+ * Create prototype node
546
+ */
547
+ _create_prototype_node : function () {
548
+ var _node = document.createElement('LI'), _temp1, _temp2;
549
+ _node.setAttribute('role', 'treeitem');
550
+ _temp1 = document.createElement('I');
551
+ _temp1.className = 'jstree-icon jstree-ocl';
552
+ _temp1.setAttribute('role', 'presentation');
553
+ _node.appendChild(_temp1);
554
+ _temp1 = document.createElement('A');
555
+ _temp1.className = 'jstree-anchor';
556
+ _temp1.setAttribute('href','#');
557
+ _temp1.setAttribute('tabindex','-1');
558
+ _temp2 = document.createElement('I');
559
+ _temp2.className = 'jstree-icon jstree-themeicon';
560
+ _temp2.setAttribute('role', 'presentation');
561
+ _temp1.appendChild(_temp2);
562
+ _node.appendChild(_temp1);
563
+ _temp1 = _temp2 = null;
564
+
565
+ return _node;
566
+ },
552
567
  /**
553
568
  * part of the destroying of an instance. Used internally.
554
569
  * @private
@@ -631,7 +646,7 @@
631
646
  e.type = "click";
632
647
  $(e.currentTarget).trigger(e);
633
648
  break;
634
- case 37: // right
649
+ case 37: // left
635
650
  e.preventDefault();
636
651
  if(this.is_open(e.currentTarget)) {
637
652
  this.close_node(e.currentTarget);
@@ -646,7 +661,7 @@
646
661
  o = this.get_prev_dom(e.currentTarget);
647
662
  if(o && o.length) { o.children('.jstree-anchor').focus(); }
648
663
  break;
649
- case 39: // left
664
+ case 39: // right
650
665
  e.preventDefault();
651
666
  if(this.is_closed(e.currentTarget)) {
652
667
  this.open_node(e.currentTarget, function (o) { this.get_node(o, true).children('.jstree-anchor').focus(); });
@@ -673,6 +688,12 @@
673
688
  e.preventDefault();
674
689
  this.element.find('.jstree-anchor').filter(':visible').last().focus();
675
690
  break;
691
+ case 113: // f2 - safe to include - if check_callback is false it will fail
692
+ e.preventDefault();
693
+ this.edit(e.currentTarget);
694
+ break;
695
+ default:
696
+ break;
676
697
  /*!
677
698
  // delete
678
699
  case 46:
@@ -683,17 +704,7 @@
683
704
  this.delete_node(o);
684
705
  }
685
706
  break;
686
- // f2
687
- case 113:
688
- e.preventDefault();
689
- o = this.get_node(e.currentTarget);
690
- if(o && o.id && o.id !== $.jstree.root) {
691
- // this.edit(o);
692
- }
693
- break;
694
- default:
695
- // console.log(e.which);
696
- break;
707
+
697
708
  */
698
709
  }
699
710
  }, this))
@@ -803,6 +814,7 @@
803
814
  this._data.core.themes.dots = s.dots;
804
815
  this._data.core.themes.stripes = s.stripes;
805
816
  this._data.core.themes.icons = s.icons;
817
+ this._data.core.themes.ellipsis = s.ellipsis;
806
818
  this.set_theme(s.name || "default", s.url);
807
819
  this.set_theme_variant(s.variant);
808
820
  }, this))
@@ -810,6 +822,7 @@
810
822
  this[ this._data.core.themes.dots ? "show_dots" : "hide_dots" ]();
811
823
  this[ this._data.core.themes.icons ? "show_icons" : "hide_icons" ]();
812
824
  this[ this._data.core.themes.stripes ? "show_stripes" : "hide_stripes" ]();
825
+ this[ this._data.core.themes.ellipsis ? "show_ellipsis" : "hide_ellipsis" ]();
813
826
  }, this))
814
827
  .on('blur.jstree', '.jstree-anchor', $.proxy(function (e) {
815
828
  this._data.core.focused = null;
@@ -1191,16 +1204,22 @@
1191
1204
  // if(obj.state.loading) { } // the node is already loading - just wait for it to load and invoke callback? but if called implicitly it should be loaded again?
1192
1205
  if(obj.state.loaded) {
1193
1206
  obj.state.loaded = false;
1207
+ for(i = 0, j = obj.parents.length; i < j; i++) {
1208
+ this._model.data[obj.parents[i]].children_d = $.vakata.array_filter(this._model.data[obj.parents[i]].children_d, function (v) {
1209
+ return $.inArray(v, obj.children_d) === -1;
1210
+ });
1211
+ }
1194
1212
  for(k = 0, l = obj.children_d.length; k < l; k++) {
1195
- for(i = 0, j = obj.parents.length; i < j; i++) {
1196
- this._model.data[obj.parents[i]].children_d = $.vakata.array_remove_item(this._model.data[obj.parents[i]].children_d, obj.children_d[k]);
1197
- }
1198
1213
  if(this._model.data[obj.children_d[k]].state.selected) {
1199
1214
  c = true;
1200
- this._data.core.selected = $.vakata.array_remove_item(this._data.core.selected, obj.children_d[k]);
1201
1215
  }
1202
1216
  delete this._model.data[obj.children_d[k]];
1203
1217
  }
1218
+ if (c) {
1219
+ this._data.core.selected = $.vakata.array_filter(this._data.core.selected, function (v) {
1220
+ return $.inArray(v, obj.children_d) === -1;
1221
+ });
1222
+ }
1204
1223
  obj.children = [];
1205
1224
  obj.children_d = [];
1206
1225
  if(c) {
@@ -1222,8 +1241,16 @@
1222
1241
  break;
1223
1242
  }
1224
1243
  }
1225
- if(obj.state.loaded && !has_children && dom && dom.length && !dom.hasClass('jstree-leaf')) {
1226
- dom.removeClass('jstree-closed jstree-open').addClass('jstree-leaf');
1244
+ if(obj.state.loaded && dom && dom.length) {
1245
+ dom.removeClass('jstree-closed jstree-open jstree-leaf');
1246
+ if (!has_children) {
1247
+ dom.addClass('jstree-leaf');
1248
+ }
1249
+ else {
1250
+ if (obj.id !== '#') {
1251
+ dom.addClass(obj.state.opened ? 'jstree-open' : 'jstree-closed');
1252
+ }
1253
+ }
1227
1254
  }
1228
1255
  dom.removeClass("jstree-loading").attr('aria-busy',false);
1229
1256
  /**
@@ -1247,12 +1274,12 @@
1247
1274
  * @param {array} nodes
1248
1275
  * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - the array passed to _load_nodes
1249
1276
  */
1250
- _load_nodes : function (nodes, callback, is_callback) {
1277
+ _load_nodes : function (nodes, callback, is_callback, force_reload) {
1251
1278
  var r = true,
1252
1279
  c = function () { this._load_nodes(nodes, callback, true); },
1253
1280
  m = this._model.data, i, j, tmp = [];
1254
1281
  for(i = 0, j = nodes.length; i < j; i++) {
1255
- if(m[nodes[i]] && ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || !is_callback)) {
1282
+ if(m[nodes[i]] && ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || (!is_callback && force_reload) )) {
1256
1283
  if(!this.is_loading(nodes[i])) {
1257
1284
  this.load_node(nodes[i], c);
1258
1285
  }
@@ -1320,6 +1347,9 @@
1320
1347
  */
1321
1348
  _load_node : function (obj, callback) {
1322
1349
  var s = this.settings.core.data, t;
1350
+ var notTextOrCommentNode = function notTextOrCommentNode () {
1351
+ return this.nodeType !== 3 && this.nodeType !== 8;
1352
+ };
1323
1353
  // use original HTML
1324
1354
  if(!s) {
1325
1355
  if(obj.id === $.jstree.root) {
@@ -1337,9 +1367,11 @@
1337
1367
  if(d === false) {
1338
1368
  callback.call(this, false);
1339
1369
  }
1340
- this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $($.parseHTML(d)).filter(function () { return this.nodeType !== 3; }) : d, function (status) {
1341
- callback.call(this, status);
1342
- });
1370
+ else {
1371
+ this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $($.parseHTML(d)).filter(notTextOrCommentNode) : d, function (status) {
1372
+ callback.call(this, status);
1373
+ });
1374
+ }
1343
1375
  // return d === false ? callback.call(this, false) : callback.call(this, this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $(d) : d));
1344
1376
  }, this));
1345
1377
  }
@@ -1360,7 +1392,7 @@
1360
1392
  //return callback.call(this, this._append_json_data(obj, d));
1361
1393
  }
1362
1394
  if((type && type.indexOf('html') !== -1) || typeof d === "string") {
1363
- return this._append_html_data(obj, $($.parseHTML(d)).filter(function () { return this.nodeType !== 3; }), function (status) { callback.call(this, status); });
1395
+ return this._append_html_data(obj, $($.parseHTML(d)).filter(notTextOrCommentNode), function (status) { callback.call(this, status); });
1364
1396
  // return callback.call(this, this._append_html_data(obj, $(d)));
1365
1397
  }
1366
1398
  this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : x }) };
@@ -1388,7 +1420,7 @@
1388
1420
  }
1389
1421
  if(typeof s === 'string') {
1390
1422
  if(obj.id === $.jstree.root) {
1391
- return this._append_html_data(obj, $($.parseHTML(s)).filter(function () { return this.nodeType !== 3; }), function (status) {
1423
+ return this._append_html_data(obj, $($.parseHTML(s)).filter(notTextOrCommentNode), function (status) {
1392
1424
  callback.call(this, status);
1393
1425
  });
1394
1426
  }
@@ -1775,10 +1807,17 @@
1775
1807
  rslt = function (rslt, worker) {
1776
1808
  if(this.element === null) { return; }
1777
1809
  this._cnt = rslt.cnt;
1810
+ var i, m = this._model.data;
1811
+ for (i in m) {
1812
+ if (m.hasOwnProperty(i) && m[i].state && m[i].state.loading && rslt.mod[i]) {
1813
+ rslt.mod[i].state.loading = true;
1814
+ }
1815
+ }
1778
1816
  this._model.data = rslt.mod; // breaks the reference in load_node - careful
1779
1817
 
1780
1818
  if(worker) {
1781
- var i, j, a = rslt.add, r = rslt.sel, s = this._data.core.selected.slice(), m = this._model.data;
1819
+ var j, a = rslt.add, r = rslt.sel, s = this._data.core.selected.slice();
1820
+ m = this._model.data;
1782
1821
  // if selection was changed while calculating in worker
1783
1822
  if(r.length !== s.length || $.vakata.array_unique(r.concat(s)).length !== r.length) {
1784
1823
  // deselect nodes that are no longer selected
@@ -2334,7 +2373,7 @@
2334
2373
  //node = d.createElement('LI');
2335
2374
  //node = node[0];
2336
2375
  }
2337
- node = _node.cloneNode(true);
2376
+ node = this._data.core.node.cloneNode(true);
2338
2377
  // node is DOM, deep is boolean
2339
2378
 
2340
2379
  c = 'jstree-node ';
@@ -2419,7 +2458,7 @@
2419
2458
  node.childNodes[1].childNodes[0].className += ' ' + obj.icon + ' jstree-themeicon-custom';
2420
2459
  }
2421
2460
  else {
2422
- node.childNodes[1].childNodes[0].style.backgroundImage = 'url('+obj.icon+')';
2461
+ node.childNodes[1].childNodes[0].style.backgroundImage = 'url("'+obj.icon+'")';
2423
2462
  node.childNodes[1].childNodes[0].style.backgroundPosition = 'center center';
2424
2463
  node.childNodes[1].childNodes[0].style.backgroundSize = 'auto';
2425
2464
  node.childNodes[1].childNodes[0].className += ' jstree-themeicon-custom';
@@ -2549,7 +2588,9 @@
2549
2588
  .children(".jstree-children").stop(true, true)
2550
2589
  .slideDown(animation, function () {
2551
2590
  this.style.display = "";
2552
- t.trigger("after_open", { "node" : obj });
2591
+ if (t.element) {
2592
+ t.trigger("after_open", { "node" : obj });
2593
+ }
2553
2594
  });
2554
2595
  }
2555
2596
  }
@@ -2630,22 +2671,7 @@
2630
2671
  animation = animation === undefined ? this.settings.core.animation : animation;
2631
2672
  t = this;
2632
2673
  d = this.get_node(obj, true);
2633
- if(d.length) {
2634
- if(!animation) {
2635
- d[0].className = d[0].className.replace('jstree-open', 'jstree-closed');
2636
- d.attr("aria-expanded", false).children('.jstree-children').remove();
2637
- }
2638
- else {
2639
- d
2640
- .children(".jstree-children").attr("style","display:block !important").end()
2641
- .removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded", false)
2642
- .children(".jstree-children").stop(true, true).slideUp(animation, function () {
2643
- this.style.display = "";
2644
- d.children('.jstree-children').remove();
2645
- t.trigger("after_close", { "node" : obj });
2646
- });
2647
- }
2648
- }
2674
+
2649
2675
  obj.state.opened = false;
2650
2676
  /**
2651
2677
  * triggered when a node is closed (if there is an animation it will not be complete yet)
@@ -2654,7 +2680,7 @@
2654
2680
  * @param {Object} node the closed node
2655
2681
  */
2656
2682
  this.trigger('close_node',{ "node" : obj });
2657
- if(!animation || !d.length) {
2683
+ if(!d.length) {
2658
2684
  /**
2659
2685
  * triggered when a node is closed and the animation is complete
2660
2686
  * @event
@@ -2663,6 +2689,25 @@
2663
2689
  */
2664
2690
  this.trigger("after_close", { "node" : obj });
2665
2691
  }
2692
+ else {
2693
+ if(!animation) {
2694
+ d[0].className = d[0].className.replace('jstree-open', 'jstree-closed');
2695
+ d.attr("aria-expanded", false).children('.jstree-children').remove();
2696
+ this.trigger("after_close", { "node" : obj });
2697
+ }
2698
+ else {
2699
+ d
2700
+ .children(".jstree-children").attr("style","display:block !important").end()
2701
+ .removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded", false)
2702
+ .children(".jstree-children").stop(true, true).slideUp(animation, function () {
2703
+ this.style.display = "";
2704
+ d.children('.jstree-children').remove();
2705
+ if (t.element) {
2706
+ t.trigger("after_close", { "node" : obj });
2707
+ }
2708
+ });
2709
+ }
2710
+ }
2666
2711
  },
2667
2712
  /**
2668
2713
  * toggles a node - closing it if it is open, opening it if it is closed
@@ -2822,11 +2867,20 @@
2822
2867
  */
2823
2868
  this.trigger('disable_node', { 'node' : obj });
2824
2869
  },
2870
+ /**
2871
+ * determines if a node is hidden
2872
+ * @name is_hidden(obj)
2873
+ * @param {mixed} obj the node
2874
+ */
2875
+ is_hidden : function (obj) {
2876
+ obj = this.get_node(obj);
2877
+ return obj.state.hidden === true;
2878
+ },
2825
2879
  /**
2826
2880
  * hides a node - it is still in the structure but will not be visible
2827
2881
  * @name hide_node(obj)
2828
2882
  * @param {mixed} obj the node to hide
2829
- * @param {Boolean} redraw internal parameter controlling if redraw is called
2883
+ * @param {Boolean} skip_redraw internal parameter controlling if redraw is called
2830
2884
  * @trigger hide_node.jstree
2831
2885
  */
2832
2886
  hide_node : function (obj, skip_redraw) {
@@ -2836,7 +2890,9 @@
2836
2890
  for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
2837
2891
  this.hide_node(obj[t1], true);
2838
2892
  }
2839
- this.redraw();
2893
+ if (!skip_redraw) {
2894
+ this.redraw();
2895
+ }
2840
2896
  return true;
2841
2897
  }
2842
2898
  obj = this.get_node(obj);
@@ -2872,7 +2928,9 @@
2872
2928
  for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
2873
2929
  this.show_node(obj[t1], true);
2874
2930
  }
2875
- this.redraw();
2931
+ if (!skip_redraw) {
2932
+ this.redraw();
2933
+ }
2876
2934
  return true;
2877
2935
  }
2878
2936
  obj = this.get_node(obj);
@@ -2993,7 +3051,9 @@
2993
3051
  c = !c;
2994
3052
  }
2995
3053
  if(!this.is_disabled(p[i]) && (c || p[i] === o || p[i] === l)) {
2996
- this.select_node(p[i], true, false, e);
3054
+ if (!this.is_hidden(p[i])) {
3055
+ this.select_node(p[i], true, false, e);
3056
+ }
2997
3057
  }
2998
3058
  else {
2999
3059
  this.deselect_node(p[i], true, e);
@@ -3338,7 +3398,7 @@
3338
3398
  this.open_node(nodes, false, 0);
3339
3399
  delete state.core.open;
3340
3400
  this.set_state(state, callback);
3341
- }, true);
3401
+ });
3342
3402
  }
3343
3403
  return false;
3344
3404
  }
@@ -3448,10 +3508,10 @@
3448
3508
  var opened = [], to_load = [], s = this._data.core.selected.concat([]);
3449
3509
  to_load.push(obj.id);
3450
3510
  if(obj.state.opened === true) { opened.push(obj.id); }
3451
- this.get_node(obj, true).find('.jstree-open').each(function() { opened.push(this.id); });
3511
+ this.get_node(obj, true).find('.jstree-open').each(function() { to_load.push(this.id); opened.push(this.id); });
3452
3512
  this._load_nodes(to_load, $.proxy(function (nodes) {
3453
3513
  this.open_node(opened, false, 0);
3454
- this.select_node(this._data.core.selected);
3514
+ this.select_node(s);
3455
3515
  /**
3456
3516
  * triggered when a node is refreshed
3457
3517
  * @event
@@ -3460,7 +3520,7 @@
3460
3520
  * @param {Array} nodes - an array of the IDs of the nodes that were reloaded
3461
3521
  */
3462
3522
  this.trigger('refresh_node', { 'node' : obj, 'nodes' : nodes });
3463
- }, this));
3523
+ }, this), false, true);
3464
3524
  },
3465
3525
  /**
3466
3526
  * set (change) the ID of a node
@@ -3468,11 +3528,12 @@
3468
3528
  * @param {mixed} obj the node
3469
3529
  * @param {String} id the new ID
3470
3530
  * @return {Boolean}
3531
+ * @trigger set_id.jstree
3471
3532
  */
3472
3533
  set_id : function (obj, id) {
3473
3534
  obj = this.get_node(obj);
3474
3535
  if(!obj || obj.id === $.jstree.root) { return false; }
3475
- var i, j, m = this._model.data;
3536
+ var i, j, m = this._model.data, old = obj.id;
3476
3537
  id = id.toString();
3477
3538
  // update parents (replace current ID with new one in children and children_d)
3478
3539
  m[obj.parent].children[$.inArray(obj.id, m[obj.parent].children)] = id;
@@ -3491,7 +3552,7 @@
3491
3552
  // update model and obj itself (obj.id, this._model.data[KEY])
3492
3553
  i = this.get_node(obj.id, true);
3493
3554
  if(i) {
3494
- i.attr('id', id).children('.jstree-anchor').attr('id', id + '_anchor').end().attr('aria-labelledby', id + '_anchor');
3555
+ i.attr('id', id); //.children('.jstree-anchor').attr('id', id + '_anchor').end().attr('aria-labelledby', id + '_anchor');
3495
3556
  if(this.element.attr('aria-activedescendant') === obj.id) {
3496
3557
  this.element.attr('aria-activedescendant', id);
3497
3558
  }
@@ -3500,6 +3561,14 @@
3500
3561
  obj.id = id;
3501
3562
  obj.li_attr.id = id;
3502
3563
  m[id] = obj;
3564
+ /**
3565
+ * triggered when a node id value is changed
3566
+ * @event
3567
+ * @name set_id.jstree
3568
+ * @param {Object} node
3569
+ * @param {String} old the old id
3570
+ */
3571
+ this.trigger('set_id',{ "node" : obj, "new" : obj.id, "old" : old });
3503
3572
  return true;
3504
3573
  },
3505
3574
  /**
@@ -3555,6 +3624,8 @@
3555
3624
  * @param {Boolean} options.no_id do not return ID
3556
3625
  * @param {Boolean} options.no_children do not include children
3557
3626
  * @param {Boolean} options.no_data do not include node data
3627
+ * @param {Boolean} options.no_li_attr do not include LI attributes
3628
+ * @param {Boolean} options.no_a_attr do not include A attributes
3558
3629
  * @param {Boolean} options.flat return flat JSON instead of nested
3559
3630
  * @return {Object}
3560
3631
  */
@@ -3584,6 +3655,14 @@
3584
3655
  tmp.state[i] = obj.state[i];
3585
3656
  }
3586
3657
  }
3658
+ } else {
3659
+ delete tmp.state;
3660
+ }
3661
+ if(options && options.no_li_attr) {
3662
+ delete tmp.li_attr;
3663
+ }
3664
+ if(options && options.no_a_attr) {
3665
+ delete tmp.a_attr;
3587
3666
  }
3588
3667
  if(options && options.no_id) {
3589
3668
  delete tmp.id;
@@ -3611,7 +3690,7 @@
3611
3690
  },
3612
3691
  /**
3613
3692
  * create a new node (do not confuse with load_node)
3614
- * @name create_node([obj, node, pos, callback, is_loaded])
3693
+ * @name create_node([par, node, pos, callback, is_loaded])
3615
3694
  * @param {mixed} par the parent node (to create a root node use either "#" (string) or `null`)
3616
3695
  * @param {mixed} node the data for the new node (a valid JSON object, or a simple string with the name)
3617
3696
  * @param {mixed} pos the index at which to insert the node, "first" and "last" are also supported, default is "last"
@@ -3765,21 +3844,22 @@
3765
3844
  }
3766
3845
  tmp = obj.children_d.concat([]);
3767
3846
  tmp.push(obj.id);
3847
+ for(i = 0, j = obj.parents.length; i < j; i++) {
3848
+ this._model.data[obj.parents[i]].children_d = $.vakata.array_filter(this._model.data[obj.parents[i]].children_d, function (v) {
3849
+ return $.inArray(v, tmp) === -1;
3850
+ });
3851
+ }
3768
3852
  for(k = 0, l = tmp.length; k < l; k++) {
3769
- for(i = 0, j = obj.parents.length; i < j; i++) {
3770
- pos = $.inArray(tmp[k], this._model.data[obj.parents[i]].children_d);
3771
- if(pos !== -1) {
3772
- this._model.data[obj.parents[i]].children_d = $.vakata.array_remove(this._model.data[obj.parents[i]].children_d, pos);
3773
- }
3774
- }
3775
3853
  if(this._model.data[tmp[k]].state.selected) {
3776
3854
  c = true;
3777
- pos = $.inArray(tmp[k], this._data.core.selected);
3778
- if(pos !== -1) {
3779
- this._data.core.selected = $.vakata.array_remove(this._data.core.selected, pos);
3780
- }
3855
+ break;
3781
3856
  }
3782
3857
  }
3858
+ if (c) {
3859
+ this._data.core.selected = $.vakata.array_filter(this._data.core.selected, function (v) {
3860
+ return $.inArray(v, tmp) === -1;
3861
+ });
3862
+ }
3783
3863
  /**
3784
3864
  * triggered when a node is deleted
3785
3865
  * @event
@@ -3799,7 +3879,9 @@
3799
3879
  top = this.element[0].scrollTop;
3800
3880
  lft = this.element[0].scrollLeft;
3801
3881
  if(par.id === $.jstree.root) {
3802
- this.get_node(this._model.data[$.jstree.root].children[0], true).children('.jstree-anchor').focus();
3882
+ if (this._model.data[$.jstree.root].children[0]) {
3883
+ this.get_node(this._model.data[$.jstree.root].children[0], true).children('.jstree-anchor').focus();
3884
+ }
3803
3885
  }
3804
3886
  else {
3805
3887
  this.get_node(par, true).children('.jstree-anchor').focus();
@@ -3827,7 +3909,7 @@
3827
3909
  var tmp = chk.match(/^move_node|copy_node|create_node$/i) ? par : obj,
3828
3910
  chc = this.settings.core.check_callback;
3829
3911
  if(chk === "move_node" || chk === "copy_node") {
3830
- if((!more || !more.is_multi) && (obj.id === par.id || $.inArray(obj.id, par.children) === pos || $.inArray(par.id, obj.children_d) !== -1)) {
3912
+ if((!more || !more.is_multi) && (obj.id === par.id || (chk === "move_node" && $.inArray(obj.id, par.children) === pos) || $.inArray(par.id, obj.children_d) !== -1)) {
3831
3913
  this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_01', 'reason' : 'Moving parent inside child', 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
3832
3914
  return false;
3833
3915
  }
@@ -4342,6 +4424,7 @@
4342
4424
  if(callback) {
4343
4425
  callback.call(this, tmp, nv, cancel);
4344
4426
  }
4427
+ h2 = null;
4345
4428
  }, this),
4346
4429
  "keydown" : function (e) {
4347
4430
  var key = e.which;
@@ -4380,6 +4463,11 @@
4380
4463
  a.replaceWith(s);
4381
4464
  h1.css(fn);
4382
4465
  h2.css(fn).width(Math.min(h1.text("pW" + h2[0].value).width(),w))[0].select();
4466
+ $(document).one('mousedown.jstree touchstart.jstree dnd_start.vakata', function (e) {
4467
+ if (h2 && e.target !== h2) {
4468
+ $(h2).blur();
4469
+ }
4470
+ });
4383
4471
  },
4384
4472
 
4385
4473
 
@@ -4445,12 +4533,30 @@
4445
4533
  * shows a striped background on the container (if the theme supports it)
4446
4534
  * @name show_stripes()
4447
4535
  */
4448
- show_stripes : function () { this._data.core.themes.stripes = true; this.get_container_ul().addClass("jstree-striped"); },
4536
+ show_stripes : function () {
4537
+ this._data.core.themes.stripes = true;
4538
+ this.get_container_ul().addClass("jstree-striped");
4539
+ /**
4540
+ * triggered when stripes are shown
4541
+ * @event
4542
+ * @name show_stripes.jstree
4543
+ */
4544
+ this.trigger('show_stripes');
4545
+ },
4449
4546
  /**
4450
4547
  * hides the striped background on the container
4451
4548
  * @name hide_stripes()
4452
4549
  */
4453
- hide_stripes : function () { this._data.core.themes.stripes = false; this.get_container_ul().removeClass("jstree-striped"); },
4550
+ hide_stripes : function () {
4551
+ this._data.core.themes.stripes = false;
4552
+ this.get_container_ul().removeClass("jstree-striped");
4553
+ /**
4554
+ * triggered when stripes are hidden
4555
+ * @event
4556
+ * @name hide_stripes.jstree
4557
+ */
4558
+ this.trigger('hide_stripes');
4559
+ },
4454
4560
  /**
4455
4561
  * toggles the striped background on the container
4456
4562
  * @name toggle_stripes()
@@ -4460,12 +4566,30 @@
4460
4566
  * shows the connecting dots (if the theme supports it)
4461
4567
  * @name show_dots()
4462
4568
  */
4463
- show_dots : function () { this._data.core.themes.dots = true; this.get_container_ul().removeClass("jstree-no-dots"); },
4569
+ show_dots : function () {
4570
+ this._data.core.themes.dots = true;
4571
+ this.get_container_ul().removeClass("jstree-no-dots");
4572
+ /**
4573
+ * triggered when dots are shown
4574
+ * @event
4575
+ * @name show_dots.jstree
4576
+ */
4577
+ this.trigger('show_dots');
4578
+ },
4464
4579
  /**
4465
4580
  * hides the connecting dots
4466
4581
  * @name hide_dots()
4467
4582
  */
4468
- hide_dots : function () { this._data.core.themes.dots = false; this.get_container_ul().addClass("jstree-no-dots"); },
4583
+ hide_dots : function () {
4584
+ this._data.core.themes.dots = false;
4585
+ this.get_container_ul().addClass("jstree-no-dots");
4586
+ /**
4587
+ * triggered when dots are hidden
4588
+ * @event
4589
+ * @name hide_dots.jstree
4590
+ */
4591
+ this.trigger('hide_dots');
4592
+ },
4469
4593
  /**
4470
4594
  * toggles the connecting dots
4471
4595
  * @name toggle_dots()
@@ -4475,17 +4599,68 @@
4475
4599
  * show the node icons
4476
4600
  * @name show_icons()
4477
4601
  */
4478
- show_icons : function () { this._data.core.themes.icons = true; this.get_container_ul().removeClass("jstree-no-icons"); },
4602
+ show_icons : function () {
4603
+ this._data.core.themes.icons = true;
4604
+ this.get_container_ul().removeClass("jstree-no-icons");
4605
+ /**
4606
+ * triggered when icons are shown
4607
+ * @event
4608
+ * @name show_icons.jstree
4609
+ */
4610
+ this.trigger('show_icons');
4611
+ },
4479
4612
  /**
4480
4613
  * hide the node icons
4481
4614
  * @name hide_icons()
4482
4615
  */
4483
- hide_icons : function () { this._data.core.themes.icons = false; this.get_container_ul().addClass("jstree-no-icons"); },
4616
+ hide_icons : function () {
4617
+ this._data.core.themes.icons = false;
4618
+ this.get_container_ul().addClass("jstree-no-icons");
4619
+ /**
4620
+ * triggered when icons are hidden
4621
+ * @event
4622
+ * @name hide_icons.jstree
4623
+ */
4624
+ this.trigger('hide_icons');
4625
+ },
4484
4626
  /**
4485
4627
  * toggle the node icons
4486
4628
  * @name toggle_icons()
4487
4629
  */
4488
4630
  toggle_icons : function () { if(this._data.core.themes.icons) { this.hide_icons(); } else { this.show_icons(); } },
4631
+ /**
4632
+ * show the node ellipsis
4633
+ * @name show_icons()
4634
+ */
4635
+ show_ellipsis : function () {
4636
+ this._data.core.themes.ellipsis = true;
4637
+ this.get_container_ul().addClass("jstree-ellipsis");
4638
+ /**
4639
+ * triggered when ellisis is shown
4640
+ * @event
4641
+ * @name show_ellipsis.jstree
4642
+ */
4643
+ this.trigger('show_ellipsis');
4644
+ },
4645
+ /**
4646
+ * hide the node ellipsis
4647
+ * @name hide_ellipsis()
4648
+ */
4649
+ hide_ellipsis : function () {
4650
+ this._data.core.themes.ellipsis = false;
4651
+ this.get_container_ul().removeClass("jstree-ellipsis");
4652
+ /**
4653
+ * triggered when ellisis is hidden
4654
+ * @event
4655
+ * @name hide_ellipsis.jstree
4656
+ */
4657
+ this.trigger('hide_ellipsis');
4658
+ },
4659
+ /**
4660
+ * toggle the node ellipsis
4661
+ * @name toggle_icons()
4662
+ */
4663
+ toggle_ellipsis : function () { if(this._data.core.themes.ellipsis) { this.hide_ellipsis(); } else { this.show_ellipsis(); } },
4489
4664
  /**
4490
4665
  * set the node icon for a node
4491
4666
  * @name set_icon(obj, icon)
@@ -4607,17 +4782,31 @@
4607
4782
  return a;
4608
4783
  };
4609
4784
  // remove item from array
4610
- $.vakata.array_remove = function(array, from, to) {
4611
- var rest = array.slice((to || from) + 1 || array.length);
4612
- array.length = from < 0 ? array.length + from : from;
4613
- array.push.apply(array, rest);
4785
+ $.vakata.array_remove = function(array, from) {
4786
+ array.splice(from, 1);
4614
4787
  return array;
4788
+ //var rest = array.slice((to || from) + 1 || array.length);
4789
+ //array.length = from < 0 ? array.length + from : from;
4790
+ //array.push.apply(array, rest);
4791
+ //return array;
4615
4792
  };
4616
4793
  // remove item from array
4617
4794
  $.vakata.array_remove_item = function(array, item) {
4618
4795
  var tmp = $.inArray(item, array);
4619
4796
  return tmp !== -1 ? $.vakata.array_remove(array, tmp) : array;
4620
4797
  };
4798
+ $.vakata.array_filter = function(c,a,b,d,e) {
4799
+ if (c.filter) {
4800
+ return c.filter(a, b);
4801
+ }
4802
+ d=[];
4803
+ for (e in c) {
4804
+ if (~~e+''===e+'' && e>=0 && a.call(b,c[e],+e,c)) {
4805
+ d.push(c[e]);
4806
+ }
4807
+ }
4808
+ return d;
4809
+ };
4621
4810
 
4622
4811
 
4623
4812
  /**
@@ -4839,12 +5028,17 @@
4839
5028
  m = this._model.data,
4840
5029
  par = this.get_node(obj.parent),
4841
5030
  dom = this.get_node(obj, true),
4842
- i, j, c, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection;
5031
+ i, j, c, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection,
5032
+ sel = {}, cur = this._data[ t ? 'core' : 'checkbox' ].selected;
4843
5033
 
5034
+ for (i = 0, j = cur.length; i < j; i++) {
5035
+ sel[cur[i]] = true;
5036
+ }
4844
5037
  // apply down
4845
5038
  if(s.indexOf('down') !== -1) {
4846
- this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected.concat(obj.children_d));
5039
+ //this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected.concat(obj.children_d));
4847
5040
  for(i = 0, j = obj.children_d.length; i < j; i++) {
5041
+ sel[obj.children_d[i]] = true;
4848
5042
  tmp = m[obj.children_d[i]];
4849
5043
  tmp.state[ t ? 'selected' : 'checked' ] = true;
4850
5044
  if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
@@ -4862,7 +5056,8 @@
4862
5056
  }
4863
5057
  if(c === j) {
4864
5058
  par.state[ t ? 'selected' : 'checked' ] = true;
4865
- this._data[ t ? 'core' : 'checkbox' ].selected.push(par.id);
5059
+ sel[par.id] = true;
5060
+ //this._data[ t ? 'core' : 'checkbox' ].selected.push(par.id);
4866
5061
  tmp = this.get_node(par, true);
4867
5062
  if(tmp && tmp.length) {
4868
5063
  tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
@@ -4875,6 +5070,14 @@
4875
5070
  }
4876
5071
  }
4877
5072
 
5073
+ cur = [];
5074
+ for (i in sel) {
5075
+ if (sel.hasOwnProperty(i)) {
5076
+ cur.push(i);
5077
+ }
5078
+ }
5079
+ this._data[ t ? 'core' : 'checkbox' ].selected = cur;
5080
+
4878
5081
  // apply down (process .children separately?)
4879
5082
  if(s.indexOf('down') !== -1 && dom.length) {
4880
5083
  dom.find('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked').parent().attr('aria-selected', true);
@@ -4894,7 +5097,8 @@
4894
5097
  .on(this.settings.checkbox.tie_selection ? 'deselect_node.jstree' : 'uncheck_node.jstree', $.proxy(function (e, data) {
4895
5098
  var obj = data.node,
4896
5099
  dom = this.get_node(obj, true),
4897
- i, j, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection;
5100
+ i, j, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection,
5101
+ cur = this._data[ t ? 'core' : 'checkbox' ].selected, sel = {};
4898
5102
  if(obj && obj.original && obj.original.state && obj.original.state.undetermined) {
4899
5103
  obj.original.state.undetermined = false;
4900
5104
  }
@@ -4924,18 +5128,24 @@
4924
5128
  }
4925
5129
  }
4926
5130
  }
4927
- tmp = [];
4928
- for(i = 0, j = this._data[ t ? 'core' : 'checkbox' ].selected.length; i < j; i++) {
5131
+ sel = {};
5132
+ for(i = 0, j = cur.length; i < j; i++) {
4929
5133
  // apply down + apply up
4930
5134
  if(
4931
- (s.indexOf('down') === -1 || $.inArray(this._data[ t ? 'core' : 'checkbox' ].selected[i], obj.children_d) === -1) &&
4932
- (s.indexOf('up') === -1 || $.inArray(this._data[ t ? 'core' : 'checkbox' ].selected[i], obj.parents) === -1)
5135
+ (s.indexOf('down') === -1 || $.inArray(cur[i], obj.children_d) === -1) &&
5136
+ (s.indexOf('up') === -1 || $.inArray(cur[i], obj.parents) === -1)
4933
5137
  ) {
4934
- tmp.push(this._data[ t ? 'core' : 'checkbox' ].selected[i]);
5138
+ sel[cur[i]] = true;
4935
5139
  }
4936
5140
  }
4937
- this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(tmp);
4938
-
5141
+ cur = [];
5142
+ for (i in sel) {
5143
+ if (sel.hasOwnProperty(i)) {
5144
+ cur.push(i);
5145
+ }
5146
+ }
5147
+ this._data[ t ? 'core' : 'checkbox' ].selected = cur;
5148
+
4939
5149
  // apply down (process .children separately?)
4940
5150
  if(s.indexOf('down') !== -1 && dom.length) {
4941
5151
  dom.find('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked').parent().attr('aria-selected', false);
@@ -5042,7 +5252,10 @@
5042
5252
  for(i = 0, j = s.length; i < j; i++) {
5043
5253
  if(m[s[i]] && m[s[i]].parents) {
5044
5254
  for(k = 0, l = m[s[i]].parents.length; k < l; k++) {
5045
- if(o[m[s[i]].parents[k]] === undefined && m[s[i]].parents[k] !== $.jstree.root) {
5255
+ if(o[m[s[i]].parents[k]] !== undefined) {
5256
+ break;
5257
+ }
5258
+ if(m[s[i]].parents[k] !== $.jstree.root) {
5046
5259
  o[m[s[i]].parents[k]] = true;
5047
5260
  p.push(m[s[i]].parents[k]);
5048
5261
  }
@@ -5553,16 +5766,18 @@
5553
5766
  /**
5554
5767
  * 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).
5555
5768
  *
5556
- * 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):
5769
+ * 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.
5557
5770
  *
5558
5771
  * * `separator_before` - a boolean indicating if there should be a separator before this item
5559
5772
  * * `separator_after` - a boolean indicating if there should be a separator after this item
5560
5773
  * * `_disabled` - a boolean indicating if this action should be disabled
5561
5774
  * * `label` - a string - the name of the action (could be a function returning a string)
5562
- * * `action` - a function to be executed if this item is chosen
5775
+ * * `title` - a string - an optional tooltip for the item
5776
+ * * `action` - a function to be executed if this item is chosen, the function will receive
5563
5777
  * * `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
5564
5778
  * * `shortcut` - keyCode which will trigger the action if the menu is open (for example `113` for rename, which equals F2)
5565
5779
  * * `shortcut_label` - shortcut label (like for example `F2` for rename)
5780
+ * * `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
5566
5781
  *
5567
5782
  * @name $.jstree.defaults.contextmenu.items
5568
5783
  * @plugin contextmenu
@@ -5680,6 +5895,9 @@
5680
5895
  var last_ts = 0, cto = null, ex, ey;
5681
5896
  this.element
5682
5897
  .on("contextmenu.jstree", ".jstree-anchor", $.proxy(function (e, data) {
5898
+ if (e.target.tagName.toLowerCase() === 'input') {
5899
+ return;
5900
+ }
5683
5901
  e.preventDefault();
5684
5902
  last_ts = e.ctrlKey ? +new Date() : 0;
5685
5903
  if(data || cto) {
@@ -5702,14 +5920,14 @@
5702
5920
  if(!e.originalEvent || !e.originalEvent.changedTouches || !e.originalEvent.changedTouches[0]) {
5703
5921
  return;
5704
5922
  }
5705
- ex = e.pageX;
5706
- ey = e.pageY;
5923
+ ex = e.originalEvent.changedTouches[0].clientX;
5924
+ ey = e.originalEvent.changedTouches[0].clientY;
5707
5925
  cto = setTimeout(function () {
5708
5926
  $(e.currentTarget).trigger('contextmenu', true);
5709
5927
  }, 750);
5710
5928
  })
5711
5929
  .on('touchmove.vakata.jstree', function (e) {
5712
- if(cto && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0] && (Math.abs(ex - e.pageX) > 50 || Math.abs(ey - e.pageY) > 50)) {
5930
+ if(cto && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0] && (Math.abs(ex - e.originalEvent.changedTouches[0].clientX) > 50 || Math.abs(ey - e.originalEvent.changedTouches[0].clientY) > 50)) {
5713
5931
  clearTimeout(cto);
5714
5932
  }
5715
5933
  })
@@ -5740,7 +5958,10 @@
5740
5958
  });
5741
5959
  }
5742
5960
  */
5743
- $(document).on("context_hide.vakata.jstree", $.proxy(function () { this._data.contextmenu.visible = false; }, this));
5961
+ $(document).on("context_hide.vakata.jstree", $.proxy(function (e, data) {
5962
+ this._data.contextmenu.visible = false;
5963
+ $(data.reference).removeClass('jstree-context');
5964
+ }, this));
5744
5965
  };
5745
5966
  this.teardown = function () {
5746
5967
  if(this._data.contextmenu.visible) {
@@ -5803,6 +6024,7 @@
5803
6024
  $(document).one("context_show.vakata.jstree", $.proxy(function (e, data) {
5804
6025
  var cls = 'jstree-contextmenu jstree-' + this.get_theme() + '-contextmenu';
5805
6026
  $(data.element).addClass(cls);
6027
+ a.addClass('jstree-context');
5806
6028
  }, this));
5807
6029
  this._data.contextmenu.visible = true;
5808
6030
  $.vakata.context.show(a, { 'x' : x, 'y' : y }, i);
@@ -5878,7 +6100,7 @@
5878
6100
  }
5879
6101
  sep = false;
5880
6102
  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+"' ":'')+">";
5881
- str += "<"+"a href='#' rel='" + (vakata_context.items.length - 1) + "'>";
6103
+ str += "<"+"a href='#' rel='" + (vakata_context.items.length - 1) + "' " + (val.title ? "title='" + val.title + "'" : "") + ">";
5882
6104
  if($.vakata.context.settings.icons) {
5883
6105
  str += "<"+"i ";
5884
6106
  if(val.icon) {
@@ -5916,7 +6138,8 @@
5916
6138
  o = $(o);
5917
6139
  if(!o.length || !o.children("ul").length) { return; }
5918
6140
  var e = o.children("ul"),
5919
- x = o.offset().left + o.outerWidth(),
6141
+ xl = o.offset().left,
6142
+ x = xl + o.outerWidth(),
5920
6143
  y = o.offset().top,
5921
6144
  w = e.width(),
5922
6145
  h = e.height(),
@@ -5927,11 +6150,23 @@
5927
6150
  o[x - (w + 10 + o.outerWidth()) < 0 ? "addClass" : "removeClass"]("vakata-context-left");
5928
6151
  }
5929
6152
  else {
5930
- o[x + w + 10 > dw ? "addClass" : "removeClass"]("vakata-context-right");
6153
+ o[x + w > dw && xl > dw - x ? "addClass" : "removeClass"]("vakata-context-right");
5931
6154
  }
5932
6155
  if(y + h + 10 > dh) {
5933
6156
  e.css("bottom","-1px");
5934
6157
  }
6158
+
6159
+ //if does not fit - stick it to the side
6160
+ if (o.hasClass('vakata-context-right')) {
6161
+ if (xl < w) {
6162
+ e.css("margin-right", xl - w);
6163
+ }
6164
+ } else {
6165
+ if (dw - x < w) {
6166
+ e.css("margin-left", dw - x - w);
6167
+ }
6168
+ }
6169
+
5935
6170
  e.show();
5936
6171
  },
5937
6172
  show : function (reference, position, data) {
@@ -6070,7 +6305,7 @@
6070
6305
  switch(e.which) {
6071
6306
  case 13:
6072
6307
  case 32:
6073
- e.type = "mouseup";
6308
+ e.type = "click";
6074
6309
  e.preventDefault();
6075
6310
  $(e.currentTarget).trigger(e);
6076
6311
  break;
@@ -6141,6 +6376,7 @@
6141
6376
  }($));
6142
6377
  // $.jstree.defaults.plugins.push("contextmenu");
6143
6378
 
6379
+
6144
6380
  /**
6145
6381
  * ### Drag'n'drop plugin
6146
6382
  *
@@ -6212,34 +6448,90 @@
6212
6448
  * @name $.jstree.defaults.dnd.large_drag_target
6213
6449
  * @plugin dnd
6214
6450
  */
6215
- large_drag_target : false
6451
+ large_drag_target : false,
6452
+ /**
6453
+ * controls whether use HTML5 dnd api instead of classical. That will allow better integration of dnd events with other HTML5 controls.
6454
+ * @reference http://caniuse.com/#feat=dragndrop
6455
+ * @name $.jstree.defaults.dnd.use_html5
6456
+ * @plugin dnd
6457
+ */
6458
+ use_html5: false
6216
6459
  };
6460
+ var drg, elm;
6217
6461
  // TODO: now check works by checking for each node individually, how about max_children, unique, etc?
6218
6462
  $.jstree.plugins.dnd = function (options, parent) {
6463
+ this.init = function (el, options) {
6464
+ parent.init.call(this, el, options);
6465
+ this.settings.dnd.use_html5 = this.settings.dnd.use_html5 && ('draggable' in document.createElement('span'));
6466
+ };
6219
6467
  this.bind = function () {
6220
6468
  parent.bind.call(this);
6221
6469
 
6222
6470
  this.element
6223
- .on('mousedown.jstree touchstart.jstree', this.settings.dnd.large_drag_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) {
6224
- if(this.settings.dnd.large_drag_target && $(e.target).closest('.jstree-node')[0] !== e.currentTarget) {
6225
- return true;
6226
- }
6227
- if(e.type === "touchstart" && (!this.settings.dnd.touch || (this.settings.dnd.touch === 'selected' && !$(e.currentTarget).closest('.jstree-node').children('.jstree-anchor').hasClass('jstree-clicked')))) {
6228
- return true;
6229
- }
6230
- var obj = this.get_node(e.target),
6231
- mlt = this.is_selected(obj) && this.settings.dnd.drag_selection ? this.get_top_selected().length : 1,
6232
- txt = (mlt > 1 ? mlt + ' ' + this.get_string('nodes') : this.get_text(e.currentTarget));
6233
- if(this.settings.core.force_text) {
6234
- txt = $.vakata.html.escape(txt);
6471
+ .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) {
6472
+ if(this.settings.dnd.large_drag_target && $(e.target).closest('.jstree-node')[0] !== e.currentTarget) {
6473
+ return true;
6474
+ }
6475
+ if(e.type === "touchstart" && (!this.settings.dnd.touch || (this.settings.dnd.touch === 'selected' && !$(e.currentTarget).closest('.jstree-node').children('.jstree-anchor').hasClass('jstree-clicked')))) {
6476
+ return true;
6477
+ }
6478
+ var obj = this.get_node(e.target),
6479
+ mlt = this.is_selected(obj) && this.settings.dnd.drag_selection ? this.get_top_selected().length : 1,
6480
+ txt = (mlt > 1 ? mlt + ' ' + this.get_string('nodes') : this.get_text(e.currentTarget));
6481
+ if(this.settings.core.force_text) {
6482
+ txt = $.vakata.html.escape(txt);
6483
+ }
6484
+ if(obj && obj.id && obj.id !== $.jstree.root && (e.which === 1 || e.type === "touchstart" || e.type === "dragstart") &&
6485
+ (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)))
6486
+ ) {
6487
+ drg = { 'jstree' : true, 'origin' : this, 'obj' : this.get_node(obj,true), 'nodes' : mlt > 1 ? this.get_top_selected() : [obj.id] };
6488
+ elm = e.currentTarget;
6489
+ if (this.settings.dnd.use_html5) {
6490
+ $.vakata.dnd._trigger('start', e, { 'helper': $(), 'element': elm, 'data': drg });
6491
+ } else {
6492
+ this.element.trigger('mousedown.jstree');
6493
+ 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>');
6494
+ }
6495
+ }
6496
+ }, this));
6497
+ if (this.settings.dnd.use_html5) {
6498
+ this.element
6499
+ .on('dragover.jstree', function (e) {
6500
+ e.preventDefault();
6501
+ $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg });
6502
+ return false;
6503
+ })
6504
+ //.on('dragenter.jstree', this.settings.dnd.large_drop_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) {
6505
+ // e.preventDefault();
6506
+ // $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg });
6507
+ // return false;
6508
+ // }, this))
6509
+ .on('drop.jstree', $.proxy(function (e) {
6510
+ e.preventDefault();
6511
+ $.vakata.dnd._trigger('stop', e, { 'helper': $(), 'element': elm, 'data': drg });
6512
+ return false;
6513
+ }, this));
6514
+ }
6515
+ };
6516
+ this.redraw_node = function(obj, deep, callback, force_render) {
6517
+ obj = parent.redraw_node.apply(this, arguments);
6518
+ if (obj && this.settings.dnd.use_html5) {
6519
+ if (this.settings.dnd.large_drag_target) {
6520
+ obj.setAttribute('draggable', true);
6521
+ } else {
6522
+ var i, j, tmp = null;
6523
+ for(i = 0, j = obj.childNodes.length; i < j; i++) {
6524
+ if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) {
6525
+ tmp = obj.childNodes[i];
6526
+ break;
6527
+ }
6235
6528
  }
6236
- if(obj && obj.id && obj.id !== $.jstree.root && (e.which === 1 || e.type === "touchstart") &&
6237
- (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)))
6238
- ) {
6239
- this.element.trigger('mousedown.jstree');
6240
- return $.vakata.dnd.start(e, { 'jstree' : true, 'origin' : this, 'obj' : this.get_node(obj,true), 'nodes' : mlt > 1 ? this.get_top_selected() : [obj.id] }, '<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>');
6529
+ if(tmp) {
6530
+ tmp.setAttribute('draggable', true);
6241
6531
  }
6242
- }, this));
6532
+ }
6533
+ }
6534
+ return obj;
6243
6535
  };
6244
6536
  };
6245
6537
 
@@ -6259,7 +6551,11 @@
6259
6551
  marker.appendTo('body'); //.show();
6260
6552
  })
6261
6553
  .on('dnd_move.vakata.jstree', function (e, data) {
6262
- if(opento) { clearTimeout(opento); }
6554
+ if(opento) {
6555
+ if (!data.event || data.event.type !== 'dragover' || data.event.target !== lastev.target) {
6556
+ clearTimeout(opento);
6557
+ }
6558
+ }
6263
6559
  if(!data || !data.data || !data.data.jstree) { return; }
6264
6560
 
6265
6561
  // if we are hovering the marker image do nothing (can happen on "inside" drags)
@@ -6272,16 +6568,17 @@
6272
6568
  ref = false,
6273
6569
  off = false,
6274
6570
  rel = false,
6275
- tmp, l, t, h, p, i, o, ok, t1, t2, op, ps, pr, ip, tm;
6571
+ tmp, l, t, h, p, i, o, ok, t1, t2, op, ps, pr, ip, tm, is_copy, pn;
6276
6572
  // if we are over an instance
6277
6573
  if(ins && ins._data && ins._data.dnd) {
6278
6574
  marker.attr('class', 'jstree-' + ins.get_theme() + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ));
6575
+ is_copy = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey)));
6279
6576
  data.helper
6280
6577
  .children().attr('class', 'jstree-' + ins.get_theme() + ' jstree-' + ins.get_theme() + '-' + ins.get_theme_variant() + ' ' + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ))
6281
- .find('.jstree-copy').first()[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'show' : 'hide' ]();
6282
-
6578
+ .find('.jstree-copy').first()[ is_copy ? 'show' : 'hide' ]();
6283
6579
 
6284
6580
  // if are hovering the container itself add a new root node
6581
+ //console.log(data.event);
6285
6582
  if( (data.event.target === ins.element[0] || data.event.target === ins.get_container_ul()[0]) && ins.get_container_ul().children().length === 0) {
6286
6583
  ok = true;
6287
6584
  for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) {
@@ -6292,6 +6589,9 @@
6292
6589
  lastmv = { 'ins' : ins, 'par' : $.jstree.root, 'pos' : 'last' };
6293
6590
  marker.hide();
6294
6591
  data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok');
6592
+ if (data.event.originalEvent && data.event.originalEvent.dataTransfer) {
6593
+ data.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move';
6594
+ }
6295
6595
  return;
6296
6596
  }
6297
6597
  }
@@ -6300,7 +6600,7 @@
6300
6600
  ref = ins.settings.dnd.large_drop_target ? $(data.event.target).closest('.jstree-node').children('.jstree-anchor') : $(data.event.target).closest('.jstree-anchor');
6301
6601
  if(ref && ref.length && ref.parent().is('.jstree-closed, .jstree-open, .jstree-leaf')) {
6302
6602
  off = ref.offset();
6303
- rel = data.event.pageY - off.top;
6603
+ rel = (data.event.pageY !== undefined ? data.event.pageY : data.event.originalEvent.pageY) - off.top;
6304
6604
  h = ref.outerHeight();
6305
6605
  if(rel < h / 3) {
6306
6606
  o = ['b', 'i', 'a'];
@@ -6354,9 +6654,17 @@
6354
6654
  opento = setTimeout((function (x, z) { return function () { x.open_node(z); }; }(ins, ref)), ins.settings.dnd.open_timeout);
6355
6655
  }
6356
6656
  if(ok) {
6657
+ pn = ins.get_node(p, true);
6658
+ if (!pn.hasClass('.jstree-dnd-parent')) {
6659
+ $('.jstree-dnd-parent').removeClass('jstree-dnd-parent');
6660
+ pn.addClass('jstree-dnd-parent');
6661
+ }
6357
6662
  lastmv = { 'ins' : ins, 'par' : p, 'pos' : v === 'i' && ip === 'last' && i === 0 && !ins.is_loaded(tm) ? 'last' : i };
6358
6663
  marker.css({ 'left' : l + 'px', 'top' : t + 'px' }).show();
6359
6664
  data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok');
6665
+ if (data.event.originalEvent && data.event.originalEvent.dataTransfer) {
6666
+ data.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move';
6667
+ }
6360
6668
  laster = {};
6361
6669
  o = true;
6362
6670
  return false;
@@ -6366,8 +6674,12 @@
6366
6674
  }
6367
6675
  }
6368
6676
  }
6677
+ $('.jstree-dnd-parent').removeClass('jstree-dnd-parent');
6369
6678
  lastmv = false;
6370
6679
  data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er');
6680
+ if (data.event.originalEvent && data.event.originalEvent.dataTransfer) {
6681
+ data.event.originalEvent.dataTransfer.dropEffect = 'none';
6682
+ }
6371
6683
  marker.hide();
6372
6684
  })
6373
6685
  .on('dnd_scroll.vakata.jstree', function (e, data) {
@@ -6378,6 +6690,7 @@
6378
6690
  data.helper.find('.jstree-icon').first().removeClass('jstree-ok').addClass('jstree-er');
6379
6691
  })
6380
6692
  .on('dnd_stop.vakata.jstree', function (e, data) {
6693
+ $('.jstree-dnd-parent').removeClass('jstree-dnd-parent');
6381
6694
  if(opento) { clearTimeout(opento); }
6382
6695
  if(!data || !data.data || !data.data.jstree) { return; }
6383
6696
  marker.hide().detach();
@@ -6403,11 +6716,21 @@
6403
6716
  .on('keyup.jstree keydown.jstree', function (e, data) {
6404
6717
  data = $.vakata.dnd._get();
6405
6718
  if(data && data.data && data.data.jstree) {
6406
- 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' ]();
6407
- if(lastev) {
6408
- lastev.metaKey = e.metaKey;
6409
- lastev.ctrlKey = e.ctrlKey;
6410
- $.vakata.dnd._trigger('move', lastev);
6719
+ if (e.type === "keyup" && e.which === 27) {
6720
+ if (opento) { clearTimeout(opento); }
6721
+ lastmv = false;
6722
+ laster = false;
6723
+ lastev = false;
6724
+ opento = false;
6725
+ marker.hide().detach();
6726
+ $.vakata.dnd._clean();
6727
+ } else {
6728
+ 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' ]();
6729
+ if(lastev) {
6730
+ lastev.metaKey = e.metaKey;
6731
+ lastev.ctrlKey = e.ctrlKey;
6732
+ $.vakata.dnd._trigger('move', lastev);
6733
+ }
6411
6734
  }
6412
6735
  }
6413
6736
  });
@@ -6450,8 +6773,10 @@
6450
6773
  threshold : 5,
6451
6774
  threshold_touch : 50
6452
6775
  },
6453
- _trigger : function (event_name, e) {
6454
- var data = $.vakata.dnd._get();
6776
+ _trigger : function (event_name, e, data) {
6777
+ if (data === undefined) {
6778
+ data = $.vakata.dnd._get();
6779
+ }
6455
6780
  data.event = e;
6456
6781
  $(document).triggerHandler("dnd_" + event_name + ".vakata", data);
6457
6782
  },
@@ -6523,7 +6848,11 @@
6523
6848
  try {
6524
6849
  e.currentTarget.unselectable = "on";
6525
6850
  e.currentTarget.onselectstart = function() { return false; };
6526
- if(e.currentTarget.style) { e.currentTarget.style.MozUserSelect = "none"; }
6851
+ if(e.currentTarget.style) {
6852
+ e.currentTarget.style.touchAction = "none";
6853
+ e.currentTarget.style.msTouchAction = "none";
6854
+ e.currentTarget.style.MozUserSelect = "none";
6855
+ }
6527
6856
  } catch(ignore) { }
6528
6857
  vakata_dnd.init_x = e.pageX;
6529
6858
  vakata_dnd.init_y = e.pageY;
@@ -6564,6 +6893,7 @@
6564
6893
  vakata_dnd.helper_w = vakata_dnd.helper.outerWidth();
6565
6894
  }
6566
6895
  vakata_dnd.is_drag = true;
6896
+ $(vakata_dnd.target).one('click.vakata', false);
6567
6897
  /**
6568
6898
  * triggered on the document when a drag starts
6569
6899
  * @event
@@ -6664,6 +6994,9 @@
6664
6994
  * @param {jQuery} helper the helper shown next to the mouse
6665
6995
  * @param {Object} event the event that caused the stop
6666
6996
  */
6997
+ if (e.target !== vakata_dnd.target) {
6998
+ $(vakata_dnd.target).off('click.vakata');
6999
+ }
6667
7000
  $.vakata.dnd._trigger("stop", e);
6668
7001
  }
6669
7002
  else {
@@ -6709,58 +7042,95 @@
6709
7042
  $.jstree.defaults.massload = null;
6710
7043
  $.jstree.plugins.massload = function (options, parent) {
6711
7044
  this.init = function (el, options) {
6712
- parent.init.call(this, el, options);
6713
7045
  this._data.massload = {};
7046
+ parent.init.call(this, el, options);
6714
7047
  };
6715
- this._load_nodes = function (nodes, callback, is_callback) {
6716
- var s = this.settings.massload;
6717
- if(is_callback && !$.isEmptyObject(this._data.massload)) {
6718
- return parent._load_nodes.call(this, nodes, callback, is_callback);
6719
- }
6720
- if($.isFunction(s)) {
6721
- return s.call(this, nodes, $.proxy(function (data) {
6722
- if(data) {
6723
- for(var i in data) {
6724
- if(data.hasOwnProperty(i)) {
6725
- this._data.massload[i] = data[i];
6726
- }
7048
+ this._load_nodes = function (nodes, callback, is_callback, force_reload) {
7049
+ var s = this.settings.massload,
7050
+ nodesString = JSON.stringify(nodes),
7051
+ toLoad = [],
7052
+ m = this._model.data,
7053
+ i, j, dom;
7054
+ if (!is_callback) {
7055
+ for(i = 0, j = nodes.length; i < j; i++) {
7056
+ if(!m[nodes[i]] || ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || force_reload) ) {
7057
+ toLoad.push(nodes[i]);
7058
+ dom = this.get_node(nodes[i], true);
7059
+ if (dom && dom.length) {
7060
+ dom.addClass("jstree-loading").attr('aria-busy',true);
6727
7061
  }
6728
7062
  }
6729
- parent._load_nodes.call(this, nodes, callback, is_callback);
6730
- }, this));
6731
- }
6732
- if(typeof s === 'object' && s && s.url) {
6733
- s = $.extend(true, {}, s);
6734
- if($.isFunction(s.url)) {
6735
- s.url = s.url.call(this, nodes);
6736
- }
6737
- if($.isFunction(s.data)) {
6738
- s.data = s.data.call(this, nodes);
6739
7063
  }
6740
- return $.ajax(s)
6741
- .done($.proxy(function (data,t,x) {
7064
+ this._data.massload = {};
7065
+ if (toLoad.length) {
7066
+ if($.isFunction(s)) {
7067
+ return s.call(this, toLoad, $.proxy(function (data) {
7068
+ var i, j;
6742
7069
  if(data) {
6743
- for(var i in data) {
7070
+ for(i in data) {
6744
7071
  if(data.hasOwnProperty(i)) {
6745
7072
  this._data.massload[i] = data[i];
6746
7073
  }
6747
7074
  }
6748
7075
  }
6749
- parent._load_nodes.call(this, nodes, callback, is_callback);
6750
- }, this))
6751
- .fail($.proxy(function (f) {
6752
- parent._load_nodes.call(this, nodes, callback, is_callback);
7076
+ for(i = 0, j = nodes.length; i < j; i++) {
7077
+ dom = this.get_node(nodes[i], true);
7078
+ if (dom && dom.length) {
7079
+ dom.removeClass("jstree-loading").attr('aria-busy',false);
7080
+ }
7081
+ }
7082
+ parent._load_nodes.call(this, nodes, callback, is_callback, force_reload);
6753
7083
  }, this));
7084
+ }
7085
+ if(typeof s === 'object' && s && s.url) {
7086
+ s = $.extend(true, {}, s);
7087
+ if($.isFunction(s.url)) {
7088
+ s.url = s.url.call(this, toLoad);
7089
+ }
7090
+ if($.isFunction(s.data)) {
7091
+ s.data = s.data.call(this, toLoad);
7092
+ }
7093
+ return $.ajax(s)
7094
+ .done($.proxy(function (data,t,x) {
7095
+ var i, j;
7096
+ if(data) {
7097
+ for(i in data) {
7098
+ if(data.hasOwnProperty(i)) {
7099
+ this._data.massload[i] = data[i];
7100
+ }
7101
+ }
7102
+ }
7103
+ for(i = 0, j = nodes.length; i < j; i++) {
7104
+ dom = this.get_node(nodes[i], true);
7105
+ if (dom && dom.length) {
7106
+ dom.removeClass("jstree-loading").attr('aria-busy',false);
7107
+ }
7108
+ }
7109
+ parent._load_nodes.call(this, nodes, callback, is_callback, force_reload);
7110
+ }, this))
7111
+ .fail($.proxy(function (f) {
7112
+ parent._load_nodes.call(this, nodes, callback, is_callback, force_reload);
7113
+ }, this));
7114
+ }
7115
+ }
6754
7116
  }
6755
- return parent._load_nodes.call(this, nodes, callback, is_callback);
7117
+ return parent._load_nodes.call(this, nodes, callback, is_callback, force_reload);
6756
7118
  };
6757
7119
  this._load_node = function (obj, callback) {
6758
- var d = this._data.massload[obj.id];
6759
- if(d) {
6760
- return this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $($.parseHTML(d)).filter(function () { return this.nodeType !== 3; }) : d, function (status) {
6761
- callback.call(this, status);
6762
- delete this._data.massload[obj.id];
6763
- });
7120
+ var data = this._data.massload[obj.id],
7121
+ rslt = null, dom;
7122
+ if(data) {
7123
+ rslt = this[typeof data === 'string' ? '_append_html_data' : '_append_json_data'](
7124
+ obj,
7125
+ typeof data === 'string' ? $($.parseHTML(data)).filter(function () { return this.nodeType !== 3; }) : data,
7126
+ function (status) { callback.call(this, status); }
7127
+ );
7128
+ dom = this.get_node(obj.id, true);
7129
+ if (dom && dom.length) {
7130
+ dom.removeClass("jstree-loading").attr('aria-busy',false);
7131
+ }
7132
+ delete this._data.massload[obj.id];
7133
+ return rslt;
6764
7134
  }
6765
7135
  return parent._load_node.call(this, obj, callback);
6766
7136
  };
@@ -6779,10 +7149,10 @@
6779
7149
  */
6780
7150
  $.jstree.defaults.search = {
6781
7151
  /**
6782
- * a jQuery-like AJAX config, which jstree uses if a server should be queried for results.
6783
- *
7152
+ * a jQuery-like AJAX config, which jstree uses if a server should be queried for results.
7153
+ *
6784
7154
  * A `str` (which is the search string) parameter will be added with the request, an optional `inside` parameter will be added if the search is limited to a node id. The expected result is a JSON array with nodes that need to be opened so that matching nodes will be revealed.
6785
- * Leave this setting as `false` to not query the server. You can also set this to a function, which will be invoked in the instance's scope and receive 3 parameters - the search string, the callback to call with the array of nodes to load, and the optional node ID to limit the search to
7155
+ * Leave this setting as `false` to not query the server. You can also set this to a function, which will be invoked in the instance's scope and receive 3 parameters - the search string, the callback to call with the array of nodes to load, and the optional node ID to limit the search to
6786
7156
  * @name $.jstree.defaults.search.ajax
6787
7157
  * @plugin search
6788
7158
  */
@@ -6800,7 +7170,7 @@
6800
7170
  */
6801
7171
  case_sensitive : false,
6802
7172
  /**
6803
- * Indicates if the tree should be filtered (by default) to show only matching nodes (keep in mind this can be a heavy on large trees in old browsers).
7173
+ * Indicates if the tree should be filtered (by default) to show only matching nodes (keep in mind this can be a heavy on large trees in old browsers).
6804
7174
  * This setting can be changed at runtime when calling the search method. Default is `false`.
6805
7175
  * @name $.jstree.defaults.search.show_only_matches
6806
7176
  * @plugin search
@@ -6849,24 +7219,30 @@
6849
7219
  this.element
6850
7220
  .on("search.jstree", $.proxy(function (e, data) {
6851
7221
  if(this._data.search.som && data.res.length) {
6852
- var m = this._model.data, i, j, p = [];
7222
+ var m = this._model.data, i, j, p = [], k, l;
6853
7223
  for(i = 0, j = data.res.length; i < j; i++) {
6854
7224
  if(m[data.res[i]] && !m[data.res[i]].state.hidden) {
6855
7225
  p.push(data.res[i]);
6856
7226
  p = p.concat(m[data.res[i]].parents);
6857
7227
  if(this._data.search.smc) {
6858
- p = p.concat(m[data.res[i]].children_d);
7228
+ for (k = 0, l = m[data.res[i]].children_d.length; k < l; k++) {
7229
+ if (m[m[data.res[i]].children_d[k]] && !m[m[data.res[i]].children_d[k]].state.hidden) {
7230
+ p.push(m[data.res[i]].children_d[k]);
7231
+ }
7232
+ }
6859
7233
  }
6860
7234
  }
6861
7235
  }
6862
7236
  p = $.vakata.array_remove_item($.vakata.array_unique(p), $.jstree.root);
6863
7237
  this._data.search.hdn = this.hide_all(true);
6864
- this.show_node(p);
7238
+ this.show_node(p, true);
7239
+ this.redraw(true);
6865
7240
  }
6866
7241
  }, this))
6867
7242
  .on("clear_search.jstree", $.proxy(function (e, data) {
6868
7243
  if(this._data.search.som && data.res.length) {
6869
- this.show_node(this._data.search.hdn);
7244
+ this.show_node(this._data.search.hdn, true);
7245
+ this.redraw(true);
6870
7246
  }
6871
7247
  }, this));
6872
7248
  };
@@ -6908,8 +7284,8 @@
6908
7284
  return a.call(this, str, $.proxy(function (d) {
6909
7285
  if(d && d.d) { d = d.d; }
6910
7286
  this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () {
6911
- this.search(str, true, show_only_matches, inside, append);
6912
- }, true);
7287
+ this.search(str, true, show_only_matches, inside, append, show_only_matches_children);
7288
+ });
6913
7289
  }, this), inside);
6914
7290
  }
6915
7291
  else {
@@ -6919,7 +7295,10 @@
6919
7295
  if(inside) {
6920
7296
  a.data.inside = inside;
6921
7297
  }
6922
- return $.ajax(a)
7298
+ if (this._data.search.lastRequest) {
7299
+ this._data.search.lastRequest.abort();
7300
+ }
7301
+ this._data.search.lastRequest = $.ajax(a)
6923
7302
  .fail($.proxy(function () {
6924
7303
  this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'search', 'id' : 'search_01', 'reason' : 'Could not load search parents', 'data' : JSON.stringify(a) };
6925
7304
  this.settings.core.error.call(this, this._data.core.last_error);
@@ -6927,9 +7306,10 @@
6927
7306
  .done($.proxy(function (d) {
6928
7307
  if(d && d.d) { d = d.d; }
6929
7308
  this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () {
6930
- this.search(str, true, show_only_matches, inside, append);
6931
- }, true);
7309
+ this.search(str, true, show_only_matches, inside, append, show_only_matches_children);
7310
+ });
6932
7311
  }, this));
7312
+ return this._data.search.lastRequest;
6933
7313
  }
6934
7314
  }
6935
7315
  if(!append) {
@@ -6944,7 +7324,7 @@
6944
7324
  f = new $.vakata.search(str, true, { caseSensitive : s.case_sensitive, fuzzy : s.fuzzy });
6945
7325
  $.each(m[inside ? inside : $.jstree.root].children_d, function (ii, i) {
6946
7326
  var v = m[i];
6947
- if(v.text && (!s.search_leaves_only || (v.state.loaded && v.children.length === 0)) && ( (s.search_callback && s.search_callback.call(this, str, v)) || (!s.search_callback && f.search(v.text).isMatch) ) ) {
7327
+ if(v.text && !v.state.hidden && (!s.search_leaves_only || (v.state.loaded && v.children.length === 0)) && ( (s.search_callback && s.search_callback.call(this, str, v)) || (!s.search_callback && f.search(v.text).isMatch) ) ) {
6948
7328
  r.push(i);
6949
7329
  p = p.concat(v.parents);
6950
7330
  }
@@ -7342,6 +7722,8 @@
7342
7722
  * * `max_depth` the maximum number of nesting this node type can have. A value of `1` would mean that the node can have children, but no grandchildren. Do not specify or set to `-1` for unlimited.
7343
7723
  * * `valid_children` an array of node type strings, that nodes of this type can have as children. Do not specify or set to `-1` for no limits.
7344
7724
  * * `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. Omit to use the default icon from your theme.
7725
+ * * `li_attr` an object of values which will be used to add HTML attributes on the resulting LI DOM node (merged with the node's own data)
7726
+ * * `a_attr` an object of values which will be used to add HTML attributes on the resulting A DOM node (merged with the node's own data)
7345
7727
  *
7346
7728
  * There are two predefined types:
7347
7729
  *
@@ -7383,7 +7765,7 @@
7383
7765
  var m = this._model.data,
7384
7766
  dpc = data.nodes,
7385
7767
  t = this.settings.types,
7386
- i, j, c = 'default';
7768
+ i, j, c = 'default', k;
7387
7769
  for(i = 0, j = dpc.length; i < j; i++) {
7388
7770
  c = 'default';
7389
7771
  if(m[dpc[i]].original && m[dpc[i]].original.type && t[m[dpc[i]].original.type]) {
@@ -7396,6 +7778,39 @@
7396
7778
  if(m[dpc[i]].icon === true && t[c].icon !== undefined) {
7397
7779
  m[dpc[i]].icon = t[c].icon;
7398
7780
  }
7781
+ if(t[c].li_attr !== undefined && typeof t[c].li_attr === 'object') {
7782
+ for (k in t[c].li_attr) {
7783
+ if (t[c].li_attr.hasOwnProperty(k)) {
7784
+ if (k === 'id') {
7785
+ continue;
7786
+ }
7787
+ else if (m[dpc[i]].li_attr[k] === undefined) {
7788
+ m[dpc[i]].li_attr[k] = t[c].li_attr[k];
7789
+ }
7790
+ else if (k === 'class') {
7791
+ m[dpc[i]].li_attr['class'] = t[c].li_attr['class'] + ' ' + m[dpc[i]].li_attr['class'];
7792
+ }
7793
+ }
7794
+ }
7795
+ }
7796
+ if(t[c].a_attr !== undefined && typeof t[c].a_attr === 'object') {
7797
+ for (k in t[c].a_attr) {
7798
+ if (t[c].a_attr.hasOwnProperty(k)) {
7799
+ if (k === 'id') {
7800
+ continue;
7801
+ }
7802
+ else if (m[dpc[i]].a_attr[k] === undefined) {
7803
+ m[dpc[i]].a_attr[k] = t[c].a_attr[k];
7804
+ }
7805
+ else if (k === 'href' && m[dpc[i]].a_attr[k] === '#') {
7806
+ m[dpc[i]].a_attr['href'] = t[c].a_attr['href'];
7807
+ }
7808
+ else if (k === 'class') {
7809
+ m[dpc[i]].a_attr['class'] = t[c].a_attr['class'] + ' ' + m[dpc[i]].a_attr['class'];
7810
+ }
7811
+ }
7812
+ }
7813
+ }
7399
7814
  }
7400
7815
  m[$.jstree.root].type = $.jstree.root;
7401
7816
  }, this));
@@ -7526,7 +7941,7 @@
7526
7941
  * @plugin types
7527
7942
  */
7528
7943
  this.set_type = function (obj, type) {
7529
- var t, t1, t2, old_type, old_icon;
7944
+ var m = this._model.data, t, t1, t2, old_type, old_icon, k, d, a;
7530
7945
  if($.isArray(obj)) {
7531
7946
  obj = obj.slice();
7532
7947
  for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
@@ -7537,18 +7952,120 @@
7537
7952
  t = this.settings.types;
7538
7953
  obj = this.get_node(obj);
7539
7954
  if(!t[type] || !obj) { return false; }
7955
+ d = this.get_node(obj, true);
7956
+ if (d && d.length) {
7957
+ a = d.children('.jstree-anchor');
7958
+ }
7540
7959
  old_type = obj.type;
7541
7960
  old_icon = this.get_icon(obj);
7542
7961
  obj.type = type;
7543
- if(old_icon === true || (t[old_type] && t[old_type].icon !== undefined && old_icon === t[old_type].icon)) {
7962
+ if(old_icon === true || !t[old_type] || (t[old_type].icon !== undefined && old_icon === t[old_type].icon)) {
7544
7963
  this.set_icon(obj, t[type].icon !== undefined ? t[type].icon : true);
7545
7964
  }
7965
+
7966
+ // remove old type props
7967
+ if(t[old_type] && t[old_type].li_attr !== undefined && typeof t[old_type].li_attr === 'object') {
7968
+ for (k in t[old_type].li_attr) {
7969
+ if (t[old_type].li_attr.hasOwnProperty(k)) {
7970
+ if (k === 'id') {
7971
+ continue;
7972
+ }
7973
+ else if (k === 'class') {
7974
+ m[obj.id].li_attr['class'] = (m[obj.id].li_attr['class'] || '').replace(t[old_type].li_attr[k], '');
7975
+ if (d) { d.removeClass(t[old_type].li_attr[k]); }
7976
+ }
7977
+ else if (m[obj.id].li_attr[k] === t[old_type].li_attr[k]) {
7978
+ m[obj.id].li_attr[k] = null;
7979
+ if (d) { d.removeAttr(k); }
7980
+ }
7981
+ }
7982
+ }
7983
+ }
7984
+ if(t[old_type] && t[old_type].a_attr !== undefined && typeof t[old_type].a_attr === 'object') {
7985
+ for (k in t[old_type].a_attr) {
7986
+ if (t[old_type].a_attr.hasOwnProperty(k)) {
7987
+ if (k === 'id') {
7988
+ continue;
7989
+ }
7990
+ else if (k === 'class') {
7991
+ m[obj.id].a_attr['class'] = (m[obj.id].a_attr['class'] || '').replace(t[old_type].a_attr[k], '');
7992
+ if (a) { a.removeClass(t[old_type].a_attr[k]); }
7993
+ }
7994
+ else if (m[obj.id].a_attr[k] === t[old_type].a_attr[k]) {
7995
+ if (k === 'href') {
7996
+ m[obj.id].a_attr[k] = '#';
7997
+ if (a) { a.attr('href', '#'); }
7998
+ }
7999
+ else {
8000
+ delete m[obj.id].a_attr[k];
8001
+ if (a) { a.removeAttr(k); }
8002
+ }
8003
+ }
8004
+ }
8005
+ }
8006
+ }
8007
+
8008
+ // add new props
8009
+ if(t[type].li_attr !== undefined && typeof t[type].li_attr === 'object') {
8010
+ for (k in t[type].li_attr) {
8011
+ if (t[type].li_attr.hasOwnProperty(k)) {
8012
+ if (k === 'id') {
8013
+ continue;
8014
+ }
8015
+ else if (m[obj.id].li_attr[k] === undefined) {
8016
+ m[obj.id].li_attr[k] = t[type].li_attr[k];
8017
+ if (d) {
8018
+ if (k === 'class') {
8019
+ d.addClass(t[type].li_attr[k]);
8020
+ }
8021
+ else {
8022
+ d.attr(k, t[type].li_attr[k]);
8023
+ }
8024
+ }
8025
+ }
8026
+ else if (k === 'class') {
8027
+ m[obj.id].li_attr['class'] = t[type].li_attr[k] + ' ' + m[obj.id].li_attr['class'];
8028
+ if (d) { d.addClass(t[type].li_attr[k]); }
8029
+ }
8030
+ }
8031
+ }
8032
+ }
8033
+ if(t[type].a_attr !== undefined && typeof t[type].a_attr === 'object') {
8034
+ for (k in t[type].a_attr) {
8035
+ if (t[type].a_attr.hasOwnProperty(k)) {
8036
+ if (k === 'id') {
8037
+ continue;
8038
+ }
8039
+ else if (m[obj.id].a_attr[k] === undefined) {
8040
+ m[obj.id].a_attr[k] = t[type].a_attr[k];
8041
+ if (a) {
8042
+ if (k === 'class') {
8043
+ a.addClass(t[type].a_attr[k]);
8044
+ }
8045
+ else {
8046
+ a.attr(k, t[type].a_attr[k]);
8047
+ }
8048
+ }
8049
+ }
8050
+ else if (k === 'href' && m[obj.id].a_attr[k] === '#') {
8051
+ m[obj.id].a_attr['href'] = t[type].a_attr['href'];
8052
+ if (a) { a.attr('href', t[type].a_attr['href']); }
8053
+ }
8054
+ else if (k === 'class') {
8055
+ m[obj.id].a_attr['class'] = t[type].a_attr['class'] + ' ' + m[obj.id].a_attr['class'];
8056
+ if (a) { a.addClass(t[type].a_attr[k]); }
8057
+ }
8058
+ }
8059
+ }
8060
+ }
8061
+
7546
8062
  return true;
7547
8063
  };
7548
8064
  };
7549
8065
  // include the types plugin by default
7550
8066
  // $.jstree.defaults.plugins.push("types");
7551
8067
 
8068
+
7552
8069
  /**
7553
8070
  * ### Unique plugin
7554
8071
  *
@@ -7699,9 +8216,11 @@
7699
8216
  this.get_node(data.node, true).children('.jstree-wholerow')[e.type === "hover_node"?"addClass":"removeClass"]('jstree-wholerow-hovered');
7700
8217
  }, this))
7701
8218
  .on("contextmenu.jstree", ".jstree-wholerow", $.proxy(function (e) {
7702
- e.preventDefault();
7703
- var tmp = $.Event('contextmenu', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey, pageX : e.pageX, pageY : e.pageY });
7704
- $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp);
8219
+ if (this._data.contextmenu) {
8220
+ e.preventDefault();
8221
+ var tmp = $.Event('contextmenu', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey, pageX : e.pageX, pageY : e.pageY });
8222
+ $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp);
8223
+ }
7705
8224
  }, this))
7706
8225
  /*!
7707
8226
  .on("mousedown.jstree touchstart.jstree", ".jstree-wholerow", function (e) {
@@ -7717,6 +8236,11 @@
7717
8236
  var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey });
7718
8237
  $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus();
7719
8238
  })
8239
+ .on("dblclick.jstree", ".jstree-wholerow", function (e) {
8240
+ e.stopImmediatePropagation();
8241
+ var tmp = $.Event('dblclick', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey });
8242
+ $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus();
8243
+ })
7720
8244
  .on("click.jstree", ".jstree-leaf > .jstree-ocl", $.proxy(function (e) {
7721
8245
  e.stopImmediatePropagation();
7722
8246
  var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey });