jqtree-rails 0.1.5.0 → 0.1.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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);