4 Copyright 2015 Marco Braak
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
18 (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
19 var $, DragAndDropHandler, DragElement, HitAreasGenerator, Position, VisibleNodeIterator, node_module, util,
20 extend = 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; },
21 hasProp = {}.hasOwnProperty;
23 node_module = require('./node');
25 util = require('./util');
27 Position = node_module.Position;
31 DragAndDropHandler = (function() {
32 function DragAndDropHandler(tree_widget) {
33 this.tree_widget = tree_widget;
34 this.hovered_area = null;
37 this.is_dragging = false;
38 this.current_item = null;
41 DragAndDropHandler.prototype.mouseCapture = function(position_info) {
42 var $element, node_element;
43 $element = $(position_info.target);
44 if (!this.mustCaptureElement($element)) {
47 if (this.tree_widget.options.onIsMoveHandle && !this.tree_widget.options.onIsMoveHandle($element)) {
50 node_element = this.tree_widget._getNodeElement($element);
51 if (node_element && this.tree_widget.options.onCanMove) {
52 if (!this.tree_widget.options.onCanMove(node_element.node)) {
56 this.current_item = node_element;
57 return this.current_item !== null;
60 DragAndDropHandler.prototype.mouseStart = function(position_info) {
61 var node, node_name, offset;
63 offset = $(position_info.target).offset();
64 node = this.current_item.node;
65 if (this.tree_widget.options.autoEscape) {
66 node_name = util.html_escape(node.name);
68 node_name = node.name;
70 this.drag_element = new DragElement(node_name, position_info.page_x - offset.left, position_info.page_y - offset.top, this.tree_widget.element);
71 this.is_dragging = true;
72 this.current_item.$element.addClass('jqtree-moving');
76 DragAndDropHandler.prototype.mouseDrag = function(position_info) {
77 var area, can_move_to;
78 this.drag_element.move(position_info.page_x, position_info.page_y);
79 area = this.findHoveredArea(position_info.page_x, position_info.page_y);
80 can_move_to = this.canMoveToArea(area);
81 if (can_move_to && area) {
82 if (!area.node.isFolder()) {
83 this.stopOpenFolderTimer();
85 if (this.hovered_area !== area) {
86 this.hovered_area = area;
87 if (this.mustOpenFolderTimer(area)) {
88 this.startOpenFolderTimer(area.node);
90 this.stopOpenFolderTimer();
92 this.updateDropHint();
96 this.removeDropHint();
97 this.stopOpenFolderTimer();
100 if (this.tree_widget.options.onDragMove != null) {
101 this.tree_widget.options.onDragMove(this.current_item.node, position_info.original_event);
107 DragAndDropHandler.prototype.mustCaptureElement = function($element) {
108 return !$element.is('input,select,textarea');
111 DragAndDropHandler.prototype.canMoveToArea = function(area) {
115 } else if (this.tree_widget.options.onCanMoveTo) {
116 position_name = Position.getName(area.position);
117 return this.tree_widget.options.onCanMoveTo(this.current_item.node, area.node, position_name);
123 DragAndDropHandler.prototype.mouseStop = function(position_info) {
125 this.moveItem(position_info);
128 this.removeDropHint();
129 this.removeHitAreas();
130 current_item = this.current_item;
131 if (this.current_item) {
132 this.current_item.$element.removeClass('jqtree-moving');
133 this.current_item = null;
135 this.is_dragging = false;
136 if (!this.hovered_area && current_item) {
137 if (this.tree_widget.options.onDragStop != null) {
138 this.tree_widget.options.onDragStop(current_item.node, position_info.original_event);
144 DragAndDropHandler.prototype.refresh = function() {
145 this.removeHitAreas();
146 if (this.current_item) {
147 this.generateHitAreas();
148 this.current_item = this.tree_widget._getNodeElementForNode(this.current_item.node);
149 if (this.is_dragging) {
150 return this.current_item.$element.addClass('jqtree-moving');
155 DragAndDropHandler.prototype.removeHitAreas = function() {
156 return this.hit_areas = [];
159 DragAndDropHandler.prototype.clear = function() {
160 this.drag_element.remove();
161 return this.drag_element = null;
164 DragAndDropHandler.prototype.removeDropHint = function() {
165 if (this.previous_ghost) {
166 return this.previous_ghost.remove();
170 DragAndDropHandler.prototype.removeHover = function() {
171 return this.hovered_area = null;
174 DragAndDropHandler.prototype.generateHitAreas = function() {
175 var hit_areas_generator;
176 hit_areas_generator = new HitAreasGenerator(this.tree_widget.tree, this.current_item.node, this.getTreeDimensions().bottom);
177 return this.hit_areas = hit_areas_generator.generate();
180 DragAndDropHandler.prototype.findHoveredArea = function(x, y) {
181 var area, dimensions, high, low, mid;
182 dimensions = this.getTreeDimensions();
183 if (x < dimensions.left || y < dimensions.top || x > dimensions.right || y > dimensions.bottom) {
187 high = this.hit_areas.length;
189 mid = (low + high) >> 1;
190 area = this.hit_areas[mid];
193 } else if (y > area.bottom) {
202 DragAndDropHandler.prototype.mustOpenFolderTimer = function(area) {
205 return node.isFolder() && !node.is_open && area.position === Position.INSIDE;
208 DragAndDropHandler.prototype.updateDropHint = function() {
210 if (!this.hovered_area) {
213 this.removeDropHint();
214 node_element = this.tree_widget._getNodeElementForNode(this.hovered_area.node);
215 return this.previous_ghost = node_element.addDropHint(this.hovered_area.position);
218 DragAndDropHandler.prototype.startOpenFolderTimer = function(folder) {
220 openFolder = (function(_this) {
222 return _this.tree_widget._openNode(folder, _this.tree_widget.options.slide, function() {
224 return _this.updateDropHint();
228 this.stopOpenFolderTimer();
229 return this.open_folder_timer = setTimeout(openFolder, this.tree_widget.options.openFolderDelay);
232 DragAndDropHandler.prototype.stopOpenFolderTimer = function() {
233 if (this.open_folder_timer) {
234 clearTimeout(this.open_folder_timer);
235 return this.open_folder_timer = null;
239 DragAndDropHandler.prototype.moveItem = function(position_info) {
240 var doMove, event, moved_node, position, previous_parent, target_node;
241 if (this.hovered_area && this.hovered_area.position !== Position.NONE && this.canMoveToArea(this.hovered_area)) {
242 moved_node = this.current_item.node;
243 target_node = this.hovered_area.node;
244 position = this.hovered_area.position;
245 previous_parent = moved_node.parent;
246 if (position === Position.INSIDE) {
247 this.hovered_area.node.is_open = true;
249 doMove = (function(_this) {
251 _this.tree_widget.tree.moveNode(moved_node, target_node, position);
252 _this.tree_widget.element.empty();
253 return _this.tree_widget._refreshElements();
256 event = this.tree_widget._triggerEvent('tree.move', {
258 moved_node: moved_node,
259 target_node: target_node,
260 position: Position.getName(position),
261 previous_parent: previous_parent,
263 original_event: position_info.original_event
266 if (!event.isDefaultPrevented()) {
272 DragAndDropHandler.prototype.getTreeDimensions = function() {
274 offset = this.tree_widget.element.offset();
278 right: offset.left + this.tree_widget.element.width(),
279 bottom: offset.top + this.tree_widget.element.height() + 16
283 return DragAndDropHandler;
287 VisibleNodeIterator = (function() {
288 function VisibleNodeIterator(tree) {
292 VisibleNodeIterator.prototype.iterate = function() {
293 var _iterateNode, is_first_node;
294 is_first_node = true;
295 _iterateNode = (function(_this) {
296 return function(node, next_node) {
297 var $element, child, children_length, i, j, len, must_iterate_inside, ref;
298 must_iterate_inside = (node.is_open || !node.element) && node.hasChildren();
300 $element = $(node.element);
301 if (!$element.is(':visible')) {
305 _this.handleFirstNode(node, $element);
306 is_first_node = false;
308 if (!node.hasChildren()) {
309 _this.handleNode(node, next_node, $element);
310 } else if (node.is_open) {
311 if (!_this.handleOpenFolder(node, $element)) {
312 must_iterate_inside = false;
315 _this.handleClosedFolder(node, next_node, $element);
318 if (must_iterate_inside) {
319 children_length = node.children.length;
321 for (i = j = 0, len = ref.length; j < len; i = ++j) {
323 if (i === (children_length - 1)) {
324 _iterateNode(node.children[i], null);
326 _iterateNode(node.children[i], node.children[i + 1]);
330 return _this.handleAfterOpenFolder(node, next_node, $element);
335 return _iterateNode(this.tree, null);
338 VisibleNodeIterator.prototype.handleNode = function(node, next_node, $element) {};
340 VisibleNodeIterator.prototype.handleOpenFolder = function(node, $element) {};
342 VisibleNodeIterator.prototype.handleClosedFolder = function(node, next_node, $element) {};
344 VisibleNodeIterator.prototype.handleAfterOpenFolder = function(node, next_node, $element) {};
346 VisibleNodeIterator.prototype.handleFirstNode = function(node, $element) {};
348 return VisibleNodeIterator;
352 HitAreasGenerator = (function(superClass) {
353 extend(HitAreasGenerator, superClass);
355 function HitAreasGenerator(tree, current_node, tree_bottom) {
356 HitAreasGenerator.__super__.constructor.call(this, tree);
357 this.current_node = current_node;
358 this.tree_bottom = tree_bottom;
361 HitAreasGenerator.prototype.generate = function() {
365 return this.generateHitAreas(this.positions);
368 HitAreasGenerator.prototype.getTop = function($element) {
369 return $element.offset().top;
372 HitAreasGenerator.prototype.addPosition = function(node, position, top) {
379 this.positions.push(area);
380 return this.last_top = top;
383 HitAreasGenerator.prototype.handleNode = function(node, next_node, $element) {
385 top = this.getTop($element);
386 if (node === this.current_node) {
387 this.addPosition(node, Position.NONE, top);
389 this.addPosition(node, Position.INSIDE, top);
391 if (next_node === this.current_node || node === this.current_node) {
392 return this.addPosition(node, Position.NONE, top);
394 return this.addPosition(node, Position.AFTER, top);
398 HitAreasGenerator.prototype.handleOpenFolder = function(node, $element) {
399 if (node === this.current_node) {
402 if (node.children[0] !== this.current_node) {
403 this.addPosition(node, Position.INSIDE, this.getTop($element));
408 HitAreasGenerator.prototype.handleClosedFolder = function(node, next_node, $element) {
410 top = this.getTop($element);
411 if (node === this.current_node) {
412 return this.addPosition(node, Position.NONE, top);
414 this.addPosition(node, Position.INSIDE, top);
415 if (next_node !== this.current_node) {
416 return this.addPosition(node, Position.AFTER, top);
421 HitAreasGenerator.prototype.handleFirstNode = function(node, $element) {
422 if (node !== this.current_node) {
423 return this.addPosition(node, Position.BEFORE, this.getTop($(node.element)));
427 HitAreasGenerator.prototype.handleAfterOpenFolder = function(node, next_node, $element) {
428 if (node === this.current_node.node || next_node === this.current_node.node) {
429 return this.addPosition(node, Position.NONE, this.last_top);
431 return this.addPosition(node, Position.AFTER, this.last_top);
435 HitAreasGenerator.prototype.generateHitAreas = function(positions) {
436 var group, hit_areas, j, len, position, previous_top;
440 for (j = 0, len = positions.length; j < len; j++) {
441 position = positions[j];
442 if (position.top !== previous_top && group.length) {
444 this.generateHitAreasForGroup(hit_areas, group, previous_top, position.top);
446 previous_top = position.top;
449 group.push(position);
451 this.generateHitAreasForGroup(hit_areas, group, previous_top, this.tree_bottom);
455 HitAreasGenerator.prototype.generateHitAreasForGroup = function(hit_areas, positions_in_group, top, bottom) {
456 var area_height, area_top, i, position, position_count;
457 position_count = Math.min(positions_in_group.length, 4);
458 area_height = Math.round((bottom - top) / position_count);
461 while (i < position_count) {
462 position = positions_in_group[i];
465 bottom: area_top + area_height,
467 position: position.position
469 area_top += area_height;
475 return HitAreasGenerator;
477 })(VisibleNodeIterator);
479 DragElement = (function() {
480 function DragElement(node_name, offset_x, offset_y, $tree) {
481 this.offset_x = offset_x;
482 this.offset_y = offset_y;
483 this.$element = $("<span class=\"jqtree-title jqtree-dragging\">" + node_name + "</span>");
484 this.$element.css("position", "absolute");
485 $tree.append(this.$element);
488 DragElement.prototype.move = function(page_x, page_y) {
489 return this.$element.offset({
490 left: page_x - this.offset_x,
491 top: page_y - this.offset_y
495 DragElement.prototype.remove = function() {
496 return this.$element.remove();
504 DragAndDropHandler: DragAndDropHandler,
505 DragElement: DragElement,
506 HitAreasGenerator: HitAreasGenerator
509 },{"./node":5,"./util":12}],2:[function(require,module,exports){
510 var $, ElementsRenderer, NodeElement, html_escape, node_element, util;
512 node_element = require('./node_element');
514 NodeElement = node_element.NodeElement;
516 util = require('./util');
518 html_escape = util.html_escape;
522 ElementsRenderer = (function() {
523 function ElementsRenderer(tree_widget) {
524 this.tree_widget = tree_widget;
525 this.opened_icon_element = this.createButtonElement(tree_widget.options.openedIcon);
526 this.closed_icon_element = this.createButtonElement(tree_widget.options.closedIcon);
529 ElementsRenderer.prototype.render = function(from_node) {
530 if (from_node && from_node.parent) {
531 return this.renderFromNode(from_node);
533 return this.renderFromRoot();
537 ElementsRenderer.prototype.renderFromRoot = function() {
539 $element = this.tree_widget.element;
541 return this.createDomElements($element[0], this.tree_widget.tree.children, true, true, 1);
544 ElementsRenderer.prototype.renderFromNode = function(node) {
545 var $previous_li, li;
546 $previous_li = $(node.element);
547 li = this.createLi(node, node.getLevel());
548 this.attachNodeData(node, li);
549 $previous_li.after(li);
550 $previous_li.remove();
552 return this.createDomElements(li, node.children, false, false, node.getLevel() + 1);
556 ElementsRenderer.prototype.createDomElements = function(element, children, is_root_node, is_open, level) {
557 var child, i, len, li, ul;
558 ul = this.createUl(is_root_node);
559 element.appendChild(ul);
560 for (i = 0, len = children.length; i < len; i++) {
562 li = this.createLi(child, level);
564 this.attachNodeData(child, li);
565 if (child.hasChildren()) {
566 this.createDomElements(li, child.children, false, child.is_open, level + 1);
572 ElementsRenderer.prototype.attachNodeData = function(node, li) {
574 return $(li).data('node', node);
577 ElementsRenderer.prototype.createUl = function(is_root_node) {
578 var class_string, role, ul;
583 class_string = 'jqtree-tree';
585 if (this.tree_widget.options.rtl) {
586 class_string += ' jqtree-rtl';
589 ul = document.createElement('ul');
590 ul.className = "jqtree_common " + class_string;
591 ul.setAttribute('role', role);
595 ElementsRenderer.prototype.createLi = function(node, level) {
597 is_selected = this.tree_widget.select_node_handler && this.tree_widget.select_node_handler.isNodeSelected(node);
598 if (node.isFolder()) {
599 li = this.createFolderLi(node, level, is_selected);
601 li = this.createNodeLi(node, level, is_selected);
603 if (this.tree_widget.options.onCreateLi) {
604 this.tree_widget.options.onCreateLi(node, $(li));
609 ElementsRenderer.prototype.createFolderLi = function(node, level, is_selected) {
610 var button_classes, button_link, div, folder_classes, icon_element, is_folder, li;
611 button_classes = this.getButtonClasses(node);
612 folder_classes = this.getFolderClasses(node, is_selected);
614 icon_element = this.opened_icon_element;
616 icon_element = this.closed_icon_element;
618 li = document.createElement('li');
619 li.className = "jqtree_common " + folder_classes;
620 li.setAttribute('role', 'presentation');
621 div = document.createElement('div');
622 div.className = "jqtree-element jqtree_common";
623 div.setAttribute('role', 'presentation');
625 button_link = document.createElement('a');
626 button_link.className = button_classes;
627 button_link.appendChild(icon_element.cloneNode(false));
628 button_link.setAttribute('role', 'presentation');
629 button_link.setAttribute('aria-hidden', 'true');
630 if (this.tree_widget.options.buttonLeft) {
631 div.appendChild(button_link);
633 div.appendChild(this.createTitleSpan(node.name, level, is_selected, node.is_open, is_folder = true));
634 if (!this.tree_widget.options.buttonLeft) {
635 div.appendChild(button_link);
640 ElementsRenderer.prototype.createNodeLi = function(node, level, is_selected) {
641 var class_string, div, is_folder, li, li_classes;
642 li_classes = ['jqtree_common'];
644 li_classes.push('jqtree-selected');
646 class_string = li_classes.join(' ');
647 li = document.createElement('li');
648 li.className = class_string;
649 li.setAttribute('role', 'presentation');
650 div = document.createElement('div');
651 div.className = "jqtree-element jqtree_common";
652 div.setAttribute('role', 'presentation');
654 div.appendChild(this.createTitleSpan(node.name, level, is_selected, node.is_open, is_folder = false));
658 ElementsRenderer.prototype.createTitleSpan = function(node_name, level, is_selected, is_open, is_folder) {
659 var classes, title_span;
660 title_span = document.createElement('span');
661 classes = "jqtree-title jqtree_common";
663 classes += " jqtree-title-folder";
665 title_span.className = classes;
666 title_span.setAttribute('role', 'treeitem');
667 title_span.setAttribute('aria-level', level);
668 title_span.setAttribute('aria-selected', util.getBoolString(is_selected));
669 title_span.setAttribute('aria-expanded', util.getBoolString(is_open));
671 title_span.setAttribute('tabindex', 0);
673 title_span.innerHTML = this.escapeIfNecessary(node_name);
677 ElementsRenderer.prototype.getButtonClasses = function(node) {
679 classes = ['jqtree-toggler', 'jqtree_common'];
681 classes.push('jqtree-closed');
683 if (this.tree_widget.options.buttonLeft) {
684 classes.push('jqtree-toggler-left');
686 classes.push('jqtree-toggler-right');
688 return classes.join(' ');
691 ElementsRenderer.prototype.getFolderClasses = function(node, is_selected) {
693 classes = ['jqtree-folder'];
695 classes.push('jqtree-closed');
698 classes.push('jqtree-selected');
700 if (node.is_loading) {
701 classes.push('jqtree-loading');
703 return classes.join(' ');
706 ElementsRenderer.prototype.escapeIfNecessary = function(value) {
707 if (this.tree_widget.options.autoEscape) {
708 return html_escape(value);
714 ElementsRenderer.prototype.createButtonElement = function(value) {
716 if (typeof value === 'string') {
717 div = document.createElement('div');
718 div.innerHTML = value;
719 return document.createTextNode(div.innerHTML);
725 return ElementsRenderer;
729 module.exports = ElementsRenderer;
731 },{"./node_element":6,"./util":12}],3:[function(require,module,exports){
733 bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
737 KeyHandler = (function() {
738 var DOWN, LEFT, RIGHT, UP;
748 function KeyHandler(tree_widget) {
749 this.selectNode = bind(this.selectNode, this);
750 this.tree_widget = tree_widget;
751 if (tree_widget.options.keyboardSupport) {
752 $(document).bind('keydown.jqtree', $.proxy(this.handleKeyDown, this));
756 KeyHandler.prototype.deinit = function() {
757 return $(document).unbind('keydown.jqtree');
760 KeyHandler.prototype.moveDown = function() {
762 node = this.tree_widget.getSelectedNode();
764 return this.selectNode(node.getNextNode());
770 KeyHandler.prototype.moveUp = function() {
772 node = this.tree_widget.getSelectedNode();
774 return this.selectNode(node.getPreviousNode());
780 KeyHandler.prototype.moveRight = function() {
782 node = this.tree_widget.getSelectedNode();
785 } else if (!node.isFolder()) {
789 return this.selectNode(node.getNextNode());
791 this.tree_widget.openNode(node);
797 KeyHandler.prototype.moveLeft = function() {
799 node = this.tree_widget.getSelectedNode();
802 } else if (node.isFolder() && node.is_open) {
803 this.tree_widget.closeNode(node);
806 return this.selectNode(node.getParent());
810 KeyHandler.prototype.handleKeyDown = function(e) {
812 if (!this.tree_widget.options.keyboardSupport) {
815 if ($(document.activeElement).is('textarea,input,select')) {
818 if (!this.tree_widget.getSelectedNode()) {
824 return this.moveDown();
826 return this.moveUp();
828 return this.moveRight();
830 return this.moveLeft();
835 KeyHandler.prototype.selectNode = function(node) {
839 this.tree_widget.selectNode(node);
840 if (this.tree_widget.scroll_handler && (!this.tree_widget.scroll_handler.isScrolledIntoView($(node.element).find('.jqtree-element')))) {
841 this.tree_widget.scrollToNode(node);
851 module.exports = KeyHandler;
853 },{}],4:[function(require,module,exports){
856 This widget does the same a the mouse widget in jqueryui.
858 var $, MouseWidget, SimpleWidget,
859 extend = 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; },
860 hasProp = {}.hasOwnProperty;
862 SimpleWidget = require('./simple.widget');
866 MouseWidget = (function(superClass) {
867 extend(MouseWidget, superClass);
869 function MouseWidget() {
870 return MouseWidget.__super__.constructor.apply(this, arguments);
873 MouseWidget.is_mouse_handled = false;
875 MouseWidget.prototype._init = function() {
876 this.$el.bind('mousedown.mousewidget', $.proxy(this._mouseDown, this));
877 this.$el.bind('touchstart.mousewidget', $.proxy(this._touchStart, this));
878 this.is_mouse_started = false;
879 this.mouse_delay = 0;
880 this._mouse_delay_timer = null;
881 this._is_mouse_delay_met = true;
882 return this.mouse_down_info = null;
885 MouseWidget.prototype._deinit = function() {
887 this.$el.unbind('mousedown.mousewidget');
888 this.$el.unbind('touchstart.mousewidget');
889 $document = $(document);
890 $document.unbind('mousemove.mousewidget');
891 return $document.unbind('mouseup.mousewidget');
894 MouseWidget.prototype._mouseDown = function(e) {
899 result = this._handleMouseDown(e, this._getPositionInfo(e));
906 MouseWidget.prototype._handleMouseDown = function(e, position_info) {
907 if (MouseWidget.is_mouse_handled) {
910 if (this.is_mouse_started) {
911 this._handleMouseUp(position_info);
913 this.mouse_down_info = position_info;
914 if (!this._mouseCapture(position_info)) {
917 this._handleStartMouse();
918 this.is_mouse_handled = true;
922 MouseWidget.prototype._handleStartMouse = function() {
924 $document = $(document);
925 $document.bind('mousemove.mousewidget', $.proxy(this._mouseMove, this));
926 $document.bind('touchmove.mousewidget', $.proxy(this._touchMove, this));
927 $document.bind('mouseup.mousewidget', $.proxy(this._mouseUp, this));
928 $document.bind('touchend.mousewidget', $.proxy(this._touchEnd, this));
929 if (this.mouse_delay) {
930 return this._startMouseDelayTimer();
934 MouseWidget.prototype._startMouseDelayTimer = function() {
935 if (this._mouse_delay_timer) {
936 clearTimeout(this._mouse_delay_timer);
938 this._mouse_delay_timer = setTimeout((function(_this) {
940 return _this._is_mouse_delay_met = true;
942 })(this), this.mouse_delay);
943 return this._is_mouse_delay_met = false;
946 MouseWidget.prototype._mouseMove = function(e) {
947 return this._handleMouseMove(e, this._getPositionInfo(e));
950 MouseWidget.prototype._handleMouseMove = function(e, position_info) {
951 if (this.is_mouse_started) {
952 this._mouseDrag(position_info);
953 return e.preventDefault();
955 if (this.mouse_delay && !this._is_mouse_delay_met) {
958 this.is_mouse_started = this._mouseStart(this.mouse_down_info) !== false;
959 if (this.is_mouse_started) {
960 this._mouseDrag(position_info);
962 this._handleMouseUp(position_info);
964 return !this.is_mouse_started;
967 MouseWidget.prototype._getPositionInfo = function(e) {
976 MouseWidget.prototype._mouseUp = function(e) {
977 return this._handleMouseUp(this._getPositionInfo(e));
980 MouseWidget.prototype._handleMouseUp = function(position_info) {
982 $document = $(document);
983 $document.unbind('mousemove.mousewidget');
984 $document.unbind('touchmove.mousewidget');
985 $document.unbind('mouseup.mousewidget');
986 $document.unbind('touchend.mousewidget');
987 if (this.is_mouse_started) {
988 this.is_mouse_started = false;
989 this._mouseStop(position_info);
993 MouseWidget.prototype._mouseCapture = function(position_info) {
997 MouseWidget.prototype._mouseStart = function(position_info) {
1001 MouseWidget.prototype._mouseDrag = function(position_info) {
1005 MouseWidget.prototype._mouseStop = function(position_info) {
1009 MouseWidget.prototype.setMouseDelay = function(mouse_delay) {
1010 return this.mouse_delay = mouse_delay;
1013 MouseWidget.prototype._touchStart = function(e) {
1015 if (e.originalEvent.touches.length > 1) {
1018 touch = e.originalEvent.changedTouches[0];
1019 return this._handleMouseDown(e, this._getPositionInfo(touch));
1022 MouseWidget.prototype._touchMove = function(e) {
1024 if (e.originalEvent.touches.length > 1) {
1027 touch = e.originalEvent.changedTouches[0];
1028 return this._handleMouseMove(e, this._getPositionInfo(touch));
1031 MouseWidget.prototype._touchEnd = function(e) {
1033 if (e.originalEvent.touches.length > 1) {
1036 touch = e.originalEvent.changedTouches[0];
1037 return this._handleMouseUp(this._getPositionInfo(touch));
1044 module.exports = MouseWidget;
1046 },{"./simple.widget":10}],5:[function(require,module,exports){
1047 var $, Node, Position;
1052 getName: function(position) {
1053 return Position.strings[position - 1];
1055 nameToIndex: function(name) {
1057 for (i = j = 1, ref = Position.strings.length; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) {
1058 if (Position.strings[i - 1] === name) {
1066 Position.BEFORE = 1;
1070 Position.INSIDE = 3;
1074 Position.strings = ['before', 'after', 'inside', 'none'];
1076 Node = (function() {
1077 function Node(o, is_root, node_class) {
1078 if (is_root == null) {
1081 if (node_class == null) {
1089 this.id_mapping = {};
1091 this.node_class = node_class;
1095 Node.prototype.setData = function(o) {
1098 Set the data of this node.
1100 setData(string): set the name of the node
1101 setdata(object): set attributes of the node
1106 setData({ name: 'node1', id: 1});
1108 setData({ name: 'node2', id: 2, color: 'green'});
1110 * This is an internal function; it is not in the docs
1111 * Does not remove existing node values
1113 var key, setName, value;
1114 setName = (function(_this) {
1115 return function(name) {
1116 if (name !== null) {
1117 return _this.name = name;
1121 if (typeof o !== 'object') {
1126 if (key === 'label') {
1128 } else if (key !== 'children') {
1136 Node.prototype.initFromData = function(data) {
1137 var addChildren, addNode;
1138 addNode = (function(_this) {
1139 return function(node_data) {
1140 _this.setData(node_data);
1141 if (node_data.children) {
1142 return addChildren(node_data.children);
1146 addChildren = (function(_this) {
1147 return function(children_data) {
1148 var child, j, len, node;
1149 for (j = 0, len = children_data.length; j < len; j++) {
1150 child = children_data[j];
1151 node = new _this.tree.node_class('');
1152 node.initFromData(child);
1153 _this.addChild(node);
1164 Create tree from data.
1166 Structure of data is:
1171 { label: 'child1' },
1181 Node.prototype.loadFromData = function(data) {
1182 var j, len, node, o;
1183 this.removeChildren();
1184 for (j = 0, len = data.length; j < len; j++) {
1186 node = new this.tree.node_class(o);
1187 this.addChild(node);
1188 if (typeof o === 'object' && o.children) {
1189 node.loadFromData(o.children);
1204 Node.prototype.addChild = function(node) {
1205 this.children.push(node);
1206 return node._setParent(this);
1211 Add child at position. Index starts at 0.
1213 tree.addChildAtPosition(
1219 Node.prototype.addChildAtPosition = function(node, index) {
1220 this.children.splice(index, 0, node);
1221 return node._setParent(this);
1224 Node.prototype._setParent = function(parent) {
1225 this.parent = parent;
1226 this.tree = parent.tree;
1227 return this.tree.addNodeToIndex(this);
1232 Remove child. This also removes the children of the node.
1234 tree.removeChild(tree.children[0]);
1237 Node.prototype.removeChild = function(node) {
1238 node.removeChildren();
1239 return this._removeChild(node);
1242 Node.prototype._removeChild = function(node) {
1243 this.children.splice(this.getChildIndex(node), 1);
1244 return this.tree.removeNodeFromIndex(node);
1251 var index = getChildIndex(node);
1254 Node.prototype.getChildIndex = function(node) {
1255 return $.inArray(node, this.children);
1260 Does the tree have children?
1262 if (tree.hasChildren()) {
1267 Node.prototype.hasChildren = function() {
1268 return this.children.length !== 0;
1271 Node.prototype.isFolder = function() {
1272 return this.hasChildren() || this.load_on_demand;
1277 Iterate over all the nodes in the tree.
1279 Calls callback with (node, level).
1281 The callback must return true to continue the iteration on current node.
1284 function(node, level) {
1285 console.log(node.name);
1287 // stop iteration after level 2
1288 return (level <= 2);
1293 Node.prototype.iterate = function(callback) {
1295 _iterate = function(node, level) {
1296 var child, j, len, ref, result;
1297 if (node.children) {
1298 ref = node.children;
1299 for (j = 0, len = ref.length; j < len; j++) {
1301 result = callback(child, level);
1302 if (result && child.hasChildren()) {
1303 _iterate(child, level + 1);
1315 Move node relative to another node.
1317 Argument position: Position.BEFORE, Position.AFTER or Position.Inside
1319 // move node1 after node2
1320 tree.moveNode(node1, node2, Position.AFTER);
1323 Node.prototype.moveNode = function(moved_node, target_node, position) {
1324 if (moved_node.isParentOf(target_node)) {
1327 moved_node.parent._removeChild(moved_node);
1328 if (position === Position.AFTER) {
1329 return target_node.parent.addChildAtPosition(moved_node, target_node.parent.getChildIndex(target_node) + 1);
1330 } else if (position === Position.BEFORE) {
1331 return target_node.parent.addChildAtPosition(moved_node, target_node.parent.getChildIndex(target_node));
1332 } else if (position === Position.INSIDE) {
1333 return target_node.addChildAtPosition(moved_node, 0);
1339 Get the tree as data.
1342 Node.prototype.getData = function(include_parent) {
1343 var getDataFromNodes;
1344 if (include_parent == null) {
1345 include_parent = false;
1347 getDataFromNodes = function(nodes) {
1348 var data, j, k, len, node, tmp_node, v;
1350 for (j = 0, len = nodes.length; j < len; j++) {
1355 if ((k !== 'parent' && k !== 'children' && k !== 'element' && k !== 'tree') && Object.prototype.hasOwnProperty.call(node, k)) {
1359 if (node.hasChildren()) {
1360 tmp_node.children = getDataFromNodes(node.children);
1362 data.push(tmp_node);
1366 if (include_parent) {
1367 return getDataFromNodes([this]);
1369 return getDataFromNodes(this.children);
1373 Node.prototype.getNodeByName = function(name) {
1374 return this.getNodeByCallback(function(node) {
1375 return node.name === name;
1379 Node.prototype.getNodeByCallback = function(callback) {
1382 this.iterate(function(node) {
1383 if (callback(node)) {
1393 Node.prototype.addAfter = function(node_info) {
1394 var child_index, node;
1398 node = new this.tree.node_class(node_info);
1399 child_index = this.parent.getChildIndex(this);
1400 this.parent.addChildAtPosition(node, child_index + 1);
1401 if (typeof node_info === 'object' && node_info.children && node_info.children.length) {
1402 node.loadFromData(node_info.children);
1408 Node.prototype.addBefore = function(node_info) {
1409 var child_index, node;
1413 node = new this.tree.node_class(node_info);
1414 child_index = this.parent.getChildIndex(this);
1415 this.parent.addChildAtPosition(node, child_index);
1416 if (typeof node_info === 'object' && node_info.children && node_info.children.length) {
1417 node.loadFromData(node_info.children);
1423 Node.prototype.addParent = function(node_info) {
1424 var child, j, len, new_parent, original_parent, ref;
1428 new_parent = new this.tree.node_class(node_info);
1429 new_parent._setParent(this.tree);
1430 original_parent = this.parent;
1431 ref = original_parent.children;
1432 for (j = 0, len = ref.length; j < len; j++) {
1434 new_parent.addChild(child);
1436 original_parent.children = [];
1437 original_parent.addChild(new_parent);
1442 Node.prototype.remove = function() {
1444 this.parent.removeChild(this);
1445 return this.parent = null;
1449 Node.prototype.append = function(node_info) {
1451 node = new this.tree.node_class(node_info);
1452 this.addChild(node);
1453 if (typeof node_info === 'object' && node_info.children && node_info.children.length) {
1454 node.loadFromData(node_info.children);
1459 Node.prototype.prepend = function(node_info) {
1461 node = new this.tree.node_class(node_info);
1462 this.addChildAtPosition(node, 0);
1463 if (typeof node_info === 'object' && node_info.children && node_info.children.length) {
1464 node.loadFromData(node_info.children);
1469 Node.prototype.isParentOf = function(node) {
1471 parent = node.parent;
1473 if (parent === this) {
1476 parent = parent.parent;
1481 Node.prototype.getLevel = function() {
1485 while (node.parent) {
1492 Node.prototype.getNodeById = function(node_id) {
1493 return this.id_mapping[node_id];
1496 Node.prototype.addNodeToIndex = function(node) {
1497 if (node.id != null) {
1498 return this.id_mapping[node.id] = node;
1502 Node.prototype.removeNodeFromIndex = function(node) {
1503 if (node.id != null) {
1504 return delete this.id_mapping[node.id];
1508 Node.prototype.removeChildren = function() {
1509 this.iterate((function(_this) {
1510 return function(child) {
1511 _this.tree.removeNodeFromIndex(child);
1515 return this.children = [];
1518 Node.prototype.getPreviousSibling = function() {
1523 previous_index = this.parent.getChildIndex(this) - 1;
1524 if (previous_index >= 0) {
1525 return this.parent.children[previous_index];
1532 Node.prototype.getNextSibling = function() {
1537 next_index = this.parent.getChildIndex(this) + 1;
1538 if (next_index < this.parent.children.length) {
1539 return this.parent.children[next_index];
1546 Node.prototype.getNodesByProperty = function(key, value) {
1547 return this.filter(function(node) {
1548 return node[key] === value;
1552 Node.prototype.filter = function(f) {
1555 this.iterate(function(node) {
1564 Node.prototype.getNextNode = function(include_children) {
1566 if (include_children == null) {
1567 include_children = true;
1569 if (include_children && this.hasChildren() && this.is_open) {
1570 return this.children[0];
1575 next_sibling = this.getNextSibling();
1577 return next_sibling;
1579 return this.parent.getNextNode(false);
1585 Node.prototype.getPreviousNode = function() {
1586 var previous_sibling;
1590 previous_sibling = this.getPreviousSibling();
1591 if (previous_sibling) {
1592 if (!previous_sibling.hasChildren() || !previous_sibling.is_open) {
1593 return previous_sibling;
1595 return previous_sibling.getLastChild();
1598 return this.getParent();
1603 Node.prototype.getParent = function() {
1606 } else if (!this.parent.parent) {
1613 Node.prototype.getLastChild = function() {
1615 if (!this.hasChildren()) {
1618 last_child = this.children[this.children.length - 1];
1619 if (!last_child.hasChildren() || !last_child.is_open) {
1622 return last_child.getLastChild();
1636 },{}],6:[function(require,module,exports){
1637 var $, BorderDropHint, FolderElement, GhostDropHint, NodeElement, Position, node,
1638 extend = 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; },
1639 hasProp = {}.hasOwnProperty;
1641 node = require('./node');
1643 Position = node.Position;
1647 NodeElement = (function() {
1648 function NodeElement(node, tree_widget) {
1649 this.init(node, tree_widget);
1652 NodeElement.prototype.init = function(node, tree_widget) {
1654 this.tree_widget = tree_widget;
1655 if (!node.element) {
1656 node.element = this.tree_widget.element;
1658 return this.$element = $(node.element);
1661 NodeElement.prototype.getUl = function() {
1662 return this.$element.children('ul:first');
1665 NodeElement.prototype.getSpan = function() {
1666 return this.$element.children('.jqtree-element').find('span.jqtree-title');
1669 NodeElement.prototype.getLi = function() {
1670 return this.$element;
1673 NodeElement.prototype.addDropHint = function(position) {
1674 if (position === Position.INSIDE) {
1675 return new BorderDropHint(this.$element);
1677 return new GhostDropHint(this.node, this.$element, position);
1681 NodeElement.prototype.select = function() {
1684 $li.addClass('jqtree-selected');
1685 $li.attr('aria-selected', 'true');
1686 $span = this.getSpan();
1687 return $span.attr('tabindex', 0);
1690 NodeElement.prototype.deselect = function() {
1693 $li.removeClass('jqtree-selected');
1694 $li.attr('aria-selected', 'false');
1695 $span = this.getSpan();
1696 return $span.attr('tabindex', -1);
1703 FolderElement = (function(superClass) {
1704 extend(FolderElement, superClass);
1706 function FolderElement() {
1707 return FolderElement.__super__.constructor.apply(this, arguments);
1710 FolderElement.prototype.open = function(on_finished, slide) {
1711 var $button, doOpen;
1712 if (slide == null) {
1715 if (!this.node.is_open) {
1716 this.node.is_open = true;
1717 $button = this.getButton();
1718 $button.removeClass('jqtree-closed');
1720 $button.append(this.tree_widget.renderer.opened_icon_element.cloneNode(false));
1721 doOpen = (function(_this) {
1724 $li = _this.getLi();
1725 $li.removeClass('jqtree-closed');
1726 $span = _this.getSpan();
1727 $span.attr('aria-expanded', 'true');
1729 on_finished(_this.node);
1731 return _this.tree_widget._triggerEvent('tree.open', {
1737 return this.getUl().slideDown('fast', doOpen);
1739 this.getUl().show();
1745 FolderElement.prototype.close = function(slide) {
1746 var $button, doClose;
1747 if (slide == null) {
1750 if (this.node.is_open) {
1751 this.node.is_open = false;
1752 $button = this.getButton();
1753 $button.addClass('jqtree-closed');
1755 $button.append(this.tree_widget.renderer.closed_icon_element.cloneNode(false));
1756 doClose = (function(_this) {
1759 $li = _this.getLi();
1760 $li.addClass('jqtree-closed');
1761 $span = _this.getSpan();
1762 $span.attr('aria-expanded', 'false');
1763 return _this.tree_widget._triggerEvent('tree.close', {
1769 return this.getUl().slideUp('fast', doClose);
1771 this.getUl().hide();
1777 FolderElement.prototype.getButton = function() {
1778 return this.$element.children('.jqtree-element').find('a.jqtree-toggler');
1781 FolderElement.prototype.addDropHint = function(position) {
1782 if (!this.node.is_open && position === Position.INSIDE) {
1783 return new BorderDropHint(this.$element);
1785 return new GhostDropHint(this.node, this.$element, position);
1789 return FolderElement;
1793 BorderDropHint = (function() {
1794 function BorderDropHint($element) {
1796 $div = $element.children('.jqtree-element');
1797 width = $element.width() - 4;
1798 this.$hint = $('<span class="jqtree-border"></span>');
1799 $div.append(this.$hint);
1802 height: $div.outerHeight() - 4
1806 BorderDropHint.prototype.remove = function() {
1807 return this.$hint.remove();
1810 return BorderDropHint;
1814 GhostDropHint = (function() {
1815 function GhostDropHint(node, $element, position) {
1816 this.$element = $element;
1818 this.$ghost = $('<li class="jqtree_common jqtree-ghost"><span class="jqtree_common jqtree-circle"></span><span class="jqtree_common jqtree-line"></span></li>');
1819 if (position === Position.AFTER) {
1821 } else if (position === Position.BEFORE) {
1823 } else if (position === Position.INSIDE) {
1824 if (node.isFolder() && node.is_open) {
1825 this.moveInsideOpenFolder();
1832 GhostDropHint.prototype.remove = function() {
1833 return this.$ghost.remove();
1836 GhostDropHint.prototype.moveAfter = function() {
1837 return this.$element.after(this.$ghost);
1840 GhostDropHint.prototype.moveBefore = function() {
1841 return this.$element.before(this.$ghost);
1844 GhostDropHint.prototype.moveInsideOpenFolder = function() {
1845 return $(this.node.children[0].element).before(this.$ghost);
1848 GhostDropHint.prototype.moveInside = function() {
1849 this.$element.after(this.$ghost);
1850 return this.$ghost.addClass('jqtree-inside');
1853 return GhostDropHint;
1858 BorderDropHint: BorderDropHint,
1859 FolderElement: FolderElement,
1860 GhostDropHint: GhostDropHint,
1861 NodeElement: NodeElement
1864 },{"./node":5}],7:[function(require,module,exports){
1865 var $, SaveStateHandler, indexOf, isInt, util;
1867 util = require('./util');
1869 indexOf = util.indexOf;
1875 SaveStateHandler = (function() {
1876 function SaveStateHandler(tree_widget) {
1877 this.tree_widget = tree_widget;
1880 SaveStateHandler.prototype.saveState = function() {
1882 state = JSON.stringify(this.getState());
1883 if (this.tree_widget.options.onSetStateFromStorage) {
1884 return this.tree_widget.options.onSetStateFromStorage(state);
1885 } else if (this.supportsLocalStorage()) {
1886 return localStorage.setItem(this.getCookieName(), state);
1887 } else if ($.cookie) {
1888 $.cookie.raw = true;
1889 return $.cookie(this.getCookieName(), state, {
1895 SaveStateHandler.prototype.getStateFromStorage = function() {
1897 json_data = this._loadFromStorage();
1899 return this._parseState(json_data);
1905 SaveStateHandler.prototype._parseState = function(json_data) {
1907 state = $.parseJSON(json_data);
1908 if (state && state.selected_node && isInt(state.selected_node)) {
1909 state.selected_node = [state.selected_node];
1914 SaveStateHandler.prototype._loadFromStorage = function() {
1915 if (this.tree_widget.options.onGetStateFromStorage) {
1916 return this.tree_widget.options.onGetStateFromStorage();
1917 } else if (this.supportsLocalStorage()) {
1918 return localStorage.getItem(this.getCookieName());
1919 } else if ($.cookie) {
1920 $.cookie.raw = true;
1921 return $.cookie(this.getCookieName());
1927 SaveStateHandler.prototype.getState = function() {
1928 var getOpenNodeIds, getSelectedNodeIds;
1929 getOpenNodeIds = (function(_this) {
1933 _this.tree_widget.tree.iterate(function(node) {
1934 if (node.is_open && node.id && node.hasChildren()) {
1935 open_nodes.push(node.id);
1942 getSelectedNodeIds = (function(_this) {
1945 return (function() {
1946 var i, len, ref, results;
1947 ref = this.tree_widget.getSelectedNodes();
1949 for (i = 0, len = ref.length; i < len; i++) {
1958 open_nodes: getOpenNodeIds(),
1959 selected_node: getSelectedNodeIds()
1963 SaveStateHandler.prototype.setInitialState = function(state) {
1964 var must_load_on_demand;
1968 must_load_on_demand = this._openInitialNodes(state.open_nodes);
1969 this._selectInitialNodes(state.selected_node);
1970 return must_load_on_demand;
1974 SaveStateHandler.prototype._openInitialNodes = function(node_ids) {
1975 var i, len, must_load_on_demand, node, node_id;
1976 must_load_on_demand = false;
1977 for (i = 0, len = node_ids.length; i < len; i++) {
1978 node_id = node_ids[i];
1979 node = this.tree_widget.getNodeById(node_id);
1981 if (!node.load_on_demand) {
1982 node.is_open = true;
1984 must_load_on_demand = true;
1988 return must_load_on_demand;
1991 SaveStateHandler.prototype._selectInitialNodes = function(node_ids) {
1992 var i, len, node, node_id, select_count;
1994 for (i = 0, len = node_ids.length; i < len; i++) {
1995 node_id = node_ids[i];
1996 node = this.tree_widget.getNodeById(node_id);
1999 this.tree_widget.select_node_handler.addToSelection(node);
2002 return select_count !== 0;
2005 SaveStateHandler.prototype.setInitialStateOnDemand = function(state, cb_finished) {
2007 return this._setInitialStateOnDemand(state.open_nodes, state.selected_node, cb_finished);
2009 return cb_finished();
2013 SaveStateHandler.prototype._setInitialStateOnDemand = function(node_ids, selected_nodes, cb_finished) {
2014 var loadAndOpenNode, loading_count, openNodes;
2016 openNodes = (function(_this) {
2018 var i, len, new_nodes_ids, node, node_id;
2020 for (i = 0, len = node_ids.length; i < len; i++) {
2021 node_id = node_ids[i];
2022 node = _this.tree_widget.getNodeById(node_id);
2024 new_nodes_ids.push(node_id);
2026 if (!node.is_loading) {
2027 if (node.load_on_demand) {
2028 loadAndOpenNode(node);
2030 _this.tree_widget._openNode(node, false);
2035 node_ids = new_nodes_ids;
2036 if (_this._selectInitialNodes(selected_nodes)) {
2037 _this.tree_widget._refreshElements();
2039 if (loading_count === 0) {
2040 return cb_finished();
2044 loadAndOpenNode = (function(_this) {
2045 return function(node) {
2047 return _this.tree_widget._openNode(node, false, function() {
2056 SaveStateHandler.prototype.getCookieName = function() {
2057 if (typeof this.tree_widget.options.saveState === 'string') {
2058 return this.tree_widget.options.saveState;
2064 SaveStateHandler.prototype.supportsLocalStorage = function() {
2066 testSupport = function() {
2068 if (typeof localStorage === "undefined" || localStorage === null) {
2072 key = '_storage_test';
2073 sessionStorage.setItem(key, true);
2074 sessionStorage.removeItem(key);
2082 if (this._supportsLocalStorage == null) {
2083 this._supportsLocalStorage = testSupport();
2085 return this._supportsLocalStorage;
2088 SaveStateHandler.prototype.getNodeIdToBeSelected = function() {
2090 state = this.getStateFromStorage();
2091 if (state && state.selected_node) {
2092 return state.selected_node[0];
2098 return SaveStateHandler;
2102 module.exports = SaveStateHandler;
2104 },{"./util":12}],8:[function(require,module,exports){
2105 var $, ScrollHandler;
2109 ScrollHandler = (function() {
2110 function ScrollHandler(tree_widget) {
2111 this.tree_widget = tree_widget;
2112 this.previous_top = -1;
2113 this.is_initialized = false;
2116 ScrollHandler.prototype._initScrollParent = function() {
2117 var $scroll_parent, getParentWithOverflow, setDocumentAsScrollParent;
2118 getParentWithOverflow = (function(_this) {
2120 var css_values, el, hasOverFlow, i, len, ref;
2121 css_values = ['overflow', 'overflow-y'];
2122 hasOverFlow = function(el) {
2123 var css_value, i, len, ref;
2124 for (i = 0, len = css_values.length; i < len; i++) {
2125 css_value = css_values[i];
2126 if ((ref = $.css(el, css_value)) === 'auto' || ref === 'scroll') {
2132 if (hasOverFlow(_this.tree_widget.$el[0])) {
2133 return _this.tree_widget.$el;
2135 ref = _this.tree_widget.$el.parents();
2136 for (i = 0, len = ref.length; i < len; i++) {
2138 if (hasOverFlow(el)) {
2145 setDocumentAsScrollParent = (function(_this) {
2147 _this.scroll_parent_top = 0;
2148 return _this.$scroll_parent = null;
2151 if (this.tree_widget.$el.css('position') === 'fixed') {
2152 setDocumentAsScrollParent();
2154 $scroll_parent = getParentWithOverflow();
2155 if ($scroll_parent && $scroll_parent.length && $scroll_parent[0].tagName !== 'HTML') {
2156 this.$scroll_parent = $scroll_parent;
2157 this.scroll_parent_top = this.$scroll_parent.offset().top;
2159 setDocumentAsScrollParent();
2161 return this.is_initialized = true;
2164 ScrollHandler.prototype._ensureInit = function() {
2165 if (!this.is_initialized) {
2166 return this._initScrollParent();
2170 ScrollHandler.prototype.checkScrolling = function() {
2173 hovered_area = this.tree_widget.dnd_handler.hovered_area;
2174 if (hovered_area && hovered_area.top !== this.previous_top) {
2175 this.previous_top = hovered_area.top;
2176 if (this.$scroll_parent) {
2177 return this._handleScrollingWithScrollParent(hovered_area);
2179 return this._handleScrollingWithDocument(hovered_area);
2184 ScrollHandler.prototype._handleScrollingWithScrollParent = function(area) {
2185 var distance_bottom;
2186 distance_bottom = this.scroll_parent_top + this.$scroll_parent[0].offsetHeight - area.bottom;
2187 if (distance_bottom < 20) {
2188 this.$scroll_parent[0].scrollTop += 20;
2189 this.tree_widget.refreshHitAreas();
2190 return this.previous_top = -1;
2191 } else if ((area.top - this.scroll_parent_top) < 20) {
2192 this.$scroll_parent[0].scrollTop -= 20;
2193 this.tree_widget.refreshHitAreas();
2194 return this.previous_top = -1;
2198 ScrollHandler.prototype._handleScrollingWithDocument = function(area) {
2200 distance_top = area.top - $(document).scrollTop();
2201 if (distance_top < 20) {
2202 return $(document).scrollTop($(document).scrollTop() - 20);
2203 } else if ($(window).height() - (area.bottom - $(document).scrollTop()) < 20) {
2204 return $(document).scrollTop($(document).scrollTop() + 20);
2208 ScrollHandler.prototype.scrollTo = function(top) {
2211 if (this.$scroll_parent) {
2212 return this.$scroll_parent[0].scrollTop = top;
2214 tree_top = this.tree_widget.$el.offset().top;
2215 return $(document).scrollTop(top + tree_top);
2219 ScrollHandler.prototype.isScrolledIntoView = function(element) {
2220 var $element, element_bottom, element_top, view_bottom, view_top;
2222 $element = $(element);
2223 if (this.$scroll_parent) {
2225 view_bottom = this.$scroll_parent.height();
2226 element_top = $element.offset().top - this.scroll_parent_top;
2227 element_bottom = element_top + $element.height();
2229 view_top = $(window).scrollTop();
2230 view_bottom = view_top + $(window).height();
2231 element_top = $element.offset().top;
2232 element_bottom = element_top + $element.height();
2234 return (element_bottom <= view_bottom) && (element_top >= view_top);
2237 return ScrollHandler;
2241 module.exports = ScrollHandler;
2243 },{}],9:[function(require,module,exports){
2244 var $, SelectNodeHandler;
2248 SelectNodeHandler = (function() {
2249 function SelectNodeHandler(tree_widget) {
2250 this.tree_widget = tree_widget;
2254 SelectNodeHandler.prototype.getSelectedNode = function() {
2256 selected_nodes = this.getSelectedNodes();
2257 if (selected_nodes.length) {
2258 return selected_nodes[0];
2264 SelectNodeHandler.prototype.getSelectedNodes = function() {
2265 var id, node, selected_nodes;
2266 if (this.selected_single_node) {
2267 return [this.selected_single_node];
2269 selected_nodes = [];
2270 for (id in this.selected_nodes) {
2271 node = this.tree_widget.getNodeById(id);
2273 selected_nodes.push(node);
2276 return selected_nodes;
2280 SelectNodeHandler.prototype.getSelectedNodesUnder = function(parent) {
2281 var id, node, selected_nodes;
2282 if (this.selected_single_node) {
2283 if (parent.isParentOf(this.selected_single_node)) {
2284 return [this.selected_single_node];
2289 selected_nodes = [];
2290 for (id in this.selected_nodes) {
2291 node = this.tree_widget.getNodeById(id);
2292 if (node && parent.isParentOf(node)) {
2293 selected_nodes.push(node);
2296 return selected_nodes;
2300 SelectNodeHandler.prototype.isNodeSelected = function(node) {
2303 } else if (node.id) {
2304 if (this.selected_nodes[node.id]) {
2309 } else if (this.selected_single_node) {
2310 return this.selected_single_node.element === node.element;
2316 SelectNodeHandler.prototype.clear = function() {
2317 this.selected_nodes = {};
2318 return this.selected_single_node = null;
2321 SelectNodeHandler.prototype.removeFromSelection = function(node, include_children) {
2322 if (include_children == null) {
2323 include_children = false;
2326 if (this.selected_single_node && node.element === this.selected_single_node.element) {
2327 return this.selected_single_node = null;
2330 delete this.selected_nodes[node.id];
2331 if (include_children) {
2332 return node.iterate((function(_this) {
2333 return function(n) {
2334 delete _this.selected_nodes[node.id];
2342 SelectNodeHandler.prototype.addToSelection = function(node) {
2344 return this.selected_nodes[node.id] = true;
2346 return this.selected_single_node = node;
2350 return SelectNodeHandler;
2354 module.exports = SelectNodeHandler;
2356 },{}],10:[function(require,module,exports){
2359 Copyright 2013 Marco Braak
2361 Licensed under the Apache License, Version 2.0 (the "License");
2362 you may not use this file except in compliance with the License.
2363 You may obtain a copy of the License at
2365 http://www.apache.org/licenses/LICENSE-2.0
2367 Unless required by applicable law or agreed to in writing, software
2368 distributed under the License is distributed on an "AS IS" BASIS,
2369 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2370 See the License for the specific language governing permissions and
2371 limitations under the License.
2373 var $, SimpleWidget,
2378 SimpleWidget = (function() {
2379 SimpleWidget.prototype.defaults = {};
2381 function SimpleWidget(el, options) {
2383 this.options = $.extend({}, this.defaults, options);
2386 SimpleWidget.prototype.destroy = function() {
2387 return this._deinit();
2390 SimpleWidget.prototype._init = function() {
2394 SimpleWidget.prototype._deinit = function() {
2398 SimpleWidget.register = function(widget_class, widget_name) {
2399 var callFunction, createWidget, destroyWidget, getDataKey, getWidgetData;
2400 getDataKey = function() {
2401 return "simple_widget_" + widget_name;
2403 getWidgetData = function(el, data_key) {
2405 widget = $.data(el, data_key);
2406 if (widget && (widget instanceof SimpleWidget)) {
2412 createWidget = function($el, options) {
2413 var data_key, el, existing_widget, i, len, widget;
2414 data_key = getDataKey();
2415 for (i = 0, len = $el.length; i < len; i++) {
2417 existing_widget = getWidgetData(el, data_key);
2418 if (!existing_widget) {
2419 widget = new widget_class(el, options);
2420 if (!$.data(el, data_key)) {
2421 $.data(el, data_key, widget);
2428 destroyWidget = function($el) {
2429 var data_key, el, i, len, results, widget;
2430 data_key = getDataKey();
2432 for (i = 0, len = $el.length; i < len; i++) {
2434 widget = getWidgetData(el, data_key);
2438 results.push($.removeData(el, data_key));
2442 callFunction = function($el, function_name, args) {
2443 var el, i, len, result, widget, widget_function;
2445 for (i = 0, len = $el.length; i < len; i++) {
2447 widget = $.data(el, getDataKey());
2448 if (widget && (widget instanceof SimpleWidget)) {
2449 widget_function = widget[function_name];
2450 if (widget_function && (typeof widget_function === 'function')) {
2451 result = widget_function.apply(widget, args);
2457 return $.fn[widget_name] = function() {
2458 var $el, args, argument1, function_name, options;
2459 argument1 = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
2461 if (argument1 === void 0 || typeof argument1 === 'object') {
2462 options = argument1;
2463 return createWidget($el, options);
2464 } else if (typeof argument1 === 'string' && argument1[0] !== '_') {
2465 function_name = argument1;
2466 if (function_name === 'destroy') {
2467 return destroyWidget($el);
2468 } else if (function_name === 'get_widget_class') {
2469 return widget_class;
2471 return callFunction($el, function_name, args);
2477 return SimpleWidget;
2481 module.exports = SimpleWidget;
2483 },{}],11:[function(require,module,exports){
2484 var $, BorderDropHint, DragAndDropHandler, DragElement, ElementsRenderer, FolderElement, GhostDropHint, HitAreasGenerator, JqTreeWidget, KeyHandler, MouseWidget, Node, NodeElement, Position, SaveStateHandler, ScrollHandler, SelectNodeHandler, SimpleWidget, __version__, drag_and_drop_handler, isFunction, node_module, ref, util_module,
2485 extend = 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; },
2486 hasProp = {}.hasOwnProperty;
2488 __version__ = require('./version');
2490 drag_and_drop_handler = require('./drag_and_drop_handler');
2492 ElementsRenderer = require('./elements_renderer');
2494 KeyHandler = require('./key_handler');
2496 MouseWidget = require('./mouse.widget');
2498 SaveStateHandler = require('./save_state_handler');
2500 ScrollHandler = require('./scroll_handler');
2502 SelectNodeHandler = require('./select_node_handler');
2504 SimpleWidget = require('./simple.widget');
2506 node_module = require('./node');
2508 Node = node_module.Node;
2510 Position = node_module.Position;
2512 util_module = require('./util');
2514 isFunction = util_module.isFunction;
2516 ref = require('./node_element'), BorderDropHint = ref.BorderDropHint, FolderElement = ref.FolderElement, GhostDropHint = ref.GhostDropHint, NodeElement = ref.NodeElement;
2518 DragAndDropHandler = drag_and_drop_handler.DragAndDropHandler, DragElement = drag_and_drop_handler.DragElement, HitAreasGenerator = drag_and_drop_handler.HitAreasGenerator;
2522 JqTreeWidget = (function(superClass) {
2523 extend(JqTreeWidget, superClass);
2525 function JqTreeWidget() {
2526 return JqTreeWidget.__super__.constructor.apply(this, arguments);
2529 JqTreeWidget.prototype.BorderDropHint = BorderDropHint;
2531 JqTreeWidget.prototype.DragElement = DragElement;
2533 JqTreeWidget.prototype.DragAndDropHandler = DragAndDropHandler;
2535 JqTreeWidget.prototype.ElementsRenderer = ElementsRenderer;
2537 JqTreeWidget.prototype.GhostDropHint = GhostDropHint;
2539 JqTreeWidget.prototype.HitAreasGenerator = HitAreasGenerator;
2541 JqTreeWidget.prototype.Node = Node;
2543 JqTreeWidget.prototype.SaveStateHandler = SaveStateHandler;
2545 JqTreeWidget.prototype.ScrollHandler = ScrollHandler;
2547 JqTreeWidget.prototype.SelectNodeHandler = SelectNodeHandler;
2549 JqTreeWidget.prototype.defaults = {
2554 useContextMenu: true,
2555 onCanSelectNode: null,
2556 onSetStateFromStorage: null,
2557 onGetStateFromStorage: null,
2559 onIsMoveHandle: null,
2566 openedIcon: '▼',
2570 keyboardSupport: true,
2571 openFolderDelay: 500,
2579 JqTreeWidget.prototype.toggle = function(node, slide) {
2580 if (slide == null) {
2583 if (slide === null) {
2584 slide = this.options.slide;
2587 this.closeNode(node, slide);
2589 this.openNode(node, slide);
2591 return this.element;
2594 JqTreeWidget.prototype.getTree = function() {
2598 JqTreeWidget.prototype.selectNode = function(node) {
2599 this._selectNode(node, false);
2600 return this.element;
2603 JqTreeWidget.prototype._selectNode = function(node, must_toggle) {
2604 var canSelect, deselected_node, openParents, saveState;
2605 if (must_toggle == null) {
2606 must_toggle = false;
2608 if (!this.select_node_handler) {
2611 canSelect = (function(_this) {
2613 if (_this.options.onCanSelectNode) {
2614 return _this.options.selectable && _this.options.onCanSelectNode(node);
2616 return _this.options.selectable;
2620 openParents = (function(_this) {
2623 parent = node.parent;
2624 if (parent && parent.parent && !parent.is_open) {
2625 return _this.openNode(parent, false);
2629 saveState = (function(_this) {
2631 if (_this.options.saveState) {
2632 return _this.save_state_handler.saveState();
2637 this._deselectCurrentNode();
2644 if (this.select_node_handler.isNodeSelected(node)) {
2646 this._deselectCurrentNode();
2647 this._triggerEvent('tree.select', {
2653 deselected_node = this.getSelectedNode();
2654 this._deselectCurrentNode();
2655 this.addToSelection(node);
2656 this._triggerEvent('tree.select', {
2658 deselected_node: deselected_node
2665 JqTreeWidget.prototype.getSelectedNode = function() {
2666 if (this.select_node_handler) {
2667 return this.select_node_handler.getSelectedNode();
2673 JqTreeWidget.prototype.toJson = function() {
2674 return JSON.stringify(this.tree.getData());
2677 JqTreeWidget.prototype.loadData = function(data, parent_node) {
2678 this._loadData(data, parent_node);
2679 return this.element;
2685 - loadDataFromUrl(url, parent_node=null, on_finished=null)
2686 loadDataFromUrl('/my_data');
2687 loadDataFromUrl('/my_data', node1);
2688 loadDataFromUrl('/my_data', node1, function() { console.log('finished'); });
2689 loadDataFromUrl('/my_data', null, function() { console.log('finished'); });
2691 - loadDataFromUrl(parent_node=null, on_finished=null)
2693 loadDataFromUrl(node1);
2694 loadDataFromUrl(null, function() { console.log('finished'); });
2695 loadDataFromUrl(node1, function() { console.log('finished'); });
2698 JqTreeWidget.prototype.loadDataFromUrl = function(param1, param2, param3) {
2699 if ($.type(param1) === 'string') {
2700 this._loadDataFromUrl(param1, param2, param3);
2702 this._loadDataFromUrl(null, param1, param2);
2704 return this.element;
2707 JqTreeWidget.prototype.reload = function(on_finished) {
2708 this._loadDataFromUrl(null, null, on_finished);
2709 return this.element;
2712 JqTreeWidget.prototype._loadDataFromUrl = function(url_info, parent_node, on_finished) {
2713 var $el, addLoadingClass, handeLoadData, handleError, handleSuccess, loadDataFromUrlInfo, parseUrlInfo, removeLoadingClass;
2715 addLoadingClass = (function(_this) {
2718 $el = $(parent_node.element);
2720 $el = _this.element;
2722 $el.addClass('jqtree-loading');
2723 return _this._notifyLoading(true, parent_node, $el);
2726 removeLoadingClass = (function(_this) {
2729 $el.removeClass('jqtree-loading');
2730 return _this._notifyLoading(false, parent_node, $el);
2734 parseUrlInfo = function() {
2735 if ($.type(url_info) === 'string') {
2740 if (!url_info.method) {
2741 url_info.method = 'get';
2745 handeLoadData = (function(_this) {
2746 return function(data) {
2747 removeLoadingClass();
2748 _this._loadData(data, parent_node);
2749 if (on_finished && $.isFunction(on_finished)) {
2750 return on_finished();
2754 handleSuccess = (function(_this) {
2755 return function(response) {
2757 if ($.isArray(response) || typeof response === 'object') {
2759 } else if (data != null) {
2760 data = $.parseJSON(response);
2764 if (_this.options.dataFilter) {
2765 data = _this.options.dataFilter(data);
2767 return handeLoadData(data);
2770 handleError = (function(_this) {
2771 return function(response) {
2772 removeLoadingClass();
2773 if (_this.options.onLoadFailed) {
2774 return _this.options.onLoadFailed(response);
2778 loadDataFromUrlInfo = function() {
2779 url_info = parseUrlInfo();
2780 return $.ajax($.extend({}, url_info, {
2781 method: url_info.method != null ? url_info.method.toUpperCase() : 'GET',
2784 success: handleSuccess,
2789 url_info = this._getDataUrlInfo(parent_node);
2793 removeLoadingClass();
2794 } else if ($.isArray(url_info)) {
2795 handeLoadData(url_info);
2797 loadDataFromUrlInfo();
2801 JqTreeWidget.prototype._loadData = function(data, parent_node) {
2802 var deselectNodes, loadSubtree;
2803 if (parent_node == null) {
2806 deselectNodes = (function(_this) {
2808 var i, len, n, selected_nodes_under_parent;
2809 if (_this.select_node_handler) {
2810 selected_nodes_under_parent = _this.select_node_handler.getSelectedNodesUnder(parent_node);
2811 for (i = 0, len = selected_nodes_under_parent.length; i < len; i++) {
2812 n = selected_nodes_under_parent[i];
2813 _this.select_node_handler.removeFromSelection(n);
2819 loadSubtree = (function(_this) {
2821 parent_node.loadFromData(data);
2822 parent_node.load_on_demand = false;
2823 parent_node.is_loading = false;
2824 return _this._refreshElements(parent_node);
2830 this._triggerEvent('tree.load_data', {
2834 this._initTree(data);
2839 if (this.isDragging()) {
2840 return this.dnd_handler.refresh();
2844 JqTreeWidget.prototype.getNodeById = function(node_id) {
2845 return this.tree.getNodeById(node_id);
2848 JqTreeWidget.prototype.getNodeByName = function(name) {
2849 return this.tree.getNodeByName(name);
2852 JqTreeWidget.prototype.getNodesByProperty = function(key, value) {
2853 return this.tree.getNodesByProperty(key, value);
2856 JqTreeWidget.prototype.getNodeByHtmlElement = function(element) {
2857 return this._getNode($(element));
2860 JqTreeWidget.prototype.getNodeByCallback = function(callback) {
2861 return this.tree.getNodeByCallback(callback);
2864 JqTreeWidget.prototype.openNode = function(node, slide_param, on_finished_param) {
2865 var on_finished, parseParams, ref1, slide;
2866 if (slide_param == null) {
2869 if (on_finished_param == null) {
2870 on_finished_param = null;
2872 parseParams = (function(_this) {
2874 var on_finished, slide;
2875 if (isFunction(slide_param)) {
2876 on_finished = slide_param;
2879 slide = slide_param;
2880 on_finished = on_finished_param;
2882 if (slide === null) {
2883 slide = _this.options.slide;
2885 return [slide, on_finished];
2888 ref1 = parseParams(), slide = ref1[0], on_finished = ref1[1];
2890 this._openNode(node, slide, on_finished);
2892 return this.element;
2895 JqTreeWidget.prototype._openNode = function(node, slide, on_finished) {
2896 var doOpenNode, parent;
2897 if (slide == null) {
2900 doOpenNode = (function(_this) {
2901 return function(_node, _slide, _on_finished) {
2903 folder_element = new FolderElement(_node, _this);
2904 return folder_element.open(_on_finished, _slide);
2907 if (node.isFolder()) {
2908 if (node.load_on_demand) {
2909 return this._loadFolderOnDemand(node, slide, on_finished);
2911 parent = node.parent;
2913 if (parent.parent) {
2914 doOpenNode(parent, false, null);
2916 parent = parent.parent;
2918 doOpenNode(node, slide, on_finished);
2919 return this._saveState();
2924 JqTreeWidget.prototype._loadFolderOnDemand = function(node, slide, on_finished) {
2925 if (slide == null) {
2928 node.is_loading = true;
2929 return this._loadDataFromUrl(null, node, (function(_this) {
2931 return _this._openNode(node, slide, on_finished);
2936 JqTreeWidget.prototype.closeNode = function(node, slide) {
2937 if (slide == null) {
2940 if (slide === null) {
2941 slide = this.options.slide;
2943 if (node.isFolder()) {
2944 new FolderElement(node, this).close(slide);
2947 return this.element;
2950 JqTreeWidget.prototype.isDragging = function() {
2951 if (this.dnd_handler) {
2952 return this.dnd_handler.is_dragging;
2958 JqTreeWidget.prototype.refreshHitAreas = function() {
2959 this.dnd_handler.refresh();
2960 return this.element;
2963 JqTreeWidget.prototype.addNodeAfter = function(new_node_info, existing_node) {
2965 new_node = existing_node.addAfter(new_node_info);
2966 this._refreshElements(existing_node.parent);
2970 JqTreeWidget.prototype.addNodeBefore = function(new_node_info, existing_node) {
2972 new_node = existing_node.addBefore(new_node_info);
2973 this._refreshElements(existing_node.parent);
2977 JqTreeWidget.prototype.addParentNode = function(new_node_info, existing_node) {
2979 new_node = existing_node.addParent(new_node_info);
2980 this._refreshElements(new_node.parent);
2984 JqTreeWidget.prototype.removeNode = function(node) {
2986 parent = node.parent;
2988 this.select_node_handler.removeFromSelection(node, true);
2990 this._refreshElements(parent);
2992 return this.element;
2995 JqTreeWidget.prototype.appendNode = function(new_node_info, parent_node) {
2997 parent_node = parent_node || this.tree;
2998 node = parent_node.append(new_node_info);
2999 this._refreshElements(parent_node);
3003 JqTreeWidget.prototype.prependNode = function(new_node_info, parent_node) {
3006 parent_node = this.tree;
3008 node = parent_node.prepend(new_node_info);
3009 this._refreshElements(parent_node);
3013 JqTreeWidget.prototype.updateNode = function(node, data) {
3015 id_is_changed = data.id && data.id !== node.id;
3016 if (id_is_changed) {
3017 this.tree.removeNodeFromIndex(node);
3020 if (id_is_changed) {
3021 this.tree.addNodeToIndex(node);
3023 if (typeof data === 'object' && data.children) {
3024 node.removeChildren();
3025 if (data.children.length) {
3026 node.loadFromData(data.children);
3029 this.renderer.renderFromNode(node);
3030 this._selectCurrentNode();
3031 return this.element;
3034 JqTreeWidget.prototype.moveNode = function(node, target_node, position) {
3036 position_index = Position.nameToIndex(position);
3037 this.tree.moveNode(node, target_node, position_index);
3038 this._refreshElements();
3039 return this.element;
3042 JqTreeWidget.prototype.getStateFromStorage = function() {
3043 return this.save_state_handler.getStateFromStorage();
3046 JqTreeWidget.prototype.addToSelection = function(node) {
3048 this.select_node_handler.addToSelection(node);
3049 this._getNodeElementForNode(node).select();
3052 return this.element;
3055 JqTreeWidget.prototype.getSelectedNodes = function() {
3056 return this.select_node_handler.getSelectedNodes();
3059 JqTreeWidget.prototype.isNodeSelected = function(node) {
3060 return this.select_node_handler.isNodeSelected(node);
3063 JqTreeWidget.prototype.removeFromSelection = function(node) {
3064 this.select_node_handler.removeFromSelection(node);
3065 this._getNodeElementForNode(node).deselect();
3067 return this.element;
3070 JqTreeWidget.prototype.scrollToNode = function(node) {
3072 $element = $(node.element);
3073 top = $element.offset().top - this.$el.offset().top;
3074 this.scroll_handler.scrollTo(top);
3075 return this.element;
3078 JqTreeWidget.prototype.getState = function() {
3079 return this.save_state_handler.getState();
3082 JqTreeWidget.prototype.setState = function(state) {
3083 this.save_state_handler.setInitialState(state);
3084 this._refreshElements();
3085 return this.element;
3088 JqTreeWidget.prototype.setOption = function(option, value) {
3089 this.options[option] = value;
3090 return this.element;
3093 JqTreeWidget.prototype.moveDown = function() {
3094 if (this.key_handler) {
3095 this.key_handler.moveDown();
3097 return this.element;
3100 JqTreeWidget.prototype.moveUp = function() {
3101 if (this.key_handler) {
3102 this.key_handler.moveUp();
3104 return this.element;
3107 JqTreeWidget.prototype.getVersion = function() {
3111 JqTreeWidget.prototype._init = function() {
3112 JqTreeWidget.__super__._init.call(this);
3113 this.element = this.$el;
3114 this.mouse_delay = 300;
3115 this.is_initialized = false;
3116 this.options.rtl = this._getRtlOption();
3117 if (!this.options.closedIcon) {
3118 this.options.closedIcon = this._getDefaultClosedIcon();
3120 this.renderer = new ElementsRenderer(this);
3121 if (SaveStateHandler != null) {
3122 this.save_state_handler = new SaveStateHandler(this);
3124 this.options.saveState = false;
3126 if (SelectNodeHandler != null) {
3127 this.select_node_handler = new SelectNodeHandler(this);
3129 if (DragAndDropHandler != null) {
3130 this.dnd_handler = new DragAndDropHandler(this);
3132 this.options.dragAndDrop = false;
3134 if (ScrollHandler != null) {
3135 this.scroll_handler = new ScrollHandler(this);
3137 if ((KeyHandler != null) && (SelectNodeHandler != null)) {
3138 this.key_handler = new KeyHandler(this);
3141 this.element.click($.proxy(this._click, this));
3142 this.element.dblclick($.proxy(this._dblclick, this));
3143 if (this.options.useContextMenu) {
3144 return this.element.bind('contextmenu', $.proxy(this._contextmenu, this));
3148 JqTreeWidget.prototype._deinit = function() {
3149 this.element.empty();
3150 this.element.unbind();
3151 if (this.key_handler) {
3152 this.key_handler.deinit();
3155 return JqTreeWidget.__super__._deinit.call(this);
3158 JqTreeWidget.prototype._initData = function() {
3160 if (this.options.data) {
3161 return this._loadData(this.options.data);
3163 data_url = this._getDataUrlInfo();
3165 return this._loadDataFromUrl();
3167 return this._loadData([]);
3172 JqTreeWidget.prototype._getDataUrlInfo = function(node) {
3173 var data_url, getUrlFromString;
3174 data_url = this.options.dataUrl || this.element.data('url');
3175 getUrlFromString = (function(_this) {
3177 var data, selected_node_id, url_info;
3181 if (node && node.id) {
3185 url_info['data'] = data;
3187 selected_node_id = _this._getNodeIdToBeSelected();
3188 if (selected_node_id) {
3190 selected_node: selected_node_id
3192 url_info['data'] = data;
3198 if ($.isFunction(data_url)) {
3199 return data_url(node);
3200 } else if ($.type(data_url) === 'string') {
3201 return getUrlFromString();
3207 JqTreeWidget.prototype._getNodeIdToBeSelected = function() {
3208 if (this.options.saveState) {
3209 return this.save_state_handler.getNodeIdToBeSelected();
3215 JqTreeWidget.prototype._initTree = function(data) {
3216 var doInit, must_load_on_demand;
3217 doInit = (function(_this) {
3219 if (!_this.is_initialized) {
3220 _this.is_initialized = true;
3221 return _this._triggerEvent('tree.init');
3225 this.tree = new this.options.nodeClass(null, true, this.options.nodeClass);
3226 if (this.select_node_handler) {
3227 this.select_node_handler.clear();
3229 this.tree.loadFromData(data);
3230 must_load_on_demand = this._setInitialState();
3231 this._refreshElements();
3232 if (!must_load_on_demand) {
3235 return this._setInitialStateOnDemand(doInit);
3239 JqTreeWidget.prototype._setInitialState = function() {
3240 var autoOpenNodes, is_restored, must_load_on_demand, ref1, restoreState;
3241 restoreState = (function(_this) {
3243 var must_load_on_demand, state;
3244 if (!(_this.options.saveState && _this.save_state_handler)) {
3245 return [false, false];
3247 state = _this.save_state_handler.getStateFromStorage();
3249 return [false, false];
3251 must_load_on_demand = _this.save_state_handler.setInitialState(state);
3252 return [true, must_load_on_demand];
3257 autoOpenNodes = (function(_this) {
3259 var max_level, must_load_on_demand;
3260 if (_this.options.autoOpen === false) {
3263 max_level = _this._getAutoOpenMaxLevel();
3264 must_load_on_demand = false;
3265 _this.tree.iterate(function(node, level) {
3266 if (node.load_on_demand) {
3267 must_load_on_demand = true;
3269 } else if (!node.hasChildren()) {
3272 node.is_open = true;
3273 return level !== max_level;
3276 return must_load_on_demand;
3279 ref1 = restoreState(), is_restored = ref1[0], must_load_on_demand = ref1[1];
3281 must_load_on_demand = autoOpenNodes();
3283 return must_load_on_demand;
3286 JqTreeWidget.prototype._setInitialStateOnDemand = function(cb_finished) {
3287 var autoOpenNodes, restoreState;
3288 restoreState = (function(_this) {
3291 if (!(_this.options.saveState && _this.save_state_handler)) {
3294 state = _this.save_state_handler.getStateFromStorage();
3298 _this.save_state_handler.setInitialStateOnDemand(state, cb_finished);
3304 autoOpenNodes = (function(_this) {
3306 var loadAndOpenNode, loading_count, max_level, openNodes;
3307 max_level = _this._getAutoOpenMaxLevel();
3309 loadAndOpenNode = function(node) {
3311 return _this._openNode(node, false, function() {
3316 openNodes = function() {
3317 _this.tree.iterate(function(node, level) {
3318 if (node.load_on_demand) {
3319 if (!node.is_loading) {
3320 loadAndOpenNode(node);
3324 _this._openNode(node, false);
3325 return level !== max_level;
3328 if (loading_count === 0) {
3329 return cb_finished();
3335 if (!restoreState()) {
3336 return autoOpenNodes();
3340 JqTreeWidget.prototype._getAutoOpenMaxLevel = function() {
3341 if (this.options.autoOpen === true) {
3344 return parseInt(this.options.autoOpen);
3350 Redraw the tree or part of the tree.
3351 * from_node: redraw this subtree
3354 JqTreeWidget.prototype._refreshElements = function(from_node) {
3355 if (from_node == null) {
3358 this.renderer.render(from_node);
3359 return this._triggerEvent('tree.refresh');
3362 JqTreeWidget.prototype._click = function(e) {
3363 var click_target, event, node;
3364 click_target = this._getClickTarget(e.target);
3366 if (click_target.type === 'button') {
3367 this.toggle(click_target.node, this.options.slide);
3369 return e.stopPropagation();
3370 } else if (click_target.type === 'label') {
3371 node = click_target.node;
3372 event = this._triggerEvent('tree.click', {
3376 if (!event.isDefaultPrevented()) {
3377 return this._selectNode(node, true);
3383 JqTreeWidget.prototype._dblclick = function(e) {
3385 click_target = this._getClickTarget(e.target);
3386 if (click_target && click_target.type === 'label') {
3387 return this._triggerEvent('tree.dblclick', {
3388 node: click_target.node,
3394 JqTreeWidget.prototype._getClickTarget = function(element) {
3395 var $button, $el, $target, node;
3396 $target = $(element);
3397 $button = $target.closest('.jqtree-toggler');
3398 if ($button.length) {
3399 node = this._getNode($button);
3407 $el = $target.closest('.jqtree-element');
3409 node = this._getNode($el);
3421 JqTreeWidget.prototype._getNode = function($element) {
3423 $li = $element.closest('li.jqtree_common');
3424 if ($li.length === 0) {
3427 return $li.data('node');
3431 JqTreeWidget.prototype._getNodeElementForNode = function(node) {
3432 if (node.isFolder()) {
3433 return new FolderElement(node, this);
3435 return new NodeElement(node, this);
3439 JqTreeWidget.prototype._getNodeElement = function($element) {
3441 node = this._getNode($element);
3443 return this._getNodeElementForNode(node);
3449 JqTreeWidget.prototype._contextmenu = function(e) {
3451 $div = $(e.target).closest('ul.jqtree-tree .jqtree-element');
3453 node = this._getNode($div);
3456 e.stopPropagation();
3457 this._triggerEvent('tree.contextmenu', {
3466 JqTreeWidget.prototype._saveState = function() {
3467 if (this.options.saveState) {
3468 return this.save_state_handler.saveState();
3472 JqTreeWidget.prototype._mouseCapture = function(position_info) {
3473 if (this.options.dragAndDrop) {
3474 return this.dnd_handler.mouseCapture(position_info);
3480 JqTreeWidget.prototype._mouseStart = function(position_info) {
3481 if (this.options.dragAndDrop) {
3482 return this.dnd_handler.mouseStart(position_info);
3488 JqTreeWidget.prototype._mouseDrag = function(position_info) {
3490 if (this.options.dragAndDrop) {
3491 result = this.dnd_handler.mouseDrag(position_info);
3492 if (this.scroll_handler) {
3493 this.scroll_handler.checkScrolling();
3501 JqTreeWidget.prototype._mouseStop = function(position_info) {
3502 if (this.options.dragAndDrop) {
3503 return this.dnd_handler.mouseStop(position_info);
3509 JqTreeWidget.prototype._triggerEvent = function(event_name, values) {
3511 event = $.Event(event_name);
3512 $.extend(event, values);
3513 this.element.trigger(event);
3517 JqTreeWidget.prototype.testGenerateHitAreas = function(moving_node) {
3518 this.dnd_handler.current_item = this._getNodeElementForNode(moving_node);
3519 this.dnd_handler.generateHitAreas();
3520 return this.dnd_handler.hit_areas;
3523 JqTreeWidget.prototype._selectCurrentNode = function() {
3524 var node, node_element;
3525 node = this.getSelectedNode();
3527 node_element = this._getNodeElementForNode(node);
3529 return node_element.select();
3534 JqTreeWidget.prototype._deselectCurrentNode = function() {
3536 node = this.getSelectedNode();
3538 return this.removeFromSelection(node);
3542 JqTreeWidget.prototype._getDefaultClosedIcon = function() {
3543 if (this.options.rtl) {
3550 JqTreeWidget.prototype._getRtlOption = function() {
3552 if (this.options.rtl !== null) {
3553 return this.options.rtl;
3555 data_rtl = this.element.data('rtl');
3556 if ((data_rtl != null) && data_rtl !== false) {
3564 JqTreeWidget.prototype._notifyLoading = function(is_loading, node, $el) {
3565 if (this.options.onLoading) {
3566 return this.options.onLoading(is_loading, node, $el);
3570 return JqTreeWidget;
3574 JqTreeWidget.getModule = function(name) {
3577 'node': node_module,
3578 'util': util_module,
3579 'drag_and_drop_handler': drag_and_drop_handler
3581 return modules[name];
3584 SimpleWidget.register(JqTreeWidget, 'tree');
3586 },{"./drag_and_drop_handler":1,"./elements_renderer":2,"./key_handler":3,"./mouse.widget":4,"./node":5,"./node_element":6,"./save_state_handler":7,"./scroll_handler":8,"./select_node_handler":9,"./simple.widget":10,"./util":12,"./version":13}],12:[function(require,module,exports){
3587 var _indexOf, getBoolString, html_escape, indexOf, isFunction, isInt;
3589 _indexOf = function(array, item) {
3590 var i, j, len, value;
3591 for (i = j = 0, len = array.length; j < len; i = ++j) {
3593 if (value === item) {
3600 indexOf = function(array, item) {
3601 if (array.indexOf) {
3602 return array.indexOf(item);
3604 return _indexOf(array, item);
3608 isInt = function(n) {
3609 return typeof n === 'number' && n % 1 === 0;
3612 isFunction = function(v) {
3613 return typeof v === 'function';
3616 html_escape = function(string) {
3617 return ('' + string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g, '/');
3620 getBoolString = function(value) {
3630 getBoolString: getBoolString,
3631 html_escape: html_escape,
3634 isFunction: isFunction
3637 },{}],13:[function(require,module,exports){
3638 module.exports = '1.3.7';