jstree-rails-4 3.1.1 → 3.2.0

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: 637c3e2030c64578c72668ab8339dec3e696ac7d
4
- data.tar.gz: 2b738a880fa41dbfd500dce03593238d72a5ac60
3
+ metadata.gz: 10c8869f306a834bdbbd828f0fcb7bb7d1812f6e
4
+ data.tar.gz: f0cf31ae828d584665f444ff7de9b746e6a74e4d
5
5
  SHA512:
6
- metadata.gz: 665ee89eeca36314c2a004a9607a943ce852114b08ae8207028a141c1cb0d8fb0e58a2d89d4545f56d3986e5ec101aeff7b91e0a7c9cd8b9f6a5f539e8d8538e
7
- data.tar.gz: d63e91d381c838e53672f7a508350a670df3bcd522026abaf32315a1d815f161a689bb5dbc4c1053551ffa83a259f8e4cb1dfc1cd0690a5ad1626e603d458f84
6
+ metadata.gz: 295125af3463ddbbdc35d455f266cbfc5e2b4d54e26a232dc0f4ee359ac9b3915319a6ebe0aac35ded73994989526c761f9ec191a46f4d329c16e4b7badbd9d1
7
+ data.tar.gz: 7ed4f4caa2d2ea716ca982d62a8f52ff9dd23867b6e86be1dc5638c6ac97d95b0f4347af18a2ce89f92bdcae49d26ea741ed924547e726e24b18e10bef4b271b
data/Gemfile.lock CHANGED
@@ -1,76 +1,76 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jstree-rails-4 (3.1.0)
4
+ jstree-rails-4 (3.1.1)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
8
8
  specs:
9
- actionmailer (4.2.1)
10
- actionpack (= 4.2.1)
11
- actionview (= 4.2.1)
12
- activejob (= 4.2.1)
9
+ actionmailer (4.2.3)
10
+ actionpack (= 4.2.3)
11
+ actionview (= 4.2.3)
12
+ activejob (= 4.2.3)
13
13
  mail (~> 2.5, >= 2.5.4)
14
14
  rails-dom-testing (~> 1.0, >= 1.0.5)
15
- actionpack (4.2.1)
16
- actionview (= 4.2.1)
17
- activesupport (= 4.2.1)
15
+ actionpack (4.2.3)
16
+ actionview (= 4.2.3)
17
+ activesupport (= 4.2.3)
18
18
  rack (~> 1.6)
19
19
  rack-test (~> 0.6.2)
20
20
  rails-dom-testing (~> 1.0, >= 1.0.5)
21
- rails-html-sanitizer (~> 1.0, >= 1.0.1)
22
- actionview (4.2.1)
23
- activesupport (= 4.2.1)
21
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
22
+ actionview (4.2.3)
23
+ activesupport (= 4.2.3)
24
24
  builder (~> 3.1)
25
25
  erubis (~> 2.7.0)
26
26
  rails-dom-testing (~> 1.0, >= 1.0.5)
27
- rails-html-sanitizer (~> 1.0, >= 1.0.1)
28
- activejob (4.2.1)
29
- activesupport (= 4.2.1)
27
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
28
+ activejob (4.2.3)
29
+ activesupport (= 4.2.3)
30
30
  globalid (>= 0.3.0)
31
- activemodel (4.2.1)
32
- activesupport (= 4.2.1)
31
+ activemodel (4.2.3)
32
+ activesupport (= 4.2.3)
33
33
  builder (~> 3.1)
34
- activerecord (4.2.1)
35
- activemodel (= 4.2.1)
36
- activesupport (= 4.2.1)
34
+ activerecord (4.2.3)
35
+ activemodel (= 4.2.3)
36
+ activesupport (= 4.2.3)
37
37
  arel (~> 6.0)
38
- activesupport (4.2.1)
38
+ activesupport (4.2.3)
39
39
  i18n (~> 0.7)
40
40
  json (~> 1.7, >= 1.7.7)
41
41
  minitest (~> 5.1)
42
42
  thread_safe (~> 0.3, >= 0.3.4)
43
43
  tzinfo (~> 1.1)
44
- arel (6.0.0)
44
+ arel (6.0.3)
45
45
  builder (3.2.2)
46
46
  erubis (2.7.0)
47
- globalid (0.3.5)
47
+ globalid (0.3.6)
48
48
  activesupport (>= 4.1.0)
49
49
  httpclient (2.6.0.1)
50
50
  i18n (0.7.0)
51
- json (1.8.2)
51
+ json (1.8.3)
52
52
  loofah (2.0.2)
53
53
  nokogiri (>= 1.5.9)
54
54
  mail (2.6.3)
55
55
  mime-types (>= 1.16, < 3)
56
- mime-types (2.5)
56
+ mime-types (2.6.1)
57
57
  mini_portile (0.6.2)
58
- minitest (5.6.1)
58
+ minitest (5.8.0)
59
59
  nokogiri (1.6.6.2)
60
60
  mini_portile (~> 0.6.0)
61
- rack (1.6.0)
61
+ rack (1.6.4)
62
62
  rack-test (0.6.3)
63
63
  rack (>= 1.0)
64
- rails (4.2.1)
65
- actionmailer (= 4.2.1)
66
- actionpack (= 4.2.1)
67
- actionview (= 4.2.1)
68
- activejob (= 4.2.1)
69
- activemodel (= 4.2.1)
70
- activerecord (= 4.2.1)
71
- activesupport (= 4.2.1)
64
+ rails (4.2.3)
65
+ actionmailer (= 4.2.3)
66
+ actionpack (= 4.2.3)
67
+ actionview (= 4.2.3)
68
+ activejob (= 4.2.3)
69
+ activemodel (= 4.2.3)
70
+ activerecord (= 4.2.3)
71
+ activesupport (= 4.2.3)
72
72
  bundler (>= 1.3.0, < 2.0)
73
- railties (= 4.2.1)
73
+ railties (= 4.2.3)
74
74
  sprockets-rails
75
75
  rails-deprecated_sanitizer (1.0.3)
76
76
  activesupport (>= 4.2.0.alpha)
@@ -80,15 +80,15 @@ GEM
80
80
  rails-deprecated_sanitizer (>= 1.0.1)
81
81
  rails-html-sanitizer (1.0.2)
82
82
  loofah (~> 2.0)
83
- railties (4.2.1)
84
- actionpack (= 4.2.1)
85
- activesupport (= 4.2.1)
83
+ railties (4.2.3)
84
+ actionpack (= 4.2.3)
85
+ activesupport (= 4.2.3)
86
86
  rake (>= 0.8.7)
87
87
  thor (>= 0.18.1, < 2.0)
88
88
  rake (10.4.2)
89
- sprockets (3.0.3)
89
+ sprockets (3.2.0)
90
90
  rack (~> 1.0)
91
- sprockets-rails (2.2.4)
91
+ sprockets-rails (2.3.2)
92
92
  actionpack (>= 3.0)
93
93
  activesupport (>= 3.0)
94
94
  sprockets (>= 2.8, < 4.0)
@@ -106,3 +106,6 @@ DEPENDENCIES
106
106
  jstree-rails-4!
107
107
  rails (>= 3.0)
108
108
  thor (~> 0.14)
109
+
110
+ BUNDLED WITH
111
+ 1.10.6
data/README.md CHANGED
@@ -38,6 +38,15 @@ If you want to contribute, please:
38
38
  * Make your feature addition or bug fix.
39
39
  * Send me a pull request on Github.
40
40
 
41
+ ## How to pull new version of jsTree yourself
42
+
43
+ Use command line:
44
+
45
+ * bundle install
46
+ * ruby -r './lib/jstree-rails-4/source_file.rb' -e 'SourceFile.new.fetch'
47
+ * Choose version and enter 'Y' on each request
48
+
41
49
  ## License
42
50
 
