jqtree-rails 0.1.5.0 → 0.1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  module JqTree
2
2
  module Rails
3
- VERSION = "0.1.5.0"
4
- JQTREE_VERSION = "0.15"
3
+ VERSION = "0.1.8.0"
4
+ JQTREE_VERSION = "0.18"
5
5
  end
6
6
  end
@@ -1,5 +1,4 @@
1
- // Generated by CoffeeScript 1.6.1
2
-
1
+ // Generated by CoffeeScript 1.6.3
3
2
  /*
4
3
  Copyright 2013 Marco Braak
5
4
 
@@ -18,7 +17,7 @@ limitations under the License.
18
17
 
19
18
 
20
19
  (function() {
21
- var $, BorderDropHint, DragAndDropHandler, DragElement, FolderElement, GhostDropHint, JqTreeWidget, MouseWidget, Node, NodeElement, Position, SaveStateHandler, ScrollHandler, SelectNodeHandler, SimpleWidget, TRIANGLE_DOWN, TRIANGLE_RIGHT, html_escape, indexOf, json_escapable, json_meta, json_quote, json_str, _indexOf,
20
+ var $, BorderDropHint, DragAndDropHandler, DragElement, FolderElement, GhostDropHint, HitAreasGenerator, JqTreeWidget, KeyHandler, MouseWidget, Node, NodeElement, Position, SaveStateHandler, ScrollHandler, SelectNodeHandler, SimpleWidget, VisibleNodeIterator, html_escape, indexOf, json_escapable, json_meta, json_quote, json_str, _indexOf, _ref, _ref1, _ref2,
22
21
  __slice = [].slice,
23
22
  __hasProp = {}.hasOwnProperty,
24
23
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
@@ -26,7 +25,6 @@ limitations under the License.
26
25
  $ = this.jQuery;
27
26
 
28
27
  SimpleWidget = (function() {
29
-
30
28
  SimpleWidget.prototype.defaults = {};
31
29
 
32
30
  function SimpleWidget(el, options) {
@@ -123,55 +121,72 @@ limitations under the License.
123
121
 
124
122
 
125
123
  MouseWidget = (function(_super) {
126
-
127
124
  __extends(MouseWidget, _super);
128
125
 
129
126
  function MouseWidget() {
130
- return MouseWidget.__super__.constructor.apply(this, arguments);
127
+ _ref = MouseWidget.__super__.constructor.apply(this, arguments);
128
+ return _ref;
131
129
  }
132
130
 
133
131
  MouseWidget.is_mouse_handled = false;
134
132
 
135
133
  MouseWidget.prototype._init = function() {
136
134
  this.$el.bind('mousedown.mousewidget', $.proxy(this._mouseDown, this));
135
+ this.$el.bind('touchstart.mousewidget', $.proxy(this._touchStart, this));
137
136
  this.is_mouse_started = false;
138
137
  this.mouse_delay = 0;
139
138
  this._mouse_delay_timer = null;
140
- return this._is_mouse_delay_met = true;
139
+ this._is_mouse_delay_met = true;
140
+ return this.mouse_down_info = null;
141
141
  };
142
142
 
143
143
  MouseWidget.prototype._deinit = function() {
144
144
  var $document;
145
145
  this.$el.unbind('mousedown.mousewidget');
146
+ this.$el.unbind('touchstart.mousewidget');
146
147
  $document = $(document);
147
148
  $document.unbind('mousemove.mousewidget');
148
149
  return $document.unbind('mouseup.mousewidget');
149
150
  };
150
151
 
151
152
  MouseWidget.prototype._mouseDown = function(e) {
152
- var $document;
153
- if (MouseWidget.is_mouse_handled) {
153
+ var result;
154
+ if (e.which !== 1) {
154
155
  return;
155
156
  }
156
- if (!this.is_mouse_started) {
157
- this._mouseUp(e);
157
+ result = this._handleMouseDown(e, this._getPositionInfo(e));
158
+ if (result) {
159
+ e.preventDefault();
158
160
  }
159
- if (e.which !== 1) {
161
+ return result;
162
+ };
163
+
164
+ MouseWidget.prototype._handleMouseDown = function(e, position_info) {
165
+ if (MouseWidget.is_mouse_handled) {
160
166
  return;
161
167
  }
162
- if (!this._mouseCapture(e)) {
168
+ if (this.is_mouse_started) {
169
+ this._handleMouseUp(position_info);
170
+ }
171
+ this.mouse_down_info = position_info;
172
+ if (!this._mouseCapture(position_info)) {
163
173
  return;
164
174
  }
165
- this.mouse_down_event = e;
175
+ this._handleStartMouse();
176
+ this.is_mouse_handled = true;
177
+ return true;
178
+ };
179
+
180
+ MouseWidget.prototype._handleStartMouse = function() {
181
+ var $document;
166
182
  $document = $(document);
167
183
  $document.bind('mousemove.mousewidget', $.proxy(this._mouseMove, this));
184
+ $document.bind('touchmove.mousewidget', $.proxy(this._touchMove, this));
168
185
  $document.bind('mouseup.mousewidget', $.proxy(this._mouseUp, this));
186
+ $document.bind('touchend.mousewidget', $.proxy(this._touchEnd, this));
169
187
  if (this.mouse_delay) {
170
- this._startMouseDelayTimer();
188
+ return this._startMouseDelayTimer();
171
189
  }
172
- e.preventDefault();
173
- this.is_mouse_handled = true;
174
- return true;
175
190
  };
176
191
 
177
192
  MouseWidget.prototype._startMouseDelayTimer = function() {
@@ -186,47 +201,65 @@ limitations under the License.
186
201
  };
187
202
 
188
203
  MouseWidget.prototype._mouseMove = function(e) {
204
+ return this._handleMouseMove(e, this._getPositionInfo(e));
205
+ };
206
+
207
+ MouseWidget.prototype._handleMouseMove = function(e, position_info) {
189
208
  if (this.is_mouse_started) {
190
- this._mouseDrag(e);
209
+ this._mouseDrag(position_info);
191
210
  return e.preventDefault();
192
211
  }
193
212
  if (this.mouse_delay && !this._is_mouse_delay_met) {
194
213
  return true;
195
214
  }
196
- this.is_mouse_started = this._mouseStart(this.mouse_down_event) !== false;
215
+ this.is_mouse_started = this._mouseStart(this.mouse_down_info) !== false;
197
216
  if (this.is_mouse_started) {
198
- this._mouseDrag(e);
217
+ this._mouseDrag(position_info);
199
218
  } else {
200
- this._mouseUp(e);
219
+ this._handleMouseUp(position_info);
201
220
  }
202
221
  return !this.is_mouse_started;
203
222
  };
204
223
 
224
+ MouseWidget.prototype._getPositionInfo = function(e) {
225
+ return {
226
+ page_x: e.pageX,
227
+ page_y: e.pageY,
228
+ target: e.target,
229
+ original_event: e
230
+ };
231
+ };
232
+
205
233
  MouseWidget.prototype._mouseUp = function(e) {
234
+ return this._handleMouseUp(this._getPositionInfo(e));
235
+ };
236
+
237
+ MouseWidget.prototype._handleMouseUp = function(position_info) {
206
238
  var $document;
207
239
  $document = $(document);
208
240
  $document.unbind('mousemove.mousewidget');
241
+ $document.unbind('touchmove.mousewidget');
209
242
  $document.unbind('mouseup.mousewidget');
243
+ $document.unbind('touchend.mousewidget');
210
244
  if (this.is_mouse_started) {
211
245
  this.is_mouse_started = false;
212
- this._mouseStop(e);
246
+ this._mouseStop(position_info);
213
247
  }
214
- return false;
215
248
  };
216
249
 
217
- MouseWidget.prototype._mouseCapture = function(e) {
250
+ MouseWidget.prototype._mouseCapture = function(position_info) {
218
251
  return true;
219
252
  };
220
253
 
221
- MouseWidget.prototype._mouseStart = function(e) {
254
+ MouseWidget.prototype._mouseStart = function(position_info) {
222
255
  return null;
223
256
  };
224
257
 
225
- MouseWidget.prototype._mouseDrag = function(e) {
258
+ MouseWidget.prototype._mouseDrag = function(position_info) {
226
259
  return null;
227
260
  };
228
261
 
229
- MouseWidget.prototype._mouseStop = function(e) {
262
+ MouseWidget.prototype._mouseStop = function(position_info) {
230
263
  return null;
231
264
  };
232
265
 
@@ -234,136 +267,48 @@ limitations under the License.
234
267
  return this.mouse_delay = mouse_delay;
235
268
  };
236
269
 
237
- return MouseWidget;
238
-
239
- })(SimpleWidget);
240
-
241
- /*
242
- Copyright 2013 Marco Braak
243
-
244
- Licensed under the Apache License, Version 2.0 (the "License");
245
- you may not use this file except in compliance with the License.
246
- You may obtain a copy of the License at
247
-
248
- http://www.apache.org/licenses/LICENSE-2.0
249
-
250
- Unless required by applicable law or agreed to in writing, software
251
- distributed under the License is distributed on an "AS IS" BASIS,
252
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
253
- See the License for the specific language governing permissions and
254
- limitations under the License.
255
- */
256
-
257
-
258
- this.Tree = {};
259
-
260
- $ = this.jQuery;
261
-
262
- _indexOf = function(array, item) {
263
- var i, value, _i, _len;
264
- for (i = _i = 0, _len = array.length; _i < _len; i = ++_i) {
265
- value = array[i];
266
- if (value === item) {
267
- return i;
270
+ MouseWidget.prototype._touchStart = function(e) {
271
+ var touch;
272
+ if (e.originalEvent.touches.length > 1) {
273
+ return;
268
274
  }
269
- }
270
- return -1;
271
- };
272
-
273
- indexOf = function(array, item) {
274
- if (array.indexOf) {
275
- return array.indexOf(item);
276
- } else {
277
- return _indexOf(array, item);
278
- }
279
- };
280
-
281
- this.Tree.indexOf = indexOf;
282
-
283
- this.Tree._indexOf = _indexOf;
284
-
285
- if (!((this.JSON != null) && (this.JSON.stringify != null) && typeof this.JSON.stringify === 'function')) {
286
- json_escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
287
- json_meta = {
288
- '\b': '\\b',
289
- '\t': '\\t',
290
- '\n': '\\n',
291
- '\f': '\\f',
292
- '\r': '\\r',
293
- '"': '\\"',
294
- '\\': '\\\\'
275
+ touch = e.originalEvent.changedTouches[0];
276
+ return this._handleMouseDown(e, this._getPositionInfo(touch));
295
277
  };
296
- json_quote = function(string) {
297
- json_escapable.lastIndex = 0;
298
- if (json_escapable.test(string)) {
299
- return '"' + string.replace(json_escapable, function(a) {
300
- var c;
301
- c = json_meta[a];
302
- return (typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4));
303
- }) + '"';
304
- } else {
305
- return '"' + string + '"';
278
+
279
+ MouseWidget.prototype._touchMove = function(e) {
280
+ var touch;
281
+ if (e.originalEvent.touches.length > 1) {
282
+ return;
306
283
  }
284
+ touch = e.originalEvent.changedTouches[0];
285
+ return this._handleMouseMove(e, this._getPositionInfo(touch));
307
286
  };
308
- json_str = function(key, holder) {
309
- var i, k, partial, v, value, _i, _len;
310
- value = holder[key];
311
- switch (typeof value) {
312
- case 'string':
313
- return json_quote(value);
314
- case 'number':
315
- if (isFinite(value)) {
316
- return String(value);
317
- } else {
318
- return 'null';
319
- }
320
- case 'boolean':
321
- case 'null':
322
- return String(value);
323
- case 'object':
324
- if (!value) {
325
- return 'null';
326
- }
327
- partial = [];
328
- if (Object.prototype.toString.apply(value) === '[object Array]') {
329
- for (i = _i = 0, _len = value.length; _i < _len; i = ++_i) {
330
- v = value[i];
331
- partial[i] = json_str(i, value) || 'null';
332
- }
333
- return (partial.length === 0 ? '[]' : '[' + partial.join(',') + ']');
334
- }
335
- for (k in value) {
336
- if (Object.prototype.hasOwnProperty.call(value, k)) {
337
- v = json_str(k, value);
338
- if (v) {
339
- partial.push(json_quote(k) + ':' + v);
340
- }
341
- }
342
- }
343
- return (partial.length === 0 ? '{}' : '{' + partial.join(',') + '}');
287
+
288
+ MouseWidget.prototype._touchEnd = function(e) {
289
+ var touch;
290
+ if (e.originalEvent.touches.length > 1) {
291
+ return;
344
292
  }
293
+ touch = e.originalEvent.changedTouches[0];
294
+ return this._handleMouseUp(this._getPositionInfo(touch));
345
295
  };
346
- if (this.JSON == null) {
347
- this.JSON = {};
348
- }
349
- this.JSON.stringify = function(value) {
350
- return json_str('', {
351
- '': value
352
- });
353
- };
354
- }
355
296
 
356
- html_escape = function(string) {
357
- return ('' + string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g, '&#x2F;');
358
- };
297
+ return MouseWidget;
298
+
299
+ })(SimpleWidget);
300
+
301
+ this.Tree = {};
302
+
303
+ $ = this.jQuery;
359
304
 
360
305
  Position = {
361
306
  getName: function(position) {
362
307
  return Position.strings[position - 1];
363
308
  },
364
309
  nameToIndex: function(name) {
365
- var i, _i, _ref;
366
- for (i = _i = 1, _ref = Position.strings.length; 1 <= _ref ? _i <= _ref : _i >= _ref; i = 1 <= _ref ? ++_i : --_i) {
310
+ var i, _i, _ref1;
311
+ for (i = _i = 1, _ref1 = Position.strings.length; 1 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 1 <= _ref1 ? ++_i : --_i) {
367
312
  if (Position.strings[i - 1] === name) {
368
313
  return i;
369
314
  }
@@ -385,7 +330,6 @@ limitations under the License.
385
330
  this.Tree.Position = Position;
386
331
 
387
332
  Node = (function() {
388
-
389
333
  function Node(o, is_root, node_class) {
390
334
  if (is_root == null) {
391
335
  is_root = false;
@@ -579,11 +523,11 @@ limitations under the License.
579
523
  var _iterate,
580
524
  _this = this;
581
525
  _iterate = function(node, level) {
582
- var child, result, _i, _len, _ref;
526
+ var child, result, _i, _len, _ref1;
583
527
  if (node.children) {
584
- _ref = node.children;
585
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
586
- child = _ref[_i];
528
+ _ref1 = node.children;
529
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
530
+ child = _ref1[_i];
587
531
  result = callback(child, level);
588
532
  if (_this.hasChildren() && result) {
589
533
  _iterate(child, level + 1);
@@ -689,16 +633,16 @@ limitations under the License.
689
633
  };
690
634
 
691
635
  Node.prototype.addParent = function(node_info) {
692
- var child, new_parent, original_parent, _i, _len, _ref;
636
+ var child, new_parent, original_parent, _i, _len, _ref1;
693
637
  if (!this.parent) {
694
638
  return null;
695
639
  } else {
696
640
  new_parent = new this.tree.node_class(node_info);
697
641
  new_parent._setParent(this.tree);
698
642
  original_parent = this.parent;
699
- _ref = original_parent.children;
700
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
701
- child = _ref[_i];
643
+ _ref1 = original_parent.children;
644
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
645
+ child = _ref1[_i];
702
646
  new_parent.addChild(child);
703
647
  }
704
648
  original_parent.children = [];
@@ -756,13 +700,13 @@ limitations under the License.
756
700
  };
757
701
 
758
702
  Node.prototype.addNodeToIndex = function(node) {
759
- if (node.id) {
703
+ if (node.id != null) {
760
704
  return this.id_mapping[node.id] = node;
761
705
  }
762
706
  };
763
707
 
764
708
  Node.prototype.removeNodeFromIndex = function(node) {
765
- if (node.id) {
709
+ if (node.id != null) {
766
710
  return delete this.id_mapping[node.id];
767
711
  }
768
712
  };
@@ -776,29 +720,71 @@ limitations under the License.
776
720
  return this.children = [];
777
721
  };
778
722
 
723
+ Node.prototype.getPreviousSibling = function() {
724
+ var previous_index;
725
+ if (!this.parent) {
726
+ return null;
727
+ } else {
728
+ previous_index = this.parent.getChildIndex(this) - 1;
729
+ if (previous_index >= 0) {
730
+ return this.parent.children[previous_index];
731
+ } else {
732
+ return null;
733
+ }
734
+ }
735
+ };
736
+
737
+ Node.prototype.getNextSibling = function() {
738
+ var next_index;
739
+ if (!this.parent) {
740
+ return null;
741
+ } else {
742
+ next_index = this.parent.getChildIndex(this) + 1;
743
+ if (next_index < this.parent.children.length) {
744
+ return this.parent.children[next_index];
745
+ } else {
746
+ return null;
747
+ }
748
+ }
749
+ };
750
+
779
751
  return Node;
780
752
 
781
753
  })();
782
754
 
783
755
  this.Tree.Node = Node;
784
756
 
785
- TRIANGLE_RIGHT = '&#x25ba;';
757
+ /*
758
+ Copyright 2013 Marco Braak
759
+
760
+ Licensed under the Apache License, Version 2.0 (the "License");
761
+ you may not use this file except in compliance with the License.
762
+ You may obtain a copy of the License at
763
+
764
+ http://www.apache.org/licenses/LICENSE-2.0
765
+
766
+ Unless required by applicable law or agreed to in writing, software
767
+ distributed under the License is distributed on an "AS IS" BASIS,
768
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
769
+ See the License for the specific language governing permissions and
770
+ limitations under the License.
771
+ */
786
772
 
787
- TRIANGLE_DOWN = '&#x25bc;';
788
773
 
789
774
  JqTreeWidget = (function(_super) {
790
-
791
775
  __extends(JqTreeWidget, _super);
792
776
 
793
777
  function JqTreeWidget() {
794
- return JqTreeWidget.__super__.constructor.apply(this, arguments);
778
+ _ref1 = JqTreeWidget.__super__.constructor.apply(this, arguments);
779
+ return _ref1;
795
780
  }
796
781
 
797
782
  JqTreeWidget.prototype.defaults = {
798
783
  autoOpen: false,
799
784
  saveState: false,
800
785
  dragAndDrop: false,
801
- selectable: false,
786
+ selectable: true,
787
+ useContextMenu: true,
802
788
  onCanSelectNode: null,
803
789
  onSetStateFromStorage: null,
804
790
  onGetStateFromStorage: null,
@@ -809,8 +795,12 @@ limitations under the License.
809
795
  onLoadFailed: null,
810
796
  autoEscape: true,
811
797
  dataUrl: null,
798
+ closedIcon: '&#x25ba;',
799
+ openedIcon: '&#x25bc;',
812
800
  slide: true,
813
- nodeClass: Node
801
+ nodeClass: Node,
802
+ dataFilter: null,
803
+ keyboardSupport: true
814
804
  };
815
805
 
816
806
  JqTreeWidget.prototype.toggle = function(node, slide) {
@@ -829,11 +819,68 @@ limitations under the License.
829
819
  };
830
820
 
831
821
  JqTreeWidget.prototype.selectNode = function(node) {
832
- return this.select_node_handler.selectNode(node);
822
+ return this._selectNode(node, false);
823
+ };
824
+
825
+ JqTreeWidget.prototype._selectNode = function(node, must_toggle) {
826
+ var canSelect, deselected_node, openParents, saveState,
827
+ _this = this;
828
+ if (must_toggle == null) {
829
+ must_toggle = false;
830
+ }
831
+ if (!this.select_node_handler) {
832
+ return;
833
+ }
834
+ canSelect = function() {
835
+ if (_this.options.onCanSelectNode) {
836
+ return _this.options.selectable && _this.options.onCanSelectNode(node);
837
+ } else {
838
+ return _this.options.selectable;
839
+ }
840
+ };
841
+ openParents = function() {
842
+ var parent;
843
+ parent = node.parent;
844
+ if (parent && parent.parent && !parent.is_open) {
845
+ return _this.openNode(parent, false);
846
+ }
847
+ };
848
+ saveState = function() {
849
+ if (_this.options.saveState) {
850
+ return _this.save_state_handler.saveState();
851
+ }
852
+ };
853
+ if (!node) {
854
+ this._deselectCurrentNode();
855
+ saveState();
856
+ return;
857
+ }
858
+ if (!canSelect()) {
859
+ return;
860
+ }
861
+ if (this.select_node_handler.isNodeSelected(node)) {
862
+ if (must_toggle) {
863
+ this._deselectCurrentNode();
864
+ this._triggerEvent('tree.select', {
865
+ node: null,
866
+ previous_node: node
867
+ });
868
+ }
869
+ } else {
870
+ deselected_node = this.getSelectedNode();
871
+ this._deselectCurrentNode();
872
+ this.addToSelection(node);
873
+ this._triggerEvent('tree.select', {
874
+ node: node,
875
+ deselected_node: deselected_node
876
+ });
877
+ openParents();
878
+ }
879
+ return saveState();
833
880
  };
834
881
 
835
882
  JqTreeWidget.prototype.getSelectedNode = function() {
836
- return this.selected_node || false;
883
+ return this.select_node_handler.getSelectedNode();
837
884
  };
838
885
 
839
886
  JqTreeWidget.prototype.toJson = function() {
@@ -841,23 +888,16 @@ limitations under the License.
841
888
  };
842
889
 
843
890
  JqTreeWidget.prototype.loadData = function(data, parent_node) {
844
- this._loadData(data, parent_node);
845
- if (!parent_node) {
846
- return this.selected_node = null;
847
- }
891
+ return this._loadData(data, parent_node);
848
892
  };
849
893
 
850
894
  JqTreeWidget.prototype.loadDataFromUrl = function(url, parent_node, on_finished) {
851
895
  if ($.type(url) !== 'string') {
852
- parent_node = url;
853
896
  on_finished = parent_node;
897
+ parent_node = url;
854
898
  url = null;
855
- on_finished = null;
856
- }
857
- this._loadDataFromUrl(url, parent_node, on_finished);
858
- if (!parent_node) {
859
- return this.selected_node = null;
860
899
  }
900
+ return this._loadDataFromUrl(url, parent_node, on_finished);
861
901
  };
862
902
 
863
903
  JqTreeWidget.prototype._loadDataFromUrl = function(url_info, parent_node, on_finished) {
@@ -907,6 +947,9 @@ limitations under the License.
907
947
  } else {
908
948
  data = $.parseJSON(response);
909
949
  }
950
+ if (_this.options.dataFilter) {
951
+ data = _this.options.dataFilter(data);
952
+ }
910
953
  removeLoadingClass();
911
954
  _this._loadData(data, parent_node);
912
955
  if (on_finished && $.isFunction(on_finished)) {
@@ -923,14 +966,17 @@ limitations under the License.
923
966
  };
924
967
 
925
968
  JqTreeWidget.prototype._loadData = function(data, parent_node) {
969
+ var n, selected_nodes_under_parent, _i, _len;
926
970
  this._triggerEvent('tree.load_data', {
927
971
  tree_data: data
928
972
  });
929
973
  if (!parent_node) {
930
- this._initTree(data, false, this.options.nodeClass);
974
+ this._initTree(data);
931
975
  } else {
932
- if (this.selected_node && parent_node.isParentOf(this.selected_node)) {
933
- this.selected_node = null;
976
+ selected_nodes_under_parent = this.select_node_handler.getSelectedNodes(parent_node);
977
+ for (_i = 0, _len = selected_nodes_under_parent.length; _i < _len; _i++) {
978
+ n = selected_nodes_under_parent[_i];
979
+ this.select_node_handler.removeFromSelection(n);
934
980
  }
935
981
  parent_node.loadFromData(data);
936
982
  parent_node.load_on_demand = false;
@@ -1034,45 +1080,23 @@ limitations under the License.
1034
1080
  };
1035
1081
 
1036
1082
  JqTreeWidget.prototype.removeNode = function(node) {
1037
- var mustUnselectedNode, parent,
1038
- _this = this;
1039
- mustUnselectedNode = function() {
1040
- var result;
1041
- if (!_this.selected_node) {
1042
- return false;
1043
- } else if (_this.selected_node === node) {
1044
- return true;
1045
- } else {
1046
- result = true;
1047
- _this.tree.iterate(function(child) {
1048
- if (node === child) {
1049
- result = true;
1050
- return false;
1051
- } else {
1052
- return true;
1053
- }
1054
- });
1055
- return result;
1056
- }
1057
- };
1083
+ var parent;
1058
1084
  parent = node.parent;
1059
1085
  if (parent) {
1060
- if (mustUnselectedNode()) {
1061
- this.selected_node = null;
1062
- }
1086
+ this.select_node_handler.removeFromSelection(node, true);
1063
1087
  node.remove();
1064
1088
  return this._refreshElements(parent.parent);
1065
1089
  }
1066
1090
  };
1067
1091
 
1068
1092
  JqTreeWidget.prototype.appendNode = function(new_node_info, parent_node) {
1069
- var is_already_root_node, node;
1093
+ var is_already_folder_node, node;
1070
1094
  if (!parent_node) {
1071
1095
  parent_node = this.tree;
1072
1096
  }
1073
- is_already_root_node = parent_node.isFolder();
1097
+ is_already_folder_node = parent_node.isFolder();
1074
1098
  node = parent_node.append(new_node_info);
1075
- if (is_already_root_node) {
1099
+ if (is_already_folder_node) {
1076
1100
  this._refreshElements(parent_node);
1077
1101
  } else {
1078
1102
  this._refreshElements(parent_node.parent);
@@ -1091,9 +1115,17 @@ limitations under the License.
1091
1115
  };
1092
1116
 
1093
1117
  JqTreeWidget.prototype.updateNode = function(node, data) {
1118
+ var id_is_changed;
1119
+ id_is_changed = data.id && data.id !== node.id;
1120
+ if (id_is_changed) {
1121
+ this.tree.removeNodeFromIndex(node);
1122
+ }
1094
1123
  node.setData(data);
1124
+ if (id_is_changed) {
1125
+ this.tree.addNodeToIndex(node);
1126
+ }
1095
1127
  this._refreshElements(node.parent);
1096
- return this.select_node_handler.selectCurrentNode();
1128
+ return this._selectCurrentNode();
1097
1129
  };
1098
1130
 
1099
1131
  JqTreeWidget.prototype.moveNode = function(node, target_node, position) {
@@ -1107,41 +1139,94 @@ limitations under the License.
1107
1139
  return this.save_state_handler.getStateFromStorage();
1108
1140
  };
1109
1141
 
1110
- JqTreeWidget.prototype._init = function() {
1111
- JqTreeWidget.__super__._init.call(this);
1112
- this.element = this.$el;
1113
- this.selected_node = null;
1114
- this.mouse_delay = 300;
1115
- this.save_state_handler = new SaveStateHandler(this);
1116
- this.select_node_handler = new SelectNodeHandler(this);
1117
- this.dnd_handler = new DragAndDropHandler(this);
1118
- this.scroll_handler = new ScrollHandler(this);
1119
- this._initData();
1120
- this.element.click($.proxy(this._click, this));
1121
- return this.element.bind('contextmenu', $.proxy(this._contextmenu, this));
1142
+ JqTreeWidget.prototype.addToSelection = function(node) {
1143
+ this.select_node_handler.addToSelection(node);
1144
+ return this._getNodeElementForNode(node).select();
1122
1145
  };
1123
1146
 
1124
- JqTreeWidget.prototype._deinit = function() {
1125
- this.element.empty();
1126
- this.element.unbind();
1127
- this.tree = null;
1128
- return JqTreeWidget.__super__._deinit.call(this);
1147
+ JqTreeWidget.prototype.getSelectedNodes = function() {
1148
+ return this.select_node_handler.getSelectedNodes();
1129
1149
  };
1130
1150
 
1131
- JqTreeWidget.prototype._initData = function() {
1132
- if (this.options.data) {
1133
- return this._loadData(this.options.data);
1134
- } else {
1135
- return this._loadDataFromUrl(this._getDataUrlInfo());
1136
- }
1151
+ JqTreeWidget.prototype.isNodeSelected = function(node) {
1152
+ return this.select_node_handler.isNodeSelected(node);
1153
+ };
1154
+
1155
+ JqTreeWidget.prototype.removeFromSelection = function(node) {
1156
+ this.select_node_handler.removeFromSelection(node);
1157
+ return this._getNodeElementForNode(node).deselect();
1158
+ };
1159
+
1160
+ JqTreeWidget.prototype.scrollToNode = function(node) {
1161
+ var $element, top;
1162
+ $element = $(node.element);
1163
+ top = $element.offset().top - this.$el.offset().top;
1164
+ return this.scroll_handler.scrollTo(top);
1165
+ };
1166
+
1167
+ JqTreeWidget.prototype.getState = function() {
1168
+ return this.save_state_handler.getState();
1169
+ };
1170
+
1171
+ JqTreeWidget.prototype.setState = function(state) {
1172
+ this.save_state_handler.setState(state);
1173
+ return this._refreshElements();
1174
+ };
1175
+
1176
+ JqTreeWidget.prototype._init = function() {
1177
+ JqTreeWidget.__super__._init.call(this);
1178
+ this.element = this.$el;
1179
+ this.mouse_delay = 300;
1180
+ this.is_initialized = false;
1181
+ if (typeof SaveStateHandler !== "undefined" && SaveStateHandler !== null) {
1182
+ this.save_state_handler = new SaveStateHandler(this);
1183
+ } else {
1184
+ this.options.saveState = false;
1185
+ }
1186
+ if (typeof SelectNodeHandler !== "undefined" && SelectNodeHandler !== null) {
1187
+ this.select_node_handler = new SelectNodeHandler(this);
1188
+ }
1189
+ if (typeof DragAndDropHandler !== "undefined" && DragAndDropHandler !== null) {
1190
+ this.dnd_handler = new DragAndDropHandler(this);
1191
+ } else {
1192
+ this.options.dragAndDrop = false;
1193
+ }
1194
+ if (typeof ScrollHandler !== "undefined" && ScrollHandler !== null) {
1195
+ this.scroll_handler = new ScrollHandler(this);
1196
+ }
1197
+ if ((typeof KeyHandler !== "undefined" && KeyHandler !== null) && (typeof SelectNodeHandler !== "undefined" && SelectNodeHandler !== null)) {
1198
+ this.key_handler = new KeyHandler(this);
1199
+ }
1200
+ this._initData();
1201
+ this.element.click($.proxy(this._click, this));
1202
+ this.element.dblclick($.proxy(this._dblclick, this));
1203
+ if (this.options.useContextMenu) {
1204
+ return this.element.bind('contextmenu', $.proxy(this._contextmenu, this));
1205
+ }
1206
+ };
1207
+
1208
+ JqTreeWidget.prototype._deinit = function() {
1209
+ this.element.empty();
1210
+ this.element.unbind();
1211
+ this.key_handler.deinit();
1212
+ this.tree = null;
1213
+ return JqTreeWidget.__super__._deinit.call(this);
1214
+ };
1215
+
1216
+ JqTreeWidget.prototype._initData = function() {
1217
+ if (this.options.data) {
1218
+ return this._loadData(this.options.data);
1219
+ } else {
1220
+ return this._loadDataFromUrl(this._getDataUrlInfo());
1221
+ }
1137
1222
  };
1138
1223
 
1139
1224
  JqTreeWidget.prototype._getDataUrlInfo = function(node) {
1140
- var data, data_url, url_info;
1225
+ var data_url, getUrlFromString,
1226
+ _this = this;
1141
1227
  data_url = this.options.dataUrl || this.element.data('url');
1142
- if ($.isFunction(data_url)) {
1143
- return data_url(node);
1144
- } else if ($.type(data_url) === 'string') {
1228
+ getUrlFromString = function() {
1229
+ var data, selected_node_id, url_info;
1145
1230
  url_info = {
1146
1231
  url: data_url
1147
1232
  };
@@ -1150,19 +1235,46 @@ limitations under the License.
1150
1235
  node: node.id
1151
1236
  };
1152
1237
  url_info['data'] = data;
1238
+ } else {
1239
+ selected_node_id = _this._getNodeIdToBeSelected();
1240
+ if (selected_node_id) {
1241
+ data = {
1242
+ selected_node: selected_node_id
1243
+ };
1244
+ url_info['data'] = data;
1245
+ }
1153
1246
  }
1154
1247
  return url_info;
1248
+ };
1249
+ if ($.isFunction(data_url)) {
1250
+ return data_url(node);
1251
+ } else if ($.type(data_url) === 'string') {
1252
+ return getUrlFromString();
1155
1253
  } else {
1156
1254
  return data_url;
1157
1255
  }
1158
1256
  };
1159
1257
 
1258
+ JqTreeWidget.prototype._getNodeIdToBeSelected = function() {
1259
+ if (this.options.saveState) {
1260
+ return this.save_state_handler.getNodeIdToBeSelected();
1261
+ } else {
1262
+ return null;
1263
+ }
1264
+ };
1265
+
1160
1266
  JqTreeWidget.prototype._initTree = function(data) {
1161
1267
  this.tree = new this.options.nodeClass(null, true, this.options.nodeClass);
1268
+ if (this.select_node_handler) {
1269
+ this.select_node_handler.clear();
1270
+ }
1162
1271
  this.tree.loadFromData(data);
1163
1272
  this._openNodes();
1164
1273
  this._refreshElements();
1165
- return this._triggerEvent('tree.init');
1274
+ if (!this.is_initialized) {
1275
+ this.is_initialized = true;
1276
+ return this._triggerEvent('tree.init');
1277
+ }
1166
1278
  };
1167
1279
 
1168
1280
  JqTreeWidget.prototype._openNodes = function() {
@@ -1224,7 +1336,7 @@ limitations under the License.
1224
1336
  createNodeLi = function(node) {
1225
1337
  var class_string, escaped_name, li_classes;
1226
1338
  li_classes = ['jqtree_common'];
1227
- if (node === _this.selected_node) {
1339
+ if (_this.select_node_handler && _this.select_node_handler.isNodeSelected(node)) {
1228
1340
  li_classes.push('jqtree-selected');
1229
1341
  }
1230
1342
  class_string = li_classes.join(' ');
@@ -1247,7 +1359,7 @@ limitations under the License.
1247
1359
  if (!node.is_open) {
1248
1360
  classes.push('jqtree-closed');
1249
1361
  }
1250
- if (node === _this.selected_node) {
1362
+ if (_this.select_node_handler && _this.select_node_handler.isNodeSelected(node)) {
1251
1363
  classes.push('jqtree-selected');
1252
1364
  }
1253
1365
  return classes.join(' ');
@@ -1256,9 +1368,9 @@ limitations under the License.
1256
1368
  folder_classes = getFolderClasses();
1257
1369
  escaped_name = escapeIfNecessary(node.name);
1258
1370
  if (node.is_open) {
1259
- button_char = TRIANGLE_DOWN;
1371
+ button_char = _this.options.openedIcon;
1260
1372
  } else {
1261
- button_char = TRIANGLE_RIGHT;
1373
+ button_char = _this.options.closedIcon;
1262
1374
  }
1263
1375
  return $("<li class=\"jqtree_common " + folder_classes + "\"><div class=\"jqtree-element jqtree_common\"><a class=\"jqtree_common " + button_classes + "\">" + button_char + "</a><span class=\"jqtree_common jqtree-title\">" + escaped_name + "</span></div></li>");
1264
1376
  };
@@ -1294,31 +1406,60 @@ limitations under the License.
1294
1406
  };
1295
1407
 
1296
1408
  JqTreeWidget.prototype._click = function(e) {
1297
- var $button, $el, $target, node;
1298
- if (e.ctrlKey) {
1299
- return;
1409
+ var click_target, event, node;
1410
+ click_target = this._getClickTarget(e.target);
1411
+ if (click_target) {
1412
+ if (click_target.type === 'button') {
1413
+ this.toggle(click_target.node, this.options.slide);
1414
+ e.preventDefault();
1415
+ return e.stopPropagation();
1416
+ } else if (click_target.type === 'label') {
1417
+ node = click_target.node;
1418
+ event = this._triggerEvent('tree.click', {
1419
+ node: node
1420
+ });
1421
+ if (!event.isDefaultPrevented()) {
1422
+ return this._selectNode(node, true);
1423
+ }
1424
+ }
1425
+ }
1426
+ };
1427
+
1428
+ JqTreeWidget.prototype._dblclick = function(e) {
1429
+ var click_target;
1430
+ click_target = this._getClickTarget(e.target);
1431
+ if (click_target && click_target.type === 'label') {
1432
+ return this._triggerEvent('tree.dblclick', {
1433
+ node: click_target.node
1434
+ });
1300
1435
  }
1301
- $target = $(e.target);
1436
+ };
1437
+
1438
+ JqTreeWidget.prototype._getClickTarget = function(element) {
1439
+ var $button, $el, $target, node;
1440
+ $target = $(element);
1302
1441
  $button = $target.closest('.jqtree-toggler');
1303
1442
  if ($button.length) {
1304
1443
  node = this._getNode($button);
1305
1444
  if (node) {
1306
- this.toggle(node, this.options.slide);
1307
- e.preventDefault();
1308
- return e.stopPropagation();
1445
+ return {
1446
+ type: 'button',
1447
+ node: node
1448
+ };
1309
1449
  }
1310
1450
  } else {
1311
1451
  $el = $target.closest('.jqtree-element');
1312
1452
  if ($el.length) {
1313
1453
  node = this._getNode($el);
1314
1454
  if (node) {
1315
- this._triggerEvent('tree.click', {
1455
+ return {
1456
+ type: 'label',
1316
1457
  node: node
1317
- });
1318
- return this.select_node_handler.selectNode(node, true);
1458
+ };
1319
1459
  }
1320
1460
  }
1321
1461
  }
1462
+ return null;
1322
1463
  };
1323
1464
 
1324
1465
  JqTreeWidget.prototype._getNode = function($element) {
@@ -1372,36 +1513,38 @@ limitations under the License.
1372
1513
  }
1373
1514
  };
1374
1515
 
1375
- JqTreeWidget.prototype._mouseCapture = function(event) {
1516
+ JqTreeWidget.prototype._mouseCapture = function(position_info) {
1376
1517
  if (this.options.dragAndDrop) {
1377
- return this.dnd_handler.mouseCapture(event);
1518
+ return this.dnd_handler.mouseCapture(position_info);
1378
1519
  } else {
1379
1520
  return false;
1380
1521
  }
1381
1522
  };
1382
1523
 
1383
- JqTreeWidget.prototype._mouseStart = function(event) {
1524
+ JqTreeWidget.prototype._mouseStart = function(position_info) {
1384
1525
  if (this.options.dragAndDrop) {
1385
- return this.dnd_handler.mouseStart(event);
1526
+ return this.dnd_handler.mouseStart(position_info);
1386
1527
  } else {
1387
1528
  return false;
1388
1529
  }
1389
1530
  };
1390
1531
 
1391
- JqTreeWidget.prototype._mouseDrag = function(event) {
1532
+ JqTreeWidget.prototype._mouseDrag = function(position_info) {
1392
1533
  var result;
1393
1534
  if (this.options.dragAndDrop) {
1394
- result = this.dnd_handler.mouseDrag(event);
1395
- this.scroll_handler.checkScrolling();
1535
+ result = this.dnd_handler.mouseDrag(position_info);
1536
+ if (this.scroll_handler) {
1537
+ this.scroll_handler.checkScrolling();
1538
+ }
1396
1539
  return result;
1397
1540
  } else {
1398
1541
  return false;
1399
1542
  }
1400
1543
  };
1401
1544
 
1402
- JqTreeWidget.prototype._mouseStop = function(e) {
1545
+ JqTreeWidget.prototype._mouseStop = function(position_info) {
1403
1546
  if (this.options.dragAndDrop) {
1404
- return this.dnd_handler.mouseStop(e);
1547
+ return this.dnd_handler.mouseStop(position_info);
1405
1548
  } else {
1406
1549
  return false;
1407
1550
  }
@@ -1421,80 +1564,32 @@ limitations under the License.
1421
1564
  return this.dnd_handler.hit_areas;
1422
1565
  };
1423
1566
 
1424
- return JqTreeWidget;
1425
-
1426
- })(MouseWidget);
1427
-
1428
- SimpleWidget.register(JqTreeWidget, 'tree');
1429
-
1430
- GhostDropHint = (function() {
1431
-
1432
- function GhostDropHint(node, $element, position) {
1433
- this.$element = $element;
1434
- this.node = node;
1435
- this.$ghost = $('<li class="jqtree_common jqtree-ghost"><span class="jqtree_common jqtree-circle"></span><span class="jqtree_common jqtree-line"></span></li>');
1436
- if (position === Position.AFTER) {
1437
- this.moveAfter();
1438
- } else if (position === Position.BEFORE) {
1439
- this.moveBefore();
1440
- } else if (position === Position.INSIDE) {
1441
- if (node.isFolder() && node.is_open) {
1442
- this.moveInsideOpenFolder();
1443
- } else {
1444
- this.moveInside();
1567
+ JqTreeWidget.prototype._selectCurrentNode = function() {
1568
+ var node, node_element;
1569
+ node = this.getSelectedNode();
1570
+ if (node) {
1571
+ node_element = this._getNodeElementForNode(node);
1572
+ if (node_element) {
1573
+ return node_element.select();
1445
1574
  }
1446
1575
  }
1447
- }
1448
-
1449
- GhostDropHint.prototype.remove = function() {
1450
- return this.$ghost.remove();
1451
- };
1452
-
1453
- GhostDropHint.prototype.moveAfter = function() {
1454
- return this.$element.after(this.$ghost);
1455
- };
1456
-
1457
- GhostDropHint.prototype.moveBefore = function() {
1458
- return this.$element.before(this.$ghost);
1459
- };
1460
-
1461
- GhostDropHint.prototype.moveInsideOpenFolder = function() {
1462
- return $(this.node.children[0].element).before(this.$ghost);
1463
1576
  };
1464
1577
 
1465
- GhostDropHint.prototype.moveInside = function() {
1466
- this.$element.after(this.$ghost);
1467
- return this.$ghost.addClass('jqtree-inside');
1578
+ JqTreeWidget.prototype._deselectCurrentNode = function() {
1579
+ var node;
1580
+ node = this.getSelectedNode();
1581
+ if (node) {
1582
+ return this.removeFromSelection(node);
1583
+ }
1468
1584
  };
1469
1585
 
1470
- return GhostDropHint;
1471
-
1472
- })();
1473
-
1474
- BorderDropHint = (function() {
1475
-
1476
- function BorderDropHint($element) {
1477
- var $div, width;
1478
- $div = $element.children('.jqtree-element');
1479
- width = $element.width() - 4;
1480
- this.$hint = $('<span class="jqtree-border"></span>');
1481
- $div.append(this.$hint);
1482
- this.$hint.css({
1483
- width: width,
1484
- height: $div.height() - 4
1485
- });
1486
- }
1487
-
1488
- BorderDropHint.prototype.remove = function() {
1489
- return this.$hint.remove();
1490
- };
1586
+ return JqTreeWidget;
1491
1587
 
1492
- return BorderDropHint;
1588
+ })(MouseWidget);
1493
1589
 
1494
- })();
1590
+ SimpleWidget.register(JqTreeWidget, 'tree');
1495
1591
 
1496
1592
  NodeElement = (function() {
1497
-
1498
1593
  function NodeElement(node, tree_widget) {
1499
1594
  this.init(node, tree_widget);
1500
1595
  }
@@ -1538,11 +1633,11 @@ limitations under the License.
1538
1633
  })();
1539
1634
 
1540
1635
  FolderElement = (function(_super) {
1541
-
1542
1636
  __extends(FolderElement, _super);
1543
1637
 
1544
1638
  function FolderElement() {
1545
- return FolderElement.__super__.constructor.apply(this, arguments);
1639
+ _ref2 = FolderElement.__super__.constructor.apply(this, arguments);
1640
+ return _ref2;
1546
1641
  }
1547
1642
 
1548
1643
  FolderElement.prototype.open = function(on_finished, slide) {
@@ -1555,7 +1650,7 @@ limitations under the License.
1555
1650
  this.node.is_open = true;
1556
1651
  $button = this.getButton();
1557
1652
  $button.removeClass('jqtree-closed');
1558
- $button.html(TRIANGLE_DOWN);
1653
+ $button.html(this.tree_widget.options.openedIcon);
1559
1654
  doOpen = function() {
1560
1655
  _this.getLi().removeClass('jqtree-closed');
1561
1656
  if (on_finished) {
@@ -1584,7 +1679,7 @@ limitations under the License.
1584
1679
  this.node.is_open = false;
1585
1680
  $button = this.getButton();
1586
1681
  $button.addClass('jqtree-closed');
1587
- $button.html(TRIANGLE_RIGHT);
1682
+ $button.html(this.tree_widget.options.closedIcon);
1588
1683
  doClose = function() {
1589
1684
  _this.getLi().addClass('jqtree-closed');
1590
1685
  return _this.tree_widget._triggerEvent('tree.close', {
@@ -1616,110 +1711,187 @@ limitations under the License.
1616
1711
 
1617
1712
  })(NodeElement);
1618
1713
 
1619
- DragElement = (function() {
1714
+ html_escape = function(string) {
1715
+ return ('' + string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g, '&#x2F;');
1716
+ };
1620
1717
 
1621
- function DragElement(node, offset_x, offset_y, $tree) {
1622
- this.offset_x = offset_x;
1623
- this.offset_y = offset_y;
1624
- this.$element = $("<span class=\"jqtree-title jqtree-dragging\">" + node.name + "</span>");
1625
- this.$element.css("position", "absolute");
1626
- $tree.append(this.$element);
1718
+ _indexOf = function(array, item) {
1719
+ var i, value, _i, _len;
1720
+ for (i = _i = 0, _len = array.length; _i < _len; i = ++_i) {
1721
+ value = array[i];
1722
+ if (value === item) {
1723
+ return i;
1724
+ }
1627
1725
  }
1726
+ return -1;
1727
+ };
1628
1728
 
1629
- DragElement.prototype.move = function(page_x, page_y) {
1630
- return this.$element.offset({
1631
- left: page_x - this.offset_x,
1632
- top: page_y - this.offset_y
1633
- });
1634
- };
1635
-
1636
- DragElement.prototype.remove = function() {
1637
- return this.$element.remove();
1638
- };
1639
-
1640
- return DragElement;
1641
-
1642
- })();
1643
-
1644
- SaveStateHandler = (function() {
1645
-
1646
- function SaveStateHandler(tree_widget) {
1647
- this.tree_widget = tree_widget;
1729
+ indexOf = function(array, item) {
1730
+ if (array.indexOf) {
1731
+ return array.indexOf(item);
1732
+ } else {
1733
+ return _indexOf(array, item);
1648
1734
  }
1735
+ };
1649
1736
 
1650
- SaveStateHandler.prototype.saveState = function() {
1651
- if (this.tree_widget.options.onSetStateFromStorage) {
1652
- return this.tree_widget.options.onSetStateFromStorage(this.getState());
1653
- } else if (typeof localStorage !== "undefined" && localStorage !== null) {
1654
- return localStorage.setItem(this.getCookieName(), this.getState());
1655
- } else if ($.cookie) {
1656
- $.cookie.raw = true;
1657
- return $.cookie(this.getCookieName(), this.getState(), {
1658
- path: '/'
1659
- });
1660
- }
1661
- };
1737
+ this.Tree.indexOf = indexOf;
1662
1738
 
1663
- SaveStateHandler.prototype.restoreState = function() {
1664
- var state;
1665
- state = this.getStateFromStorage();
1666
- if (state) {
1667
- this.setState(state);
1668
- return true;
1669
- } else {
1670
- return false;
1671
- }
1672
- };
1739
+ this.Tree._indexOf = _indexOf;
1673
1740
 
1674
- SaveStateHandler.prototype.getStateFromStorage = function() {
1675
- if (this.tree_widget.options.onGetStateFromStorage) {
1676
- return this.tree_widget.options.onGetStateFromStorage();
1677
- } else if (typeof localStorage !== "undefined" && localStorage !== null) {
1678
- return localStorage.getItem(this.getCookieName());
1679
- } else if ($.cookie) {
1680
- $.cookie.raw = true;
1681
- return $.cookie(this.getCookieName());
1741
+ if (!((this.JSON != null) && (this.JSON.stringify != null) && typeof this.JSON.stringify === 'function')) {
1742
+ json_escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
1743
+ json_meta = {
1744
+ '\b': '\\b',
1745
+ '\t': '\\t',
1746
+ '\n': '\\n',
1747
+ '\f': '\\f',
1748
+ '\r': '\\r',
1749
+ '"': '\\"',
1750
+ '\\': '\\\\'
1751
+ };
1752
+ json_quote = function(string) {
1753
+ json_escapable.lastIndex = 0;
1754
+ if (json_escapable.test(string)) {
1755
+ return '"' + string.replace(json_escapable, function(a) {
1756
+ var c;
1757
+ c = json_meta[a];
1758
+ return (typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4));
1759
+ }) + '"';
1682
1760
  } else {
1683
- return null;
1761
+ return '"' + string + '"';
1684
1762
  }
1685
1763
  };
1686
-
1687
- SaveStateHandler.prototype.getState = function() {
1688
- var open_nodes, selected_node,
1689
- _this = this;
1690
- open_nodes = [];
1691
- this.tree_widget.tree.iterate(function(node) {
1692
- if (node.is_open && node.id && node.hasChildren()) {
1693
- open_nodes.push(node.id);
1694
- }
1695
- return true;
1696
- });
1697
- selected_node = '';
1698
- if (this.tree_widget.selected_node) {
1699
- selected_node = this.tree_widget.selected_node.id;
1700
- }
1701
- return JSON.stringify({
1702
- open_nodes: open_nodes,
1703
- selected_node: selected_node
1704
- });
1764
+ json_str = function(key, holder) {
1765
+ var i, k, partial, v, value, _i, _len;
1766
+ value = holder[key];
1767
+ switch (typeof value) {
1768
+ case 'string':
1769
+ return json_quote(value);
1770
+ case 'number':
1771
+ if (isFinite(value)) {
1772
+ return String(value);
1773
+ } else {
1774
+ return 'null';
1775
+ }
1776
+ case 'boolean':
1777
+ case 'null':
1778
+ return String(value);
1779
+ case 'object':
1780
+ if (!value) {
1781
+ return 'null';
1782
+ }
1783
+ partial = [];
1784
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
1785
+ for (i = _i = 0, _len = value.length; _i < _len; i = ++_i) {
1786
+ v = value[i];
1787
+ partial[i] = json_str(i, value) || 'null';
1788
+ }
1789
+ return (partial.length === 0 ? '[]' : '[' + partial.join(',') + ']');
1790
+ }
1791
+ for (k in value) {
1792
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
1793
+ v = json_str(k, value);
1794
+ if (v) {
1795
+ partial.push(json_quote(k) + ':' + v);
1796
+ }
1797
+ }
1798
+ }
1799
+ return (partial.length === 0 ? '{}' : '{' + partial.join(',') + '}');
1800
+ }
1801
+ };
1802
+ if (this.JSON == null) {
1803
+ this.JSON = {};
1804
+ }
1805
+ this.JSON.stringify = function(value) {
1806
+ return json_str('', {
1807
+ '': value
1808
+ });
1809
+ };
1810
+ }
1811
+
1812
+ SaveStateHandler = (function() {
1813
+ function SaveStateHandler(tree_widget) {
1814
+ this.tree_widget = tree_widget;
1815
+ }
1816
+
1817
+ SaveStateHandler.prototype.saveState = function() {
1818
+ var state;
1819
+ state = JSON.stringify(this.getState());
1820
+ if (this.tree_widget.options.onSetStateFromStorage) {
1821
+ return this.tree_widget.options.onSetStateFromStorage(state);
1822
+ } else if (this.supportsLocalStorage()) {
1823
+ return localStorage.setItem(this.getCookieName(), state);
1824
+ } else if ($.cookie) {
1825
+ $.cookie.raw = true;
1826
+ return $.cookie(this.getCookieName(), state, {
1827
+ path: '/'
1828
+ });
1829
+ }
1830
+ };
1831
+
1832
+ SaveStateHandler.prototype.restoreState = function() {
1833
+ var state;
1834
+ state = this.getStateFromStorage();
1835
+ if (state) {
1836
+ this.setState($.parseJSON(state));
1837
+ return true;
1838
+ } else {
1839
+ return false;
1840
+ }
1841
+ };
1842
+
1843
+ SaveStateHandler.prototype.getStateFromStorage = function() {
1844
+ if (this.tree_widget.options.onGetStateFromStorage) {
1845
+ return this.tree_widget.options.onGetStateFromStorage();
1846
+ } else if (this.supportsLocalStorage()) {
1847
+ return localStorage.getItem(this.getCookieName());
1848
+ } else if ($.cookie) {
1849
+ $.cookie.raw = true;
1850
+ return $.cookie(this.getCookieName());
1851
+ } else {
1852
+ return null;
1853
+ }
1854
+ };
1855
+
1856
+ SaveStateHandler.prototype.getState = function() {
1857
+ var open_nodes, selected_node, selected_node_id,
1858
+ _this = this;
1859
+ open_nodes = [];
1860
+ this.tree_widget.tree.iterate(function(node) {
1861
+ if (node.is_open && node.id && node.hasChildren()) {
1862
+ open_nodes.push(node.id);
1863
+ }
1864
+ return true;
1865
+ });
1866
+ selected_node = this.tree_widget.getSelectedNode();
1867
+ if (selected_node) {
1868
+ selected_node_id = selected_node.id;
1869
+ } else {
1870
+ selected_node_id = '';
1871
+ }
1872
+ return {
1873
+ open_nodes: open_nodes,
1874
+ selected_node: selected_node_id
1875
+ };
1705
1876
  };
1706
1877
 
1707
1878
  SaveStateHandler.prototype.setState = function(state) {
1708
- var data, open_nodes, selected_node_id,
1879
+ var open_nodes, selected_node, selected_node_id,
1709
1880
  _this = this;
1710
- data = $.parseJSON(state);
1711
- if (data) {
1712
- open_nodes = data.open_nodes;
1713
- selected_node_id = data.selected_node;
1714
- return this.tree_widget.tree.iterate(function(node) {
1715
- if (node.id && node.hasChildren() && (indexOf(open_nodes, node.id) >= 0)) {
1716
- node.is_open = true;
1717
- }
1718
- if (selected_node_id && (node.id === selected_node_id)) {
1719
- _this.tree_widget.selected_node = node;
1720
- }
1881
+ if (state) {
1882
+ open_nodes = state.open_nodes;
1883
+ selected_node_id = state.selected_node;
1884
+ this.tree_widget.tree.iterate(function(node) {
1885
+ node.is_open = node.id && node.hasChildren() && (indexOf(open_nodes, node.id) >= 0);
1721
1886
  return true;
1722
1887
  });
1888
+ if (selected_node_id && this.tree_widget.select_node_handler) {
1889
+ this.tree_widget.select_node_handler.clear();
1890
+ selected_node = this.tree_widget.getNodeById(selected_node_id);
1891
+ if (selected_node) {
1892
+ return this.tree_widget.select_node_handler.addToSelection(selected_node);
1893
+ }
1894
+ }
1723
1895
  }
1724
1896
  };
1725
1897
 
@@ -1731,79 +1903,117 @@ limitations under the License.
1731
1903
  }
1732
1904
  };
1733
1905
 
1906
+ SaveStateHandler.prototype.supportsLocalStorage = function() {
1907
+ var testSupport;
1908
+ testSupport = function() {
1909
+ var error, key;
1910
+ if (typeof localStorage === "undefined" || localStorage === null) {
1911
+ return false;
1912
+ } else {
1913
+ try {
1914
+ key = '_storage_test';
1915
+ sessionStorage.setItem(key, true);
1916
+ sessionStorage.removeItem(key);
1917
+ } catch (_error) {
1918
+ error = _error;
1919
+ return false;
1920
+ }
1921
+ return true;
1922
+ }
1923
+ };
1924
+ if (this._supportsLocalStorage == null) {
1925
+ this._supportsLocalStorage = testSupport();
1926
+ }
1927
+ return this._supportsLocalStorage;
1928
+ };
1929
+
1930
+ SaveStateHandler.prototype.getNodeIdToBeSelected = function() {
1931
+ var state, state_json;
1932
+ state_json = this.getStateFromStorage();
1933
+ if (state_json) {
1934
+ state = $.parseJSON(state_json);
1935
+ return state.selected_node;
1936
+ } else {
1937
+ return null;
1938
+ }
1939
+ };
1940
+
1734
1941
  return SaveStateHandler;
1735
1942
 
1736
1943
  })();
1737
1944
 
1738
1945
  SelectNodeHandler = (function() {
1739
-
1740
1946
  function SelectNodeHandler(tree_widget) {
1741
1947
  this.tree_widget = tree_widget;
1948
+ this.clear();
1742
1949
  }
1743
1950
 
1744
- SelectNodeHandler.prototype.selectNode = function(node, must_toggle) {
1745
- var canSelect, mustToggle, node_element, parent, previous_node,
1746
- _this = this;
1747
- if (must_toggle == null) {
1748
- must_toggle = false;
1951
+ SelectNodeHandler.prototype.getSelectedNode = function() {
1952
+ var selected_nodes;
1953
+ selected_nodes = this.getSelectedNodes();
1954
+ if (selected_nodes.length) {
1955
+ return selected_nodes[0];
1956
+ } else {
1957
+ return false;
1749
1958
  }
1750
- canSelect = function() {
1751
- if (!_this.tree_widget.options.onCanSelectNode) {
1752
- return true;
1753
- }
1754
- return _this.tree_widget.options.onCanSelectNode(node);
1755
- };
1756
- mustToggle = function(previous_node, node) {
1757
- if (must_toggle && previous_node && node) {
1758
- if (node.id) {
1759
- return node.id === previous_node.id;
1760
- } else {
1761
- return node.element === previous_node.element;
1959
+ };
1960
+
1961
+ SelectNodeHandler.prototype.getSelectedNodes = function() {
1962
+ var id, node, selected_nodes;
1963
+ if (this.selected_single_node) {
1964
+ return [this.selected_single_node];
1965
+ } else {
1966
+ selected_nodes = [];
1967
+ for (id in this.selected_nodes) {
1968
+ node = this.tree_widget.getNodeById(id);
1969
+ if (node) {
1970
+ selected_nodes.push(node);
1762
1971
  }
1763
- } else {
1764
- return false;
1765
1972
  }
1766
- };
1767
- if (canSelect()) {
1768
- if (this.tree_widget.selected_node) {
1769
- previous_node = this.tree_widget.selected_node;
1770
- this.tree_widget._getNodeElementForNode(previous_node).deselect();
1771
- this.tree_widget.selected_node = null;
1772
- } else {
1773
- previous_node = null;
1774
- }
1775
- if (node) {
1776
- node_element = this.tree_widget._getNodeElementForNode(node);
1777
- if (mustToggle(previous_node, node)) {
1778
- node_element.deselect();
1779
- this.tree_widget._triggerEvent('tree.select', {
1780
- node: null
1781
- });
1782
- } else {
1783
- node_element.select();
1784
- this.tree_widget.selected_node = node;
1785
- this.tree_widget._triggerEvent('tree.select', {
1786
- node: node
1787
- });
1788
- parent = this.tree_widget.selected_node.parent;
1789
- if (!parent.is_open) {
1790
- this.tree_widget.openNode(parent, false);
1791
- }
1792
- }
1973
+ return selected_nodes;
1974
+ }
1975
+ };
1976
+
1977
+ SelectNodeHandler.prototype.isNodeSelected = function(node) {
1978
+ if (node.id) {
1979
+ return this.selected_nodes[node.id];
1980
+ } else if (this.selected_single_node) {
1981
+ return this.selected_single_node.element === node.element;
1982
+ } else {
1983
+ return false;
1984
+ }
1985
+ };
1986
+
1987
+ SelectNodeHandler.prototype.clear = function() {
1988
+ this.selected_nodes = {};
1989
+ return this.selected_single_node = null;
1990
+ };
1991
+
1992
+ SelectNodeHandler.prototype.removeFromSelection = function(node, include_children) {
1993
+ var _this = this;
1994
+ if (include_children == null) {
1995
+ include_children = false;
1996
+ }
1997
+ if (!node.id) {
1998
+ if (node.element === this.selected_single_node.element) {
1999
+ return this.selected_single_node = null;
1793
2000
  }
1794
- if (this.tree_widget.options.saveState) {
1795
- return this.tree_widget.save_state_handler.saveState();
2001
+ } else {
2002
+ delete this.selected_nodes[node.id];
2003
+ if (include_children) {
2004
+ return node.iterate(function(n) {
2005
+ delete _this.selected_nodes[node.id];
2006
+ return true;
2007
+ });
1796
2008
  }
1797
2009
  }
1798
2010
  };
1799
2011
 
1800
- SelectNodeHandler.prototype.selectCurrentNode = function() {
1801
- var node_element;
1802
- if (this.tree_widget.selected_node) {
1803
- node_element = this.tree_widget._getNodeElementForNode(this.tree_widget.selected_node);
1804
- if (node_element) {
1805
- return node_element.select();
1806
- }
2012
+ SelectNodeHandler.prototype.addToSelection = function(node) {
2013
+ if (node.id) {
2014
+ return this.selected_nodes[node.id] = true;
2015
+ } else {
2016
+ return this.selected_single_node = node;
1807
2017
  }
1808
2018
  };
1809
2019
 
@@ -1812,7 +2022,6 @@ limitations under the License.
1812
2022
  })();
1813
2023
 
1814
2024
  DragAndDropHandler = (function() {
1815
-
1816
2025
  function DragAndDropHandler(tree_widget) {
1817
2026
  this.tree_widget = tree_widget;
1818
2027
  this.hovered_area = null;
@@ -1821,9 +2030,9 @@ limitations under the License.
1821
2030
  this.is_dragging = false;
1822
2031
  }
1823
2032
 
1824
- DragAndDropHandler.prototype.mouseCapture = function(event) {
2033
+ DragAndDropHandler.prototype.mouseCapture = function(position_info) {
1825
2034
  var $element, node_element;
1826
- $element = $(event.target);
2035
+ $element = $(position_info.target);
1827
2036
  if (this.tree_widget.options.onIsMoveHandle && !this.tree_widget.options.onIsMoveHandle($element)) {
1828
2037
  return null;
1829
2038
  }
@@ -1837,54 +2046,64 @@ limitations under the License.
1837
2046
  return this.current_item !== null;
1838
2047
  };
1839
2048
 
1840
- DragAndDropHandler.prototype.mouseStart = function(event) {
1841
- var offsetX, offsetY, _ref;
2049
+ DragAndDropHandler.prototype.mouseStart = function(position_info) {
2050
+ var offset;
1842
2051
  this.refreshHitAreas();
1843
- _ref = this.getOffsetFromEvent(event), offsetX = _ref[0], offsetY = _ref[1];
1844
- this.drag_element = new DragElement(this.current_item.node, offsetX, offsetY, this.tree_widget.element);
2052
+ offset = $(position_info.target).offset();
2053
+ this.drag_element = new DragElement(this.current_item.node, position_info.page_x - offset.left, position_info.page_y - offset.top, this.tree_widget.element);
1845
2054
  this.is_dragging = true;
1846
2055
  this.current_item.$element.addClass('jqtree-moving');
1847
2056
  return true;
1848
2057
  };
1849
2058
 
1850
- DragAndDropHandler.prototype.mouseDrag = function(event) {
1851
- var area, position_name;
1852
- this.drag_element.move(event.pageX, event.pageY);
1853
- area = this.findHoveredArea(event.pageX, event.pageY);
1854
- if (area && this.tree_widget.options.onCanMoveTo) {
1855
- position_name = Position.getName(area.position);
1856
- if (!this.tree_widget.options.onCanMoveTo(this.current_item.node, area.node, position_name)) {
1857
- area = null;
2059
+ DragAndDropHandler.prototype.mouseDrag = function(position_info) {
2060
+ var area, can_move_to;
2061
+ this.drag_element.move(position_info.page_x, position_info.page_y);
2062
+ area = this.findHoveredArea(position_info.page_x, position_info.page_y);
2063
+ can_move_to = this.canMoveToArea(area);
2064
+ if (area) {
2065
+ if (this.hovered_area !== area) {
2066
+ this.hovered_area = area;
2067
+ if (this.mustOpenFolderTimer(area)) {
2068
+ this.startOpenFolderTimer(area.node);
2069
+ }
2070
+ if (can_move_to) {
2071
+ this.updateDropHint();
2072
+ }
1858
2073
  }
1859
- }
1860
- if (!area) {
1861
- this.removeDropHint();
2074
+ } else {
1862
2075
  this.removeHover();
2076
+ this.removeDropHint();
1863
2077
  this.stopOpenFolderTimer();
1864
- } else if (this.hovered_area !== area) {
1865
- this.hovered_area = area;
1866
- this.updateDropHint();
1867
2078
  }
1868
2079
  return true;
1869
2080
  };
1870
2081
 
1871
- DragAndDropHandler.prototype.mouseStop = function(e) {
1872
- this.moveItem(e);
2082
+ DragAndDropHandler.prototype.canMoveToArea = function(area) {
2083
+ var position_name;
2084
+ if (!area) {
2085
+ return false;
2086
+ } else if (this.tree_widget.options.onCanMoveTo) {
2087
+ position_name = Position.getName(area.position);
2088
+ return this.tree_widget.options.onCanMoveTo(this.current_item.node, area.node, position_name);
2089
+ } else {
2090
+ return true;
2091
+ }
2092
+ };
2093
+
2094
+ DragAndDropHandler.prototype.mouseStop = function(position_info) {
2095
+ this.moveItem(position_info);
1873
2096
  this.clear();
1874
2097
  this.removeHover();
1875
2098
  this.removeDropHint();
1876
2099
  this.removeHitAreas();
1877
- this.current_item.$element.removeClass('jqtree-moving');
2100
+ if (this.current_item) {
2101
+ this.current_item.$element.removeClass('jqtree-moving');
2102
+ }
1878
2103
  this.is_dragging = false;
1879
2104
  return false;
1880
2105
  };
1881
2106
 
1882
- DragAndDropHandler.prototype.getOffsetFromEvent = function(event) {
1883
- var element_offset;
1884
- element_offset = $(event.target).offset();
1885
- return [event.pageX - element_offset.left, event.pageY - element_offset.top];
1886
- };
1887
-
1888
2107
  DragAndDropHandler.prototype.refreshHitAreas = function() {
1889
2108
  this.removeHitAreas();
1890
2109
  return this.generateHitAreas();
@@ -1910,155 +2129,15 @@ limitations under the License.
1910
2129
  };
1911
2130
 
1912
2131
  DragAndDropHandler.prototype.generateHitAreas = function() {
1913
- var addPosition, getTop, groupPositions, handleAfterOpenFolder, handleClosedFolder, handleFirstNode, handleNode, handleOpenFolder, hit_areas, last_top, positions,
1914
- _this = this;
1915
- positions = [];
1916
- last_top = 0;
1917
- getTop = function($element) {
1918
- return $element.offset().top;
1919
- };
1920
- addPosition = function(node, position, top) {
1921
- positions.push({
1922
- top: top,
1923
- node: node,
1924
- position: position
1925
- });
1926
- return last_top = top;
1927
- };
1928
- groupPositions = function(handle_group) {
1929
- var group, position, previous_top, _i, _len;
1930
- previous_top = -1;
1931
- group = [];
1932
- for (_i = 0, _len = positions.length; _i < _len; _i++) {
1933
- position = positions[_i];
1934
- if (position.top !== previous_top) {
1935
- if (group.length) {
1936
- handle_group(group, previous_top, position.top);
1937
- }
1938
- previous_top = position.top;
1939
- group = [];
1940
- }
1941
- group.push(position);
1942
- }
1943
- return handle_group(group, previous_top, _this.tree_widget.element.offset().top + _this.tree_widget.element.height());
1944
- };
1945
- handleNode = function(node, next_node, $element) {
1946
- var top;
1947
- top = getTop($element);
1948
- if (node === _this.current_item.node) {
1949
- addPosition(node, Position.NONE, top);
1950
- } else {
1951
- addPosition(node, Position.INSIDE, top);
1952
- }
1953
- if (next_node === _this.current_item.node || node === _this.current_item.node) {
1954
- return addPosition(node, Position.NONE, top);
1955
- } else {
1956
- return addPosition(node, Position.AFTER, top);
1957
- }
1958
- };
1959
- handleOpenFolder = function(node, $element) {
1960
- if (node === _this.current_item.node) {
1961
- return false;
1962
- }
1963
- if (node.children[0] !== _this.current_item.node) {
1964
- addPosition(node, Position.INSIDE, getTop($element));
1965
- }
1966
- return true;
1967
- };
1968
- handleAfterOpenFolder = function(node, next_node, $element) {
1969
- if (node === _this.current_item.node || next_node === _this.current_item.node) {
1970
- return addPosition(node, Position.NONE, last_top);
1971
- } else {
1972
- return addPosition(node, Position.AFTER, last_top);
1973
- }
1974
- };
1975
- handleClosedFolder = function(node, next_node, $element) {
1976
- var top;
1977
- top = getTop($element);
1978
- if (node === _this.current_item.node) {
1979
- return addPosition(node, Position.NONE, top);
1980
- } else {
1981
- addPosition(node, Position.INSIDE, top);
1982
- if (next_node !== _this.current_item.node) {
1983
- return addPosition(node, Position.AFTER, top);
1984
- }
1985
- }
1986
- };
1987
- handleFirstNode = function(node, $element) {
1988
- if (node !== _this.current_item.node) {
1989
- return addPosition(node, Position.BEFORE, getTop($(node.element)));
1990
- }
1991
- };
1992
- this.iterateVisibleNodes(handleNode, handleOpenFolder, handleClosedFolder, handleAfterOpenFolder, handleFirstNode);
1993
- hit_areas = [];
1994
- groupPositions(function(positions_in_group, top, bottom) {
1995
- var area_height, area_top, position, _i, _len;
1996
- area_height = (bottom - top) / positions_in_group.length;
1997
- area_top = top;
1998
- for (_i = 0, _len = positions_in_group.length; _i < _len; _i++) {
1999
- position = positions_in_group[_i];
2000
- hit_areas.push({
2001
- top: area_top,
2002
- bottom: area_top + area_height,
2003
- node: position.node,
2004
- position: position.position
2005
- });
2006
- area_top += area_height;
2007
- }
2008
- return null;
2009
- });
2010
- return this.hit_areas = hit_areas;
2011
- };
2012
-
2013
- DragAndDropHandler.prototype.iterateVisibleNodes = function(handle_node, handle_open_folder, handle_closed_folder, handle_after_open_folder, handle_first_node) {
2014
- var is_first_node, iterate,
2015
- _this = this;
2016
- is_first_node = true;
2017
- iterate = function(node, next_node) {
2018
- var $element, child, children_length, i, must_iterate_inside, _i, _len, _ref;
2019
- must_iterate_inside = (node.is_open || !node.element) && node.hasChildren();
2020
- if (node.element) {
2021
- $element = $(node.element);
2022
- if (!$element.is(':visible')) {
2023
- return;
2024
- }
2025
- if (is_first_node) {
2026
- handle_first_node(node, $element);
2027
- is_first_node = false;
2028
- }
2029
- if (!node.hasChildren()) {
2030
- handle_node(node, next_node, $element);
2031
- } else if (node.is_open) {
2032
- if (!handle_open_folder(node, $element)) {
2033
- must_iterate_inside = false;
2034
- }
2035
- } else {
2036
- handle_closed_folder(node, next_node, $element);
2037
- }
2038
- }
2039
- if (must_iterate_inside) {
2040
- children_length = node.children.length;
2041
- _ref = node.children;
2042
- for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
2043
- child = _ref[i];
2044
- if (i === (children_length - 1)) {
2045
- iterate(node.children[i], null);
2046
- } else {
2047
- iterate(node.children[i], node.children[i + 1]);
2048
- }
2049
- }
2050
- if (node.is_open) {
2051
- return handle_after_open_folder(node, next_node, $element);
2052
- }
2053
- }
2054
- };
2055
- return iterate(this.tree_widget.tree);
2132
+ var hit_areas_generator;
2133
+ hit_areas_generator = new HitAreasGenerator(this.tree_widget.tree, this.current_item.node, this.getTreeDimensions().bottom);
2134
+ return this.hit_areas = hit_areas_generator.generate();
2056
2135
  };
2057
2136
 
2058
2137
  DragAndDropHandler.prototype.findHoveredArea = function(x, y) {
2059
- var area, high, low, mid, tree_offset;
2060
- tree_offset = this.tree_widget.element.offset();
2061
- if (x < tree_offset.left || y < tree_offset.top || x > (tree_offset.left + this.tree_widget.element.width()) || y > (tree_offset.top + this.tree_widget.element.height())) {
2138
+ var area, dimensions, high, low, mid;
2139
+ dimensions = this.getTreeDimensions();
2140
+ if (x < dimensions.left || y < dimensions.top || x > dimensions.right || y > dimensions.bottom) {
2062
2141
  return null;
2063
2142
  }
2064
2143
  low = 0;
@@ -2077,16 +2156,17 @@ limitations under the License.
2077
2156
  return null;
2078
2157
  };
2079
2158
 
2159
+ DragAndDropHandler.prototype.mustOpenFolderTimer = function(area) {
2160
+ var node;
2161
+ node = area.node;
2162
+ return node.isFolder() && !node.is_open && area.position === Position.INSIDE;
2163
+ };
2164
+
2080
2165
  DragAndDropHandler.prototype.updateDropHint = function() {
2081
- var node, node_element;
2082
- this.stopOpenFolderTimer();
2166
+ var node_element;
2083
2167
  if (!this.hovered_area) {
2084
2168
  return;
2085
2169
  }
2086
- node = this.hovered_area.node;
2087
- if (node.isFolder() && !node.is_open && this.hovered_area.position === Position.INSIDE) {
2088
- this.startOpenFolderTimer(node);
2089
- }
2090
2170
  this.removeDropHint();
2091
2171
  node_element = this.tree_widget._getNodeElementForNode(this.hovered_area.node);
2092
2172
  return this.previous_ghost = node_element.addDropHint(this.hovered_area.position);
@@ -2111,10 +2191,10 @@ limitations under the License.
2111
2191
  }
2112
2192
  };
2113
2193
 
2114
- DragAndDropHandler.prototype.moveItem = function(original_event) {
2194
+ DragAndDropHandler.prototype.moveItem = function(position_info) {
2115
2195
  var doMove, event, moved_node, position, previous_parent, target_node,
2116
2196
  _this = this;
2117
- if (this.hovered_area && this.hovered_area.position !== Position.NONE) {
2197
+ if (this.hovered_area && this.hovered_area.position !== Position.NONE && this.canMoveToArea(this.hovered_area)) {
2118
2198
  moved_node = this.current_item.node;
2119
2199
  target_node = this.hovered_area.node;
2120
2200
  position = this.hovered_area.position;
@@ -2134,7 +2214,7 @@ limitations under the License.
2134
2214
  position: Position.getName(position),
2135
2215
  previous_parent: previous_parent,
2136
2216
  do_move: doMove,
2137
- original_event: original_event
2217
+ original_event: position_info.original_event
2138
2218
  }
2139
2219
  });
2140
2220
  if (!event.isDefaultPrevented()) {
@@ -2143,12 +2223,296 @@ limitations under the License.
2143
2223
  }
2144
2224
  };
2145
2225
 
2226
+ DragAndDropHandler.prototype.getTreeDimensions = function() {
2227
+ var offset;
2228
+ offset = this.tree_widget.element.offset();
2229
+ return {
2230
+ left: offset.left,
2231
+ top: offset.top,
2232
+ right: offset.left + this.tree_widget.element.width(),
2233
+ bottom: offset.top + this.tree_widget.element.height() + 16
2234
+ };
2235
+ };
2236
+
2146
2237
  return DragAndDropHandler;
2147
2238
 
2148
2239
  })();
2149
2240
 
2150
- ScrollHandler = (function() {
2241
+ VisibleNodeIterator = (function() {
2242
+ function VisibleNodeIterator(tree) {
2243
+ this.tree = tree;
2244
+ }
2245
+
2246
+ VisibleNodeIterator.prototype.iterate = function() {
2247
+ var is_first_node, _iterateNode,
2248
+ _this = this;
2249
+ is_first_node = true;
2250
+ _iterateNode = function(node, next_node) {
2251
+ var $element, child, children_length, i, must_iterate_inside, _i, _len, _ref3;
2252
+ must_iterate_inside = (node.is_open || !node.element) && node.hasChildren();
2253
+ if (node.element) {
2254
+ $element = $(node.element);
2255
+ if (!$element.is(':visible')) {
2256
+ return;
2257
+ }
2258
+ if (is_first_node) {
2259
+ _this.handleFirstNode(node, $element);
2260
+ is_first_node = false;
2261
+ }
2262
+ if (!node.hasChildren()) {
2263
+ _this.handleNode(node, next_node, $element);
2264
+ } else if (node.is_open) {
2265
+ if (!_this.handleOpenFolder(node, $element)) {
2266
+ must_iterate_inside = false;
2267
+ }
2268
+ } else {
2269
+ _this.handleClosedFolder(node, next_node, $element);
2270
+ }
2271
+ }
2272
+ if (must_iterate_inside) {
2273
+ children_length = node.children.length;
2274
+ _ref3 = node.children;
2275
+ for (i = _i = 0, _len = _ref3.length; _i < _len; i = ++_i) {
2276
+ child = _ref3[i];
2277
+ if (i === (children_length - 1)) {
2278
+ _iterateNode(node.children[i], null);
2279
+ } else {
2280
+ _iterateNode(node.children[i], node.children[i + 1]);
2281
+ }
2282
+ }
2283
+ if (node.is_open) {
2284
+ return _this.handleAfterOpenFolder(node, next_node, $element);
2285
+ }
2286
+ }
2287
+ };
2288
+ return _iterateNode(this.tree, null);
2289
+ };
2290
+
2291
+ VisibleNodeIterator.prototype.handleNode = function(node, next_node, $element) {};
2292
+
2293
+ VisibleNodeIterator.prototype.handleOpenFolder = function(node, $element) {};
2294
+
2295
+ VisibleNodeIterator.prototype.handleClosedFolder = function(node, next_node, $element) {};
2296
+
2297
+ VisibleNodeIterator.prototype.handleAfterOpenFolder = function(node, next_node, $element) {};
2298
+
2299
+ VisibleNodeIterator.prototype.handleFirstNode = function(node, $element) {};
2300
+
2301
+ return VisibleNodeIterator;
2302
+
2303
+ })();
2304
+
2305
+ HitAreasGenerator = (function(_super) {
2306
+ __extends(HitAreasGenerator, _super);
2307
+
2308
+ function HitAreasGenerator(tree, current_node, tree_bottom) {
2309
+ HitAreasGenerator.__super__.constructor.call(this, tree);
2310
+ this.current_node = current_node;
2311
+ this.tree_bottom = tree_bottom;
2312
+ }
2313
+
2314
+ HitAreasGenerator.prototype.generate = function() {
2315
+ this.positions = [];
2316
+ this.last_top = 0;
2317
+ this.iterate();
2318
+ return this.generateHitAreas(this.positions);
2319
+ };
2151
2320
 
2321
+ HitAreasGenerator.prototype.getTop = function($element) {
2322
+ return $element.offset().top;
2323
+ };
2324
+
2325
+ HitAreasGenerator.prototype.addPosition = function(node, position, top) {
2326
+ this.positions.push({
2327
+ top: top,
2328
+ node: node,
2329
+ position: position
2330
+ });
2331
+ return this.last_top = top;
2332
+ };
2333
+
2334
+ HitAreasGenerator.prototype.handleNode = function(node, next_node, $element) {
2335
+ var top;
2336
+ top = this.getTop($element);
2337
+ if (node === this.current_node) {
2338
+ this.addPosition(node, Position.NONE, top);
2339
+ } else {
2340
+ this.addPosition(node, Position.INSIDE, top);
2341
+ }
2342
+ if (next_node === this.current_node || node === this.current_node) {
2343
+ return this.addPosition(node, Position.NONE, top);
2344
+ } else {
2345
+ return this.addPosition(node, Position.AFTER, top);
2346
+ }
2347
+ };
2348
+
2349
+ HitAreasGenerator.prototype.handleOpenFolder = function(node, $element) {
2350
+ if (node === this.current_node) {
2351
+ return false;
2352
+ }
2353
+ if (node.children[0] !== this.current_node) {
2354
+ this.addPosition(node, Position.INSIDE, this.getTop($element));
2355
+ }
2356
+ return true;
2357
+ };
2358
+
2359
+ HitAreasGenerator.prototype.handleClosedFolder = function(node, next_node, $element) {
2360
+ var top;
2361
+ top = this.getTop($element);
2362
+ if (node === this.current_node) {
2363
+ return this.addPosition(node, Position.NONE, top);
2364
+ } else {
2365
+ this.addPosition(node, Position.INSIDE, top);
2366
+ if (next_node !== this.current_node) {
2367
+ return this.addPosition(node, Position.AFTER, top);
2368
+ }
2369
+ }
2370
+ };
2371
+
2372
+ HitAreasGenerator.prototype.handleAfterOpenFolder = function(node, next_node, $element) {
2373
+ if (node === this.current_node || next_node === this.current_node) {
2374
+ return this.addPosition(node, Position.NONE, this.last_top);
2375
+ } else {
2376
+ return this.addPosition(node, Position.AFTER, this.last_top);
2377
+ }
2378
+ };
2379
+
2380
+ HitAreasGenerator.prototype.handleFirstNode = function(node, $element) {
2381
+ if (node !== this.current_node) {
2382
+ return this.addPosition(node, Position.BEFORE, this.getTop($(node.element)));
2383
+ }
2384
+ };
2385
+
2386
+ HitAreasGenerator.prototype.generateHitAreas = function(positions) {
2387
+ var group, hit_areas, position, previous_top, _i, _len;
2388
+ previous_top = -1;
2389
+ group = [];
2390
+ hit_areas = [];
2391
+ for (_i = 0, _len = positions.length; _i < _len; _i++) {
2392
+ position = positions[_i];
2393
+ if (position.top !== previous_top && group.length) {
2394
+ if (group.length) {
2395
+ this.generateHitAreasForGroup(hit_areas, group, previous_top, position.top);
2396
+ }
2397
+ previous_top = position.top;
2398
+ group = [];
2399
+ }
2400
+ group.push(position);
2401
+ }
2402
+ this.generateHitAreasForGroup(hit_areas, group, previous_top, this.tree_bottom);
2403
+ return hit_areas;
2404
+ };
2405
+
2406
+ HitAreasGenerator.prototype.generateHitAreasForGroup = function(hit_areas, positions_in_group, top, bottom) {
2407
+ var area_height, area_top, position, _i, _len;
2408
+ area_height = (bottom - top) / positions_in_group.length;
2409
+ area_top = top;
2410
+ for (_i = 0, _len = positions_in_group.length; _i < _len; _i++) {
2411
+ position = positions_in_group[_i];
2412
+ hit_areas.push({
2413
+ top: area_top,
2414
+ bottom: area_top + area_height,
2415
+ node: position.node,
2416
+ position: position.position
2417
+ });
2418
+ area_top += area_height;
2419
+ }
2420
+ return null;
2421
+ };
2422
+
2423
+ return HitAreasGenerator;
2424
+
2425
+ })(VisibleNodeIterator);
2426
+
2427
+ DragElement = (function() {
2428
+ function DragElement(node, offset_x, offset_y, $tree) {
2429
+ this.offset_x = offset_x;
2430
+ this.offset_y = offset_y;
2431
+ this.$element = $("<span class=\"jqtree-title jqtree-dragging\">" + node.name + "</span>");
2432
+ this.$element.css("position", "absolute");
2433
+ $tree.append(this.$element);
2434
+ }
2435
+
2436
+ DragElement.prototype.move = function(page_x, page_y) {
2437
+ return this.$element.offset({
2438
+ left: page_x - this.offset_x,
2439
+ top: page_y - this.offset_y
2440
+ });
2441
+ };
2442
+
2443
+ DragElement.prototype.remove = function() {
2444
+ return this.$element.remove();
2445
+ };
2446
+
2447
+ return DragElement;
2448
+
2449
+ })();
2450
+
2451
+ GhostDropHint = (function() {
2452
+ function GhostDropHint(node, $element, position) {
2453
+ this.$element = $element;
2454
+ this.node = node;
2455
+ this.$ghost = $('<li class="jqtree_common jqtree-ghost"><span class="jqtree_common jqtree-circle"></span><span class="jqtree_common jqtree-line"></span></li>');
2456
+ if (position === Position.AFTER) {
2457
+ this.moveAfter();
2458
+ } else if (position === Position.BEFORE) {
2459
+ this.moveBefore();
2460
+ } else if (position === Position.INSIDE) {
2461
+ if (node.isFolder() && node.is_open) {
2462
+ this.moveInsideOpenFolder();
2463
+ } else {
2464
+ this.moveInside();
2465
+ }
2466
+ }
2467
+ }
2468
+
2469
+ GhostDropHint.prototype.remove = function() {
2470
+ return this.$ghost.remove();
2471
+ };
2472
+
2473
+ GhostDropHint.prototype.moveAfter = function() {
2474
+ return this.$element.after(this.$ghost);
2475
+ };
2476
+
2477
+ GhostDropHint.prototype.moveBefore = function() {
2478
+ return this.$element.before(this.$ghost);
2479
+ };
2480
+
2481
+ GhostDropHint.prototype.moveInsideOpenFolder = function() {
2482
+ return $(this.node.children[0].element).before(this.$ghost);
2483
+ };
2484
+
2485
+ GhostDropHint.prototype.moveInside = function() {
2486
+ this.$element.after(this.$ghost);
2487
+ return this.$ghost.addClass('jqtree-inside');
2488
+ };
2489
+
2490
+ return GhostDropHint;
2491
+
2492
+ })();
2493
+
2494
+ BorderDropHint = (function() {
2495
+ function BorderDropHint($element) {
2496
+ var $div, width;
2497
+ $div = $element.children('.jqtree-element');
2498
+ width = $element.width() - 4;
2499
+ this.$hint = $('<span class="jqtree-border"></span>');
2500
+ $div.append(this.$hint);
2501
+ this.$hint.css({
2502
+ width: width,
2503
+ height: $div.height() - 4
2504
+ });
2505
+ }
2506
+
2507
+ BorderDropHint.prototype.remove = function() {
2508
+ return this.$hint.remove();
2509
+ };
2510
+
2511
+ return BorderDropHint;
2512
+
2513
+ })();
2514
+
2515
+ ScrollHandler = (function() {
2152
2516
  function ScrollHandler(tree_widget) {
2153
2517
  this.tree_widget = tree_widget;
2154
2518
  this.previous_top = -1;
@@ -2159,15 +2523,15 @@ limitations under the License.
2159
2523
  var $scroll_parent, getParentWithOverflow, setDocumentAsScrollParent,
2160
2524
  _this = this;
2161
2525
  getParentWithOverflow = function() {
2162
- var css_value, css_values, parent, scroll_parent, _i, _j, _len, _len1, _ref, _ref1;
2526
+ var css_value, css_values, parent, scroll_parent, _i, _j, _len, _len1, _ref3, _ref4;
2163
2527
  css_values = ['overflow', 'overflow-y'];
2164
2528
  scroll_parent = null;
2165
- _ref = _this.tree_widget.$el.parents();
2166
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2167
- parent = _ref[_i];
2529
+ _ref3 = _this.tree_widget.$el.parents();
2530
+ for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
2531
+ parent = _ref3[_i];
2168
2532
  for (_j = 0, _len1 = css_values.length; _j < _len1; _j++) {
2169
2533
  css_value = css_values[_j];
2170
- if ((_ref1 = $.css(parent, css_value)) === 'auto' || _ref1 === 'scroll') {
2534
+ if ((_ref4 = $.css(parent, css_value)) === 'auto' || _ref4 === 'scroll') {
2171
2535
  return $(parent);
2172
2536
  }
2173
2537
  }
@@ -2227,8 +2591,175 @@ limitations under the License.
2227
2591
  }
2228
2592
  };
2229
2593
 
2594
+ ScrollHandler.prototype.scrollTo = function(top) {
2595
+ var tree_top;
2596
+ if (this.$scroll_parent) {
2597
+ return this.$scroll_parent[0].scrollTop = top;
2598
+ } else {
2599
+ tree_top = this.tree_widget.$el.offset().top;
2600
+ return $(document).scrollTop(top + tree_top);
2601
+ }
2602
+ };
2603
+
2604
+ ScrollHandler.prototype.isScrolledIntoView = function(element) {
2605
+ var $element, element_bottom, element_top, view_bottom, view_top;
2606
+ $element = $(element);
2607
+ if (this.$scroll_parent) {
2608
+ view_top = 0;
2609
+ view_bottom = this.$scroll_parent.height();
2610
+ element_top = $element.offset().top - this.scroll_parent_top;
2611
+ element_bottom = element_top + $element.height();
2612
+ } else {
2613
+ view_top = $(window).scrollTop();
2614
+ view_bottom = view_top + $(window).height();
2615
+ element_top = $element.offset().top;
2616
+ element_bottom = element_top + $element.height();
2617
+ }
2618
+ return (element_bottom <= view_bottom) && (element_top >= view_top);
2619
+ };
2620
+
2230
2621
  return ScrollHandler;
2231
2622
 
2232
2623
  })();
2233
2624
 
2625
+ KeyHandler = (function() {
2626
+ var DOWN, LEFT, RIGHT, UP;
2627
+
2628
+ LEFT = 37;
2629
+
2630
+ UP = 38;
2631
+
2632
+ RIGHT = 39;
2633
+
2634
+ DOWN = 40;
2635
+
2636
+ function KeyHandler(tree_widget) {
2637
+ this.tree_widget = tree_widget;
2638
+ if (tree_widget.options.keyboardSupport) {
2639
+ $(document).bind('keydown.jqtree', $.proxy(this.handleKeyDown, this));
2640
+ }
2641
+ }
2642
+
2643
+ KeyHandler.prototype.deinit = function() {
2644
+ return $(document).unbind('keydown.jqtree');
2645
+ };
2646
+
2647
+ KeyHandler.prototype.handleKeyDown = function(e) {
2648
+ var current_node, key, moveDown, moveLeft, moveRight, moveUp, selectNode,
2649
+ _this = this;
2650
+ if ($(document.activeElement).is('textarea,input')) {
2651
+ return true;
2652
+ }
2653
+ current_node = this.tree_widget.getSelectedNode();
2654
+ selectNode = function(node) {
2655
+ if (node) {
2656
+ _this.tree_widget.selectNode(node);
2657
+ if (_this.tree_widget.scroll_handler && (!_this.tree_widget.scroll_handler.isScrolledIntoView($(node.element).find('.jqtree-element')))) {
2658
+ _this.tree_widget.scrollToNode(node);
2659
+ }
2660
+ return false;
2661
+ } else {
2662
+ return true;
2663
+ }
2664
+ };
2665
+ moveDown = function() {
2666
+ return selectNode(_this.getNextNode(current_node));
2667
+ };
2668
+ moveUp = function() {
2669
+ return selectNode(_this.getPreviousNode(current_node));
2670
+ };
2671
+ moveRight = function() {
2672
+ if (current_node.hasChildren() && !current_node.is_open) {
2673
+ _this.tree_widget.openNode(current_node);
2674
+ return false;
2675
+ } else {
2676
+ return true;
2677
+ }
2678
+ };
2679
+ moveLeft = function() {
2680
+ if (current_node.hasChildren() && current_node.is_open) {
2681
+ _this.tree_widget.closeNode(current_node);
2682
+ return false;
2683
+ } else {
2684
+ return true;
2685
+ }
2686
+ };
2687
+ if (!current_node) {
2688
+ return true;
2689
+ } else {
2690
+ key = e.which;
2691
+ switch (key) {
2692
+ case DOWN:
2693
+ return moveDown();
2694
+ case UP:
2695
+ return moveUp();
2696
+ case RIGHT:
2697
+ return moveRight();
2698
+ case LEFT:
2699
+ return moveLeft();
2700
+ }
2701
+ }
2702
+ };
2703
+
2704
+ KeyHandler.prototype.getNextNode = function(node, include_children) {
2705
+ var next_sibling;
2706
+ if (include_children == null) {
2707
+ include_children = true;
2708
+ }
2709
+ if (include_children && node.hasChildren() && node.is_open) {
2710
+ return node.children[0];
2711
+ } else {
2712
+ if (!node.parent) {
2713
+ return null;
2714
+ } else {
2715
+ next_sibling = node.getNextSibling();
2716
+ if (next_sibling) {
2717
+ return next_sibling;
2718
+ } else {
2719
+ return this.getNextNode(node.parent, false);
2720
+ }
2721
+ }
2722
+ }
2723
+ };
2724
+
2725
+ KeyHandler.prototype.getPreviousNode = function(node) {
2726
+ var previous_sibling;
2727
+ if (!node.parent) {
2728
+ return null;
2729
+ } else {
2730
+ previous_sibling = node.getPreviousSibling();
2731
+ if (previous_sibling) {
2732
+ if (!previous_sibling.hasChildren() || !previous_sibling.is_open) {
2733
+ return previous_sibling;
2734
+ } else {
2735
+ return this.getLastChild(previous_sibling);
2736
+ }
2737
+ } else {
2738
+ if (node.parent.parent) {
2739
+ return node.parent;
2740
+ } else {
2741
+ return null;
2742
+ }
2743
+ }
2744
+ }
2745
+ };
2746
+
2747
+ KeyHandler.prototype.getLastChild = function(node) {
2748
+ var last_child;
2749
+ if (!node.hasChildren()) {
2750
+ return null;
2751
+ } else {
2752
+ last_child = node.children[node.children.length - 1];
2753
+ if (!last_child.hasChildren() || !last_child.is_open) {
2754
+ return last_child;
2755
+ } else {
2756
+ return this.getLastChild(last_child);
2757
+ }
2758
+ }
2759
+ };
2760
+
2761
+ return KeyHandler;
2762
+
2763
+ })();
2764
+
2234
2765
  }).call(this);