43
51
  jsTree-Rails-4 is released under the [MIT License](http://www.opensource.org/licenses/MIT).
52
+
@@ -1,33 +1,33 @@
1
- require "thor"
2
- require "json"
3
- require "httpclient"
1
+ require 'thor'
2
+ require 'json'
3
+ require 'httpclient'
4
4
 
5
5
  class SourceFile < Thor
6
6
  include Thor::Actions
7
7
 
8
- desc "fetch source files", "fetch source files from GitHub"
8
+ desc 'fetch source files', 'fetch source files from GitHub'
9
9
  def fetch
10
10
  filtered_tags = fetch_tags
11
- tag = select("Which tag do you want to fetch?", filtered_tags)
12
- self.destination_root = "vendor/assets"
13
- remote = "https://github.com/vakata/jstree"
11
+ tag = select('Which tag do you want to fetch?', filtered_tags)
12
+ self.destination_root = 'vendor/assets'
13
+ remote = 'https://github.com/vakata/jstree'
14
14
  # IMAGES
15
- get "#{remote}/raw/#{tag}/dist/themes/default/32px.png", "images/default/32px.png"
16
- get "#{remote}/raw/#{tag}/dist/themes/default/40px.png", "images/default/40px.png"
17
- get "#{remote}/raw/#{tag}/dist/themes/default/throbber.gif", "images/default/throbber.gif"
18
- get "#{remote}/raw/#{tag}/dist/themes/default-dark/32px.png", "images/default-dark/32px.png"
19
- get "#{remote}/raw/#{tag}/dist/themes/default-dark/40px.png", "images/default-dark/40px.png"
20
- get "#{remote}/raw/#{tag}/dist/themes/default-dark/throbber.gif", "images/default-dark/throbber.gif"
15
+ get "#{remote}/raw/#{tag}/dist/themes/default/32px.png", 'images/default/32px.png'
16
+ get "#{remote}/raw/#{tag}/dist/themes/default/40px.png", 'images/default/40px.png'
17
+ get "#{remote}/raw/#{tag}/dist/themes/default/throbber.gif", 'images/default/throbber.gif'
18
+ get "#{remote}/raw/#{tag}/dist/themes/default-dark/32px.png", 'images/default-dark/32px.png'
19
+ get "#{remote}/raw/#{tag}/dist/themes/default-dark/40px.png", 'images/default-dark/40px.png'
20
+ get "#{remote}/raw/#{tag}/dist/themes/default-dark/throbber.gif", 'images/default-dark/throbber.gif'
21
21
  # CSS
22
- get "#{remote}/raw/#{tag}/dist/themes/default/style.css", "stylesheets/jstree-default.scss"
23
- get "#{remote}/raw/#{tag}/dist/themes/default-dark/style.css", "stylesheets/jstree-default-dark.scss"
22
+ get "#{remote}/raw/#{tag}/dist/themes/default/style.css", 'stylesheets/jstree-default.scss'
23
+ get "#{remote}/raw/#{tag}/dist/themes/default-dark/style.css", 'stylesheets/jstree-default-dark.scss'
24
24
  # JS
25
- get "#{remote}/raw/#{tag}/dist/jstree.js", "javascripts/jstree.js"
25
+ get "#{remote}/raw/#{tag}/dist/jstree.js", 'javascripts/jstree.js'
26
26
  end
27
27
 
28
- desc "convert css to use rails paths", "make css use rails paths"
28
+ desc 'convert css to use rails paths', 'make css use rails paths'
29
29
  def convert
30
- self.destination_root = "vendor/assets"
30
+ self.destination_root = 'vendor/assets'
31
31
  inside destination_root do
32
32
  gsub_file 'stylesheets/jstree-default.scss', %r/url\((?:\"|\')([^\)]+\.(?:gif|png))(?:\"|\')\)/, 'image-url("default/\1")'
33
33
  gsub_file 'stylesheets/jstree-default-dark.scss', %r/url\((?:\"|\')([^\)]+\.(?:gif|png))(?:\"|\')\)/, 'image-url("default-dark/\1")'
@@ -39,8 +39,8 @@ class SourceFile < Thor
39
39
  def fetch_tags
40
40
  http = HTTPClient.new
41
41
  #http.ssl_config.ssl_version = :SSLv23
42
- response = JSON.parse(http.get("https://api.github.com/repos/vakata/jstree/tags").body)
43
- response.map{|tag| tag["name"]}.sort
42
+ response = JSON.parse(http.get('https://api.github.com/repos/vakata/jstree/tags').body)
43
+ response.map{|tag| tag['name']}.sort
44
44
  end
45
45
 
46
46
  def select msg, elements
@@ -1,5 +1,5 @@
1
1
  module JSTree
2
2
  module Rails
3
- VERSION = "3.1.1"
3
+ VERSION = '3.2.0'
4
4
  end
5
5
  end
@@ -1,11 +1,11 @@
1
- /*globals jQuery, define, exports, require, window, document, postMessage */
1
+ /*globals jQuery, define, module, exports, require, window, document, postMessage */
2
2
  (function (factory) {
3
3
  "use strict";
4
4
  if (typeof define === 'function' && define.amd) {
5
5
  define(['jquery'], factory);
6
6
  }
7
- else if(typeof exports === 'object') {
8
- factory(require('jquery'));
7
+ else if(typeof module !== 'undefined' && module.exports) {
8
+ module.exports = factory(require('jquery'));
9
9
  }
10
10
  else {
11
11
  factory(jQuery);
@@ -13,7 +13,7 @@
13
13
  }(function ($, undefined) {
14
14
  "use strict";
15
15
  /*!
16
- * jsTree 3.1.1
16
+ * jsTree 3.2.0
17
17
  * http://jstree.com/
18
18
  *
19
19
  * Copyright (c) 2014 Ivan Bozhanov (http://vakata.com)
@@ -28,7 +28,6 @@
28
28
 
29
29
  // prevent another load? maybe there is a better way?
30
30
  if($.jstree) {
31
- return;
32
31
  }
33
32
 
34
33
  /**
@@ -71,7 +70,7 @@
71
70
  * specifies the jstree version in use
72
71
  * @name $.jstree.version
73
72
  */
74
- version : '3.1.1',
73
+ version : '3.2.0',
75
74
  /**
76
75
  * holds all the default options used when creating new instances
77
76
  * @name $.jstree.defaults
@@ -89,7 +88,8 @@
89
88
  */
90
89
  plugins : {},
91
90
  path : src && src.indexOf('/') !== -1 ? src.replace(/\/[^\/]+$/,'') : '',
92
- idregex : /[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g
91
+ idregex : /[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g,
92
+ root : '#'
93
93
  };
94
94
  /**
95
95
  * creates a jstree instance
@@ -471,16 +471,7 @@
471
471
  */
472
472
  init : function (el, options) {
473
473
  this._model = {
474
- data : {
475
- '#' : {
476
- id : '#',
477
- parent : null,
478
- parents : [],
479
- children : [],
480
- children_d : [],
481
- state : { loaded : false }
482
- }
483
- },
474
+ data : {},
484
475
  changed : [],
485
476
  force_full_redraw : false,
486
477
  redraw_timeout : false,
@@ -491,6 +482,14 @@
491
482
  disabled : false
492
483
  }
493
484
  };
485
+ this._model.data[$.jstree.root] = {
486
+ id : $.jstree.root,
487
+ parent : null,
488
+ parents : [],
489
+ children : [],
490
+ children_d : [],
491
+ state : { loaded : false }
492
+ };
494
493
 
495
494
  this.element = $(el).addClass('jstree jstree-' + this._id);
496
495
  this.settings = options;
@@ -531,7 +530,7 @@
531
530
  * @name loading.jstree
532
531
  */
533
532
  this.trigger("loading");
534
- this.load_node('#');
533
+ this.load_node($.jstree.root);
535
534
  },
536
535
  /**
537
536
  * destroy an instance
@@ -574,7 +573,8 @@
574
573
  tout = null,
575
574
  was_click = 0;
576
575
  this.element
577
- .on("dblclick.jstree", function () {
576
+ .on("dblclick.jstree", function (e) {
577
+ if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; }
578
578
  if(document.selection && document.selection.empty) {
579
579
  document.selection.empty();
580
580
  }
@@ -601,6 +601,7 @@
601
601
  this.toggle_node(e.target);
602
602
  }, this))
603
603
  .on("dblclick.jstree", ".jstree-anchor", $.proxy(function (e) {
604
+ if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; }
604
605
  if(this.settings.core.dblclick_toggle) {
605
606
  this.toggle_node(e.target);
606
607
  }
@@ -611,7 +612,7 @@
611
612
  this.activate_node(e.currentTarget, e);
612
613
  }, this))
613
614
  .on('keydown.jstree', '.jstree-anchor', $.proxy(function (e) {
614
- if(e.target.tagName === "INPUT") { return true; }
615
+ if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; }
615
616
  if(e.which !== 32 && e.which !== 13 && (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey)) { return true; }
616
617
  var o = null;
617
618
  if(this._data.core.rtl) {
@@ -636,7 +637,7 @@
636
637
  }
637
638
  else {
638
639
  o = this.get_parent(e.currentTarget);
639
- if(o && o.id !== '#') { this.get_node(o, true).children('.jstree-anchor').focus(); }
640
+ if(o && o.id !== $.jstree.root) { this.get_node(o, true).children('.jstree-anchor').focus(); }
640
641
  }
641
642
  break;
642
643
  case 38: // up
@@ -676,7 +677,7 @@
676
677
  case 46:
677
678
  e.preventDefault();
678
679
  o = this.get_node(e.currentTarget);
679
- if(o && o.id && o.id !== '#') {
680
+ if(o && o.id && o.id !== $.jstree.root) {
680
681
  o = this.is_selected(o) ? this.get_selected() : o;
681
682
  this.delete_node(o);
682
683
  }
@@ -685,7 +686,7 @@
685
686
  case 113:
686
687
  e.preventDefault();
687
688
  o = this.get_node(e.currentTarget);
688
- if(o && o.id && o.id !== '#') {
689
+ if(o && o.id && o.id !== $.jstree.root) {
689
690
  // this.edit(o);
690
691
  }
691
692
  break;
@@ -697,7 +698,7 @@
697
698
  }, this))
698
699
  .on("load_node.jstree", $.proxy(function (e, data) {
699
700
  if(data.status) {
700
- if(data.node.id === '#' && !this._data.core.loaded) {
701
+ if(data.node.id === $.jstree.root && !this._data.core.loaded) {
701
702
  this._data.core.loaded = true;
702
703
  if(this._firstChild(this.get_container_ul()[0])) {
703
704
  this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id);
@@ -739,7 +740,7 @@
739
740
  }, this))
740
741
  // quick searching when the tree is focused
741
742
  .on('keypress.jstree', $.proxy(function (e) {
742
- if(e.target.tagName === "INPUT") { return true; }
743
+ if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; }
743
744
  if(tout) { clearTimeout(tout); }
744
745
  tout = setTimeout(function () {
745
746
  word = '';
@@ -773,7 +774,7 @@
773
774
  if(end) { return; }
774
775
  }
775
776
  // list nodes that start with that letter (only if word consists of a single char)
776
- if(new RegExp('^' + chr + '+$').test(word)) {
777
+ if(new RegExp('^' + chr.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '+$').test(word)) {
777
778
  // search for the next node starting with that letter
778
779
  col.slice(ind + 1).each($.proxy(function (i, v) {
779
780
  if($(v).text().toLowerCase().charAt(0) === chr) {
@@ -960,14 +961,14 @@
960
961
  obj = this._model.data[dom.closest('.jstree-node').attr('id')];
961
962
  }
962
963
  else if((dom = $(obj, this.element)).length && dom.hasClass('jstree')) {
963
- obj = this._model.data['#'];
964
+ obj = this._model.data[$.jstree.root];
964
965
  }
965
966
  else {
966
967
  return false;
967
968
  }
968
969
 
969
970
  if(as_dom) {
970
- obj = obj.id === '#' ? this.element : $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element);
971
+ obj = obj.id === $.jstree.root ? this.element : $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element);
971
972
  }
972
973
  return obj;
973
974
  } catch (ex) { return false; }
@@ -982,7 +983,7 @@
982
983
  */
983
984
  get_path : function (obj, glue, ids) {
984
985
  obj = obj.parents ? obj : this.get_node(obj);
985
- if(!obj || obj.id === '#' || !obj.parents) {
986
+ if(!obj || obj.id === $.jstree.root || !obj.parents) {
986
987
  return false;
987
988
  }
988
989
  var i, j, p = [];
@@ -1087,7 +1088,7 @@
1087
1088
  */
1088
1089
  get_parent : function (obj) {
1089
1090
  obj = this.get_node(obj);
1090
- if(!obj || obj.id === '#') {
1091
+ if(!obj || obj.id === $.jstree.root) {
1091
1092
  return false;
1092
1093
  }
1093
1094
  return obj.parent;
@@ -1213,8 +1214,14 @@
1213
1214
  obj.state.loading = false;
1214
1215
  obj.state.loaded = status;
1215
1216
  obj.state.failed = !obj.state.loaded;
1216
- var dom = this.get_node(obj, true);
1217
- if(obj.state.loaded && !obj.children.length && dom && dom.length && !dom.hasClass('jstree-leaf')) {
1217
+ var dom = this.get_node(obj, true), i = 0, j = 0, m = this._model.data, has_children = false;
1218
+ for(i = 0, j = obj.children.length; i < j; i++) {
1219
+ if(m[obj.children[i]] && !m[obj.children[i]].state.hidden) {
1220
+ has_children = true;
1221
+ break;
1222
+ }
1223
+ }
1224
+ if(obj.state.loaded && !has_children && dom && dom.length && !dom.hasClass('jstree-leaf')) {
1218
1225
  dom.removeClass('jstree-closed jstree-open').addClass('jstree-leaf');
1219
1226
  }
1220
1227
  dom.removeClass("jstree-loading").attr('aria-busy',false);
@@ -1271,7 +1278,7 @@
1271
1278
  * @trigger load_all.jstree
1272
1279
  */
1273
1280
  load_all : function (obj, callback) {
1274
- if(!obj) { obj = '#'; }
1281
+ if(!obj) { obj = $.jstree.root; }
1275
1282
  obj = this.get_node(obj);
1276
1283
  if(!obj) { return false; }
1277
1284
  var to_load = [],
@@ -1314,7 +1321,7 @@
1314
1321
  var s = this.settings.core.data, t;
1315
1322
  // use original HTML
1316
1323
  if(!s) {
1317
- if(obj.id === '#') {
1324
+ if(obj.id === $.jstree.root) {
1318
1325
  return this._append_html_data(obj, this._data.core.original_container_html.clone(true), function (status) {
1319
1326
  callback.call(this, status);
1320
1327
  });
@@ -1322,7 +1329,7 @@
1322
1329
  else {
1323
1330
  return callback.call(this, false);
1324
1331
  }
1325
- // return callback.call(this, obj.id === '#' ? this._append_html_data(obj, this._data.core.original_container_html.clone(true)) : false);
1332
+ // return callback.call(this, obj.id === $.jstree.root ? this._append_html_data(obj, this._data.core.original_container_html.clone(true)) : false);
1326
1333
  }
1327
1334
  if($.isFunction(s)) {
1328
1335
  return s.call(this, obj, $.proxy(function (d) {
@@ -1366,7 +1373,7 @@
1366
1373
  }, this));
1367
1374
  }
1368
1375
  t = ($.isArray(s) || $.isPlainObject(s)) ? JSON.parse(JSON.stringify(s)) : s;
1369
- if(obj.id === '#') {
1376
+ if(obj.id === $.jstree.root) {
1370
1377
  return this._append_json_data(obj, t, function (status) {
1371
1378
  callback.call(this, status);
1372
1379
  });
@@ -1376,10 +1383,10 @@
1376
1383
  this.settings.core.error.call(this, this._data.core.last_error);
1377
1384
  return callback.call(this, false);
1378
1385
  }
1379
- //return callback.call(this, (obj.id === "#" ? this._append_json_data(obj, t) : false) );
1386
+ //return callback.call(this, (obj.id === $.jstree.root ? this._append_json_data(obj, t) : false) );
1380
1387
  }
1381
1388
  if(typeof s === 'string') {
1382
- if(obj.id === '#') {
1389
+ if(obj.id === $.jstree.root) {
1383
1390
  return this._append_html_data(obj, $($.parseHTML(s)).filter(function () { return this.nodeType !== 3; }), function (status) {
1384
1391
  callback.call(this, status);
1385
1392
  });
@@ -1389,7 +1396,7 @@
1389
1396
  this.settings.core.error.call(this, this._data.core.last_error);
1390
1397
  return callback.call(this, false);
1391
1398
  }
1392
- //return callback.call(this, (obj.id === "#" ? this._append_html_data(obj, $(s)) : false) );
1399
+ //return callback.call(this, (obj.id === $.jstree.root ? this._append_html_data(obj, $(s)) : false) );
1393
1400
  }
1394
1401
  return callback.call(this, false);
1395
1402
  },
@@ -1448,7 +1455,7 @@
1448
1455
  * @param {String} parent the parent ID of the nodes
1449
1456
  */
1450
1457
  this.trigger('model', { "nodes" : dpc, 'parent' : par });
1451
- if(par !== '#') {
1458
+ if(par !== $.jstree.root) {
1452
1459
  this._node_changed(par);
1453
1460
  this.redraw();
1454
1461
  }
@@ -1793,7 +1800,7 @@
1793
1800
 
1794
1801
  this.trigger('model', { "nodes" : rslt.dpc, 'parent' : rslt.par });
1795
1802
 
1796
- if(rslt.par !== '#') {
1803
+ if(rslt.par !== $.jstree.root) {
1797
1804
  this._node_changed(rslt.par);
1798
1805
  this.redraw();
1799
1806
  }
@@ -2186,7 +2193,7 @@
2186
2193
  * @trigger redraw.jstree
2187
2194
  */
2188
2195
  _redraw : function () {
2189
- var nodes = this._model.force_full_redraw ? this._model.data['#'].children.concat([]) : this._model.changed.concat([]),
2196
+ var nodes = this._model.force_full_redraw ? this._model.data[$.jstree.root].children.concat([]) : this._model.changed.concat([]),
2190
2197
  f = document.createElement('UL'), tmp, i, j, fe = this._data.core.focused;
2191
2198
  for(i = 0, j = nodes.length; i < j; i++) {
2192
2199
  tmp = this.redraw_node(nodes[i], true, this._model.force_full_redraw);
@@ -2247,7 +2254,7 @@
2247
2254
  k = false,
2248
2255
  d = document;
2249
2256
  if(!obj) { return false; }
2250
- if(obj.id === '#') { return this.redraw(true); }
2257
+ if(obj.id === $.jstree.root) { return this.redraw(true); }
2251
2258
  node = this.get_node(node, true);
2252
2259
  if(!node || !node.length) { return false; } // TODO: quick toggle
2253
2260
 
@@ -2287,20 +2294,22 @@
2287
2294
  s = false,
2288
2295
  tmp = null,
2289
2296
  t = 0,
2290
- l = 0;
2297
+ l = 0,
2298
+ has_children = false,
2299
+ last_sibling = false;
2291
2300
  if(!obj) { return false; }
2292
- if(obj.id === '#') { return this.redraw(true); }
2301
+ if(obj.id === $.jstree.root) { return this.redraw(true); }
2293
2302
  deep = deep || obj.children.length === 0;
2294
2303
  node = !document.querySelector ? document.getElementById(obj.id) : this.element[0].querySelector('#' + ("0123456789".indexOf(obj.id[0]) !== -1 ? '\\3' + obj.id[0] + ' ' + obj.id.substr(1).replace($.jstree.idregex,'\\$&') : obj.id.replace($.jstree.idregex,'\\$&')) ); //, this.element);
2295
2304
  if(!node) {
2296
2305
  deep = true;
2297
2306
  //node = d.createElement('LI');
2298
2307
  if(!is_callback) {
2299
- par = obj.parent !== '#' ? $('#' + obj.parent.replace($.jstree.idregex,'\\$&'), this.element)[0] : null;
2308
+ par = obj.parent !== $.jstree.root ? $('#' + obj.parent.replace($.jstree.idregex,'\\$&'), this.element)[0] : null;
2300
2309
  if(par !== null && (!par || !m[obj.parent].state.opened)) {
2301
2310
  return false;
2302
2311
  }
2303
- ind = $.inArray(obj.id, par === null ? m['#'].children : m[obj.parent].children);
2312
+ ind = $.inArray(obj.id, par === null ? m[$.jstree.root].children : m[obj.parent].children);
2304
2313
  }
2305
2314
  }
2306
2315
  else {
@@ -2349,14 +2358,39 @@
2349
2358
  node.setAttribute('aria-disabled', true);
2350
2359
  }
2351
2360
 
2352
- if(obj.state.loaded && !obj.children.length) {
2361
+ for(i = 0, j = obj.children.length; i < j; i++) {
2362
+ if(!m[obj.children[i]].state.hidden) {
2363
+ has_children = true;
2364
+ break;
2365
+ }
2366
+ }
2367
+ if(obj.parent !== null && m[obj.parent] && !obj.state.hidden) {
2368
+ i = $.inArray(obj.id, m[obj.parent].children);
2369
+ last_sibling = obj.id;
2370
+ if(i !== -1) {
2371
+ i++;
2372
+ for(j = m[obj.parent].children.length; i < j; i++) {
2373
+ if(!m[m[obj.parent].children[i]].state.hidden) {
2374
+ last_sibling = m[obj.parent].children[i];
2375
+ }
2376
+ if(last_sibling !== obj.id) {
2377
+ break;
2378
+ }
2379
+ }
2380
+ }
2381
+ }
2382
+
2383
+ if(obj.state.hidden) {
2384
+ c += ' jstree-hidden';
2385
+ }
2386
+ if(obj.state.loaded && !has_children) {
2353
2387
  c += ' jstree-leaf';
2354
2388
  }
2355
2389
  else {
2356
2390
  c += obj.state.opened && obj.state.loaded ? ' jstree-open' : ' jstree-closed';
2357
2391
  node.setAttribute('aria-expanded', (obj.state.opened && obj.state.loaded) );
2358
2392
  }
2359
- if(obj.parent !== null && m[obj.parent].children[m[obj.parent].children.length - 1] === obj.id) {
2393
+ if(last_sibling === obj.id) {
2360
2394
  c += ' jstree-last';
2361
2395
  }
2362
2396
  node.id = obj.id;
@@ -2470,7 +2504,7 @@
2470
2504
  return true;
2471
2505
  }
2472
2506
  obj = this.get_node(obj);
2473
- if(!obj || obj.id === '#') {
2507
+ if(!obj || obj.id === $.jstree.root) {
2474
2508
  return false;
2475
2509
  }
2476
2510
  animation = animation === undefined ? this.settings.core.animation : animation;
@@ -2557,12 +2591,12 @@
2557
2591
  */
2558
2592
  _open_to : function (obj) {
2559
2593
  obj = this.get_node(obj);
2560
- if(!obj || obj.id === '#') {
2594
+ if(!obj || obj.id === $.jstree.root) {
2561
2595
  return false;
2562
2596
  }
2563
2597
  var i, j, p = obj.parents;
2564
2598
  for(i = 0, j = p.length; i < j; i+=1) {
2565
- if(i !== '#') {
2599
+ if(i !== $.jstree.root) {
2566
2600
  this.open_node(p[i], false, 0);
2567
2601
  }
2568
2602
  }
@@ -2585,7 +2619,7 @@
2585
2619
  return true;
2586
2620
  }
2587
2621
  obj = this.get_node(obj);
2588
- if(!obj || obj.id === '#') {
2622
+ if(!obj || obj.id === $.jstree.root) {
2589
2623
  return false;
2590
2624
  }
2591
2625
  if(this.is_closed(obj)) {
@@ -2658,10 +2692,10 @@
2658
2692
  * @trigger open_all.jstree
2659
2693
  */
2660
2694
  open_all : function (obj, animation, original_obj) {
2661
- if(!obj) { obj = '#'; }
2695
+ if(!obj) { obj = $.jstree.root; }
2662
2696
  obj = this.get_node(obj);
2663
2697
  if(!obj) { return false; }
2664
- var dom = obj.id === '#' ? this.get_container_ul() : this.get_node(obj, true), i, j, _this;
2698
+ var dom = obj.id === $.jstree.root ? this.get_container_ul() : this.get_node(obj, true), i, j, _this;
2665
2699
  if(!dom.length) {
2666
2700
  for(i = 0, j = obj.children_d.length; i < j; i++) {
2667
2701
  if(this.is_closed(this._model.data[obj.children_d[i]])) {
@@ -2698,19 +2732,18 @@
2698
2732
  * @trigger close_all.jstree
2699
2733
  */
2700
2734
  close_all : function (obj, animation) {
2701
- if(!obj) { obj = '#'; }
2735
+ if(!obj) { obj = $.jstree.root; }
2702
2736
  obj = this.get_node(obj);
2703
2737
  if(!obj) { return false; }
2704
- var dom = obj.id === '#' ? this.get_container_ul() : this.get_node(obj, true),
2738
+ var dom = obj.id === $.jstree.root ? this.get_container_ul() : this.get_node(obj, true),
2705
2739
  _this = this, i, j;
2706
- if(!dom.length) {
2707
- for(i = 0, j = obj.children_d.length; i < j; i++) {
2708
- this._model.data[obj.children_d[i]].state.opened = false;
2709
- }
2710
- return this.trigger('close_all', { "node" : obj });
2740
+ if(dom.length) {
2741
+ dom = this.is_open(obj) ? dom.find('.jstree-open').addBack() : dom.find('.jstree-open');
2742
+ $(dom.get().reverse()).each(function () { _this.close_node(this, animation || 0); });
2743
+ }
2744
+ for(i = 0, j = obj.children_d.length; i < j; i++) {
2745
+ this._model.data[obj.children_d[i]].state.opened = false;
2711
2746
  }
2712
- dom = this.is_open(obj) ? dom.find('.jstree-open').addBack() : dom.find('.jstree-open');
2713
- $(dom.get().reverse()).each(function () { _this.close_node(this, animation || 0); });
2714
2747
  /**
2715
2748
  * triggered when an `close_all` call completes
2716
2749
  * @event
@@ -2745,7 +2778,7 @@
2745
2778
  return true;
2746
2779
  }
2747
2780
  obj = this.get_node(obj);
2748
- if(!obj || obj.id === '#') {
2781
+ if(!obj || obj.id === $.jstree.root) {
2749
2782
  return false;
2750
2783
  }
2751
2784
  obj.state.disabled = false;
@@ -2774,7 +2807,7 @@
2774
2807
  return true;
2775
2808
  }
2776
2809
  obj = this.get_node(obj);
2777
- if(!obj || obj.id === '#') {
2810
+ if(!obj || obj.id === $.jstree.root) {
2778
2811
  return false;
2779
2812
  }
2780
2813
  obj.state.disabled = true;
@@ -2787,6 +2820,126 @@
2787
2820
  */
2788
2821
  this.trigger('disable_node', { 'node' : obj });
2789
2822
  },
2823
+ /**
2824
+ * hides a node - it is still in the structure but will not be visible
2825
+ * @name hide_node(obj)
2826
+ * @param {mixed} obj the node to hide
2827
+ * @param {Boolean} redraw internal parameter controlling if redraw is called
2828
+ * @trigger hide_node.jstree
2829
+ */
2830
+ hide_node : function (obj, skip_redraw) {
2831
+ var t1, t2;
2832
+ if($.isArray(obj)) {
2833
+ obj = obj.slice();
2834
+ for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
2835
+ this.hide_node(obj[t1], true);
2836
+ }
2837
+ this.redraw();
2838
+ return true;
2839
+ }
2840
+ obj = this.get_node(obj);
2841
+ if(!obj || obj.id === $.jstree.root) {
2842
+ return false;
2843
+ }
2844
+ if(!obj.state.hidden) {
2845
+ obj.state.hidden = true;
2846
+ this._node_changed(obj.parent);
2847
+ if(!skip_redraw) {
2848
+ this.redraw();
2849
+ }
2850
+ /**
2851
+ * triggered when an node is hidden
2852
+ * @event
2853
+ * @name hide_node.jstree
2854
+ * @param {Object} node the hidden node
2855
+ */
2856
+ this.trigger('hide_node', { 'node' : obj });
2857
+ }
2858
+ },
2859
+ /**
2860
+ * shows a node
2861
+ * @name show_node(obj)
2862
+ * @param {mixed} obj the node to show
2863
+ * @param {Boolean} skip_redraw internal parameter controlling if redraw is called
2864
+ * @trigger show_node.jstree
2865
+ */
2866
+ show_node : function (obj, skip_redraw) {
2867
+ var t1, t2;
2868
+ if($.isArray(obj)) {
2869
+ obj = obj.slice();
2870
+ for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
2871
+ this.show_node(obj[t1], true);
2872
+ }
2873
+ this.redraw();
2874
+ return true;
2875
+ }
2876
+ obj = this.get_node(obj);
2877
+ if(!obj || obj.id === $.jstree.root) {
2878
+ return false;
2879
+ }
2880
+ if(obj.state.hidden) {
2881
+ obj.state.hidden = false;
2882
+ this._node_changed(obj.parent);
2883
+ if(!skip_redraw) {
2884
+ this.redraw();
2885
+ }
2886
+ /**
2887
+ * triggered when an node is shown
2888
+ * @event
2889
+ * @name show_node.jstree
2890
+ * @param {Object} node the shown node
2891
+ */
2892
+ this.trigger('show_node', { 'node' : obj });
2893
+ }
2894
+ },
2895
+ /**
2896
+ * hides all nodes
2897
+ * @name hide_all()
2898
+ * @trigger hide_all.jstree
2899
+ */
2900
+ hide_all : function (obj) {
2901
+ var i, m = this._model.data, ids = [];
2902
+ for(i in m) {
2903
+ if(m.hasOwnProperty(i) && i !== $.jstree.root && !m[i].state.hidden) {
2904
+ m[i].state.hidden = true;
2905
+ ids.push(i);
2906
+ }
2907
+ }
2908
+ this._model.force_full_redraw = true;
2909
+ this.redraw();
2910
+ /**
2911
+ * triggered when all nodes are hidden
2912
+ * @event
2913
+ * @name hide_all.jstree
2914
+ * @param {Array} nodes the IDs of all hidden nodes
2915
+ */
2916
+ this.trigger('hide_all', { 'nodes' : ids });
2917
+ return ids;
2918
+ },
2919
+ /**
2920
+ * shows all nodes
2921
+ * @name show_all()
2922
+ * @trigger show_all.jstree
2923
+ */
2924
+ show_all : function (obj) {
2925
+ var i, m = this._model.data, ids = [];
2926
+ for(i in m) {
2927
+ if(m.hasOwnProperty(i) && i !== $.jstree.root && m[i].state.hidden) {
2928
+ m[i].state.hidden = false;
2929
+ ids.push(i);
2930
+ }
2931
+ }
2932
+ this._model.force_full_redraw = true;
2933
+ this.redraw();
2934
+ /**
2935
+ * triggered when all nodes are shown
2936
+ * @event
2937
+ * @name show_all.jstree
2938
+ * @param {Array} nodes the IDs of all shown nodes
2939
+ */
2940
+ this.trigger('show_all', { 'nodes' : ids });
2941
+ return ids;
2942
+ },
2790
2943
  /**
2791
2944
  * called when a node is selected by the user. Used internally.
2792
2945
  * @private
@@ -2799,6 +2952,9 @@
2799
2952
  if(this.is_disabled(obj)) {
2800
2953
  return false;
2801
2954
  }
2955
+ if(!e || typeof e !== 'object') {
2956
+ e = {};
2957
+ }
2802
2958
 
2803
2959
  // ensure last_clicked is still in the DOM, make it fresh (maybe it was moved?) and make sure it is still selected, if not - make last_clicked the last selected node
2804
2960
  this._data.core.last_clicked = this._data.core.last_clicked && this._data.core.last_clicked.id !== undefined ? this.get_node(this._data.core.last_clicked.id) : null;
@@ -2853,8 +3009,9 @@
2853
3009
  * @event
2854
3010
  * @name activate_node.jstree
2855
3011
  * @param {Object} node
3012
+ * @param {Object} event the ooriginal event (if any) which triggered the call (may be an empty object)
2856
3013
  */
2857
- this.trigger('activate_node', { 'node' : this.get_node(obj) });
3014
+ this.trigger('activate_node', { 'node' : this.get_node(obj), 'event' : e });
2858
3015
  },
2859
3016
  /**
2860
3017
  * applies the hover state on a node, called when a node is hovered by the user. Used internally.
@@ -2920,7 +3077,7 @@
2920
3077
  return true;
2921
3078
  }
2922
3079
  obj = this.get_node(obj);
2923
- if(!obj || obj.id === '#') {
3080
+ if(!obj || obj.id === $.jstree.root) {
2924
3081
  return false;
2925
3082
  }
2926
3083
  dom = this.get_node(obj, true);
@@ -2973,7 +3130,7 @@
2973
3130
  return true;
2974
3131
  }
2975
3132
  obj = this.get_node(obj);
2976
- if(!obj || obj.id === '#') {
3133
+ if(!obj || obj.id === $.jstree.root) {
2977
3134
  return false;
2978
3135
  }
2979
3136
  dom = this.get_node(obj, true);
@@ -3005,7 +3162,7 @@
3005
3162
  */
3006
3163
  select_all : function (supress_event) {
3007
3164
  var tmp = this._data.core.selected.concat([]), i, j;
3008
- this._data.core.selected = this._model.data['#'].children_d.concat();
3165
+ this._data.core.selected = this._model.data[$.jstree.root].children_d.concat();
3009
3166
  for(i = 0, j = this._data.core.selected.length; i < j; i++) {
3010
3167
  if(this._model.data[this._data.core.selected[i]]) {
3011
3168
  this._model.data[this._data.core.selected[i]].state.selected = true;
@@ -3058,7 +3215,7 @@
3058
3215
  */
3059
3216
  is_selected : function (obj) {
3060
3217
  obj = this.get_node(obj);
3061
- if(!obj || obj.id === '#') {
3218
+ if(!obj || obj.id === $.jstree.root) {
3062
3219
  return false;
3063
3220
  }
3064
3221
  return obj.state.selected;
@@ -3141,7 +3298,7 @@
3141
3298
  }, i;
3142
3299
  for(i in this._model.data) {
3143
3300
  if(this._model.data.hasOwnProperty(i)) {
3144
- if(i !== '#') {
3301
+ if(i !== $.jstree.root) {
3145
3302
  if(this._model.data[i].state.opened) {
3146
3303
  state.core.open.push(i);
3147
3304
  }
@@ -3157,7 +3314,7 @@
3157
3314
  * sets the state of the tree. Used internally.
3158
3315
  * @name set_state(state [, callback])
3159
3316
  * @private
3160
- * @param {Object} state the state to restore
3317
+ * @param {Object} state the state to restore. Keep in mind this object is passed by reference and jstree will modify it.
3161
3318
  * @param {Function} callback an optional function to execute once the state is restored.
3162
3319
  * @trigger set_state.jstree
3163
3320
  */
@@ -3237,22 +3394,25 @@
3237
3394
  this._data.core.state = forget_state === true ? {} : this.get_state();
3238
3395
  if(forget_state && $.isFunction(forget_state)) { this._data.core.state = forget_state.call(this, this._data.core.state); }
3239
3396
  this._cnt = 0;
3240
- this._model.data = {
3241
- '#' : {
3242
- id : '#',
3243
- parent : null,
3244
- parents : [],
3245
- children : [],
3246
- children_d : [],
3247
- state : { loaded : false }
3248
- }
3397
+ this._model.data = {};
3398
+ this._model.data[$.jstree.root] = {
3399
+ id : $.jstree.root,
3400
+ parent : null,
3401
+ parents : [],
3402
+ children : [],
3403
+ children_d : [],
3404
+ state : { loaded : false }
3249
3405
  };
3406
+ this._data.core.selected = [];
3407
+ this._data.core.last_clicked = null;
3408
+ this._data.core.focused = null;
3409
+
3250
3410
  var c = this.get_container_ul()[0].className;
3251
3411
  if(!skip_loading) {
3252
3412
  this.element.html("<"+"ul class='"+c+"' role='group'><"+"li class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='treeitem' id='j"+this._id+"_loading'><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>");
3253
3413
  this.element.attr('aria-activedescendant','j'+this._id+'_loading');
3254
3414
  }
3255
- this.load_node('#', function (o, s) {
3415
+ this.load_node($.jstree.root, function (o, s) {
3256
3416
  if(s) {
3257
3417
  this.get_container_ul()[0].className = c;
3258
3418
  if(this._firstChild(this.get_container_ul()[0])) {
@@ -3278,7 +3438,7 @@
3278
3438
  */
3279
3439
  refresh_node : function (obj) {
3280
3440
  obj = this.get_node(obj);
3281
- if(!obj || obj.id === '#') { return false; }
3441
+ if(!obj || obj.id === $.jstree.root) { return false; }
3282
3442
  var opened = [], to_load = [], s = this._data.core.selected.concat([]);
3283
3443
  to_load.push(obj.id);
3284
3444
  if(obj.state.opened === true) { opened.push(obj.id); }
@@ -3305,7 +3465,7 @@
3305
3465
  */
3306
3466
  set_id : function (obj, id) {
3307
3467
  obj = this.get_node(obj);
3308
- if(!obj || obj.id === '#') { return false; }
3468
+ if(!obj || obj.id === $.jstree.root) { return false; }
3309
3469
  var i, j, m = this._model.data;
3310
3470
  id = id.toString();
3311
3471
  // update parents (replace current ID with new one in children and children_d)
@@ -3344,7 +3504,7 @@
3344
3504
  */
3345
3505
  get_text : function (obj) {
3346
3506
  obj = this.get_node(obj);
3347
- return (!obj || obj.id === '#') ? false : obj.text;
3507
+ return (!obj || obj.id === $.jstree.root) ? false : obj.text;
3348
3508
  },
3349
3509
  /**
3350
3510
  * set the text value of a node. Used internally, please use `rename_node(obj, val)`.
@@ -3365,7 +3525,7 @@
3365
3525
  return true;
3366
3526
  }
3367
3527
  obj = this.get_node(obj);
3368
- if(!obj || obj.id === '#') { return false; }
3528
+ if(!obj || obj.id === $.jstree.root) { return false; }
3369
3529
  obj.text = val;
3370
3530
  if(this.get_node(obj, true).length) {
3371
3531
  this.redraw_node(obj.id);
@@ -3393,7 +3553,7 @@
3393
3553
  * @return {Object}
3394
3554
  */
3395
3555
  get_json : function (obj, options, flat) {
3396
- obj = this.get_node(obj || '#');
3556
+ obj = this.get_node(obj || $.jstree.root);
3397
3557
  if(!obj) { return false; }
3398
3558
  if(options && options.flat && !flat) { flat = []; }
3399
3559
  var tmp = {
@@ -3428,7 +3588,7 @@
3428
3588
  delete tmp.a_attr.id;
3429
3589
  }
3430
3590
  }
3431
- if(options && options.flat && obj.id !== '#') {
3591
+ if(options && options.flat && obj.id !== $.jstree.root) {
3432
3592
  flat.push(tmp);
3433
3593
  }
3434
3594
  if(!options || !options.no_children) {
@@ -3441,7 +3601,7 @@
3441
3601
  }
3442
3602
  }
3443
3603
  }
3444
- return options && options.flat ? flat : (obj.id === '#' ? tmp.children : tmp);
3604
+ return options && options.flat ? flat : (obj.id === $.jstree.root ? tmp.children : tmp);
3445
3605
  },
3446
3606
  /**
3447
3607
  * create a new node (do not confuse with load_node)
@@ -3455,7 +3615,7 @@
3455
3615
  * @trigger model.jstree, create_node.jstree
3456
3616
  */
3457
3617
  create_node : function (par, node, pos, callback, is_loaded) {
3458
- if(par === null) { par = "#"; }
3618
+ if(par === null) { par = $.jstree.root; }
3459
3619
  par = this.get_node(par);
3460
3620
  if(!par) { return false; }
3461
3621
  pos = pos === undefined ? "last" : pos;
@@ -3467,7 +3627,7 @@
3467
3627
  if(node.text === undefined) { node.text = this.get_string('New node'); }
3468
3628
  var tmp, dpc, i, j;
3469
3629
 
3470
- if(par.id === '#') {
3630
+ if(par.id === $.jstree.root) {
3471
3631
  if(pos === "before") { pos = "first"; }
3472
3632
  if(pos === "after") { pos = "last"; }
3473
3633
  }
@@ -3551,7 +3711,7 @@
3551
3711
  return true;
3552
3712
  }
3553
3713
  obj = this.get_node(obj);
3554
- if(!obj || obj.id === '#') { return false; }
3714
+ if(!obj || obj.id === $.jstree.root) { return false; }
3555
3715
  old = obj.text;
3556
3716
  if(!this.check("rename_node", obj, this.get_parent(obj), val)) {
3557
3717
  this.settings.core.error.call(this, this._data.core.last_error);
@@ -3577,7 +3737,7 @@
3577
3737
  * @trigger delete_node.jstree, changed.jstree
3578
3738
  */
3579
3739
  delete_node : function (obj) {
3580
- var t1, t2, par, pos, tmp, i, j, k, l, c;
3740
+ var t1, t2, par, pos, tmp, i, j, k, l, c, top, lft;
3581
3741
  if($.isArray(obj)) {
3582
3742
  obj = obj.slice();
3583
3743
  for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
@@ -3586,7 +3746,7 @@
3586
3746
  return true;
3587
3747
  }
3588
3748
  obj = this.get_node(obj);
3589
- if(!obj || obj.id === '#') { return false; }
3749
+ if(!obj || obj.id === $.jstree.root) { return false; }
3590
3750
  par = this.get_node(obj.parent);
3591
3751
  pos = $.inArray(obj.id, par.children);
3592
3752
  c = false;
@@ -3628,6 +3788,19 @@
3628
3788
  for(k = 0, l = tmp.length; k < l; k++) {
3629
3789
  delete this._model.data[tmp[k]];
3630
3790
  }
3791
+ if($.inArray(this._data.core.focused, tmp) !== -1) {
3792
+ this._data.core.focused = null;
3793
+ top = this.element[0].scrollTop;
3794
+ lft = this.element[0].scrollLeft;
3795
+ if(par.id === $.jstree.root) {
3796
+ this.get_node(this._model.data[$.jstree.root].children[0], true).children('.jstree-anchor').focus();
3797
+ }
3798
+ else {
3799
+ this.get_node(par, true).children('.jstree-anchor').focus();
3800
+ }
3801
+ this.element[0].scrollTop = top;
3802
+ this.element[0].scrollLeft = lft;
3803
+ }
3631
3804
  this.redraw_node(par, true);
3632
3805
  return true;
3633
3806
  },
@@ -3714,10 +3887,10 @@
3714
3887
  }
3715
3888
  obj = obj && obj.id ? obj : this.get_node(obj);
3716
3889
 
3717
- if(!obj || obj.id === '#') { return false; }
3890
+ if(!obj || obj.id === $.jstree.root) { return false; }
3718
3891
 
3719
- old_par = (obj.parent || '#').toString();
3720
- new_par = (!pos.toString().match(/^(before|after)$/) || par.id === '#') ? par : this.get_node(par.parent);
3892
+ old_par = (obj.parent || $.jstree.root).toString();
3893
+ new_par = (!pos.toString().match(/^(before|after)$/) || par.id === $.jstree.root) ? par : this.get_node(par.parent);
3721
3894
  old_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id));
3722
3895
  is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id);
3723
3896
  old_pos = old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1;
@@ -3733,7 +3906,7 @@
3733
3906
  return false;
3734
3907
  }
3735
3908
  //var m = this._model.data;
3736
- if(par.id === '#') {
3909
+ if(par.id === $.jstree.root) {
3737
3910
  if(pos === "before") { pos = "first"; }
3738
3911
  if(pos === "after") { pos = "last"; }
3739
3912
  }
@@ -3774,7 +3947,7 @@
3774
3947
  tmp[pos] = obj.id;
3775
3948
  new_par.children = tmp;
3776
3949
  this._node_changed(new_par.id);
3777
- this.redraw(new_par.id === '#');
3950
+ this.redraw(new_par.id === $.jstree.root);
3778
3951
  }
3779
3952
  else {
3780
3953
  // clean old parent and up
@@ -3819,7 +3992,7 @@
3819
3992
  Array.prototype.push.apply(this._model.data[obj.children_d[i]].parents, tmp);
3820
3993
  }
3821
3994
 
3822
- if(old_par === '#' || new_par.id === '#') {
3995
+ if(old_par === $.jstree.root || new_par.id === $.jstree.root) {
3823
3996
  this._model.force_full_redraw = true;
3824
3997
  }
3825
3998
  if(!this._model.force_full_redraw) {
@@ -3886,10 +4059,10 @@
3886
4059
  }
3887
4060
  }
3888
4061
  obj = obj && obj.id ? obj : this.get_node(obj);
3889
- if(!obj || obj.id === '#') { return false; }
4062
+ if(!obj || obj.id === $.jstree.root) { return false; }
3890
4063
 
3891
- old_par = (obj.parent || '#').toString();
3892
- new_par = (!pos.toString().match(/^(before|after)$/) || par.id === '#') ? par : this.get_node(par.parent);
4064
+ old_par = (obj.parent || $.jstree.root).toString();
4065
+ new_par = (!pos.toString().match(/^(before|after)$/) || par.id === $.jstree.root) ? par : this.get_node(par.parent);
3893
4066
  old_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id));
3894
4067
  is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id);
3895
4068
 
@@ -3897,7 +4070,7 @@
3897
4070
  obj = old_ins._model.data[obj.id];
3898
4071
  }
3899
4072
 
3900
- if(par.id === '#') {
4073
+ if(par.id === $.jstree.root) {
3901
4074
  if(pos === "before") { pos = "first"; }
3902
4075
  if(pos === "after") { pos = "last"; }
3903
4076
  }
@@ -3949,14 +4122,14 @@
3949
4122
  new_par.children_d.push(tmp.id);
3950
4123
  new_par.children_d = new_par.children_d.concat(tmp.children_d);
3951
4124
 
3952
- if(new_par.id === '#') {
4125
+ if(new_par.id === $.jstree.root) {
3953
4126
  this._model.force_full_redraw = true;
3954
4127
  }
3955
4128
  if(!this._model.force_full_redraw) {
3956
4129
  this._node_changed(new_par.id);
3957
4130
  }
3958
4131
  if(!skip_redraw) {
3959
- this.redraw(new_par.id === '#');
4132
+ this.redraw(new_par.id === $.jstree.root);
3960
4133
  }
3961
4134
  if(callback) { callback.call(this, tmp, new_par, pos); }
3962
4135
  /**
@@ -3989,7 +4162,7 @@
3989
4162
  var tmp = [], o, t1, t2;
3990
4163
  for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
3991
4164
  o = this.get_node(obj[t1]);
3992
- if(o && o.id && o.id !== '#') { tmp.push(o); }
4165
+ if(o && o.id && o.id !== $.jstree.root) { tmp.push(o); }
3993
4166
  }
3994
4167
  if(!tmp.length) { return false; }
3995
4168
  ccp_node = tmp;
@@ -4016,7 +4189,7 @@
4016
4189
  var tmp = [], o, t1, t2;
4017
4190
  for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
4018
4191
  o = this.get_node(obj[t1]);
4019
- if(o && o.id && o.id !== '#') { tmp.push(o); }
4192
+ if(o && o.id && o.id !== $.jstree.root) { tmp.push(o); }
4020
4193
  }
4021
4194
  if(!tmp.length) { return false; }
4022
4195
  ccp_node = tmp;
@@ -4092,10 +4265,10 @@
4092
4265
  * @name edit(obj [, default_text, callback])
4093
4266
  * @param {mixed} obj
4094
4267
  * @param {String} default_text the text to populate the input with (if omitted or set to a non-string value the node's text value is used)
4095
- * @param {Function} callback a function to be called once the text box is blurred, it is called in the instance's scope and receives the node and a status parameter - true if the rename is successful, false otherwise. You can access the node's title using .text
4268
+ * @param {Function} callback a function to be called once the text box is blurred, it is called in the instance's scope and receives the node, a status parameter (true if the rename is successful, false otherwise) and a boolean indicating if the user cancelled the edit. You can access the node's title using .text
4096
4269
  */
4097
4270
  edit : function (obj, default_text, callback) {
4098
- var rtl, w, a, s, t, h1, h2, fn, tmp;
4271
+ var rtl, w, a, s, t, h1, h2, fn, tmp, cancel = false;
4099
4272
  obj = this.get_node(obj);
4100
4273
  if(!obj) { return false; }
4101
4274
  if(this.settings.core.check_callback === false) {
@@ -4111,7 +4284,8 @@
4111
4284
 
4112
4285
  rtl = this._data.core.rtl;
4113
4286
  w = this.element.width();
4114
- a = obj.children('.jstree-anchor');
4287
+ this._data.core.focused = tmp.id;
4288
+ a = obj.children('.jstree-anchor').focus();
4115
4289
  s = $('<span>');
4116
4290
  /*!
4117
4291
  oi = obj.children("i:visible"),
@@ -4134,7 +4308,9 @@
4134
4308
  "lineHeight" : (this._data.core.li_height) + "px",
4135
4309
  "width" : "150px" // will be set a bit further down
4136
4310
  },
4137
- "blur" : $.proxy(function () {
4311
+ "blur" : $.proxy(function (e) {
4312
+ e.stopImmediatePropagation();
4313
+ e.preventDefault();
4138
4314
  var i = s.children(".jstree-rename-input"),
4139
4315
  v = i.val(),
4140
4316
  f = this.settings.core.force_text,
@@ -4149,30 +4325,39 @@
4149
4325
  if(!nv) {
4150
4326
  this.set_text(obj, t); // move this up? and fix #483
4151
4327
  }
4328
+ this._data.core.focused = tmp.id;
4329
+ setTimeout($.proxy(function () {
4330
+ var node = this.get_node(tmp.id, true);
4331
+ if(node.length) {
4332
+ this._data.core.focused = tmp.id;
4333
+ node.children('.jstree-anchor').focus();
4334
+ }
4335
+ }, this), 0);
4152
4336
  if(callback) {
4153
- callback.call(this, tmp, nv);
4337
+ callback.call(this, tmp, nv, cancel);
4154
4338
  }
4155
4339
  }, this),
4156
- "keydown" : function (event) {
4157
- var key = event.which;
4340
+ "keydown" : function (e) {
4341
+ var key = e.which;
4158
4342
  if(key === 27) {
4343
+ cancel = true;
4159
4344
  this.value = t;
4160
4345
  }
4161
4346
  if(key === 27 || key === 13 || key === 37 || key === 38 || key === 39 || key === 40 || key === 32) {
4162
- event.stopImmediatePropagation();
4347
+ e.stopImmediatePropagation();
4163
4348
  }
4164
4349
  if(key === 27 || key === 13) {
4165
- event.preventDefault();
4350
+ e.preventDefault();
4166
4351
  this.blur();
4167
4352
  }
4168
4353
  },
4169
4354
  "click" : function (e) { e.stopImmediatePropagation(); },
4170
4355
  "mousedown" : function (e) { e.stopImmediatePropagation(); },
4171
- "keyup" : function (event) {
4356
+ "keyup" : function (e) {
4172
4357
  h2.width(Math.min(h1.text("pW" + this.value).width(),w));
4173
4358
  },
4174
- "keypress" : function(event) {
4175
- if(event.which === 13) { return false; }
4359
+ "keypress" : function(e) {
4360
+ if(e.which === 13) { return false; }
4176
4361
  }
4177
4362
  });
4178
4363
  fn = {
@@ -4311,7 +4496,7 @@
4311
4496
  return true;
4312
4497
  }
4313
4498
  obj = this.get_node(obj);
4314
- if(!obj || obj.id === '#') { return false; }
4499
+ if(!obj || obj.id === $.jstree.root) { return false; }
4315
4500
  old = obj.icon;
4316
4501
  obj.icon = icon === true || icon === null || icon === undefined || icon === '' ? true : icon;
4317
4502
  dom = this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon");
@@ -4342,7 +4527,7 @@
4342
4527
  */
4343
4528
  get_icon : function (obj) {
4344
4529
  obj = this.get_node(obj);
4345
- return (!obj || obj.id === '#') ? false : obj.icon;
4530
+ return (!obj || obj.id === $.jstree.root) ? false : obj.icon;
4346
4531
  },
4347
4532
  /**
4348
4533
  * hide the icon on an individual node
@@ -4359,7 +4544,7 @@
4359
4544
  return true;
4360
4545
  }
4361
4546
  obj = this.get_node(obj);
4362
- if(!obj || obj === '#') { return false; }
4547
+ if(!obj || obj === $.jstree.root) { return false; }
4363
4548
  obj.icon = false;
4364
4549
  this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon").addClass('jstree-themeicon-hidden');
4365
4550
  return true;
@@ -4379,7 +4564,7 @@
4379
4564
  return true;
4380
4565
  }
4381
4566
  obj = this.get_node(obj);
4382
- if(!obj || obj === '#') { return false; }
4567
+ if(!obj || obj === $.jstree.root) { return false; }
4383
4568
  dom = this.get_node(obj, true);
4384
4569
  obj.icon = dom.length ? dom.children(".jstree-anchor").children(".jstree-themeicon").attr('rel') : true;
4385
4570
  if(!obj.icon) { obj.icon = true; }
@@ -4429,6 +4614,59 @@
4429
4614
  };
4430
4615
 
4431
4616
 
4617
+ /**
4618
+ * ### Changed plugin
4619
+ *
4620
+ * This plugin adds more information to the `changed.jstree` event. The new data is contained in the `changed` event data property, and contains a lists of `selected` and `deselected` nodes.
4621
+ */
4622
+
4623
+ $.jstree.plugins.changed = function (options, parent) {
4624
+ var last = [];
4625
+ this.trigger = function (ev, data) {
4626
+ var i, j;
4627
+ if(!data) {
4628
+ data = {};
4629
+ }
4630
+ if(ev.replace('.jstree','') === 'changed') {
4631
+ data.changed = { selected : [], deselected : [] };
4632
+ var tmp = {};
4633
+ for(i = 0, j = last.length; i < j; i++) {
4634
+ tmp[last[i]] = 1;
4635
+ }
4636
+ for(i = 0, j = data.selected.length; i < j; i++) {
4637
+ if(!tmp[data.selected[i]]) {
4638
+ data.changed.selected.push(data.selected[i]);
4639
+ }
4640
+ else {
4641
+ tmp[data.selected[i]] = 2;
4642
+ }
4643
+ }
4644
+ for(i = 0, j = last.length; i < j; i++) {
4645
+ if(tmp[last[i]] === 1) {
4646
+ data.changed.deselected.push(last[i]);
4647
+ }
4648
+ }
4649
+ last = data.selected.slice();
4650
+ }
4651
+ /**
4652
+ * triggered when selection changes (the "changed" plugin enhances the original event with more data)
4653
+ * @event
4654
+ * @name changed.jstree
4655
+ * @param {Object} node
4656
+ * @param {Object} action the action that caused the selection to change
4657
+ * @param {Array} selected the current selection
4658
+ * @param {Object} changed an object containing two properties `selected` and `deselected` - both arrays of node IDs, which were selected or deselected since the last changed event
4659
+ * @param {Object} event the event (if any) that triggered this changed event
4660
+ * @plugin changed
4661
+ */
4662
+ parent.trigger.call(this, ev, data);
4663
+ };
4664
+ this.refresh = function (skip_loading, forget_state) {
4665
+ last = [];
4666
+ return parent.refresh.apply(this, arguments);
4667
+ };
4668
+ };
4669
+
4432
4670
  /**
4433
4671
  * ### Checkbox plugin
4434
4672
  *
@@ -4521,7 +4759,7 @@
4521
4759
  dpc = data.nodes,
4522
4760
  i, j;
4523
4761
  for(i = 0, j = dpc.length; i < j; i++) {
4524
- m[dpc[i]].state.checked = (m[dpc[i]].original && m[dpc[i]].original.state && m[dpc[i]].original.state.checked);
4762
+ m[dpc[i]].state.checked = m[dpc[i]].state.checked || (m[dpc[i]].original && m[dpc[i]].original.state && m[dpc[i]].original.state.checked);
4525
4763
  if(m[dpc[i]].state.checked) {
4526
4764
  this._data.checkbox.selected.push(dpc[i]);
4527
4765
  }
@@ -4567,7 +4805,7 @@
4567
4805
  chd = $.vakata.array_unique(chd);
4568
4806
  for(k = 0, l = chd.length; k < l; k++) {
4569
4807
  p = m[chd[k]];
4570
- while(p && p.id !== '#') {
4808
+ while(p && p.id !== $.jstree.root) {
4571
4809
  c = 0;
4572
4810
  for(i = 0, j = p.children.length; i < j; i++) {
4573
4811
  c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
@@ -4611,7 +4849,7 @@
4611
4849
 
4612
4850
  // apply up
4613
4851
  if(s.indexOf('up') !== -1) {
4614
- while(par && par.id !== '#') {
4852
+ while(par && par.id !== $.jstree.root) {
4615
4853
  c = 0;
4616
4854
  for(i = 0, j = par.children.length; i < j; i++) {
4617
4855
  c += m[par.children[i]].state[ t ? 'selected' : 'checked' ];
@@ -4637,7 +4875,7 @@
4637
4875
  }
4638
4876
  }, this))
4639
4877
  .on(this.settings.checkbox.tie_selection ? 'deselect_all.jstree' : 'uncheck_all.jstree', $.proxy(function (e, data) {
4640
- var obj = this.get_node('#'),
4878
+ var obj = this.get_node($.jstree.root),
4641
4879
  m = this._model.data,
4642
4880
  i, j, tmp;
4643
4881
  for(i = 0, j = obj.children_d.length; i < j; i++) {
@@ -4705,7 +4943,7 @@
4705
4943
  var p = this.get_node(data.parent),
4706
4944
  m = this._model.data,
4707
4945
  i, j, c, tmp, t = this.settings.checkbox.tie_selection;
4708
- while(p && p.id !== '#') {
4946
+ while(p && p.id !== $.jstree.root) {
4709
4947
  c = 0;
4710
4948
  for(i = 0, j = p.children.length; i < j; i++) {
4711
4949
  c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
@@ -4733,7 +4971,7 @@
4733
4971
  p, c, i, j, tmp, t = this.settings.checkbox.tie_selection;
4734
4972
  if(!is_multi) {
4735
4973
  p = this.get_node(old_par);
4736
- while(p && p.id !== '#') {
4974
+ while(p && p.id !== $.jstree.root) {
4737
4975
  c = 0;
4738
4976
  for(i = 0, j = p.children.length; i < j; i++) {
4739
4977
  c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
@@ -4753,7 +4991,7 @@
4753
4991
  }
4754
4992
  }
4755
4993
  p = new_par;
4756
- while(p && p.id !== '#') {
4994
+ while(p && p.id !== $.jstree.root) {
4757
4995
  c = 0;
4758
4996
  for(i = 0, j = p.children.length; i < j; i++) {
4759
4997
  c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
@@ -4798,7 +5036,7 @@
4798
5036
  for(i = 0, j = s.length; i < j; i++) {
4799
5037
  if(m[s[i]] && m[s[i]].parents) {
4800
5038
  for(k = 0, l = m[s[i]].parents.length; k < l; k++) {
4801
- if(o[m[s[i]].parents[k]] === undefined && m[s[i]].parents[k] !== '#') {
5039
+ if(o[m[s[i]].parents[k]] === undefined && m[s[i]].parents[k] !== $.jstree.root) {
4802
5040
  o[m[s[i]].parents[k]] = true;
4803
5041
  p.push(m[s[i]].parents[k]);
4804
5042
  }
@@ -4811,12 +5049,12 @@
4811
5049
  var tmp = tt.get_node(this), tmp2;
4812
5050
  if(!tmp.state.loaded) {
4813
5051
  if(tmp.original && tmp.original.state && tmp.original.state.undetermined && tmp.original.state.undetermined === true) {
4814
- if(o[tmp.id] === undefined && tmp.id !== '#') {
5052
+ if(o[tmp.id] === undefined && tmp.id !== $.jstree.root) {
4815
5053
  o[tmp.id] = true;
4816
5054
  p.push(tmp.id);
4817
5055
  }
4818
5056
  for(k = 0, l = tmp.parents.length; k < l; k++) {
4819
- if(o[tmp.parents[k]] === undefined && tmp.parents[k] !== '#') {
5057
+ if(o[tmp.parents[k]] === undefined && tmp.parents[k] !== $.jstree.root) {
4820
5058
  o[tmp.parents[k]] = true;
4821
5059
  p.push(tmp.parents[k]);
4822
5060
  }
@@ -4827,12 +5065,12 @@
4827
5065
  for(i = 0, j = tmp.children_d.length; i < j; i++) {
4828
5066
  tmp2 = m[tmp.children_d[i]];
4829
5067
  if(!tmp2.state.loaded && tmp2.original && tmp2.original.state && tmp2.original.state.undetermined && tmp2.original.state.undetermined === true) {
4830
- if(o[tmp2.id] === undefined && tmp2.id !== '#') {
5068
+ if(o[tmp2.id] === undefined && tmp2.id !== $.jstree.root) {
4831
5069
  o[tmp2.id] = true;
4832
5070
  p.push(tmp2.id);
4833
5071
  }
4834
5072
  for(k = 0, l = tmp2.parents.length; k < l; k++) {
4835
- if(o[tmp2.parents[k]] === undefined && tmp2.parents[k] !== '#') {
5073
+ if(o[tmp2.parents[k]] === undefined && tmp2.parents[k] !== $.jstree.root) {
4836
5074
  o[tmp2.parents[k]] = true;
4837
5075
  p.push(tmp2.parents[k]);
4838
5076
  }
@@ -4855,7 +5093,7 @@
4855
5093
  this.redraw_node = function(obj, deep, is_callback, force_render) {
4856
5094
  obj = parent.redraw_node.apply(this, arguments);
4857
5095
  if(obj) {
4858
- var i, j, tmp = null;
5096
+ var i, j, tmp = null, icon = null;
4859
5097
  for(i = 0, j = obj.childNodes.length; i < j; i++) {
4860
5098
  if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) {
4861
5099
  tmp = obj.childNodes[i];
@@ -4864,7 +5102,9 @@
4864
5102
  }
4865
5103
  if(tmp) {
4866
5104
  if(!this.settings.checkbox.tie_selection && this._model.data[obj.id].state.checked) { tmp.className += ' jstree-checked'; }
4867
- tmp.insertBefore(_i.cloneNode(false), tmp.childNodes[0]);
5105
+ icon = _i.cloneNode(false);
5106
+ if(this._model.data[obj.id].state.checkbox_disabled) { icon.className += ' jstree-checkbox-disabled'; }
5107
+ tmp.insertBefore(icon, tmp.childNodes[0]);
4868
5108
  }
4869
5109
  }
4870
5110
  if(!is_callback && this.settings.checkbox.cascade.indexOf('undetermined') !== -1) {
@@ -4913,8 +5153,83 @@
4913
5153
  }
4914
5154
  return false;
4915
5155
  };
5156
+ /**
5157
+ * disable a node's checkbox
5158
+ * @name disable_checkbox(obj)
5159
+ * @param {mixed} obj an array can be used too
5160
+ * @trigger disable_checkbox.jstree
5161
+ * @plugin checkbox
5162
+ */
5163
+ this.disable_checkbox = function (obj) {
5164
+ var t1, t2, dom;
5165
+ if($.isArray(obj)) {
5166
+ obj = obj.slice();
5167
+ for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
5168
+ this.disable_checkbox(obj[t1]);
5169
+ }
5170
+ return true;
5171
+ }
5172
+ obj = this.get_node(obj);
5173
+ if(!obj || obj.id === $.jstree.root) {
5174
+ return false;
5175
+ }
5176
+ dom = this.get_node(obj, true);
5177
+ if(!obj.state.checkbox_disabled) {
5178
+ obj.state.checkbox_disabled = true;
5179
+ if(dom && dom.length) {
5180
+ dom.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-checkbox-disabled');
5181
+ }
5182
+ /**
5183
+ * triggered when an node's checkbox is disabled
5184
+ * @event
5185
+ * @name disable_checkbox.jstree
5186
+ * @param {Object} node
5187
+ * @plugin checkbox
5188
+ */
5189
+ this.trigger('disable_checkbox', { 'node' : obj });
5190
+ }
5191
+ };
5192
+ /**
5193
+ * enable a node's checkbox
5194
+ * @name disable_checkbox(obj)
5195
+ * @param {mixed} obj an array can be used too
5196
+ * @trigger enable_checkbox.jstree
5197
+ * @plugin checkbox
5198
+ */
5199
+ this.enable_checkbox = function (obj) {
5200
+ var t1, t2, dom;
5201
+ if($.isArray(obj)) {
5202
+ obj = obj.slice();
5203
+ for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
5204
+ this.enable_checkbox(obj[t1]);
5205
+ }
5206
+ return true;
5207
+ }
5208
+ obj = this.get_node(obj);
5209
+ if(!obj || obj.id === $.jstree.root) {
5210
+ return false;
5211
+ }
5212
+ dom = this.get_node(obj, true);
5213
+ if(obj.state.checkbox_disabled) {
5214
+ obj.state.checkbox_disabled = false;
5215
+ if(dom && dom.length) {
5216
+ dom.children('.jstree-anchor').children('.jstree-checkbox').removeClass('jstree-checkbox-disabled');
5217
+ }
5218
+ /**
5219
+ * triggered when an node's checkbox is enabled
5220
+ * @event
5221
+ * @name enable_checkbox.jstree
5222
+ * @param {Object} node
5223
+ * @plugin checkbox
5224
+ */
5225
+ this.trigger('enable_checkbox', { 'node' : obj });
5226
+ }
5227
+ };
4916
5228
 
4917
5229
  this.activate_node = function (obj, e) {
5230
+ if($(e.target).hasClass('jstree-checkbox-disabled')) {
5231
+ return false;
5232
+ }
4918
5233
  if(this.settings.checkbox.tie_selection && (this.settings.checkbox.whole_node || $(e.target).hasClass('jstree-checkbox'))) {
4919
5234
  e.ctrlKey = true;
4920
5235
  }
@@ -4951,7 +5266,7 @@
4951
5266
  return true;
4952
5267
  }
4953
5268
  obj = this.get_node(obj);
4954
- if(!obj || obj.id === '#') {
5269
+ if(!obj || obj.id === $.jstree.root) {
4955
5270
  return false;
4956
5271
  }
4957
5272
  dom = this.get_node(obj, true);
@@ -4991,7 +5306,7 @@
4991
5306
  return true;
4992
5307
  }
4993
5308
  obj = this.get_node(obj);
4994
- if(!obj || obj.id === '#') {
5309
+ if(!obj || obj.id === $.jstree.root) {
4995
5310
  return false;
4996
5311
  }
4997
5312
  dom = this.get_node(obj, true);
@@ -5022,7 +5337,7 @@
5022
5337
  this.check_all = function () {
5023
5338
  if(this.settings.checkbox.tie_selection) { return this.select_all(); }
5024
5339
  var tmp = this._data.checkbox.selected.concat([]), i, j;
5025
- this._data.checkbox.selected = this._model.data['#'].children_d.concat();
5340
+ this._data.checkbox.selected = this._model.data[$.jstree.root].children_d.concat();
5026
5341
  for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) {
5027
5342
  if(this._model.data[this._data.checkbox.selected[i]]) {
5028
5343
  this._model.data[this._data.checkbox.selected[i]].state.checked = true;
@@ -5074,7 +5389,7 @@
5074
5389
  this.is_checked = function (obj) {
5075
5390
  if(this.settings.checkbox.tie_selection) { return this.is_selected(obj); }
5076
5391
  obj = this.get_node(obj);
5077
- if(!obj || obj.id === '#') { return false; }
5392
+ if(!obj || obj.id === $.jstree.root) { return false; }
5078
5393
  return obj.state.checked;
5079
5394
  };
5080
5395
  /**
@@ -5172,11 +5487,39 @@
5172
5487
  }
5173
5488
  return res;
5174
5489
  };
5490
+ this.refresh = function (skip_loading, forget_state) {
5491
+ if(!this.settings.checkbox.tie_selection) {
5492
+ this._data.checkbox.selected = [];
5493
+ }
5494
+ return parent.refresh.apply(this, arguments);
5495
+ };
5175
5496
  };
5176
5497
 
5177
5498
  // include the checkbox plugin by default
5178
5499
  // $.jstree.defaults.plugins.push("checkbox");
5179
5500
 
5501
+ /**
5502
+ * ### Conditionalselect plugin
5503
+ *
5504
+ * This plugin allows defining a callback to allow or deny node selection by user input (activate node method).
5505
+ */
5506
+
5507
+ /**
5508
+ * a callback (function) which is invoked in the instance's scope and receives two arguments - the node and the event that triggered the `activate_node` call. Returning false prevents working with the node, returning true allows invoking activate_node. Defaults to returning `true`.
5509
+ * @name $.jstree.defaults.checkbox.visible
5510
+ * @plugin checkbox
5511
+ */
5512
+ $.jstree.defaults.conditionalselect = function () { return true; };
5513
+ $.jstree.plugins.conditionalselect = function (options, parent) {
5514
+ // own function
5515
+ this.activate_node = function (obj, e) {
5516
+ if(this.settings.conditionalselect.call(this, this.get_node(obj), e)) {
5517
+ parent.activate_node.call(this, obj, e);
5518
+ }
5519
+ };
5520
+ };
5521
+
5522
+
5180
5523
  /**
5181
5524
  * ### Contextmenu plugin
5182
5525
  *
@@ -5412,7 +5755,7 @@
5412
5755
  */
5413
5756
  this.show_contextmenu = function (obj, x, y, e) {
5414
5757
  obj = this.get_node(obj);
5415
- if(!obj || obj.id === '#') { return false; }
5758
+ if(!obj || obj.id === $.jstree.root) { return false; }
5416
5759
  var s = this.settings.contextmenu,
5417
5760
  d = this.get_node(obj, true),
5418
5761
  a = d.children(".jstree-anchor"),
@@ -5817,7 +6160,7 @@
5817
6160
  */
5818
6161
  open_timeout : 500,
5819
6162
  /**
5820
- * a function invoked each time a node is about to be dragged, invoked in the tree's scope and receives the nodes about to be dragged as an argument (array) - return `false` to prevent dragging
6163
+ * 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
5821
6164
  * @name $.jstree.defaults.dnd.is_draggable
5822
6165
  * @plugin dnd
5823
6166
  */
@@ -5884,8 +6227,8 @@
5884
6227
  if(this.settings.core.force_text) {
5885
6228
  txt = $.vakata.html.escape(txt);
5886
6229
  }
5887
- if(obj && obj.id && obj.id !== "#" && (e.which === 1 || e.type === "touchstart") &&
5888
- (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]))))
6230
+ if(obj && obj.id && obj.id !== $.jstree.root && (e.which === 1 || e.type === "touchstart") &&
6231
+ (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)))
5889
6232
  ) {
5890
6233
  this.element.trigger('mousedown.jstree');
5891
6234
  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>');
@@ -5898,12 +6241,14 @@
5898
6241
  // bind only once for all instances
5899
6242
  var lastmv = false,
5900
6243
  laster = false,
6244
+ lastev = false,
5901
6245
  opento = false,
5902
6246
  marker = $('<div id="jstree-marker">&#160;</div>').hide(); //.appendTo('body');
5903
6247
 
5904
6248
  $(document)
5905
6249
  .on('dnd_start.vakata.jstree', function (e, data) {
5906
6250
  lastmv = false;
6251
+ lastev = false;
5907
6252
  if(!data || !data.data || !data.data.jstree) { return; }
5908
6253
  marker.appendTo('body'); //.show();
5909
6254
  })
@@ -5915,6 +6260,7 @@
5915
6260
  if(data.event.target.id && data.event.target.id === 'jstree-marker') {
5916
6261
  return;
5917
6262
  }
6263
+ lastev = data.event;
5918
6264
 
5919
6265
  var ins = $.jstree.reference(data.event.target),
5920
6266
  ref = false,
@@ -5933,11 +6279,11 @@
5933
6279
  if( (data.event.target === ins.element[0] || data.event.target === ins.get_container_ul()[0]) && ins.get_container_ul().children().length === 0) {
5934
6280
  ok = true;
5935
6281
  for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) {
5936
- ok = ok && ins.check( (data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey)) ) ? "copy_node" : "move_node"), (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), '#', 'last', { 'dnd' : true, 'ref' : ins.get_node('#'), 'pos' : 'i', 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) });
6282
+ 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) });
5937
6283
  if(!ok) { break; }
5938
6284
  }
5939
6285
  if(ok) {
5940
- lastmv = { 'ins' : ins, 'par' : '#', 'pos' : 'last' };
6286
+ lastmv = { 'ins' : ins, 'par' : $.jstree.root, 'pos' : 'last' };
5941
6287
  marker.hide();
5942
6288
  data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok');
5943
6289
  return;
@@ -6022,6 +6368,7 @@
6022
6368
  if(!data || !data.data || !data.data.jstree) { return; }
6023
6369
  marker.hide();
6024
6370
  lastmv = false;
6371
+ lastev = false;
6025
6372
  data.helper.find('.jstree-icon').first().removeClass('jstree-ok').addClass('jstree-er');
6026
6373
  })
6027
6374
  .on('dnd_stop.vakata.jstree', function (e, data) {
@@ -6044,11 +6391,18 @@
6044
6391
  }
6045
6392
  }
6046
6393
  }
6394
+ lastev = false;
6395
+ lastmv = false;
6047
6396
  })
6048
6397
  .on('keyup.jstree keydown.jstree', function (e, data) {
6049
6398
  data = $.vakata.dnd._get();
6050
6399
  if(data && data.data && data.data.jstree) {
6051
6400
  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' ]();
6401
+ if(lastev) {
6402
+ lastev.metaKey = e.metaKey;
6403
+ lastev.ctrlKey = e.ctrlKey;
6404
+ $.vakata.dnd._trigger('move', lastev);
6405
+ }
6052
6406
  }
6053
6407
  });
6054
6408
  });
@@ -6484,45 +6838,29 @@
6484
6838
  this._data.search.opn = [];
6485
6839
  this._data.search.som = false;
6486
6840
  this._data.search.smc = false;
6841
+ this._data.search.hdn = [];
6487
6842
 
6488
6843
  this.element
6489
- .on('before_open.jstree', $.proxy(function (e, data) {
6490
- var i, j, f, r = this._data.search.res, s = [], o = $();
6491
- if(r && r.length) {
6492
- this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #')));
6493
- this._data.search.dom.children(".jstree-anchor").addClass('jstree-search');
6494
- if(this._data.search.som && this._data.search.res.length) {
6495
- for(i = 0, j = r.length; i < j; i++) {
6496
- s = s.concat(this.get_node(r[i]).parents);
6497
- }
6498
- s = $.vakata.array_remove_item($.vakata.array_unique(s),'#');
6499
- o = s.length ? $(this.element[0].querySelectorAll('#' + $.map(s, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #'))) : $();
6500
-
6501
- this.element.find(".jstree-node").hide().filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last');
6502
- o = o.add(this._data.search.dom);
6503
- if(this._data.search.smc) {
6504
- this._data.search.dom.children(".jstree-children").find(".jstree-node").show();
6505
- }
6506
- o.parentsUntil(".jstree").addBack().show()
6507
- .filter(".jstree-children").each(function () { $(this).children(".jstree-node:visible").eq(-1).addClass("jstree-last"); });
6508
- }
6509
- }
6510
- }, this))
6511
6844
  .on("search.jstree", $.proxy(function (e, data) {
6512
- if(this._data.search.som) {
6513
- if(data.nodes.length) {
6514
- this.element.find(".jstree-node").hide().filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last');
6515
- if(this._data.search.smc) {
6516
- data.nodes.children(".jstree-children").find(".jstree-node").show();
6845
+ if(this._data.search.som && data.res.length) {
6846
+ var m = this._model.data, i, j, p = [];
6847
+ for(i = 0, j = data.res.length; i < j; i++) {
6848
+ if(m[data.res[i]] && !m[data.res[i]].state.hidden) {
6849
+ p.push(data.res[i]);
6850
+ p = p.concat(m[data.res[i]].parents);
6851
+ if(this._data.search.smc) {
6852
+ p = p.concat(m[data.res[i]].children_d);
6853
+ }
6517
6854
  }
6518
- data.nodes.parentsUntil(".jstree").addBack().show()
6519
- .filter(".jstree-children").each(function () { $(this).children(".jstree-node:visible").eq(-1).addClass("jstree-last"); });
6520
6855
  }
6856
+ p = $.vakata.array_remove_item($.vakata.array_unique(p), $.jstree.root);
6857
+ this._data.search.hdn = this.hide_all();
6858
+ this.show_node(p);
6521
6859
  }
6522
6860
  }, this))
6523
6861
  .on("clear_search.jstree", $.proxy(function (e, data) {
6524
- if(this._data.search.som && data.nodes.length) {
6525
- this.element.find(".jstree-node").css("display","").filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last');
6862
+ if(this._data.search.som && data.res.length) {
6863
+ this.show_node(this._data.search.hdn);
6526
6864
  }
6527
6865
  }, this));
6528
6866
  };
@@ -6598,9 +6936,9 @@
6598
6936
  }
6599
6937
 
6600
6938
  f = new $.vakata.search(str, true, { caseSensitive : s.case_sensitive, fuzzy : s.fuzzy });
6601
- $.each(m[inside ? inside : '#'].children_d, function (ii, i) {
6939
+ $.each(m[inside ? inside : $.jstree.root].children_d, function (ii, i) {
6602
6940
  var v = m[i];
6603
- if(v.text && ( (s.search_callback && s.search_callback.call(this, str, v)) || (!s.search_callback && f.search(v.text).isMatch) ) && (!s.search_leaves_only || (v.state.loaded && v.children.length === 0)) ) {
6941
+ 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) ) ) {
6604
6942
  r.push(i);
6605
6943
  p = p.concat(v.parents);
6606
6944
  }
@@ -6636,7 +6974,6 @@
6636
6974
  * @trigger clear_search.jstree
6637
6975
  */
6638
6976
  this.clear_search = function () {
6639
- this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search");
6640
6977
  if(this.settings.search.close_opened_onclear) {
6641
6978
  this.close_node(this._data.search.opn, 0);
6642
6979
  }
@@ -6650,6 +6987,12 @@
6650
6987
  * @plugin search
6651
6988
  */
6652
6989
  this.trigger('clear_search', { 'nodes' : this._data.search.dom, str : this._data.search.str, res : this._data.search.res });
6990
+ if(this._data.search.res.length) {
6991
+ this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(this._data.search.res, function (v) {
6992
+ return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&');
6993
+ }).join(', #')));
6994
+ this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search");
6995
+ }
6653
6996
  this._data.search.str = "";
6654
6997
  this._data.search.res = [];
6655
6998
  this._data.search.opn = [];
@@ -6665,7 +7008,7 @@
6665
7008
  this._search_open = function (d) {
6666
7009
  var t = this;
6667
7010
  $.each(d.concat([]), function (i, v) {
6668
- if(v === "#") { return true; }
7011
+ if(v === $.jstree.root) { return true; }
6669
7012
  try { v = $('#' + v.replace($.jstree.idregex,'\\$&'), t.element); } catch(ignore) { }
6670
7013
  if(v && v.length) {
6671
7014
  if(t.is_closed(v)) {
@@ -6675,6 +7018,25 @@
6675
7018
  }
6676
7019
  });
6677
7020
  };
7021
+
7022
+ this.redraw_node = function(obj, deep, callback, force_render) {
7023
+ obj = parent.redraw_node.apply(this, arguments);
7024
+ if(obj) {
7025
+ if($.inArray(obj.id, this._data.search.res) !== -1) {
7026
+ var i, j, tmp = null;
7027
+ for(i = 0, j = obj.childNodes.length; i < j; i++) {
7028
+ if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) {
7029
+ tmp = obj.childNodes[i];
7030
+ break;
7031
+ }
7032
+ }
7033
+ if(tmp) {
7034
+ tmp.className += ' jstree-search';
7035
+ }
7036
+ }
7037
+ }
7038
+ return obj;
7039
+ };
6678
7040
  };
6679
7041
 
6680
7042
  // helpers
@@ -6809,6 +7171,7 @@
6809
7171
  // include the search plugin by default
6810
7172
  // $.jstree.defaults.plugins.push("search");
6811
7173
 
7174
+
6812
7175
  /**
6813
7176
  * ### Sort plugin
6814
7177
  *
@@ -6999,16 +7362,16 @@
6999
7362
  * @plugin types
7000
7363
  */
7001
7364
  $.jstree.defaults.types = {
7002
- '#' : {},
7003
7365
  'default' : {}
7004
7366
  };
7367
+ $.jstree.defaults.types[$.jstree.root] = {};
7005
7368
 
7006
7369
  $.jstree.plugins.types = function (options, parent) {
7007
7370
  this.init = function (el, options) {
7008
7371
  var i, j;
7009
7372
  if(options && options.types && options.types['default']) {
7010
7373
  for(i in options.types) {
7011
- if(i !== "default" && i !== "#" && options.types.hasOwnProperty(i)) {
7374
+ if(i !== "default" && i !== $.jstree.root && options.types.hasOwnProperty(i)) {
7012
7375
  for(j in options.types['default']) {
7013
7376
  if(options.types['default'].hasOwnProperty(j) && options.types[i][j] === undefined) {
7014
7377
  options.types[i][j] = options.types['default'][j];
@@ -7018,11 +7381,11 @@
7018
7381
  }
7019
7382
  }
7020
7383
  parent.init.call(this, el, options);
7021
- this._model.data['#'].type = '#';
7384
+ this._model.data[$.jstree.root].type = $.jstree.root;
7022
7385
  };
7023
7386
  this.refresh = function (skip_loading, forget_state) {
7024
7387
  parent.refresh.call(this, skip_loading, forget_state);
7025
- this._model.data['#'].type = '#';
7388
+ this._model.data[$.jstree.root].type = $.jstree.root;
7026
7389
  };
7027
7390
  this.bind = function () {
7028
7391
  this.element
@@ -7044,7 +7407,7 @@
7044
7407
  m[dpc[i]].icon = t[c].icon;
7045
7408
  }
7046
7409
  }
7047
- m['#'].type = '#';
7410
+ m[$.jstree.root].type = $.jstree.root;
7048
7411
  }, this));
7049
7412
  parent.bind.call(this);
7050
7413
  };
@@ -7271,7 +7634,7 @@
7271
7634
  this.create_node = function (par, node, pos, callback, is_loaded) {
7272
7635
  if(!node || node.text === undefined) {
7273
7636
  if(par === null) {
7274
- par = "#";
7637
+ par = $.jstree.root;
7275
7638
  }
7276
7639
  par = this.get_node(par);
7277
7640
  if(!par) {
@@ -7425,4 +7788,5 @@
7425
7788
  } catch(ignore) { }
7426
7789
  }
7427
7790
 
7791
+ return $.fn.jstree;
7428
7792
  }));