diff --git a/README.md b/README.md
index 527c8f59..d290f7fb 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,6 @@
-[![Travis Status](https://secure.travis-ci.org/mbraak/jqTree.svg)](http://travis-ci.org/mbraak/jqTree) [![Coverage Status](https://img.shields.io/coveralls/mbraak/jqTree.svg)](https://coveralls.io/r/mbraak/jqTree) [![Bower version](https://badge.fury.io/bo/jqtree.svg)](http://badge.fury.io/bo/jqtree)
+[![Travis Status](https://secure.travis-ci.org/mbraak/jqTree.svg)](http://travis-ci.org/mbraak/jqTree) [![Coverage Status](https://img.shields.io/coveralls/mbraak/jqTree.svg)](https://coveralls.io/r/mbraak/jqTree)
+
+[![Bower version](https://badge.fury.io/bo/jqtree.svg)](http://badge.fury.io/bo/jqtree) [![NPM version](https://badge.fury.io/js/jqtree.svg)](http://badge.fury.io/js/jqtree)
#jqTree
diff --git a/build b/build
deleted file mode 100755
index ef323461..00000000
--- a/build
+++ /dev/null
@@ -1,2 +0,0 @@
-# Build and watch coffeescript
-coffee -w -j tree.jquery.js -c src/version.coffee src/simple.widget.coffee src/mouse.widget.coffee src/node.coffee src/elements_renderer.coffee src/tree.jquery.coffee src/save_state_handler.coffee src/select_node_handler.coffee src/drag_and_drop_handler.coffee src/scroll_handler.coffee src/key_handler.coffee
diff --git a/gulpfile.coffee b/gulpfile.coffee
new file mode 100644
index 00000000..ac8e1af8
--- /dev/null
+++ b/gulpfile.coffee
@@ -0,0 +1,27 @@
+gulp = require 'gulp'
+coffee = require 'gulp-coffee'
+coffeeify = require 'gulp-coffeeify'
+exec = require('child_process').exec
+
+gulp.task 'jqtree', ->
+ gulp.src './src/tree.jquery.coffee'
+ .pipe coffeeify()
+ .pipe gulp.dest('./')
+
+gulp.task 'lib', ->
+ gulp.src './src/*.coffee'
+ .pipe coffee(bare: true)
+ .pipe gulp.dest('./lib')
+
+gulp.task 'build_test', ->
+ gulp.src './src/test.js'
+ .pipe coffeeify()
+ .pipe gulp.dest('./test')
+
+gulp.task 'jekyll', (cb) ->
+ exec 'jekyll build', (err, stdout, stderr) ->
+ console.log(stdout)
+ console.log(stderr)
+ cb(err)
+
+gulp.task 'default', ['jqtree', 'build_test', 'lib']
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 00000000..c7f2b8b8
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,2 @@
+require('coffee-script/register');
+require('./gulpfile.coffee');
diff --git a/package.json b/package.json
new file mode 100644
index 00000000..12106d3d
--- /dev/null
+++ b/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "jqtree",
+ "version": "0.22.0",
+ "description": "Tree widget for jQuery",
+ "main": "lib/tree.jquery.js",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/mbraak/jqtree"
+ },
+ "dependencies": {
+ "jquery": ">1.5"
+ },
+ "devDependencies": {
+ "coffee-script": "1.8.0",
+ "gulp": "3.8.8",
+ "gulp-coffee": "2.2.0",
+ "gulp-coffeeify": "0.1.2"
+ }
+}
diff --git a/src/drag_and_drop_handler.coffee b/src/drag_and_drop_handler.coffee
index e6e42e7b..bfa8ebe9 100644
--- a/src/drag_and_drop_handler.coffee
+++ b/src/drag_and_drop_handler.coffee
@@ -1,3 +1,7 @@
+node_module = require './node'
+Position = node_module.Position
+
+
class DragAndDropHandler
constructor: (tree_widget) ->
@tree_widget = tree_widget
@@ -459,52 +463,4 @@ class DragElement
@$element.remove()
-class GhostDropHint
- constructor: (node, $element, position) ->
- @$element = $element
-
- @node = node
- @$ghost = $('
')
-
- if position == Position.AFTER
- @moveAfter()
- else if position == Position.BEFORE
- @moveBefore()
- else if position == Position.INSIDE
- if node.isFolder() and node.is_open
- @moveInsideOpenFolder()
- else
- @moveInside()
-
- remove: ->
- @$ghost.remove()
-
- moveAfter: ->
- @$element.after(@$ghost)
-
- moveBefore: ->
- @$element.before(@$ghost)
-
- moveInsideOpenFolder: ->
- $(@node.children[0].element).before(@$ghost)
-
- moveInside: ->
- @$element.after(@$ghost)
- @$ghost.addClass('jqtree-inside')
-
-
-class BorderDropHint
- constructor: ($element) ->
- $div = $element.children('.jqtree-element')
- width = $element.width() - 4
-
- @$hint = $('')
- $div.append(@$hint)
-
- @$hint.css(
- width: width
- height: $div.height() - 4
- )
-
- remove: ->
- @$hint.remove()
+module.exports = DragAndDropHandler
diff --git a/src/elements_renderer.coffee b/src/elements_renderer.coffee
index 73f78f98..df7f3c01 100644
--- a/src/elements_renderer.coffee
+++ b/src/elements_renderer.coffee
@@ -1,3 +1,10 @@
+node_element = require './node_element'
+NodeElement = node_element.NodeElement
+
+util = require './util'
+html_escape = util.html_escape
+
+
class ElementsRenderer
constructor: (tree_widget) ->
@tree_widget = tree_widget
@@ -192,3 +199,6 @@ class ElementsRenderer
return document.createTextNode(div.innerHTML)
else
return $(value)[0]
+
+
+module.exports = ElementsRenderer
diff --git a/src/key_handler.coffee b/src/key_handler.coffee
index 04c6fbc3..f4ed2c8d 100644
--- a/src/key_handler.coffee
+++ b/src/key_handler.coffee
@@ -117,4 +117,7 @@ class KeyHandler
if not last_child.hasChildren() or not last_child.is_open
return last_child
else
- return @getLastChild(last_child)
\ No newline at end of file
+ return @getLastChild(last_child)
+
+
+module.exports = KeyHandler
diff --git a/src/mouse.widget.coffee b/src/mouse.widget.coffee
index da97e610..6d622649 100644
--- a/src/mouse.widget.coffee
+++ b/src/mouse.widget.coffee
@@ -2,6 +2,9 @@
This widget does the same a the mouse widget in jqueryui.
###
+SimpleWidget = require './simple.widget'
+
+
class MouseWidget extends SimpleWidget
@is_mouse_handled = false
@@ -173,4 +176,6 @@ class MouseWidget extends SimpleWidget
return @_handleMouseUp(
@_getPositionInfo(touch)
- )
\ No newline at end of file
+ )
+
+module.exports = MouseWidget
diff --git a/src/node.coffee b/src/node.coffee
index 01b65618..c09baa2f 100644
--- a/src/node.coffee
+++ b/src/node.coffee
@@ -1,6 +1,3 @@
-@Tree = {}
-$ = @jQuery
-
Position =
getName: (position) ->
return Position.strings[position - 1]
@@ -18,8 +15,6 @@ Position.NONE = 4
Position.strings = ['before', 'after', 'inside', 'none']
-@Tree.Position = Position
-
class Node
constructor: (o, is_root=false, node_class=Node) ->
@setData(o)
@@ -386,4 +381,6 @@ class Node
return result
-@Tree.Node = Node
+module.exports =
+ Node: Node
+ Position: Position
diff --git a/src/node_element.coffee b/src/node_element.coffee
new file mode 100644
index 00000000..489d1a43
--- /dev/null
+++ b/src/node_element.coffee
@@ -0,0 +1,144 @@
+node = require './node'
+Position = node.Position
+
+
+class NodeElement
+ constructor: (node, tree_widget) ->
+ @init(node, tree_widget)
+
+ init: (node, tree_widget) ->
+ @node = node
+ @tree_widget = tree_widget
+
+ if not node.element
+ node.element = @tree_widget.element
+
+ @$element = $(node.element)
+
+ getUl: ->
+ return @$element.children('ul:first')
+
+ getSpan: ->
+ return @$element.children('.jqtree-element').find('span.jqtree-title')
+
+ getLi: ->
+ return @$element
+
+ addDropHint: (position) ->
+ if position == Position.INSIDE
+ return new BorderDropHint(@$element)
+ else
+ return new GhostDropHint(@node, @$element, position)
+
+ select: ->
+ @getLi().addClass('jqtree-selected')
+
+ deselect: ->
+ @getLi().removeClass('jqtree-selected')
+
+
+class FolderElement extends NodeElement
+ open: (on_finished, slide=true) ->
+ if not @node.is_open
+ @node.is_open = true
+ $button = @getButton()
+ $button.removeClass('jqtree-closed')
+ $button.html('')
+ $button.append(@tree_widget.renderer.opened_icon_element.cloneNode())
+
+ doOpen = =>
+ @getLi().removeClass('jqtree-closed')
+ if on_finished
+ on_finished()
+
+ @tree_widget._triggerEvent('tree.open', node: @node)
+
+ if slide
+ @getUl().slideDown('fast', doOpen)
+ else
+ @getUl().show()
+ doOpen()
+
+ close: (slide=true) ->
+ if @node.is_open
+ @node.is_open = false
+ $button = @getButton()
+ $button.addClass('jqtree-closed')
+ $button.html('')
+ $button.append(@tree_widget.renderer.closed_icon_element.cloneNode())
+
+ doClose = =>
+ @getLi().addClass('jqtree-closed')
+
+ @tree_widget._triggerEvent('tree.close', node: @node)
+
+ if slide
+ @getUl().slideUp('fast', doClose)
+ else
+ @getUl().hide()
+ doClose()
+
+ getButton: ->
+ return @$element.children('.jqtree-element').find('a.jqtree-toggler')
+
+ addDropHint: (position) ->
+ if not @node.is_open and position == Position.INSIDE
+ return new BorderDropHint(@$element)
+ else
+ return new GhostDropHint(@node, @$element, position)
+
+
+class BorderDropHint
+ constructor: ($element) ->
+ $div = $element.children('.jqtree-element')
+ width = $element.width() - 4
+
+ @$hint = $('')
+ $div.append(@$hint)
+
+ @$hint.css(
+ width: width
+ height: $div.height() - 4
+ )
+
+ remove: ->
+ @$hint.remove()
+
+
+class GhostDropHint
+ constructor: (node, $element, position) ->
+ @$element = $element
+
+ @node = node
+ @$ghost = $('')
+
+ if position == Position.AFTER
+ @moveAfter()
+ else if position == Position.BEFORE
+ @moveBefore()
+ else if position == Position.INSIDE
+ if node.isFolder() and node.is_open
+ @moveInsideOpenFolder()
+ else
+ @moveInside()
+
+ remove: ->
+ @$ghost.remove()
+
+ moveAfter: ->
+ @$element.after(@$ghost)
+
+ moveBefore: ->
+ @$element.before(@$ghost)
+
+ moveInsideOpenFolder: ->
+ $(@node.children[0].element).before(@$ghost)
+
+ moveInside: ->
+ @$element.after(@$ghost)
+ @$ghost.addClass('jqtree-inside')
+
+
+module.exports =
+ FolderElement: FolderElement
+ NodeElement: NodeElement
diff --git a/src/save_state_handler.coffee b/src/save_state_handler.coffee
index 3375d256..af9ed908 100644
--- a/src/save_state_handler.coffee
+++ b/src/save_state_handler.coffee
@@ -1,106 +1,7 @@
-# Standard javascript indexOf. Implemented here because not all browsers support it.
-_indexOf = (array, item) ->
- for value, i in array
- if value == item
- return i
- return -1
-
-indexOf = (array, item) ->
- if array.indexOf
- # The browser supports indexOf
- return array.indexOf(item)
- else
- # Do our own indexOf
- return _indexOf(array, item)
-
-@Tree.indexOf = indexOf
-@Tree._indexOf = _indexOf
-
-isInt = (n) ->
- return typeof n is 'number' and n % 1 == 0
-
-
-# JSON.stringify function; copied from json2
-get_json_stringify_function = ->
- json_escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g
- json_meta = {
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- }
-
- json_quote = (string) ->
- json_escapable.lastIndex = 0
-
- if json_escapable.test(string)
- return '"' + string.replace(json_escapable, (a) ->
- c = json_meta[a]
- return (
- if typeof c is 'string' then c
- else '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4)
- )
- ) + '"'
- else
- return '"' + string + '"'
-
- json_str = (key, holder) ->
- value = holder[key]
-
- switch typeof value
- when 'string'
- return json_quote(value)
-
- when 'number'
- return if isFinite(value) then String(value) else 'null'
+util = require './util'
- when 'boolean', 'null'
- return String(value)
-
- when 'object'
- if not value
- return 'null'
-
- partial = []
- if Object::toString.apply(value) is '[object Array]'
- for v, i in value
- partial[i] = json_str(i, value) or 'null'
-
- return (
- if partial.length is 0 then '[]'
- else '[' + partial.join(',') + ']'
- )
-
- for k of value
- if Object::hasOwnProperty.call(value, k)
- v = json_str(k, value)
- if v
- partial.push(json_quote(k) + ':' + v)
-
- return (
- if partial.length is 0 then '{}'
- else '{' + partial.join(',') + '}'
- )
-
- stringify = (value) ->
- return json_str(
- '',
- {'': value}
- )
-
- return stringify
-
-
-@Tree.get_json_stringify_function = get_json_stringify_function
-
-if not (@JSON? and @JSON.stringify? and typeof @JSON.stringify == 'function')
- if not @JSON?
- @JSON = {}
-
- @JSON.stringify = get_json_stringify_function()
+indexOf = util.indexOf
+isInt = util.isInt
class SaveStateHandler
@@ -245,3 +146,6 @@ class SaveStateHandler
return state.selected_node[0]
else
return null
+
+
+module.exports = SaveStateHandler
diff --git a/src/scroll_handler.coffee b/src/scroll_handler.coffee
index 13ec1971..57310eea 100644
--- a/src/scroll_handler.coffee
+++ b/src/scroll_handler.coffee
@@ -94,4 +94,7 @@ class ScrollHandler
element_top = $element.offset().top
element_bottom = element_top + $element.height()
- return (element_bottom <= view_bottom) and (element_top >= view_top)
\ No newline at end of file
+ return (element_bottom <= view_bottom) and (element_top >= view_top)
+
+
+module.exports = ScrollHandler
diff --git a/src/select_node_handler.coffee b/src/select_node_handler.coffee
index 7be75168..9f936c91 100644
--- a/src/select_node_handler.coffee
+++ b/src/select_node_handler.coffee
@@ -71,3 +71,6 @@ class SelectNodeHandler
@selected_nodes[node.id] = true
else
@selected_single_node = node
+
+
+module.exports = SelectNodeHandler
diff --git a/src/simple.widget.coffee b/src/simple.widget.coffee
index e0b21d70..cbbdd1bb 100644
--- a/src/simple.widget.coffee
+++ b/src/simple.widget.coffee
@@ -14,9 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
###
-$ = @jQuery
-
-
class SimpleWidget
defaults: {}
@@ -101,4 +98,5 @@ class SimpleWidget
else
return callFunction($el, function_name, args)
-@SimpleWidget = SimpleWidget
+
+module.exports = SimpleWidget
diff --git a/src/test.js b/src/test.js
new file mode 100644
index 00000000..e9a42936
--- /dev/null
+++ b/src/test.js
@@ -0,0 +1,1871 @@
+var node = require('./node')
+var Node = node.Node;
+var Position = node.Position;
+
+var util = require('./util')
+_indexOf = util._indexOf
+indexOf = util.indexOf
+get_json_stringify_function = util.get_json_stringify_function
+
+QUnit.config.testTimeout = 5000;
+
+/*
+example data:
+
+node1
+---child1
+---child2
+-node2
+---child3
+*/
+
+var example_data = [
+ {
+ label: 'node1',
+ id: 123, // extra data
+ children: [
+ { label: 'child1', id: 125 },
+ { label: 'child2', id: 126 }
+ ]
+ },
+ {
+ label: 'node2',
+ id: 124,
+ children: [
+ { label: 'child3', id: 127 }
+ ]
+ }
+
+];
+
+/*
+example data 2:
+
+-main
+---c1
+---c2
+*/
+
+var example_data2 = [
+ {
+ label: 'main',
+ children: [
+ { label: 'c1' },
+ { label: 'c2' }
+ ]
+ }
+];
+
+function formatNodes(nodes) {
+ var strings = $.map(nodes, function(node) {
+ return node.name;
+ });
+ return strings.join(' ');
+};
+
+function isNodeClosed($node) {
+ return (
+ ($node.is('li.jqtree-folder.jqtree-closed')) &&
+ ($node.find('a:eq(0)').is('a.jqtree-toggler.jqtree-closed')) &&
+ ($node.find('ul:eq(0)').is('ul'))
+ );
+}
+
+function isNodeOpen($node) {
+ return (
+ ($node.is('li.jqtree-folder')) &&
+ ($node.find('a:eq(0)').is('a.jqtree-toggler')) &&
+ ($node.find('ul:eq(0)').is('ul')) &&
+ (! $node.is('li.jqtree-folder.jqtree-closed')) &&
+ (! $node.find('span:eq(0)').is('a.jqtree-toggler.jqtree-closed'))
+ );
+}
+
+function formatTitles($node) {
+ var titles = $node.find('.jqtree-title').map(
+ function(i, el) {
+ return $(el).text();
+ }
+ );
+ return titles.toArray().join(' ');
+}
+
+
+QUnit.module("jqtree", {
+ setup: function() {
+ $('body').append('');
+ },
+
+ teardown: function() {
+ var $tree = $('#tree1');
+ $tree.tree('destroy');
+ $tree.remove();
+ }
+});
+
+test("create jqtree from data", function() {
+ $('#tree1').tree({
+ data: example_data
+ });
+
+ equal(
+ $('#tree1').children().length, 1,
+ 'number of children on level 0'
+ );
+ ok(
+ $('#tree1').children().is('ul.jqtree-tree'),
+ 'first element is ul.jqtree-tree'
+ );
+ equal(
+ $('#tree1 ul.jqtree-tree > li').length, 2,
+ 'number of children on level 1'
+ );
+ ok(
+ $('#tree1 ul.jqtree-tree li:eq(0)').is('li.jqtree-folder.jqtree-closed'),
+ 'first child is li.jqtree-folder.jqtree-closed'
+ );
+ ok(
+ $('#tree1 ul.jqtree-tree li:eq(0) > .jqtree-element > a.jqtree-toggler').is('a.jqtree-toggler.jqtree-closed'),
+ 'button in first folder'
+ );
+ equal(
+ $('#tree1 ul.jqtree-tree li:eq(0) > .jqtree-element span.jqtree-title').text(),
+ 'node1'
+ );
+});
+
+test('toggle', function() {
+ // create tree
+ var $tree = $('#tree1');
+ var $node1;
+ var node1;
+
+ $tree.tree({
+ data: example_data
+ });
+
+ $tree.bind(
+ 'tree.open',
+ function(e) {
+ start();
+
+ ok(! isNodeClosed($node1), 'node1 is open');
+
+ // 2. close node1
+ $tree.tree('toggle', node1);
+
+ stop();
+ }
+ );
+
+ $tree.bind(
+ 'tree.close',
+ function(e) {
+ start();
+
+ ok(isNodeClosed($node1), 'node1 is closed');
+ }
+ );
+
+ var tree = $tree.tree('getTree');
+ node1 = tree.children[0];
+ $node1 = $tree.find('ul.jqtree-tree li:eq(0)');
+
+ // node1 is initially closed
+ ok(isNodeClosed($node1), 'node1 is closed');
+
+ // 1. open node1
+ $tree.tree('toggle', node1);
+
+ stop();
+});
+
+test("click event", function() {
+ stop();
+
+ // create tree
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data,
+ selectable: true
+ });
+
+ $tree.bind('tree.click', function(e) {
+ equal(e.node.name, 'node1');
+ });
+
+ $tree.bind('tree.select', function(e) {
+ start();
+ equal(e.node.name, 'node1');
+ });
+
+ // click on node1
+ var $node1 = $tree.find('ul.jqtree-tree li:first');
+ var $text_span = $node1.find('span:first');
+ $text_span.click();
+});
+
+test('saveState', function() {
+ var $tree = $('#tree1');
+
+ var saved_state;
+
+ function setState(state) {
+ saved_state = state;
+ }
+
+ function getState() {
+ return saved_state;
+ }
+
+ function createTree() {
+ $tree.tree({
+ data: example_data,
+ saveState: true,
+ onSetStateFromStorage: setState,
+ onGetStateFromStorage: getState,
+ selectable: true
+ });
+ }
+
+ // create tree
+ createTree();
+
+ // nodes are initially closed
+ var tree = $tree.tree('getTree');
+ tree.iterate(function(node) {
+ ok(! node.is_open, 'jqtree-closed');
+ return true;
+ });
+
+ // open node1
+ $tree.tree('toggle', tree.children[0]);
+
+ // node1 is open
+ ok(tree.children[0].is_open, 'node1 is_open');
+
+ // select node2
+ $tree.tree('selectNode', tree.children[1]);
+
+ // node2 is selected
+ equal(
+ $tree.tree('getSelectedNode').name,
+ 'node2',
+ 'getSelectedNode (1)'
+ );
+
+ // create tree again
+ $tree.tree('destroy');
+ createTree();
+
+ tree = $tree.tree('getTree');
+ ok(tree.children[0].is_open, 'node1 is_open');
+ ok(! tree.children[1].is_open, 'node2 is closed');
+
+ // node2 is selected
+ equal(
+ $tree.tree('getSelectedNode').name,
+ 'node2',
+ 'getSelectedNode (2)'
+ );
+});
+
+test('getSelectedNode', function() {
+ var $tree = $('#tree1');
+
+ // create tree
+ $tree.tree({
+ data: example_data,
+ selectable: true
+ });
+
+ // there is no node selected
+ equal(
+ $tree.tree('getSelectedNode'),
+ false,
+ 'getSelectedNode'
+ );
+
+ // select node1
+ var tree = $tree.tree('getTree');
+ var node1 = tree.children[0];
+ $tree.tree('selectNode', node1);
+
+ // node1 is selected
+ equal(
+ $tree.tree('getSelectedNode').name,
+ 'node1',
+ 'getSelectedNode'
+ );
+});
+
+test("toJson", function() {
+ // setup
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data
+ });
+
+ // 1. call toJson
+ equal(
+ $tree.tree('toJson'),
+ '[{"name":"node1","id":123,"children":'+
+ '[{"name":"child1","id":125},{"name":"child2","id":126}]},'+
+ '{"name":"node2","id":124,"children":[{"name":"child3","id":127}]}]'
+ );
+
+ // Check that properties 'children', 'parent' and 'element' still exist.
+ var tree = $tree.tree('getTree');
+ equal(tree.children.length, 2);
+ ok(tree.children[0].parent != undefined, 'parent');
+ ok($(tree.children[0].element).is('li'), 'element');
+});
+
+test('loadData', function() {
+ // setup
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data,
+ autoOpen: true
+ });
+
+ // first node is 'node1'
+ equal(
+ $tree.find('> ul > li:first .jqtree-element:first > span').text(),
+ 'node1'
+ );
+
+ // - load new data
+ $tree.tree('loadData', example_data2);
+
+ // first node is 'main'
+ equal(
+ $tree.find('> ul > li:first .jqtree-element:first > span').text(),
+ 'main'
+ );
+
+ // - load new data under node 'child3'
+ $tree.tree('loadData', example_data);
+
+ var child3 = $tree.tree('getNodeByName', 'child3');
+
+ var data = [
+ { label: 'c4', id: 200 },
+ {
+ label: 'c5', id: 201,
+ children: [
+ { label: 'c6', id: 202 }
+ ]
+ }
+ ];
+ $tree.tree('loadData', data, child3);
+
+ // first node in html is still 'node1'
+ equal(
+ $tree.find('li:eq(0)').find('.jqtree-element:eq(0) span.jqtree-title').text(),
+ 'node1'
+ );
+
+ // Node 'child3' now has a children 'c4' and 'c5'
+ var $child3 = $tree.find('span:contains(child3)');
+ var $li = $child3.closest('li');
+ equal(
+ $li.children('ul').children('li:eq(0)').find('.jqtree-element span.jqtree-title').text(),
+ 'c4'
+ );
+
+ // Node 'child3' must have toggler button
+ ok($child3.prev().is('a.jqtree-toggler'));
+
+ // - select node 'c5' and load new data under 'child3'
+ var c5 = $tree.tree('getNodeByName', 'c5');
+ $tree.tree('selectNode', c5);
+
+ equal($tree.tree('getSelectedNode').name, 'c5');
+
+ var data2 = [
+ { label: 'c7' },
+ { label: 'c8' }
+ ];
+ $tree.tree('loadData', data2, child3);
+
+ // c5 must be deselected
+ equal($tree.tree('getSelectedNode'), false);
+
+ // - select c7; load new data under child3; note that c7 has no id
+ $tree.tree('selectNode', $tree.tree('getNodeByName', 'c7'));
+
+ equal($tree.tree('getSelectedNode').name, 'c7');
+
+ $tree.tree('loadData', [ 'c9' ], child3);
+
+ equal($tree.tree('getSelectedNode'), false);
+
+ // - select c9 (which has no id); load new nodes under child2
+ $tree.tree('selectNode', $tree.tree('getNodeByName', 'c9'));
+
+ var child2 = $tree.tree('getNodeByName', 'child2');
+ $tree.tree('loadData', [ 'c10' ], child2);
+
+ equal($tree.tree('getSelectedNode').name, 'c9');
+});
+
+test('openNode and closeNode', function() {
+ // setup
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data
+ });
+
+ var node2 = $tree.tree('getNodeByName', 'node2');
+ equal(node2.name, 'node2');
+ equal(node2.is_open, undefined);
+
+ // 1. open node2
+ $tree.tree('openNode', node2, false);
+ equal(node2.is_open, true);
+ equal(isNodeOpen($(node2.element)), true);
+
+ // 2. close node2
+ $tree.tree('closeNode', node2, false);
+ equal(node2.is_open, false);
+ equal(isNodeClosed($(node2.element)), true);
+
+ // 3. open child1
+ var node1 = $tree.tree('getNodeByName', 'node1');
+ var child1 = $tree.tree('getNodeByName', 'child1');
+
+ // add a child to child1 so it is a folder
+ $tree.tree('appendNode', 'child1a', child1);
+
+ // node1 is initialy closed
+ equal(node1.is_open, undefined);
+
+ // open child1
+ $tree.tree('openNode', child1, false);
+
+ // node1 and child1 are now open1
+ equal(node1.is_open, true);
+ equal(child1.is_open, true);
+});
+
+test('selectNode', function() {
+ // setup
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data,
+ selectable: true
+ });
+
+ var node1 = $tree.tree('getTree').children[0];
+ var node2 = $tree.tree('getTree').children[1];
+ var child3 = node2.children[0];
+
+ equal(child3.name, 'child3');
+ equal(node1.is_open, undefined);
+ equal(node2.is_open, undefined);
+ equal(child3.is_open, undefined);
+
+ // -- select node 'child3', which is a child of 'node2'; must_open_parents = true
+ $tree.tree('selectNode', child3, true);
+ equal($tree.tree('getSelectedNode').name, 'child3');
+
+ equal(node1.is_open, undefined);
+ equal(node2.is_open, true);
+ equal(child3.is_open, undefined);
+
+ // -- select node 'node1'
+ $tree.tree('selectNode', node1);
+ equal($tree.tree('getSelectedNode').name, 'node1');
+
+ // -- is 'node1' selected?
+ ok($tree.tree('isNodeSelected', node1));
+});
+
+test('selectNode when another node is selected', function() {
+ // setup
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data,
+ selectable: true
+ });
+
+ var node1 = $tree.tree('getTree').children[0];
+ var node2 = $tree.tree('getTree').children[1];
+
+
+ // -- select node 'node2'
+ $tree.tree('selectNode', node2);
+ equal($tree.tree('getSelectedNode').name, 'node2');
+
+ // -- setting event
+ // -- is node 'node2' named 'deselected_node' in object's attributes?
+ stop();
+ $tree.bind('tree.select', function(e) {
+ start();
+ equal(e.deselected_node, node2);
+ });
+
+ // -- select node 'node1'; node 'node2' is selected before it
+ $tree.tree('selectNode', node1);
+ equal($tree.tree('getSelectedNode').name, 'node1');
+
+ ok($tree.tree('isNodeSelected', node1));
+});
+
+test('click toggler', function() {
+ // setup
+ stop();
+
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data,
+ selectable: true
+ });
+
+ var $title = $tree.find('li:eq(0)').find('> .jqtree-element > span.jqtree-title');
+ equal($title.text(), 'node1');
+ var $toggler = $title.prev();
+ ok($toggler.is('a.jqtree-toggler.jqtree-closed'));
+
+ $tree.bind('tree.open', function(e) {
+ // 2. handle 'open' event
+ start();
+ equal(e.node.name, 'node1');
+ stop();
+
+ // 3. click toggler again
+ $toggler.click();
+ });
+
+ $tree.bind('tree.close', function(e) {
+ start();
+ equal(e.node.name, 'node1');
+ });
+
+ // 1. click toggler of 'node1'
+ $toggler.click();
+});
+
+test('getNodeById', function() {
+ // setup
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data
+ });
+ var node2 = $tree.tree('getNodeByName', 'node2');
+
+ // 1. get 'node2' by id
+ equal(
+ $tree.tree('getNodeById', 124).name,
+ 'node2'
+ );
+
+ // 2. get id that does not exist
+ equal($tree.tree('getNodeById', 333), null);
+
+ // 3. get id by string
+ equal(
+ $tree.tree('getNodeById', '124').name,
+ 'node2'
+ );
+
+ // 4. add node with string id; search by int
+ $tree.tree(
+ 'appendNode',
+ {
+ label: 'abc',
+ id: '234'
+ }
+ );
+
+ equal(
+ $tree.tree('getNodeById', 234).name,
+ 'abc'
+ );
+ equal(
+ $tree.tree('getNodeById', '234').name,
+ 'abc'
+ );
+
+ // 5. load subtree in node2
+ var subtree_data = [
+ {
+ label: 'sub1',
+ id: 200,
+ children: [
+ {label: 'sub2', id: 201}
+ ]
+ }
+ ];
+ $tree.tree('loadData', subtree_data, node2);
+ var t = $tree.tree('getTree');
+
+ equal(
+ $tree.tree('getNodeById', 200).name,
+ 'sub1'
+ );
+ equal(
+ $tree.tree('getNodeById', 201).name,
+ 'sub2'
+ );
+});
+
+test('autoOpen', function() {
+ var $tree = $('#tree1');
+
+ function formatOpenFolders() {
+ var open_nodes = [];
+ $tree.find('li').each(function() {
+ var $li = $(this);
+ if ($li.is('.jqtree-folder') && ! $li.is('.jqtree-closed')) {
+ var label = $li.children('.jqtree-element').find('span').text();
+ open_nodes.push(label);
+ };
+ });
+
+ return open_nodes.join(';');
+ }
+
+ /*
+ -l1n1 (level 0)
+ ----l2n1 (1)
+ ----l2n2 (1)
+ -------l3n1 (2)
+ ----------l4n1 (3)
+ -l1n2
+ */
+ var data = [
+ {
+ label: 'l1n1',
+ children: [
+ 'l2n1',
+ {
+ label: 'l2n2',
+ children: [
+ {
+ label: 'l3n1',
+ children: [
+ 'l4n1'
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ 'l1n2'
+ ];
+
+ // 1. autoOpen is false
+ $tree.tree({
+ data: data,
+ autoOpen: false
+ });
+ equal(formatOpenFolders(), '');
+
+ $tree.tree('destroy');
+
+ // 2. autoOpen is true
+ $tree.tree({
+ data: data,
+ autoOpen: true
+ });
+ equal(formatOpenFolders(), 'l1n1;l2n2;l3n1');
+
+ $tree.tree('destroy');
+
+ // 3. autoOpen level 1
+ $tree.tree({
+ data: data,
+ autoOpen: 1
+ });
+ equal(formatOpenFolders(), 'l1n1;l2n2');
+});
+
+test('onCreateLi', function() {
+ // 1. init tree with onCreateLi
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data,
+ onCreateLi: function(node, $li) {
+ var $span = $li.children('.jqtree-element').find('span');
+ $span.html('_' + node.name + '_');
+ }
+ });
+
+ equal(
+ $tree.find('span:eq(0)').text(),
+ '_node1_'
+ );
+});
+
+test('save state', function() {
+ // setup
+ var state = null;
+
+ // Fake $.cookie plugin for browsers that do not support localstorage
+ $.cookie = function(key, param2, param3) {
+ if (typeof param3 == 'object') {
+ // set
+ state = param2;
+ }
+ else {
+ // get
+ return state;
+ }
+ }
+
+ // Remove state from localstorage
+ if (typeof localStorage != 'undefined') {
+ localStorage.setItem('my_tree', null);
+ }
+
+ // 1. init tree
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data,
+ selectable: true,
+ saveState: 'my_tree'
+ });
+
+ var tree = $tree.tree('getTree');
+ equal($tree.tree('getSelectedNode'), false);
+
+ // 2. select node -> state is saved
+ $tree.tree('selectNode', tree.children[0]);
+ equal($tree.tree('getSelectedNode').name, 'node1');
+
+ // 3. init tree again
+ $tree.tree('destroy');
+
+ $tree.tree({
+ data: example_data,
+ selectable: true,
+ saveState: 'my_tree'
+ });
+
+ equal($tree.tree('getSelectedNode').name, 'node1');
+
+ $.cookie = null;
+});
+
+test('generate hit areas', function() {
+ // setup
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data
+ });
+
+ // 1. get hit areas
+ var node = $tree.tree('getNodeById', 123);
+ var hit_areas = $tree.tree('testGenerateHitAreas', node);
+
+ var strings = $.map(hit_areas, function(hit_area) {
+ return hit_area.node.name + ' ' + Position.getName(hit_area.position);
+ });
+ equal(strings.join(';'), 'node1 none;node2 inside;node2 after');
+});
+
+test('removeNode', function() {
+ // setup
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data,
+ selectable: true
+ });
+
+ // 1. Remove selected node; node is 'child1'
+ var child1 = $tree.tree('getNodeByName', 'child1');
+ $tree.tree('selectNode', child1);
+
+ equal($tree.tree('getSelectedNode').name, 'child1');
+
+ $tree.tree('removeNode', child1);
+
+ equal(
+ formatTitles($tree),
+ 'node1 child2 node2 child3'
+ );
+
+ // getSelectedNode must now return false
+ equal($tree.tree('getSelectedNode'), false);
+
+ // 2. No node is selected; remove child3
+ $tree.tree('loadData', example_data);
+
+ var child3 = $tree.tree('getNodeByName', 'child3');
+ $tree.tree('removeNode', child3);
+
+ equal(
+ formatTitles($tree),
+ 'node1 child1 child2 node2'
+ );
+
+ equal($tree.tree('getSelectedNode'), false);
+
+ // 3. Remove parent of selected node
+ $tree.tree('loadData', example_data);
+
+ child1 = $tree.tree('getNodeByName', 'child1');
+ var node1 = $tree.tree('getNodeByName', 'node1');
+
+ $tree.tree('selectNode', child1);
+
+ $tree.tree('removeNode', node1);
+
+ // node is unselected
+ equal($tree.tree('getSelectedNode'), false);
+
+ // 4. Remove unselected node without an id
+ $tree.tree('loadData', example_data2);
+
+ var c1 = $tree.tree('getNodeByName', 'c1');
+
+ $tree.tree('removeNode', c1);
+
+ equal(
+ formatTitles($tree),
+ 'main c2'
+ )
+});
+
+test('appendNode', function() {
+ // setup
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data
+ });
+
+ var node1 = $tree.tree('getNodeByName', 'node1');
+
+ // 1. Add child3 to node1
+ $tree.tree('appendNode', 'child3', node1);
+
+ equal(
+ formatTitles($(node1.element)),
+ 'node1 child1 child2 child3'
+ );
+
+ // 2. Add child4 to child1
+ var child1 = $tree.tree('getNodeByName', 'child1');
+
+ // Node 'child1' does not have a toggler button
+ equal(
+ $(child1.element).find('> .jqtree-element > .jqtree-toggler').length,
+ 0
+ );
+
+ $tree.tree('appendNode', 'child4', child1);
+
+ equal(formatTitles($(child1.element)), 'child1 child4');
+
+ // Node 'child1' must get a toggler button
+ equal(
+ $(child1.element).find('> .jqtree-element > .jqtree-toggler').length,
+ 1
+ );
+});
+
+test('prependNode', function() {
+ // setup
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data
+ });
+
+ var node1 = $tree.tree('getNodeByName', 'node1');
+
+ // 1. Prepend child0 to node1
+ $tree.tree('prependNode', 'child0', node1);
+
+ equal(
+ formatTitles($(node1.element)),
+ 'node1 child0 child1 child2'
+ );
+});
+test('init event', function() {
+ // setup
+ var $tree = $('#tree1');
+
+ $tree.bind('tree.init', function() {
+ start();
+
+ // Check that we can call functions in 'tree.init' event
+ equal($tree.tree('getNodeByName', 'node2').name, 'node2');
+ });
+ stop();
+
+ $tree.tree({
+ data: example_data
+ });
+});
+
+test('updateNode', function() {
+ // setup
+ var $tree = $('#tree1');
+
+ $tree.tree({ data: example_data });
+
+ equal(formatTitles($tree), 'node1 child1 child2 node2 child3');
+
+ // -- update label
+ var node2 = $tree.tree('getNodeByName', 'node2');
+ $tree.tree('updateNode', node2, 'CHANGED');
+
+ equal(formatTitles($tree), 'node1 child1 child2 CHANGED child3');
+ equal(node2.name, 'CHANGED');
+
+ // -- update data
+ $tree.tree(
+ 'updateNode',
+ node2,
+ {
+ name: 'xyz',
+ tag1: 'abc'
+ }
+ );
+
+ equal(formatTitles($tree), 'node1 child1 child2 xyz child3');
+ equal(node2.name, 'xyz');
+ equal(node2.tag1, 'abc');
+
+ // - update id
+ equal(node2.id, 124);
+
+ $tree.tree('updateNode', node2, {id: 555});
+
+ equal(node2.id, 555);
+ equal(node2.name, 'xyz');
+
+ // get node by id
+ var node_555 = $tree.tree('getNodeById', 555);
+ equal(node_555.name, 'xyz');
+
+ var node_124 = $tree.tree('getNodeById', 124);
+ equal(node_124, undefined);
+
+ // update child1
+ var child1 = $tree.tree('getNodeByName', 'child1');
+
+ $tree.tree('updateNode', child1, 'child1a');
+
+ equal(formatTitles($tree), 'node1 child1a child2 xyz child3');
+
+ // select child1
+ $tree.tree('selectNode', child1);
+ $tree.tree('updateNode', child1, 'child1b');
+
+ ok($(child1.element).hasClass('jqtree-selected'));
+});
+
+test('moveNode', function() {
+ // setup
+ var $tree = $('#tree1');
+
+ $tree.tree({ data: example_data });
+
+ var child1 = $tree.tree('getNodeByName', 'child1');
+ var child2 = $tree.tree('getNodeByName', 'child2');
+ var node1 = $tree.tree('getNodeByName', 'node1');
+ var node2 = $tree.tree('getNodeByName', 'node2');
+
+ // -- Move child1 after node2
+ $tree.tree('moveNode', child1, node2, 'after');
+
+ equal(formatTitles($tree), 'node1 child2 node2 child3 child1');
+
+ // -- Check that illegal moves are skipped
+ $tree.tree('moveNode', node1, child2, 'inside');
+});
+
+test('load on demand', function() {
+ // setup
+ var $tree = $('#tree1');
+
+ $tree.tree({
+ data: [
+ {
+ id: 1,
+ label: 'node1',
+ load_on_demand: true
+ }
+ ],
+ dataUrl: '/tree/'
+ });
+
+ $.mockjax({
+ url: '*',
+ response: function(options) {
+ equal(options.url, '/tree/', '2');
+ deepEqual(options.data, { 'node' : 1 }, '3')
+
+ this.responseText = [
+ {
+ id: 2,
+ label: 'child1'
+ }
+ ];
+ },
+ logging: false
+ });
+
+ // -- open node
+ $tree.bind('tree.refresh', function(e) {
+ start();
+
+ equal(formatTitles($tree), 'node1 child1', '4');
+ });
+
+ var node1 = $tree.tree('getNodeByName', 'node1');
+ equal(formatTitles($tree), 'node1', '1');
+
+ $tree.tree('openNode', node1, true);
+
+ stop();
+});
+
+test('addNodeAfter', function() {
+ // setup
+ var $tree = $('#tree1');
+
+ $tree.tree({ data: example_data });
+ var node1 = $tree.tree('getNodeByName', 'node1');
+
+ // -- add node after node1
+ $tree.tree('addNodeAfter', 'node3', node1);
+
+ equal(formatTitles($tree), 'node1 child1 child2 node3 node2 child3');
+});
+
+test('addNodeBefore', function() {
+ // setup
+ var $tree = $('#tree1');
+
+ $tree.tree({ data: example_data });
+ var node1 = $tree.tree('getNodeByName', 'node1');
+
+ // -- add node before node1
+ var new_node = $tree.tree('addNodeBefore', 'node3', node1);
+
+ equal(formatTitles($tree), 'node3 node1 child1 child2 node2 child3');
+});
+
+test('addParentNode', function() {
+ // setup
+ var $tree = $('#tree1');
+
+ $tree.tree({ data: example_data });
+ var child3 = $tree.tree('getNodeByName', 'child3');
+
+ // -- add parent to child3
+ $tree.tree('addParentNode', 'node3', child3);
+
+ equal(formatTitles($tree), 'node1 child1 child2 node2 node3 child3');
+});
+
+test('mouse events', function() {
+ // setup
+ var $tree = $('#tree1');
+ $tree.tree({
+ data: example_data,
+ dragAndDrop: true,
+ autoOpen: true
+ });
+ $tree.tree('setMouseDelay', 0);
+
+ function getTitleElement(node_name) {
+ var node = $tree.tree('getNodeByName', node_name);
+ var $el = $(node.element);
+ return $($el.find('.jqtree-title'));
+ }
+
+ var $node1 = getTitleElement('node1');
+ var $child3 = getTitleElement('child3');
+
+ // Move node1 inside child3
+ // trigger mousedown event on node1
+ $node1.trigger(
+ $.Event('mousedown', { which: 1 })
+ );
+
+ // trigger mouse move to child3
+ var child3_offset = $child3.offset();
+ $tree.trigger(
+ $.Event('mousemove', { pageX: child3_offset.left, pageY: child3_offset.top })
+ );
+ $tree.trigger('mouseup');
+
+ equal(
+ formatTitles($tree),
+ 'node2 child3 node1 child1 child2'
+ );
+});
+
+test('multiple select', function() {
+ // setup
+ var $tree = $('#tree1');
+ $tree.tree({ data: example_data });
+
+ var child1 = $tree.tree('getNodeByName', 'child1');
+ var child2 = $tree.tree('getNodeByName', 'child2');
+
+ // -- add nodes to selection
+ // todo: more nodes as parameters?
+ // todo: rename to 'selection.add' or 'selection' 'add'?
+ $tree.tree('addToSelection', child1);
+ $tree.tree('addToSelection', child2);
+
+ // -- get selected nodes
+ var selected_nodes = $tree.tree('getSelectedNodes');
+ equal(
+ formatNodes(selected_nodes),
+ 'child1 child2'
+ );
+});
+
+test('keyboard', function() {
+ // setup
+ var $tree = $('#tree1');
+
+ function keyDown(key) {
+ $tree.trigger(
+ $.Event('keydown', { which: key })
+ );
+ }
+
+ $tree.tree({ data: example_data });
+
+ var node1 = $tree.tree('getNodeByName', 'node1');
+
+ // select node1
+ $tree.tree('selectNode', node1);
+ equal(node1.is_open, undefined);
+
+ // - move down; -> node2
+ keyDown(40);
+ equal($tree.tree('getSelectedNode').name, 'node2');
+
+ // - move up; -> back to node1
+ keyDown(38);
+ equal($tree.tree('getSelectedNode').name, 'node1');
+
+ // - move right; open node1
+ keyDown(39);
+ equal(node1.is_open, true);
+ equal($tree.tree('getSelectedNode').name, 'node1');
+
+ // - select child3 and move up -> node2
+ $tree.tree('selectNode', $tree.tree('getNodeByName', 'child3'));
+ keyDown(38);
+ equal($tree.tree('getSelectedNode').name, 'node2');
+
+ // - move up -> child2
+ keyDown(38);
+ equal($tree.tree('getSelectedNode').name, 'child2');
+
+ // - select node1 and move left -> close
+ $tree.tree('selectNode', node1);
+ keyDown(37);
+ equal(node1.is_open, false);
+ equal($tree.tree('getSelectedNode').name, 'node1');
+});
+
+QUnit.module("Tree");
+test('constructor', function() {
+ // 1. Create node from string
+ var node = new Node('n1');
+
+ equal(node.name, 'n1');
+ equal(node.children.length, 0);
+ equal(node.parent, null);
+
+ // 2. Create node from object
+ node = new Node({
+ label: 'n2',
+ id: 123,
+ parent: 'abc', // parent must be ignored
+ children: ['c'], // children must be ignored
+ url: '/'
+ });
+
+ equal(node.name, 'n2');
+ equal(node.id, 123);
+ equal(node.url, '/');
+ equal(node.label, undefined);
+ equal(node.children.length, 0);
+ equal(node.parent, null);
+});
+
+test("create tree from data", function() {
+ function checkData(tree) {
+ equal(
+ formatNodes(tree.children),
+ 'node1 node2',
+ 'nodes on level 1'
+ );
+ equal(
+ formatNodes(tree.children[0].children),
+ 'child1 child2',
+ 'children of node1'
+ );
+ equal(
+ formatNodes(tree.children[1].children),
+ 'child3',
+ 'children of node2'
+ );
+ equal(
+ tree.children[0].id,
+ 123,
+ 'id'
+ );
+ }
+
+ // - create tree from example data
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+ checkData(tree);
+
+ // - create tree from new data format
+ var data = [
+ {
+ label: 'node1',
+ id: 123,
+ children: ['child1', 'child2'] // nodes are only defined by a string
+ },
+ {
+ label: 'node2',
+ id: 124,
+ children: ['child3']
+ }
+ ];
+ var tree = new Node(null, true);
+ tree.loadFromData(data);
+ checkData(tree);
+});
+
+test("addChild", function() {
+ var tree = new Node('tree1', true);
+ tree.addChild(
+ new Node('abc')
+ );
+ tree.addChild(
+ new Node('def')
+ );
+
+ equal(
+ formatNodes(tree.children),
+ 'abc def',
+ 'children'
+ );
+
+ var node = tree.children[0];
+ equal(
+ node.parent.name,
+ 'tree1',
+ 'parent of node'
+ );
+});
+
+test('addChildAtPosition', function() {
+ var tree = new Node(null, true);
+ tree.addChildAtPosition(new Node('abc'), 0); // first
+ tree.addChildAtPosition(new Node('ghi'), 2); // index 2 does not exist
+ tree.addChildAtPosition(new Node('def'), 1);
+ tree.addChildAtPosition(new Node('123'), 0);
+
+ equal(
+ formatNodes(tree.children),
+ '123 abc def ghi',
+ 'children'
+ );
+});
+
+test('removeChild', function() {
+ var tree = new Node(null, true);
+
+ var abc = new Node({'label': 'abc', 'id': 1});
+ var def = new Node({'label': 'def', 'id': 2});
+ var ghi = new Node({'label': 'ghi', 'id': 3});
+
+ tree.addChild(abc);
+ tree.addChild(def);
+ tree.addChild(ghi);
+
+ var jkl = new Node({'label': 'jkl', 'id': 4});
+ def.addChild(jkl);
+
+ equal(
+ formatNodes(tree.children),
+ 'abc def ghi',
+ 'children'
+ );
+
+ equal(tree.id_mapping[2].name, 'def');
+ equal(tree.id_mapping[4].name, 'jkl');
+
+ // remove 'def'
+ tree.removeChild(def);
+ equal(
+ formatNodes(tree.children),
+ 'abc ghi',
+ 'children'
+ );
+
+ equal(tree.id_mapping[2], null);
+ equal(tree.id_mapping[4], null);
+
+ // remove 'ghi'
+ tree.removeChild(ghi);
+ equal(
+ formatNodes(tree.children),
+ 'abc',
+ 'children'
+ );
+
+ // remove 'abc'
+ tree.removeChild(abc);
+ equal(
+ formatNodes(tree.children),
+ '',
+ 'children'
+ );
+});
+
+test('getChildIndex', function() {
+ // setup
+ var tree = new Node(null, true);
+
+ var abc = new Node('abc');
+ var def = new Node('def');
+ var ghi = new Node('ghi');
+ tree.addChild(abc);
+ tree.addChild(def);
+ tree.addChild(ghi);
+
+ // 1. Get child index of 'def'
+ equal(tree.getChildIndex(def), 1);
+
+ // 2. Get child index of non-existing node
+ equal(tree.getChildIndex(new Node('xyz')), -1);
+});
+
+test('hasChildren', function() {
+ var tree = new Node(null, true);
+ equal(
+ tree.hasChildren(),
+ false,
+ 'tree without children'
+ );
+
+ tree.addChild(new Node('abc'));
+ equal(
+ tree.hasChildren(),
+ true,
+ 'tree has children'
+ );
+});
+
+test('iterate', function() {
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+
+ // iterate over all the nodes
+ var nodes = [];
+ tree.iterate(
+ function(node, level) {
+ nodes.push(node);
+ return true;
+ }
+ );
+
+ equal(
+ formatNodes(nodes),
+ 'node1 child1 child2 node2 child3',
+ 'all nodes'
+ );
+
+ // iterate over nodes on first level
+ nodes = [];
+ tree.iterate(
+ function(node, level) {
+ nodes.push(node);
+ return false;
+ }
+ );
+
+ equal(
+ formatNodes(nodes),
+ 'node1 node2',
+ 'nodes on first level'
+ );
+
+ // add child 4
+ var node3 = tree.getNodeById(124).children[0];
+ node3.addChild(
+ new Node('child4')
+ );
+
+ // test level parameter
+ nodes = [];
+ tree.iterate(
+ function(node, level) {
+ nodes.push(node.name + ' ' + level);
+ return true;
+ }
+ );
+
+ equal(
+ nodes.join(','),
+ 'node1 0,child1 1,child2 1,node2 0,child3 1,child4 2'
+ );
+});
+
+test('moveNode', function() {
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+
+ /*
+ node1
+ ---child1
+ ---child2
+ node2
+ ---child3
+ */
+
+ var node1 = tree.children[0];
+ var node2 = tree.children[1];
+ var child1 = node1.children[0];
+ var child2 = node1.children[1];
+ equal(node2.name, 'node2', 'node2 name');
+ equal(child2.name, 'child2', 'child2 name');
+
+ // move child2 after node2
+ tree.moveNode(child2, node2, Position.AFTER);
+
+ /*
+ node1
+ ---child1
+ node2
+ ---child3
+ child2
+ */
+ equal(
+ formatNodes(tree.children),
+ 'node1 node2 child2',
+ 'tree nodes at first level'
+ );
+ equal(
+ formatNodes(node1.children),
+ 'child1',
+ 'node1 children'
+ );
+
+ // move child1 inside node2
+ // this means it's the first child
+ tree.moveNode(child1, node2, Position.INSIDE);
+
+ /*
+ node1
+ node2
+ ---child1
+ ---child3
+ child2
+ */
+ equal(
+ formatNodes(node2.children),
+ 'child1 child3',
+ 'node2 children'
+ );
+ equal(
+ formatNodes(node1.children),
+ '',
+ 'node1 has no children'
+ );
+
+ // move child2 before child1
+ tree.moveNode(child2, child1, Position.BEFORE);
+
+ /*
+ node1
+ node2
+ ---child2
+ ---child1
+ ---child3
+ */
+ equal(
+ formatNodes(node2.children),
+ 'child2 child1 child3',
+ 'node2 children'
+ );
+ equal(
+ formatNodes(tree.children),
+ 'node1 node2',
+ 'tree nodes at first level'
+ );
+});
+
+test('initFromData', function() {
+ var data =
+ {
+ label: 'main',
+ children: [
+ 'c1',
+ {
+ label: 'c2',
+ id: 201
+ }
+ ]
+ };
+ var node = new Node(null, true);
+ node.initFromData(data);
+
+ equal(node.name, 'main')
+ equal(
+ formatNodes(node.children),
+ 'c1 c2',
+ 'children'
+ );
+ equal(node.children[1].id, 201);
+});
+
+test('getData', function() {
+ // 1. empty node
+ var node = new Node(null, true);
+ deepEqual(node.getData(), []);
+
+ // 2.node with data
+ node.loadFromData(
+ [
+ {
+ label: 'n1',
+ children: [
+ {
+ label: 'c1'
+ }
+ ]
+ }
+ ]
+ );
+ deepEqual(
+ node.getData(),
+ [
+ {
+ name: 'n1',
+ children: [
+ {
+ name: 'c1'
+ }
+ ]
+ }
+ ]
+ );
+});
+
+test('addAfter', function() {
+ // setup
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+
+ /*
+ -node1
+ ---c1
+ ---c2
+ -node2
+ ---c3
+ */
+
+ equal(formatNodes(tree.children), 'node1 node2');
+
+ // - Add 'node_b' after node2
+ var node2 = tree.getNodeByName('node2');
+ node2.addAfter('node_b');
+
+ equal(formatNodes(tree.children), 'node1 node2 node_b');
+
+ var node_b = tree.getNodeByName('node_b');
+ equal(node_b.name, 'node_b');
+
+ // - Add 'node_a' after node1
+ var node1 = tree.getNodeByName('node1');
+ node1.addAfter('node_a');
+
+ equal(formatNodes(tree.children), 'node1 node_a node2 node_b');
+
+ // - Add 'node_c' after node_b; new node is an object
+ node_b.addAfter({
+ label: 'node_c',
+ id: 789
+ });
+
+ var node_c = tree.getNodeByName('node_c');
+ equal(node_c.id, 789);
+
+ equal(formatNodes(tree.children), 'node1 node_a node2 node_b node_c');
+
+ // - Add after root node; this is not possible
+ equal(tree.addAfter('node_x'), null);
+});
+
+test('addBefore', function() {
+ // setup
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+
+ // - Add 'node_0' before node1
+ var node1 = tree.getNodeByName('node1');
+ node1.addBefore('node0');
+ equal(formatNodes(tree.children), 'node0 node1 node2');
+
+ // - Add before root node; this is not possile
+ equal(tree.addBefore('x'), null);
+});
+
+test('addParent', function() {
+ // setup
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+
+ // - Add node 'root' as parent of node1
+ // Note that node also becomes a child of 'root'
+ var node1 = tree.getNodeByName('node1');
+ node1.addParent('root');
+
+ var root = tree.getNodeByName('root');
+ equal(formatNodes(root.children), 'node1 node2');
+
+ // - Add parent to root node; not possible
+ equal(tree.addParent('x'), null);
+});
+
+test('remove', function() {
+ // setup
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+
+ var child1 = tree.getNodeByName('child1');
+ var node1 = tree.getNodeByName('node1');
+
+ equal(formatNodes(node1.children), 'child1 child2');
+ equal(child1.parent, node1);
+
+ // 1. Remove child1
+ child1.remove();
+
+ equal(formatNodes(node1.children), 'child2');
+ equal(child1.parent, null);
+});
+
+test('append', function() {
+ // setup
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+
+ var node1 = tree.getNodeByName('node1');
+
+ // 1. Add child3 to node1
+ node1.append('child3');
+
+ equal(formatNodes(node1.children), 'child1 child2 child3');
+});
+
+test('prepend', function() {
+ // setup
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+
+ var node1 = tree.getNodeByName('node1');
+
+ // 1. Prepend child0 to node1
+ node1.prepend('child0');
+
+ equal(formatNodes(node1.children), 'child0 child1 child2');
+});
+
+test('getNodeById', function() {
+ // setup
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+
+ // 1. Get node with id 124
+ var node = tree.getNodeById(124);
+ equal(node.name, 'node2');
+
+ // 2. Delete node with id 124 and search again
+ node.remove();
+
+ equal(tree.getNodeById(124), null);
+
+ // 3. Add node with id 456 and search for it
+ var child3 = tree.getNodeByName('child2');
+ child3.append({
+ id: 456,
+ label: 'new node'
+ });
+
+ node = tree.getNodeById(456);
+ equal(node.name, 'new node');
+});
+
+test('getLevel', function() {
+ // setup
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+
+ // 1. get level for node1 and child1
+ equal(tree.getNodeByName('node1').getLevel(), 1);
+ equal(tree.getNodeByName('child1').getLevel(), 2);
+});
+
+test('loadFromData and id mapping', function() {
+ // - get node from empty tree
+ var tree = new Node(null, true);
+ equal(tree.getNodeById(999), null);
+
+ // - load example data in tree
+ tree.loadFromData(example_data);
+ equal(tree.getNodeById(124).name, 'node2');
+
+ var child2 = tree.getNodeById(126);
+ child2.addChild(
+ new Node({label: 'child4', id: 128})
+ );
+ child2.addChild(
+ new Node({label: 'child5', id: 129})
+ );
+
+ // - load data in node child2
+ child2.loadFromData(['abc', 'def']);
+
+ equal(tree.getNodeById(128), null);
+ equal(child2.children.length, 2);
+ equal(child2.children[0].name, 'abc');
+});
+
+test('removeChildren', function() {
+ // - load example data
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+
+ // add child4 and child5
+ var child2 = tree.getNodeById(126);
+ equal(child2.name, 'child2');
+
+ child2.addChild(
+ new Node({label: 'child4', id: 128})
+ );
+ child2.addChild(
+ new Node({label: 'child5', id: 129})
+ );
+ equal(tree.getNodeById(128).name, 'child4');
+
+ // - remove children from child2
+ child2.removeChildren();
+ equal(tree.getNodeById(128), null);
+ equal(child2.children.length, 0);
+});
+
+test('node with id 0', function() {
+ // - load node with id 0
+ var tree = new Node(null, true);
+ tree.loadFromData([
+ {
+ id: 0,
+ label: 'mynode'
+ }
+ ]);
+
+ // - get node by id
+ var node = tree.getNodeById(0);
+ equal(node.name, 'mynode');
+
+ // -- remove the node
+ node.remove();
+
+ equal(tree.getNodeById(0), undefined);
+});
+
+test('getPreviousSibling', function() {
+ // setup
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+
+ // - getPreviousSibling
+ equal(
+ tree.getNodeByName('child2').getPreviousSibling().name,
+ 'child1'
+ );
+ equal(tree.getPreviousSibling(), null);
+ equal(
+ tree.getNodeByName('child1').getPreviousSibling(),
+ null
+ );
+});
+
+test('getNextSibling', function() {
+ // setup
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+
+ // - getNextSibling
+ equal(
+ tree.getNodeByName('node1').getNextSibling().name,
+ 'node2'
+ );
+ equal(
+ tree.getNodeByName('node2').getNextSibling(),
+ null
+ );
+ equal(tree.getNextSibling(), null);
+});
+
+test('getNodesByProperty', function() {
+ var tree = new Node(null, true);
+ tree.loadFromData(example_data);
+
+ nodes = tree.getNodesByProperty('name', 'child1');
+
+ equal(nodes.length, 1);
+ equal(nodes[0].name, 'child1');
+});
+
+
+QUnit.module('util');
+
+test('JSON.stringify', function() {
+ function test_stringify(stringify) {
+ equal(stringify('abc'), '"abc"');
+ equal(stringify(123), '123');
+ equal(stringify(true), 'true');
+ equal(stringify({abc: 'def'}), '{"abc":"def"}');
+ equal(stringify({}), '{}');
+ equal(stringify([1, 2, 3]), '[1,2,3]');
+ equal(stringify(null), 'null');
+ equal(stringify(Number.NEGATIVE_INFINITY), 'null');
+
+ // test escapable
+ JSON.stringify("\u200c");
+ }
+
+ test_stringify(JSON.stringify);
+ test_stringify(get_json_stringify_function());
+});
+
+test('indexOf', function() {
+ equal(indexOf([3, 2, 1], 1), 2);
+ equal(_indexOf([3, 2, 1], 1), 2);
+ equal(indexOf([4, 5, 6], 1), -1);
+ equal(_indexOf([4, 5, 6], 1), -1);
+});
+
+test('Position.getName', function() {
+ equal(Position.getName(Position.BEFORE), 'before');
+ equal(Position.getName(Position.AFTER), 'after');
+ equal(Position.getName(Position.INSIDE), 'inside');
+ equal(Position.getName(Position.NONE), 'none');
+});
+
+test('Position.nameToIndex', function() {
+ equal(Position.nameToIndex('before'), Position.BEFORE);
+ equal(Position.nameToIndex('after'), Position.AFTER);
+ equal(Position.nameToIndex(''), 0);
+});
diff --git a/src/tree.jquery.coffee b/src/tree.jquery.coffee
index c623ff99..b7b48ee5 100644
--- a/src/tree.jquery.coffee
+++ b/src/tree.jquery.coffee
@@ -1,5 +1,4 @@
-
-###
+###
Copyright 2013 Marco Braak
Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,6 +14,25 @@ See the License for the specific language governing permissions and
limitations under the License.
###
+__version__ = require './version'
+DragAndDropHandler = require './drag_and_drop_handler'
+ElementsRenderer = require './elements_renderer'
+KeyHandler = require './key_handler'
+MouseWidget = require './mouse.widget'
+SaveStateHandler = require './save_state_handler'
+ScrollHandler = require './scroll_handler'
+SelectNodeHandler = require './select_node_handler'
+SimpleWidget = require './simple.widget'
+
+node = require './node'
+Node = node.Node
+Position = node.Position
+
+node_element = require './node_element'
+NodeElement = node_element.NodeElement
+FolderElement = node_element.FolderElement
+
+
class JqTreeWidget extends MouseWidget
defaults:
autoOpen: false # true / false / int (open n levels starting at 0)
@@ -102,7 +120,10 @@ class JqTreeWidget extends MouseWidget
saveState()
getSelectedNode: ->
- return @select_node_handler.getSelectedNode()
+ if @select_node_handler
+ return @select_node_handler.getSelectedNode()
+ else
+ return null
toJson: ->
return JSON.stringify(
@@ -205,9 +226,10 @@ class JqTreeWidget extends MouseWidget
@_initTree(data)
else
# Node is loaded; unselect all nodes under this node.
- selected_nodes_under_parent = @select_node_handler.getSelectedNodesUnder(parent_node)
- for n in selected_nodes_under_parent
- @select_node_handler.removeFromSelection(n)
+ if @select_node_handler
+ selected_nodes_under_parent = @select_node_handler.getSelectedNodesUnder(parent_node)
+ for n in selected_nodes_under_parent
+ @select_node_handler.removeFromSelection(n)
parent_node.loadFromData(data)
parent_node.load_on_demand = false
@@ -424,7 +446,10 @@ class JqTreeWidget extends MouseWidget
_deinit: ->
@element.empty()
@element.unbind()
- @key_handler.deinit()
+
+ if @key_handler
+ @key_handler.deinit()
+
@tree = null
super()
@@ -652,100 +677,3 @@ class JqTreeWidget extends MouseWidget
@removeFromSelection(node)
SimpleWidget.register(JqTreeWidget, 'tree')
-
-
-class NodeElement
- constructor: (node, tree_widget) ->
- @init(node, tree_widget)
-
- init: (node, tree_widget) ->
- @node = node
- @tree_widget = tree_widget
-
- if not node.element
- node.element = @tree_widget.element
-
- @$element = $(node.element)
-
- getUl: ->
- return @$element.children('ul:first')
-
- getSpan: ->
- return @$element.children('.jqtree-element').find('span.jqtree-title')
-
- getLi: ->
- return @$element
-
- addDropHint: (position) ->
- if position == Position.INSIDE
- return new BorderDropHint(@$element)
- else
- return new GhostDropHint(@node, @$element, position)
-
- select: ->
- @getLi().addClass('jqtree-selected')
-
- deselect: ->
- @getLi().removeClass('jqtree-selected')
-
-
-class FolderElement extends NodeElement
- open: (on_finished, slide=true) ->
- if not @node.is_open
- @node.is_open = true
- $button = @getButton()
- $button.removeClass('jqtree-closed')
- $button.html('')
- $button.append(@tree_widget.renderer.opened_icon_element.cloneNode())
-
- doOpen = =>
- @getLi().removeClass('jqtree-closed')
- if on_finished
- on_finished()
-
- @tree_widget._triggerEvent('tree.open', node: @node)
-
- if slide
- @getUl().slideDown('fast', doOpen)
- else
- @getUl().show()
- doOpen()
-
- close: (slide=true) ->
- if @node.is_open
- @node.is_open = false
- $button = @getButton()
- $button.addClass('jqtree-closed')
- $button.html('')
- $button.append(@tree_widget.renderer.closed_icon_element.cloneNode())
-
- doClose = =>
- @getLi().addClass('jqtree-closed')
-
- @tree_widget._triggerEvent('tree.close', node: @node)
-
- if slide
- @getUl().slideUp('fast', doClose)
- else
- @getUl().hide()
- doClose()
-
- getButton: ->
- return @$element.children('.jqtree-element').find('a.jqtree-toggler')
-
- addDropHint: (position) ->
- if not @node.is_open and position == Position.INSIDE
- return new BorderDropHint(@$element)
- else
- return new GhostDropHint(@node, @$element, position)
-
-
-# Escape a string for HTML interpolation; copied from underscore js
-html_escape = (string) ->
- return (''+string)
- .replace(/&/g, '&')
- .replace(//g, '>')
- .replace(/"/g, '"')
- .replace(/'/g, ''')
- .replace(/\//g,'/')
\ No newline at end of file
diff --git a/src/util.coffee b/src/util.coffee
new file mode 100644
index 00000000..0ee9aa89
--- /dev/null
+++ b/src/util.coffee
@@ -0,0 +1,117 @@
+# Standard javascript indexOf. Implemented here because not all browsers support it.
+_indexOf = (array, item) ->
+ for value, i in array
+ if value == item
+ return i
+ return -1
+
+indexOf = (array, item) ->
+ if array.indexOf
+ # The browser supports indexOf
+ return array.indexOf(item)
+ else
+ # Do our own indexOf
+ return _indexOf(array, item)
+
+isInt = (n) ->
+ return typeof n is 'number' and n % 1 == 0
+
+
+# JSON.stringify function; copied from json2
+get_json_stringify_function = ->
+ json_escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g
+ json_meta = {
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ }
+
+ json_quote = (string) ->
+ json_escapable.lastIndex = 0
+
+ if json_escapable.test(string)
+ return '"' + string.replace(json_escapable, (a) ->
+ c = json_meta[a]
+ return (
+ if typeof c is 'string' then c
+ else '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4)
+ )
+ ) + '"'
+ else
+ return '"' + string + '"'
+
+ json_str = (key, holder) ->
+ value = holder[key]
+
+ switch typeof value
+ when 'string'
+ return json_quote(value)
+
+ when 'number'
+ return if isFinite(value) then String(value) else 'null'
+
+ when 'boolean', 'null'
+ return String(value)
+
+ when 'object'
+ if not value
+ return 'null'
+
+ partial = []
+ if Object::toString.apply(value) is '[object Array]'
+ for v, i in value
+ partial[i] = json_str(i, value) or 'null'
+
+ return (
+ if partial.length is 0 then '[]'
+ else '[' + partial.join(',') + ']'
+ )
+
+ for k of value
+ if Object::hasOwnProperty.call(value, k)
+ v = json_str(k, value)
+ if v
+ partial.push(json_quote(k) + ':' + v)
+
+ return (
+ if partial.length is 0 then '{}'
+ else '{' + partial.join(',') + '}'
+ )
+
+ stringify = (value) ->
+ return json_str(
+ '',
+ {'': value}
+ )
+
+ return stringify
+
+
+if not (@JSON? and @JSON.stringify? and typeof @JSON.stringify == 'function')
+ if not @JSON?
+ @JSON = {}
+
+ @JSON.stringify = get_json_stringify_function()
+
+
+# Escape a string for HTML interpolation; copied from underscore js
+html_escape = (string) ->
+ return (''+string)
+ .replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''')
+ .replace(/\//g,'/')
+
+
+module.exports =
+ _indexOf:_indexOf
+ get_json_stringify_function: get_json_stringify_function
+ html_escape: html_escape
+ indexOf: indexOf
+ isInt: isInt
diff --git a/src/version.coffee b/src/version.coffee
index 81edede8..3090b4c4 100644
--- a/src/version.coffee
+++ b/src/version.coffee
@@ -1 +1 @@
-__version__ = '0.22.0'
+module.exports = '0.22.0'
diff --git a/test/test.js b/test/test.js
index 26ac9cbb..7fec1cc4 100644
--- a/test/test.js
+++ b/test/test.js
@@ -1,4 +1,12 @@
-$(function() {
+(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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o');
},
@@ -244,7 +252,7 @@ test('saveState', function() {
equal(
$tree.tree('getSelectedNode').name,
'node2',
- 'getSelectedNode'
+ 'getSelectedNode (1)'
);
// create tree again
@@ -259,7 +267,7 @@ test('saveState', function() {
equal(
$tree.tree('getSelectedNode').name,
'node2',
- 'getSelectedNode'
+ 'getSelectedNode (2)'
);
});
@@ -754,7 +762,7 @@ test('generate hit areas', function() {
var hit_areas = $tree.tree('testGenerateHitAreas', node);
var strings = $.map(hit_areas, function(hit_area) {
- return hit_area.node.name + ' ' + Tree.Position.getName(hit_area.position);
+ return hit_area.node.name + ' ' + Position.getName(hit_area.position);
});
equal(strings.join(';'), 'node1 none;node2 inside;node2 after');
});
@@ -1163,17 +1171,17 @@ test('keyboard', function() {
equal($tree.tree('getSelectedNode').name, 'node1');
});
-module("Tree");
+QUnit.module("Tree");
test('constructor', function() {
// 1. Create node from string
- var node = new Tree.Node('n1');
+ var node = new Node('n1');
equal(node.name, 'n1');
equal(node.children.length, 0);
equal(node.parent, null);
// 2. Create node from object
- node = new Tree.Node({
+ node = new Node({
label: 'n2',
id: 123,
parent: 'abc', // parent must be ignored
@@ -1214,7 +1222,7 @@ test("create tree from data", function() {
}
// - create tree from example data
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
checkData(tree);
@@ -1231,18 +1239,18 @@ test("create tree from data", function() {
children: ['child3']
}
];
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(data);
checkData(tree);
});
test("addChild", function() {
- var tree = new Tree.Node('tree1', true);
+ var tree = new Node('tree1', true);
tree.addChild(
- new Tree.Node('abc')
+ new Node('abc')
);
tree.addChild(
- new Tree.Node('def')
+ new Node('def')
);
equal(
@@ -1260,11 +1268,11 @@ test("addChild", function() {
});
test('addChildAtPosition', function() {
- var tree = new Tree.Node(null, true);
- tree.addChildAtPosition(new Tree.Node('abc'), 0); // first
- tree.addChildAtPosition(new Tree.Node('ghi'), 2); // index 2 does not exist
- tree.addChildAtPosition(new Tree.Node('def'), 1);
- tree.addChildAtPosition(new Tree.Node('123'), 0);
+ var tree = new Node(null, true);
+ tree.addChildAtPosition(new Node('abc'), 0); // first
+ tree.addChildAtPosition(new Node('ghi'), 2); // index 2 does not exist
+ tree.addChildAtPosition(new Node('def'), 1);
+ tree.addChildAtPosition(new Node('123'), 0);
equal(
formatNodes(tree.children),
@@ -1274,17 +1282,17 @@ test('addChildAtPosition', function() {
});
test('removeChild', function() {
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
- var abc = new Tree.Node({'label': 'abc', 'id': 1});
- var def = new Tree.Node({'label': 'def', 'id': 2});
- var ghi = new Tree.Node({'label': 'ghi', 'id': 3});
+ var abc = new Node({'label': 'abc', 'id': 1});
+ var def = new Node({'label': 'def', 'id': 2});
+ var ghi = new Node({'label': 'ghi', 'id': 3});
tree.addChild(abc);
tree.addChild(def);
tree.addChild(ghi);
- var jkl = new Tree.Node({'label': 'jkl', 'id': 4});
+ var jkl = new Node({'label': 'jkl', 'id': 4});
def.addChild(jkl);
equal(
@@ -1326,11 +1334,11 @@ test('removeChild', function() {
test('getChildIndex', function() {
// setup
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
- var abc = new Tree.Node('abc');
- var def = new Tree.Node('def');
- var ghi = new Tree.Node('ghi');
+ var abc = new Node('abc');
+ var def = new Node('def');
+ var ghi = new Node('ghi');
tree.addChild(abc);
tree.addChild(def);
tree.addChild(ghi);
@@ -1339,18 +1347,18 @@ test('getChildIndex', function() {
equal(tree.getChildIndex(def), 1);
// 2. Get child index of non-existing node
- equal(tree.getChildIndex(new Tree.Node('xyz')), -1);
+ equal(tree.getChildIndex(new Node('xyz')), -1);
});
test('hasChildren', function() {
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
equal(
tree.hasChildren(),
false,
'tree without children'
);
- tree.addChild(new Tree.Node('abc'));
+ tree.addChild(new Node('abc'));
equal(
tree.hasChildren(),
true,
@@ -1359,7 +1367,7 @@ test('hasChildren', function() {
});
test('iterate', function() {
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
// iterate over all the nodes
@@ -1395,7 +1403,7 @@ test('iterate', function() {
// add child 4
var node3 = tree.getNodeById(124).children[0];
node3.addChild(
- new Tree.Node('child4')
+ new Node('child4')
);
// test level parameter
@@ -1414,7 +1422,7 @@ test('iterate', function() {
});
test('moveNode', function() {
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
/*
@@ -1433,7 +1441,7 @@ test('moveNode', function() {
equal(child2.name, 'child2', 'child2 name');
// move child2 after node2
- tree.moveNode(child2, node2, Tree.Position.AFTER);
+ tree.moveNode(child2, node2, Position.AFTER);
/*
node1
@@ -1455,7 +1463,7 @@ test('moveNode', function() {
// move child1 inside node2
// this means it's the first child
- tree.moveNode(child1, node2, Tree.Position.INSIDE);
+ tree.moveNode(child1, node2, Position.INSIDE);
/*
node1
@@ -1476,7 +1484,7 @@ test('moveNode', function() {
);
// move child2 before child1
- tree.moveNode(child2, child1, Tree.Position.BEFORE);
+ tree.moveNode(child2, child1, Position.BEFORE);
/*
node1
@@ -1509,7 +1517,7 @@ test('initFromData', function() {
}
]
};
- var node = new Tree.Node(null, true);
+ var node = new Node(null, true);
node.initFromData(data);
equal(node.name, 'main')
@@ -1523,7 +1531,7 @@ test('initFromData', function() {
test('getData', function() {
// 1. empty node
- var node = new Tree.Node(null, true);
+ var node = new Node(null, true);
deepEqual(node.getData(), []);
// 2.node with data
@@ -1556,7 +1564,7 @@ test('getData', function() {
test('addAfter', function() {
// setup
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
/*
@@ -1601,7 +1609,7 @@ test('addAfter', function() {
test('addBefore', function() {
// setup
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
// - Add 'node_0' before node1
@@ -1615,7 +1623,7 @@ test('addBefore', function() {
test('addParent', function() {
// setup
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
// - Add node 'root' as parent of node1
@@ -1632,7 +1640,7 @@ test('addParent', function() {
test('remove', function() {
// setup
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
var child1 = tree.getNodeByName('child1');
@@ -1650,7 +1658,7 @@ test('remove', function() {
test('append', function() {
// setup
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
var node1 = tree.getNodeByName('node1');
@@ -1663,7 +1671,7 @@ test('append', function() {
test('prepend', function() {
// setup
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
var node1 = tree.getNodeByName('node1');
@@ -1676,7 +1684,7 @@ test('prepend', function() {
test('getNodeById', function() {
// setup
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
// 1. Get node with id 124
@@ -1701,7 +1709,7 @@ test('getNodeById', function() {
test('getLevel', function() {
// setup
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
// 1. get level for node1 and child1
@@ -1711,7 +1719,7 @@ test('getLevel', function() {
test('loadFromData and id mapping', function() {
// - get node from empty tree
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
equal(tree.getNodeById(999), null);
// - load example data in tree
@@ -1720,10 +1728,10 @@ test('loadFromData and id mapping', function() {
var child2 = tree.getNodeById(126);
child2.addChild(
- new Tree.Node({label: 'child4', id: 128})
+ new Node({label: 'child4', id: 128})
);
child2.addChild(
- new Tree.Node({label: 'child5', id: 129})
+ new Node({label: 'child5', id: 129})
);
// - load data in node child2
@@ -1736,7 +1744,7 @@ test('loadFromData and id mapping', function() {
test('removeChildren', function() {
// - load example data
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
// add child4 and child5
@@ -1744,10 +1752,10 @@ test('removeChildren', function() {
equal(child2.name, 'child2');
child2.addChild(
- new Tree.Node({label: 'child4', id: 128})
+ new Node({label: 'child4', id: 128})
);
child2.addChild(
- new Tree.Node({label: 'child5', id: 129})
+ new Node({label: 'child5', id: 129})
);
equal(tree.getNodeById(128).name, 'child4');
@@ -1759,7 +1767,7 @@ test('removeChildren', function() {
test('node with id 0', function() {
// - load node with id 0
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData([
{
id: 0,
@@ -1779,7 +1787,7 @@ test('node with id 0', function() {
test('getPreviousSibling', function() {
// setup
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
// - getPreviousSibling
@@ -1796,7 +1804,7 @@ test('getPreviousSibling', function() {
test('getNextSibling', function() {
// setup
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
// - getNextSibling
@@ -1812,7 +1820,7 @@ test('getNextSibling', function() {
});
test('getNodesByProperty', function() {
- var tree = new Tree.Node(null, true);
+ var tree = new Node(null, true);
tree.loadFromData(example_data);
nodes = tree.getNodesByProperty('name', 'child1');
@@ -1822,7 +1830,7 @@ test('getNodesByProperty', function() {
});
-module('util');
+QUnit.module('util');
test('JSON.stringify', function() {
function test_stringify(stringify) {
@@ -1840,27 +1848,628 @@ test('JSON.stringify', function() {
}
test_stringify(JSON.stringify);
- test_stringify(Tree.get_json_stringify_function());
+ test_stringify(get_json_stringify_function());
});
test('indexOf', function() {
- equal(Tree.indexOf([3, 2, 1], 1), 2);
- equal(Tree._indexOf([3, 2, 1], 1), 2);
- equal(Tree.indexOf([4, 5, 6], 1), -1);
- equal(Tree._indexOf([4, 5, 6], 1), -1);
+ equal(indexOf([3, 2, 1], 1), 2);
+ equal(_indexOf([3, 2, 1], 1), 2);
+ equal(indexOf([4, 5, 6], 1), -1);
+ equal(_indexOf([4, 5, 6], 1), -1);
});
test('Position.getName', function() {
- equal(Tree.Position.getName(Tree.Position.BEFORE), 'before');
- equal(Tree.Position.getName(Tree.Position.AFTER), 'after');
- equal(Tree.Position.getName(Tree.Position.INSIDE), 'inside');
- equal(Tree.Position.getName(Tree.Position.NONE), 'none');
+ equal(Position.getName(Position.BEFORE), 'before');
+ equal(Position.getName(Position.AFTER), 'after');
+ equal(Position.getName(Position.INSIDE), 'inside');
+ equal(Position.getName(Position.NONE), 'none');
});
test('Position.nameToIndex', function() {
- equal(Tree.Position.nameToIndex('before'), Tree.Position.BEFORE);
- equal(Tree.Position.nameToIndex('after'), Tree.Position.AFTER);
- equal(Tree.Position.nameToIndex(''), 0);
+ equal(Position.nameToIndex('before'), Position.BEFORE);
+ equal(Position.nameToIndex('after'), Position.AFTER);
+ equal(Position.nameToIndex(''), 0);
});
-});
+},{"./node":2,"./util":3}],2:[function(require,module,exports){
+(function() {
+ var Node, Position;
+
+ Position = {
+ getName: function(position) {
+ return Position.strings[position - 1];
+ },
+ nameToIndex: function(name) {
+ var i, _i, _ref;
+ for (i = _i = 1, _ref = Position.strings.length; 1 <= _ref ? _i <= _ref : _i >= _ref; i = 1 <= _ref ? ++_i : --_i) {
+ if (Position.strings[i - 1] === name) {
+ return i;
+ }
+ }
+ return 0;
+ }
+ };
+
+ Position.BEFORE = 1;
+
+ Position.AFTER = 2;
+
+ Position.INSIDE = 3;
+
+ Position.NONE = 4;
+
+ Position.strings = ['before', 'after', 'inside', 'none'];
+
+ Node = (function() {
+ function Node(o, is_root, node_class) {
+ if (is_root == null) {
+ is_root = false;
+ }
+ if (node_class == null) {
+ node_class = Node;
+ }
+ this.setData(o);
+ this.children = [];
+ this.parent = null;
+ if (is_root) {
+ this.id_mapping = {};
+ this.tree = this;
+ this.node_class = node_class;
+ }
+ }
+
+ Node.prototype.setData = function(o) {
+ var key, value, _results;
+ if (typeof o !== 'object') {
+ return this.name = o;
+ } else {
+ _results = [];
+ for (key in o) {
+ value = o[key];
+ if (key === 'label') {
+ _results.push(this.name = value);
+ } else {
+ _results.push(this[key] = value);
+ }
+ }
+ return _results;
+ }
+ };
+
+ Node.prototype.initFromData = function(data) {
+ var addChildren, addNode;
+ addNode = (function(_this) {
+ return function(node_data) {
+ _this.setData(node_data);
+ if (node_data.children) {
+ return addChildren(node_data.children);
+ }
+ };
+ })(this);
+ addChildren = (function(_this) {
+ return function(children_data) {
+ var child, node, _i, _len;
+ for (_i = 0, _len = children_data.length; _i < _len; _i++) {
+ child = children_data[_i];
+ node = new _this.tree.node_class('');
+ node.initFromData(child);
+ _this.addChild(node);
+ }
+ return null;
+ };
+ })(this);
+ addNode(data);
+ return null;
+ };
+
+
+ /*
+ Create tree from data.
+
+ Structure of data is:
+ [
+ {
+ label: 'node1',
+ children: [
+ { label: 'child1' },
+ { label: 'child2' }
+ ]
+ },
+ {
+ label: 'node2'
+ }
+ ]
+ */
+
+ Node.prototype.loadFromData = function(data) {
+ var node, o, _i, _len;
+ this.removeChildren();
+ for (_i = 0, _len = data.length; _i < _len; _i++) {
+ o = data[_i];
+ node = new this.tree.node_class(o);
+ this.addChild(node);
+ if (typeof o === 'object' && o.children) {
+ node.loadFromData(o.children);
+ }
+ }
+ return null;
+ };
+
+
+ /*
+ Add child.
+
+ tree.addChild(
+ new Node('child1')
+ );
+ */
+
+ Node.prototype.addChild = function(node) {
+ this.children.push(node);
+ return node._setParent(this);
+ };
+
+
+ /*
+ Add child at position. Index starts at 0.
+
+ tree.addChildAtPosition(
+ new Node('abc'),
+ 1
+ );
+ */
+
+ Node.prototype.addChildAtPosition = function(node, index) {
+ this.children.splice(index, 0, node);
+ return node._setParent(this);
+ };
+
+ Node.prototype._setParent = function(parent) {
+ this.parent = parent;
+ this.tree = parent.tree;
+ return this.tree.addNodeToIndex(this);
+ };
+
+
+ /*
+ Remove child. This also removes the children of the node.
+
+ tree.removeChild(tree.children[0]);
+ */
+
+ Node.prototype.removeChild = function(node) {
+ node.removeChildren();
+ return this._removeChild(node);
+ };
+
+ Node.prototype._removeChild = function(node) {
+ this.children.splice(this.getChildIndex(node), 1);
+ return this.tree.removeNodeFromIndex(node);
+ };
+
+
+ /*
+ Get child index.
+
+ var index = getChildIndex(node);
+ */
+
+ Node.prototype.getChildIndex = function(node) {
+ return $.inArray(node, this.children);
+ };
+
+
+ /*
+ Does the tree have children?
+
+ if (tree.hasChildren()) {
+ //
+ }
+ */
+
+ Node.prototype.hasChildren = function() {
+ return this.children.length !== 0;
+ };
+
+ Node.prototype.isFolder = function() {
+ return this.hasChildren() || this.load_on_demand;
+ };
+
+
+ /*
+ Iterate over all the nodes in the tree.
+
+ Calls callback with (node, level).
+
+ The callback must return true to continue the iteration on current node.
+
+ tree.iterate(
+ function(node, level) {
+ console.log(node.name);
+
+ // stop iteration after level 2
+ return (level <= 2);
+ }
+ );
+ */
+
+ Node.prototype.iterate = function(callback) {
+ var _iterate;
+ _iterate = (function(_this) {
+ return function(node, level) {
+ var child, result, _i, _len, _ref;
+ if (node.children) {
+ _ref = node.children;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ child = _ref[_i];
+ result = callback(child, level);
+ if (_this.hasChildren() && result) {
+ _iterate(child, level + 1);
+ }
+ }
+ return null;
+ }
+ };
+ })(this);
+ _iterate(this, 0);
+ return null;
+ };
+
+
+ /*
+ Move node relative to another node.
+
+ Argument position: Position.BEFORE, Position.AFTER or Position.Inside
+
+ // move node1 after node2
+ tree.moveNode(node1, node2, Position.AFTER);
+ */
+
+ Node.prototype.moveNode = function(moved_node, target_node, position) {
+ if (moved_node.isParentOf(target_node)) {
+ return;
+ }
+ moved_node.parent._removeChild(moved_node);
+ if (position === Position.AFTER) {
+ return target_node.parent.addChildAtPosition(moved_node, target_node.parent.getChildIndex(target_node) + 1);
+ } else if (position === Position.BEFORE) {
+ return target_node.parent.addChildAtPosition(moved_node, target_node.parent.getChildIndex(target_node));
+ } else if (position === Position.INSIDE) {
+ return target_node.addChildAtPosition(moved_node, 0);
+ }
+ };
+
+
+ /*
+ Get the tree as data.
+ */
+
+ Node.prototype.getData = function() {
+ var getDataFromNodes;
+ getDataFromNodes = (function(_this) {
+ return function(nodes) {
+ var data, k, node, tmp_node, v, _i, _len;
+ data = [];
+ for (_i = 0, _len = nodes.length; _i < _len; _i++) {
+ node = nodes[_i];
+ tmp_node = {};
+ for (k in node) {
+ v = node[k];
+ if ((k !== 'parent' && k !== 'children' && k !== 'element' && k !== 'tree') && Object.prototype.hasOwnProperty.call(node, k)) {
+ tmp_node[k] = v;
+ }
+ }
+ if (node.hasChildren()) {
+ tmp_node.children = getDataFromNodes(node.children);
+ }
+ data.push(tmp_node);
+ }
+ return data;
+ };
+ })(this);
+ return getDataFromNodes(this.children);
+ };
+
+ Node.prototype.getNodeByName = function(name) {
+ var result;
+ result = null;
+ this.iterate(function(node) {
+ if (node.name === name) {
+ result = node;
+ return false;
+ } else {
+ return true;
+ }
+ });
+ return result;
+ };
+
+ Node.prototype.addAfter = function(node_info) {
+ var child_index, node;
+ if (!this.parent) {
+ return null;
+ } else {
+ node = new this.tree.node_class(node_info);
+ child_index = this.parent.getChildIndex(this);
+ this.parent.addChildAtPosition(node, child_index + 1);
+ return node;
+ }
+ };
+
+ Node.prototype.addBefore = function(node_info) {
+ var child_index, node;
+ if (!this.parent) {
+ return null;
+ } else {
+ node = new this.tree.node_class(node_info);
+ child_index = this.parent.getChildIndex(this);
+ this.parent.addChildAtPosition(node, child_index);
+ return node;
+ }
+ };
+
+ Node.prototype.addParent = function(node_info) {
+ var child, new_parent, original_parent, _i, _len, _ref;
+ if (!this.parent) {
+ return null;
+ } else {
+ new_parent = new this.tree.node_class(node_info);
+ new_parent._setParent(this.tree);
+ original_parent = this.parent;
+ _ref = original_parent.children;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ child = _ref[_i];
+ new_parent.addChild(child);
+ }
+ original_parent.children = [];
+ original_parent.addChild(new_parent);
+ return new_parent;
+ }
+ };
+
+ Node.prototype.remove = function() {
+ if (this.parent) {
+ this.parent.removeChild(this);
+ return this.parent = null;
+ }
+ };
+
+ Node.prototype.append = function(node_info) {
+ var node;
+ node = new this.tree.node_class(node_info);
+ this.addChild(node);
+ return node;
+ };
+
+ Node.prototype.prepend = function(node_info) {
+ var node;
+ node = new this.tree.node_class(node_info);
+ this.addChildAtPosition(node, 0);
+ return node;
+ };
+
+ Node.prototype.isParentOf = function(node) {
+ var parent;
+ parent = node.parent;
+ while (parent) {
+ if (parent === this) {
+ return true;
+ }
+ parent = parent.parent;
+ }
+ return false;
+ };
+
+ Node.prototype.getLevel = function() {
+ var level, node;
+ level = 0;
+ node = this;
+ while (node.parent) {
+ level += 1;
+ node = node.parent;
+ }
+ return level;
+ };
+
+ Node.prototype.getNodeById = function(node_id) {
+ return this.id_mapping[node_id];
+ };
+
+ Node.prototype.addNodeToIndex = function(node) {
+ if (node.id != null) {
+ return this.id_mapping[node.id] = node;
+ }
+ };
+
+ Node.prototype.removeNodeFromIndex = function(node) {
+ if (node.id != null) {
+ return delete this.id_mapping[node.id];
+ }
+ };
+
+ Node.prototype.removeChildren = function() {
+ this.iterate((function(_this) {
+ return function(child) {
+ _this.tree.removeNodeFromIndex(child);
+ return true;
+ };
+ })(this));
+ return this.children = [];
+ };
+
+ Node.prototype.getPreviousSibling = function() {
+ var previous_index;
+ if (!this.parent) {
+ return null;
+ } else {
+ previous_index = this.parent.getChildIndex(this) - 1;
+ if (previous_index >= 0) {
+ return this.parent.children[previous_index];
+ } else {
+ return null;
+ }
+ }
+ };
+
+ Node.prototype.getNextSibling = function() {
+ var next_index;
+ if (!this.parent) {
+ return null;
+ } else {
+ next_index = this.parent.getChildIndex(this) + 1;
+ if (next_index < this.parent.children.length) {
+ return this.parent.children[next_index];
+ } else {
+ return null;
+ }
+ }
+ };
+
+ Node.prototype.getNodesByProperty = function(key, value) {
+ return this.filter(function(node) {
+ return node[key] === value;
+ });
+ };
+
+ Node.prototype.filter = function(f) {
+ var result;
+ result = [];
+ this.iterate(function(node) {
+ if (f(node)) {
+ result.push(node);
+ }
+ return true;
+ });
+ return result;
+ };
+
+ return Node;
+
+ })();
+
+ module.exports = {
+ Node: Node,
+ Position: Position
+ };
+
+}).call(this);
+
+},{}],3:[function(require,module,exports){
+(function() {
+ var get_json_stringify_function, html_escape, indexOf, isInt, _indexOf;
+
+ _indexOf = function(array, item) {
+ var i, value, _i, _len;
+ for (i = _i = 0, _len = array.length; _i < _len; i = ++_i) {
+ value = array[i];
+ if (value === item) {
+ return i;
+ }
+ }
+ return -1;
+ };
+
+ indexOf = function(array, item) {
+ if (array.indexOf) {
+ return array.indexOf(item);
+ } else {
+ return _indexOf(array, item);
+ }
+ };
+
+ isInt = function(n) {
+ return typeof n === 'number' && n % 1 === 0;
+ };
+
+ get_json_stringify_function = function() {
+ var json_escapable, json_meta, json_quote, json_str, stringify;
+ json_escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+ json_meta = {
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"': '\\"',
+ '\\': '\\\\'
+ };
+ json_quote = function(string) {
+ json_escapable.lastIndex = 0;
+ if (json_escapable.test(string)) {
+ return '"' + string.replace(json_escapable, function(a) {
+ var c;
+ c = json_meta[a];
+ return (typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4));
+ }) + '"';
+ } else {
+ return '"' + string + '"';
+ }
+ };
+ json_str = function(key, holder) {
+ var i, k, partial, v, value, _i, _len;
+ value = holder[key];
+ switch (typeof value) {
+ case 'string':
+ return json_quote(value);
+ case 'number':
+ if (isFinite(value)) {
+ return String(value);
+ } else {
+ return 'null';
+ }
+ case 'boolean':
+ case 'null':
+ return String(value);
+ case 'object':
+ if (!value) {
+ return 'null';
+ }
+ partial = [];
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
+ for (i = _i = 0, _len = value.length; _i < _len; i = ++_i) {
+ v = value[i];
+ partial[i] = json_str(i, value) || 'null';
+ }
+ return (partial.length === 0 ? '[]' : '[' + partial.join(',') + ']');
+ }
+ for (k in value) {
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
+ v = json_str(k, value);
+ if (v) {
+ partial.push(json_quote(k) + ':' + v);
+ }
+ }
+ }
+ return (partial.length === 0 ? '{}' : '{' + partial.join(',') + '}');
+ }
+ };
+ stringify = function(value) {
+ return json_str('', {
+ '': value
+ });
+ };
+ return stringify;
+ };
+
+ if (!((this.JSON != null) && (this.JSON.stringify != null) && typeof this.JSON.stringify === 'function')) {
+ if (this.JSON == null) {
+ this.JSON = {};
+ }
+ this.JSON.stringify = get_json_stringify_function();
+ }
+
+ html_escape = function(string) {
+ return ('' + string).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g, '/');
+ };
+
+ module.exports = {
+ _indexOf: _indexOf,
+ get_json_stringify_function: get_json_stringify_function,
+ html_escape: html_escape,
+ indexOf: indexOf,
+ isInt: isInt
+ };
+
+}).call(this);
+
+},{}]},{},[1])
\ No newline at end of file
diff --git a/tree.jquery.js b/tree.jquery.js
index 37c8f740..6ac453f0 100644
--- a/tree.jquery.js
+++ b/tree.jquery.js
@@ -1,942 +1,627 @@
-// Generated by CoffeeScript 1.7.1
+(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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o dimensions.right || y > dimensions.bottom) {
+ return null;
}
- result = this._handleMouseDown(e, this._getPositionInfo(e));
- if (result) {
- e.preventDefault();
+ low = 0;
+ high = this.hit_areas.length;
+ while (low < high) {
+ mid = (low + high) >> 1;
+ area = this.hit_areas[mid];
+ if (y < area.top) {
+ high = mid;
+ } else if (y > area.bottom) {
+ low = mid + 1;
+ } else {
+ return area;
+ }
}
- return result;
+ return null;
};
- MouseWidget.prototype._handleMouseDown = function(e, position_info) {
- if (MouseWidget.is_mouse_handled) {
+ DragAndDropHandler.prototype.mustOpenFolderTimer = function(area) {
+ var node;
+ node = area.node;
+ return node.isFolder() && !node.is_open && area.position === Position.INSIDE;
+ };
+
+ DragAndDropHandler.prototype.updateDropHint = function() {
+ var node_element;
+ if (!this.hovered_area) {
return;
}
- if (this.is_mouse_started) {
- this._handleMouseUp(position_info);
- }
- this.mouse_down_info = position_info;
- if (!this._mouseCapture(position_info)) {
- return;
- }
- this._handleStartMouse();
- this.is_mouse_handled = true;
- return true;
- };
-
- MouseWidget.prototype._handleStartMouse = function() {
- var $document;
- $document = $(document);
- $document.bind('mousemove.mousewidget', $.proxy(this._mouseMove, this));
- $document.bind('touchmove.mousewidget', $.proxy(this._touchMove, this));
- $document.bind('mouseup.mousewidget', $.proxy(this._mouseUp, this));
- $document.bind('touchend.mousewidget', $.proxy(this._touchEnd, this));
- if (this.mouse_delay) {
- return this._startMouseDelayTimer();
- }
+ this.removeDropHint();
+ node_element = this.tree_widget._getNodeElementForNode(this.hovered_area.node);
+ return this.previous_ghost = node_element.addDropHint(this.hovered_area.position);
};
- MouseWidget.prototype._startMouseDelayTimer = function() {
- if (this._mouse_delay_timer) {
- clearTimeout(this._mouse_delay_timer);
- }
- this._mouse_delay_timer = setTimeout((function(_this) {
+ DragAndDropHandler.prototype.startOpenFolderTimer = function(folder) {
+ var openFolder;
+ openFolder = (function(_this) {
return function() {
- return _this._is_mouse_delay_met = true;
+ return _this.tree_widget._openNode(folder, _this.tree_widget.options.slide, function() {
+ _this.refresh();
+ return _this.updateDropHint();
+ });
};
- })(this), this.mouse_delay);
- return this._is_mouse_delay_met = false;
+ })(this);
+ this.stopOpenFolderTimer();
+ return this.open_folder_timer = setTimeout(openFolder, this.tree_widget.options.openFolderDelay);
};
- MouseWidget.prototype._mouseMove = function(e) {
- return this._handleMouseMove(e, this._getPositionInfo(e));
+ DragAndDropHandler.prototype.stopOpenFolderTimer = function() {
+ if (this.open_folder_timer) {
+ clearTimeout(this.open_folder_timer);
+ return this.open_folder_timer = null;
+ }
};
- MouseWidget.prototype._handleMouseMove = function(e, position_info) {
- if (this.is_mouse_started) {
- this._mouseDrag(position_info);
- return e.preventDefault();
- }
- if (this.mouse_delay && !this._is_mouse_delay_met) {
- return true;
- }
- this.is_mouse_started = this._mouseStart(this.mouse_down_info) !== false;
- if (this.is_mouse_started) {
- this._mouseDrag(position_info);
- } else {
- this._handleMouseUp(position_info);
+ DragAndDropHandler.prototype.moveItem = function(position_info) {
+ var doMove, event, moved_node, position, previous_parent, target_node;
+ if (this.hovered_area && this.hovered_area.position !== Position.NONE && this.canMoveToArea(this.hovered_area)) {
+ moved_node = this.current_item.node;
+ target_node = this.hovered_area.node;
+ position = this.hovered_area.position;
+ previous_parent = moved_node.parent;
+ if (position === Position.INSIDE) {
+ this.hovered_area.node.is_open = true;
+ }
+ doMove = (function(_this) {
+ return function() {
+ _this.tree_widget.tree.moveNode(moved_node, target_node, position);
+ _this.tree_widget.element.empty();
+ return _this.tree_widget._refreshElements();
+ };
+ })(this);
+ event = this.tree_widget._triggerEvent('tree.move', {
+ move_info: {
+ moved_node: moved_node,
+ target_node: target_node,
+ position: Position.getName(position),
+ previous_parent: previous_parent,
+ do_move: doMove,
+ original_event: position_info.original_event
+ }
+ });
+ if (!event.isDefaultPrevented()) {
+ return doMove();
+ }
}
- return !this.is_mouse_started;
};
- MouseWidget.prototype._getPositionInfo = function(e) {
+ DragAndDropHandler.prototype.getTreeDimensions = function() {
+ var offset;
+ offset = this.tree_widget.element.offset();
return {
- page_x: e.pageX,
- page_y: e.pageY,
- target: e.target,
- original_event: e
+ left: offset.left,
+ top: offset.top,
+ right: offset.left + this.tree_widget.element.width(),
+ bottom: offset.top + this.tree_widget.element.height() + 16
};
};
- MouseWidget.prototype._mouseUp = function(e) {
- return this._handleMouseUp(this._getPositionInfo(e));
- };
-
- MouseWidget.prototype._handleMouseUp = function(position_info) {
- var $document;
- $document = $(document);
- $document.unbind('mousemove.mousewidget');
- $document.unbind('touchmove.mousewidget');
- $document.unbind('mouseup.mousewidget');
- $document.unbind('touchend.mousewidget');
- if (this.is_mouse_started) {
- this.is_mouse_started = false;
- this._mouseStop(position_info);
- }
- };
-
- MouseWidget.prototype._mouseCapture = function(position_info) {
- return true;
- };
+ return DragAndDropHandler;
- MouseWidget.prototype._mouseStart = function(position_info) {
- return null;
- };
+ })();
- MouseWidget.prototype._mouseDrag = function(position_info) {
- return null;
- };
+ VisibleNodeIterator = (function() {
+ function VisibleNodeIterator(tree) {
+ this.tree = tree;
+ }
- MouseWidget.prototype._mouseStop = function(position_info) {
- return null;
+ VisibleNodeIterator.prototype.iterate = function() {
+ var is_first_node, _iterateNode;
+ is_first_node = true;
+ _iterateNode = (function(_this) {
+ return function(node, next_node) {
+ var $element, child, children_length, i, must_iterate_inside, _i, _len, _ref;
+ must_iterate_inside = (node.is_open || !node.element) && node.hasChildren();
+ if (node.element) {
+ $element = $(node.element);
+ if (!$element.is(':visible')) {
+ return;
+ }
+ if (is_first_node) {
+ _this.handleFirstNode(node, $element);
+ is_first_node = false;
+ }
+ if (!node.hasChildren()) {
+ _this.handleNode(node, next_node, $element);
+ } else if (node.is_open) {
+ if (!_this.handleOpenFolder(node, $element)) {
+ must_iterate_inside = false;
+ }
+ } else {
+ _this.handleClosedFolder(node, next_node, $element);
+ }
+ }
+ if (must_iterate_inside) {
+ children_length = node.children.length;
+ _ref = node.children;
+ for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
+ child = _ref[i];
+ if (i === (children_length - 1)) {
+ _iterateNode(node.children[i], null);
+ } else {
+ _iterateNode(node.children[i], node.children[i + 1]);
+ }
+ }
+ if (node.is_open) {
+ return _this.handleAfterOpenFolder(node, next_node, $element);
+ }
+ }
+ };
+ })(this);
+ return _iterateNode(this.tree, null);
};
- MouseWidget.prototype.setMouseDelay = function(mouse_delay) {
- return this.mouse_delay = mouse_delay;
- };
+ VisibleNodeIterator.prototype.handleNode = function(node, next_node, $element) {};
- MouseWidget.prototype._touchStart = function(e) {
- var touch;
- if (e.originalEvent.touches.length > 1) {
- return;
- }
- touch = e.originalEvent.changedTouches[0];
- return this._handleMouseDown(e, this._getPositionInfo(touch));
- };
+ VisibleNodeIterator.prototype.handleOpenFolder = function(node, $element) {};
- MouseWidget.prototype._touchMove = function(e) {
- var touch;
- if (e.originalEvent.touches.length > 1) {
- return;
- }
- touch = e.originalEvent.changedTouches[0];
- return this._handleMouseMove(e, this._getPositionInfo(touch));
- };
+ VisibleNodeIterator.prototype.handleClosedFolder = function(node, next_node, $element) {};
- MouseWidget.prototype._touchEnd = function(e) {
- var touch;
- if (e.originalEvent.touches.length > 1) {
- return;
- }
- touch = e.originalEvent.changedTouches[0];
- return this._handleMouseUp(this._getPositionInfo(touch));
- };
+ VisibleNodeIterator.prototype.handleAfterOpenFolder = function(node, next_node, $element) {};
- return MouseWidget;
+ VisibleNodeIterator.prototype.handleFirstNode = function(node, $element) {};
- })(SimpleWidget);
+ return VisibleNodeIterator;
- this.Tree = {};
+ })();
- $ = this.jQuery;
+ HitAreasGenerator = (function(_super) {
+ __extends(HitAreasGenerator, _super);
- Position = {
- getName: function(position) {
- return Position.strings[position - 1];
- },
- nameToIndex: function(name) {
- var i, _i, _ref;
- for (i = _i = 1, _ref = Position.strings.length; 1 <= _ref ? _i <= _ref : _i >= _ref; i = 1 <= _ref ? ++_i : --_i) {
- if (Position.strings[i - 1] === name) {
- return i;
- }
- }
- return 0;
+ function HitAreasGenerator(tree, current_node, tree_bottom) {
+ HitAreasGenerator.__super__.constructor.call(this, tree);
+ this.current_node = current_node;
+ this.tree_bottom = tree_bottom;
}
- };
-
- Position.BEFORE = 1;
-
- Position.AFTER = 2;
-
- Position.INSIDE = 3;
- Position.NONE = 4;
+ HitAreasGenerator.prototype.generate = function() {
+ this.positions = [];
+ this.last_top = 0;
+ this.iterate();
+ return this.generateHitAreas(this.positions);
+ };
- Position.strings = ['before', 'after', 'inside', 'none'];
+ HitAreasGenerator.prototype.getTop = function($element) {
+ return $element.offset().top;
+ };
- this.Tree.Position = Position;
+ HitAreasGenerator.prototype.addPosition = function(node, position, top) {
+ var area;
+ area = {
+ top: top,
+ node: node,
+ position: position
+ };
+ this.positions.push(area);
+ return this.last_top = top;
+ };
- Node = (function() {
- function Node(o, is_root, node_class) {
- if (is_root == null) {
- is_root = false;
+ HitAreasGenerator.prototype.handleNode = function(node, next_node, $element) {
+ var top;
+ top = this.getTop($element);
+ if (node === this.current_node) {
+ this.addPosition(node, Position.NONE, top);
+ } else {
+ this.addPosition(node, Position.INSIDE, top);
}
- if (node_class == null) {
- node_class = Node;
+ if (next_node === this.current_node || node === this.current_node) {
+ return this.addPosition(node, Position.NONE, top);
+ } else {
+ return this.addPosition(node, Position.AFTER, top);
}
- this.setData(o);
- this.children = [];
- this.parent = null;
- if (is_root) {
- this.id_mapping = {};
- this.tree = this;
- this.node_class = node_class;
+ };
+
+ HitAreasGenerator.prototype.handleOpenFolder = function(node, $element) {
+ if (node === this.current_node) {
+ return false;
}
- }
+ if (node.children[0] !== this.current_node) {
+ this.addPosition(node, Position.INSIDE, this.getTop($element));
+ }
+ return true;
+ };
- Node.prototype.setData = function(o) {
- var key, value, _results;
- if (typeof o !== 'object') {
- return this.name = o;
+ HitAreasGenerator.prototype.handleClosedFolder = function(node, next_node, $element) {
+ var top;
+ top = this.getTop($element);
+ if (node === this.current_node) {
+ return this.addPosition(node, Position.NONE, top);
} else {
- _results = [];
- for (key in o) {
- value = o[key];
- if (key === 'label') {
- _results.push(this.name = value);
- } else {
- _results.push(this[key] = value);
- }
+ this.addPosition(node, Position.INSIDE, top);
+ if (next_node !== this.current_node) {
+ return this.addPosition(node, Position.AFTER, top);
}
- return _results;
}
};
- Node.prototype.initFromData = function(data) {
- var addChildren, addNode;
- addNode = (function(_this) {
- return function(node_data) {
- _this.setData(node_data);
- if (node_data.children) {
- return addChildren(node_data.children);
- }
- };
- })(this);
- addChildren = (function(_this) {
- return function(children_data) {
- var child, node, _i, _len;
- for (_i = 0, _len = children_data.length; _i < _len; _i++) {
- child = children_data[_i];
- node = new _this.tree.node_class('');
- node.initFromData(child);
- _this.addChild(node);
- }
- return null;
- };
- })(this);
- addNode(data);
- return null;
+ HitAreasGenerator.prototype.handleFirstNode = function(node, $element) {
+ if (node !== this.current_node) {
+ return this.addPosition(node, Position.BEFORE, this.getTop($(node.element)));
+ }
};
+ HitAreasGenerator.prototype.handleAfterOpenFolder = function(node, next_node, $element) {
+ if (node === this.current_node.node || next_node === this.current_node.node) {
+ return this.addPosition(node, Position.NONE, this.last_top);
+ } else {
+ return this.addPosition(node, Position.AFTER, this.last_top);
+ }
+ };
- /*
- Create tree from data.
-
- Structure of data is:
- [
- {
- label: 'node1',
- children: [
- { label: 'child1' },
- { label: 'child2' }
- ]
- },
- {
- label: 'node2'
+ HitAreasGenerator.prototype.generateHitAreas = function(positions) {
+ var group, hit_areas, position, previous_top, _i, _len;
+ previous_top = -1;
+ group = [];
+ hit_areas = [];
+ for (_i = 0, _len = positions.length; _i < _len; _i++) {
+ position = positions[_i];
+ if (position.top !== previous_top && group.length) {
+ if (group.length) {
+ this.generateHitAreasForGroup(hit_areas, group, previous_top, position.top);
+ }
+ previous_top = position.top;
+ group = [];
}
- ]
- */
+ group.push(position);
+ }
+ this.generateHitAreasForGroup(hit_areas, group, previous_top, this.tree_bottom);
+ return hit_areas;
+ };
- Node.prototype.loadFromData = function(data) {
- var node, o, _i, _len;
- this.removeChildren();
- for (_i = 0, _len = data.length; _i < _len; _i++) {
- o = data[_i];
- node = new this.tree.node_class(o);
- this.addChild(node);
- if (typeof o === 'object' && o.children) {
- node.loadFromData(o.children);
- }
+ HitAreasGenerator.prototype.generateHitAreasForGroup = function(hit_areas, positions_in_group, top, bottom) {
+ var area_height, area_top, i, position, position_count;
+ position_count = Math.min(positions_in_group.length, 4);
+ area_height = Math.round((bottom - top) / position_count);
+ area_top = top;
+ i = 0;
+ while (i < position_count) {
+ position = positions_in_group[i];
+ hit_areas.push({
+ top: area_top,
+ bottom: area_top + area_height,
+ node: position.node,
+ position: position.position
+ });
+ area_top += area_height;
+ i += 1;
}
return null;
};
+ return HitAreasGenerator;
- /*
- Add child.
-
- tree.addChild(
- new Node('child1')
- );
- */
-
- Node.prototype.addChild = function(node) {
- this.children.push(node);
- return node._setParent(this);
- };
-
+ })(VisibleNodeIterator);
- /*
- Add child at position. Index starts at 0.
-
- tree.addChildAtPosition(
- new Node('abc'),
- 1
- );
- */
+ DragElement = (function() {
+ function DragElement(node, offset_x, offset_y, $tree) {
+ this.offset_x = offset_x;
+ this.offset_y = offset_y;
+ this.$element = $("" + node.name + "");
+ this.$element.css("position", "absolute");
+ $tree.append(this.$element);
+ }
- Node.prototype.addChildAtPosition = function(node, index) {
- this.children.splice(index, 0, node);
- return node._setParent(this);
+ DragElement.prototype.move = function(page_x, page_y) {
+ return this.$element.offset({
+ left: page_x - this.offset_x,
+ top: page_y - this.offset_y
+ });
};
- Node.prototype._setParent = function(parent) {
- this.parent = parent;
- this.tree = parent.tree;
- return this.tree.addNodeToIndex(this);
+ DragElement.prototype.remove = function() {
+ return this.$element.remove();
};
+ return DragElement;
- /*
- Remove child. This also removes the children of the node.
-
- tree.removeChild(tree.children[0]);
- */
+ })();
- Node.prototype.removeChild = function(node) {
- node.removeChildren();
- return this._removeChild(node);
- };
+ module.exports = DragAndDropHandler;
- Node.prototype._removeChild = function(node) {
- this.children.splice(this.getChildIndex(node), 1);
- return this.tree.removeNodeFromIndex(node);
- };
+}).call(this);
+},{"./node":6}],2:[function(require,module,exports){
+(function() {
+ var ElementsRenderer, NodeElement, html_escape, node_element, util;
- /*
- Get child index.
-
- var index = getChildIndex(node);
- */
+ node_element = require('./node_element');
- Node.prototype.getChildIndex = function(node) {
- return $.inArray(node, this.children);
- };
+ NodeElement = node_element.NodeElement;
+ util = require('./util');
- /*
- Does the tree have children?
-
- if (tree.hasChildren()) {
- //
- }
- */
+ html_escape = util.html_escape;
- Node.prototype.hasChildren = function() {
- return this.children.length !== 0;
- };
+ ElementsRenderer = (function() {
+ function ElementsRenderer(tree_widget) {
+ this.tree_widget = tree_widget;
+ this.opened_icon_element = this.createButtonElement(tree_widget.options.openedIcon);
+ this.closed_icon_element = this.createButtonElement(tree_widget.options.closedIcon);
+ }
- Node.prototype.isFolder = function() {
- return this.hasChildren() || this.load_on_demand;
+ ElementsRenderer.prototype.render = function(from_node) {
+ if (from_node && from_node.parent) {
+ return this.renderFromNode(from_node);
+ } else {
+ return this.renderFromRoot();
+ }
};
-
- /*
- Iterate over all the nodes in the tree.
-
- Calls callback with (node, level).
-
- The callback must return true to continue the iteration on current node.
-
- tree.iterate(
- function(node, level) {
- console.log(node.name);
-
- // stop iteration after level 2
- return (level <= 2);
- }
- );
- */
-
- Node.prototype.iterate = function(callback) {
- var _iterate;
- _iterate = (function(_this) {
- return function(node, level) {
- var child, result, _i, _len, _ref;
- if (node.children) {
- _ref = node.children;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- child = _ref[_i];
- result = callback(child, level);
- if (_this.hasChildren() && result) {
- _iterate(child, level + 1);
- }
- }
- return null;
- }
- };
- })(this);
- _iterate(this, 0);
- return null;
- };
-
-
- /*
- Move node relative to another node.
-
- Argument position: Position.BEFORE, Position.AFTER or Position.Inside
-
- // move node1 after node2
- tree.moveNode(node1, node2, Position.AFTER);
- */
-
- Node.prototype.moveNode = function(moved_node, target_node, position) {
- if (moved_node.isParentOf(target_node)) {
- return;
+ ElementsRenderer.prototype.renderNode = function(node) {
+ var li, parent_node_element, previous_node;
+ $(node.element).remove();
+ parent_node_element = new NodeElement(node.parent, this.tree_widget);
+ li = this.createLi(node);
+ this.attachNodeData(node, li);
+ previous_node = node.getPreviousSibling();
+ if (previous_node) {
+ $(previous_node.element).after(li);
+ } else {
+ parent_node_element.getUl().prepend(li);
}
- moved_node.parent._removeChild(moved_node);
- if (position === Position.AFTER) {
- return target_node.parent.addChildAtPosition(moved_node, target_node.parent.getChildIndex(target_node) + 1);
- } else if (position === Position.BEFORE) {
- return target_node.parent.addChildAtPosition(moved_node, target_node.parent.getChildIndex(target_node));
- } else if (position === Position.INSIDE) {
- return target_node.addChildAtPosition(moved_node, 0);
+ if (node.children) {
+ return this.renderFromNode(node);
}
};
+ ElementsRenderer.prototype.renderFromRoot = function() {
+ var $element;
+ $element = this.tree_widget.element;
+ $element.empty();
+ return this.createDomElements($element[0], this.tree_widget.tree.children, true, true);
+ };
- /*
- Get the tree as data.
- */
-
- Node.prototype.getData = function() {
- var getDataFromNodes;
- getDataFromNodes = (function(_this) {
- return function(nodes) {
- var data, k, node, tmp_node, v, _i, _len;
- data = [];
- for (_i = 0, _len = nodes.length; _i < _len; _i++) {
- node = nodes[_i];
- tmp_node = {};
- for (k in node) {
- v = node[k];
- if ((k !== 'parent' && k !== 'children' && k !== 'element' && k !== 'tree') && Object.prototype.hasOwnProperty.call(node, k)) {
- tmp_node[k] = v;
- }
- }
- if (node.hasChildren()) {
- tmp_node.children = getDataFromNodes(node.children);
- }
- data.push(tmp_node);
- }
- return data;
- };
- })(this);
- return getDataFromNodes(this.children);
+ ElementsRenderer.prototype.renderFromNode = function(from_node) {
+ node_element = this.tree_widget._getNodeElementForNode(from_node);
+ node_element.getUl().remove();
+ return this.createDomElements(node_element.$element[0], from_node.children, false, false);
};
- Node.prototype.getNodeByName = function(name) {
- var result;
- result = null;
- this.iterate(function(node) {
- if (node.name === name) {
- result = node;
- return false;
- } else {
- return true;
+ ElementsRenderer.prototype.createDomElements = function(element, children, is_root_node, is_open) {
+ var child, li, ul, _i, _len;
+ ul = this.createUl(is_root_node);
+ element.appendChild(ul);
+ for (_i = 0, _len = children.length; _i < _len; _i++) {
+ child = children[_i];
+ li = this.createLi(child);
+ ul.appendChild(li);
+ this.attachNodeData(child, li);
+ if (child.hasChildren()) {
+ this.createDomElements(li, child.children, false, child.is_open);
}
- });
- return result;
+ }
+ return null;
};
- Node.prototype.addAfter = function(node_info) {
- var child_index, node;
- if (!this.parent) {
- return null;
- } else {
- node = new this.tree.node_class(node_info);
- child_index = this.parent.getChildIndex(this);
- this.parent.addChildAtPosition(node, child_index + 1);
- return node;
- }
+ ElementsRenderer.prototype.attachNodeData = function(node, li) {
+ node.element = li;
+ return $(li).data('node', node);
};
- Node.prototype.addBefore = function(node_info) {
- var child_index, node;
- if (!this.parent) {
- return null;
+ ElementsRenderer.prototype.createUl = function(is_root_node) {
+ var class_string, ul;
+ if (is_root_node) {
+ class_string = 'jqtree-tree';
} else {
- node = new this.tree.node_class(node_info);
- child_index = this.parent.getChildIndex(this);
- this.parent.addChildAtPosition(node, child_index);
- return node;
+ class_string = '';
}
+ ul = document.createElement('ul');
+ ul.className = "jqtree_common " + class_string;
+ return ul;
};
- Node.prototype.addParent = function(node_info) {
- var child, new_parent, original_parent, _i, _len, _ref;
- if (!this.parent) {
- return null;
+ ElementsRenderer.prototype.createLi = function(node) {
+ var li;
+ if (node.isFolder()) {
+ li = this.createFolderLi(node);
} else {
- new_parent = new this.tree.node_class(node_info);
- new_parent._setParent(this.tree);
- original_parent = this.parent;
- _ref = original_parent.children;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- child = _ref[_i];
- new_parent.addChild(child);
- }
- original_parent.children = [];
- original_parent.addChild(new_parent);
- return new_parent;
+ li = this.createNodeLi(node);
+ }
+ if (this.tree_widget.options.onCreateLi) {
+ this.tree_widget.options.onCreateLi(node, $(li));
}
+ return li;
};
- Node.prototype.remove = function() {
- if (this.parent) {
- this.parent.removeChild(this);
- return this.parent = null;
+ ElementsRenderer.prototype.createFolderLi = function(node) {
+ var button_classes, button_link, div, escaped_name, folder_classes, icon_element, li, title_span;
+ button_classes = this.getButtonClasses(node);
+ folder_classes = this.getFolderClasses(node);
+ escaped_name = this.escapeIfNecessary(node.name);
+ if (node.is_open) {
+ icon_element = this.opened_icon_element;
+ } else {
+ icon_element = this.closed_icon_element;
}
+ li = document.createElement('li');
+ li.className = "jqtree_common " + folder_classes;
+ div = document.createElement('div');
+ div.className = "jqtree-element jqtree_common";
+ li.appendChild(div);
+ button_link = document.createElement('a');
+ button_link.className = "jqtree_common " + button_classes;
+ button_link.appendChild(icon_element.cloneNode());
+ div.appendChild(button_link);
+ title_span = document.createElement('span');
+ title_span.className = "jqtree_common jqtree-title jqtree-title-folder";
+ div.appendChild(title_span);
+ title_span.innerHTML = escaped_name;
+ return li;
};
- Node.prototype.append = function(node_info) {
- var node;
- node = new this.tree.node_class(node_info);
- this.addChild(node);
- return node;
+ ElementsRenderer.prototype.createNodeLi = function(node) {
+ var class_string, div, escaped_name, li, li_classes, title_span;
+ li_classes = ['jqtree_common'];
+ if (this.tree_widget.select_node_handler && this.tree_widget.select_node_handler.isNodeSelected(node)) {
+ li_classes.push('jqtree-selected');
+ }
+ class_string = li_classes.join(' ');
+ escaped_name = this.escapeIfNecessary(node.name);
+ li = document.createElement('li');
+ li.className = class_string;
+ div = document.createElement('div');
+ div.className = "jqtree-element jqtree_common";
+ li.appendChild(div);
+ title_span = document.createElement('span');
+ title_span.className = "jqtree-title jqtree_common";
+ title_span.innerHTML = escaped_name;
+ div.appendChild(title_span);
+ return li;
};
- Node.prototype.prepend = function(node_info) {
- var node;
- node = new this.tree.node_class(node_info);
- this.addChildAtPosition(node, 0);
- return node;
- };
-
- Node.prototype.isParentOf = function(node) {
- var parent;
- parent = node.parent;
- while (parent) {
- if (parent === this) {
- return true;
- }
- parent = parent.parent;
- }
- return false;
- };
-
- Node.prototype.getLevel = function() {
- var level, node;
- level = 0;
- node = this;
- while (node.parent) {
- level += 1;
- node = node.parent;
- }
- return level;
- };
-
- Node.prototype.getNodeById = function(node_id) {
- return this.id_mapping[node_id];
- };
-
- Node.prototype.addNodeToIndex = function(node) {
- if (node.id != null) {
- return this.id_mapping[node.id] = node;
- }
- };
-
- Node.prototype.removeNodeFromIndex = function(node) {
- if (node.id != null) {
- return delete this.id_mapping[node.id];
- }
- };
-
- Node.prototype.removeChildren = function() {
- this.iterate((function(_this) {
- return function(child) {
- _this.tree.removeNodeFromIndex(child);
- return true;
- };
- })(this));
- return this.children = [];
- };
-
- Node.prototype.getPreviousSibling = function() {
- var previous_index;
- if (!this.parent) {
- return null;
- } else {
- previous_index = this.parent.getChildIndex(this) - 1;
- if (previous_index >= 0) {
- return this.parent.children[previous_index];
- } else {
- return null;
- }
- }
- };
-
- Node.prototype.getNextSibling = function() {
- var next_index;
- if (!this.parent) {
- return null;
- } else {
- next_index = this.parent.getChildIndex(this) + 1;
- if (next_index < this.parent.children.length) {
- return this.parent.children[next_index];
- } else {
- return null;
- }
- }
- };
-
- Node.prototype.getNodesByProperty = function(key, value) {
- return this.filter(function(node) {
- return node[key] === value;
- });
- };
-
- Node.prototype.filter = function(f) {
- var result;
- result = [];
- this.iterate(function(node) {
- if (f(node)) {
- result.push(node);
- }
- return true;
- });
- return result;
- };
-
- return Node;
-
- })();
-
- this.Tree.Node = Node;
-
- ElementsRenderer = (function() {
- function ElementsRenderer(tree_widget) {
- this.tree_widget = tree_widget;
- this.opened_icon_element = this.createButtonElement(tree_widget.options.openedIcon);
- this.closed_icon_element = this.createButtonElement(tree_widget.options.closedIcon);
- }
-
- ElementsRenderer.prototype.render = function(from_node) {
- if (from_node && from_node.parent) {
- return this.renderFromNode(from_node);
- } else {
- return this.renderFromRoot();
- }
- };
-
- ElementsRenderer.prototype.renderNode = function(node) {
- var li, parent_node_element, previous_node;
- $(node.element).remove();
- parent_node_element = new NodeElement(node.parent, this.tree_widget);
- li = this.createLi(node);
- this.attachNodeData(node, li);
- previous_node = node.getPreviousSibling();
- if (previous_node) {
- $(previous_node.element).after(li);
- } else {
- parent_node_element.getUl().prepend(li);
- }
- if (node.children) {
- return this.renderFromNode(node);
- }
- };
-
- ElementsRenderer.prototype.renderFromRoot = function() {
- var $element;
- $element = this.tree_widget.element;
- $element.empty();
- return this.createDomElements($element[0], this.tree_widget.tree.children, true, true);
- };
-
- ElementsRenderer.prototype.renderFromNode = function(from_node) {
- var node_element;
- node_element = this.tree_widget._getNodeElementForNode(from_node);
- node_element.getUl().remove();
- return this.createDomElements(node_element.$element[0], from_node.children, false, false);
- };
-
- ElementsRenderer.prototype.createDomElements = function(element, children, is_root_node, is_open) {
- var child, li, ul, _i, _len;
- ul = this.createUl(is_root_node);
- element.appendChild(ul);
- for (_i = 0, _len = children.length; _i < _len; _i++) {
- child = children[_i];
- li = this.createLi(child);
- ul.appendChild(li);
- this.attachNodeData(child, li);
- if (child.hasChildren()) {
- this.createDomElements(li, child.children, false, child.is_open);
- }
- }
- return null;
- };
-
- ElementsRenderer.prototype.attachNodeData = function(node, li) {
- node.element = li;
- return $(li).data('node', node);
- };
-
- ElementsRenderer.prototype.createUl = function(is_root_node) {
- var class_string, ul;
- if (is_root_node) {
- class_string = 'jqtree-tree';
- } else {
- class_string = '';
- }
- ul = document.createElement('ul');
- ul.className = "jqtree_common " + class_string;
- return ul;
- };
-
- ElementsRenderer.prototype.createLi = function(node) {
- var li;
- if (node.isFolder()) {
- li = this.createFolderLi(node);
- } else {
- li = this.createNodeLi(node);
- }
- if (this.tree_widget.options.onCreateLi) {
- this.tree_widget.options.onCreateLi(node, $(li));
- }
- return li;
- };
-
- ElementsRenderer.prototype.createFolderLi = function(node) {
- var button_classes, button_link, div, escaped_name, folder_classes, icon_element, li, title_span;
- button_classes = this.getButtonClasses(node);
- folder_classes = this.getFolderClasses(node);
- escaped_name = this.escapeIfNecessary(node.name);
- if (node.is_open) {
- icon_element = this.opened_icon_element;
- } else {
- icon_element = this.closed_icon_element;
- }
- li = document.createElement('li');
- li.className = "jqtree_common " + folder_classes;
- div = document.createElement('div');
- div.className = "jqtree-element jqtree_common";
- li.appendChild(div);
- button_link = document.createElement('a');
- button_link.className = "jqtree_common " + button_classes;
- button_link.appendChild(icon_element.cloneNode());
- div.appendChild(button_link);
- title_span = document.createElement('span');
- title_span.className = "jqtree_common jqtree-title jqtree-title-folder";
- div.appendChild(title_span);
- title_span.innerHTML = escaped_name;
- return li;
- };
-
- ElementsRenderer.prototype.createNodeLi = function(node) {
- var class_string, div, escaped_name, li, li_classes, title_span;
- li_classes = ['jqtree_common'];
- if (this.tree_widget.select_node_handler && this.tree_widget.select_node_handler.isNodeSelected(node)) {
- li_classes.push('jqtree-selected');
- }
- class_string = li_classes.join(' ');
- escaped_name = this.escapeIfNecessary(node.name);
- li = document.createElement('li');
- li.className = class_string;
- div = document.createElement('div');
- div.className = "jqtree-element jqtree_common";
- li.appendChild(div);
- title_span = document.createElement('span');
- title_span.className = "jqtree-title jqtree_common";
- title_span.innerHTML = escaped_name;
- div.appendChild(title_span);
- return li;
- };
-
- ElementsRenderer.prototype.getButtonClasses = function(node) {
- var classes;
- classes = ['jqtree-toggler'];
- if (!node.is_open) {
- classes.push('jqtree-closed');
- }
- return classes.join(' ');
+ ElementsRenderer.prototype.getButtonClasses = function(node) {
+ var classes;
+ classes = ['jqtree-toggler'];
+ if (!node.is_open) {
+ classes.push('jqtree-closed');
+ }
+ return classes.join(' ');
};
ElementsRenderer.prototype.getFolderClasses = function(node) {
@@ -974,40 +659,80 @@
})();
+ module.exports = ElementsRenderer;
- /*
- Copyright 2013 Marco Braak
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
+}).call(this);
- JqTreeWidget = (function(_super) {
- __extends(JqTreeWidget, _super);
+},{"./node_element":7,"./util":12}],3:[function(require,module,exports){
- function JqTreeWidget() {
- return JqTreeWidget.__super__.constructor.apply(this, arguments);
- }
+/*
+Copyright 2013 Marco Braak
- JqTreeWidget.prototype.defaults = {
- autoOpen: false,
- saveState: false,
- dragAndDrop: false,
- selectable: true,
- useContextMenu: true,
- onCanSelectNode: null,
- onSetStateFromStorage: null,
- onGetStateFromStorage: null,
- onCreateLi: null,
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+(function() {
+ var DragAndDropHandler, ElementsRenderer, FolderElement, JqTreeWidget, KeyHandler, MouseWidget, Node, NodeElement, Position, SaveStateHandler, ScrollHandler, SelectNodeHandler, SimpleWidget, node, node_element, __version__,
+ __hasProp = {}.hasOwnProperty,
+ __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; };
+
+ __version__ = require('./version');
+
+ DragAndDropHandler = require('./drag_and_drop_handler');
+
+ ElementsRenderer = require('./elements_renderer');
+
+ KeyHandler = require('./key_handler');
+
+ MouseWidget = require('./mouse.widget');
+
+ SaveStateHandler = require('./save_state_handler');
+
+ ScrollHandler = require('./scroll_handler');
+
+ SelectNodeHandler = require('./select_node_handler');
+
+ SimpleWidget = require('./simple.widget');
+
+ node = require('./node');
+
+ Node = node.Node;
+
+ Position = node.Position;
+
+ node_element = require('./node_element');
+
+ NodeElement = node_element.NodeElement;
+
+ FolderElement = node_element.FolderElement;
+
+ JqTreeWidget = (function(_super) {
+ __extends(JqTreeWidget, _super);
+
+ function JqTreeWidget() {
+ return JqTreeWidget.__super__.constructor.apply(this, arguments);
+ }
+
+ JqTreeWidget.prototype.defaults = {
+ autoOpen: false,
+ saveState: false,
+ dragAndDrop: false,
+ selectable: true,
+ useContextMenu: true,
+ onCanSelectNode: null,
+ onSetStateFromStorage: null,
+ onGetStateFromStorage: null,
+ onCreateLi: null,
onIsMoveHandle: null,
onCanMove: null,
onCanMoveTo: null,
@@ -1108,7 +833,11 @@
};
JqTreeWidget.prototype.getSelectedNode = function() {
- return this.select_node_handler.getSelectedNode();
+ if (this.select_node_handler) {
+ return this.select_node_handler.getSelectedNode();
+ } else {
+ return null;
+ }
};
JqTreeWidget.prototype.toJson = function() {
@@ -1229,10 +958,12 @@
if (!parent_node) {
this._initTree(data);
} else {
- selected_nodes_under_parent = this.select_node_handler.getSelectedNodesUnder(parent_node);
- for (_i = 0, _len = selected_nodes_under_parent.length; _i < _len; _i++) {
- n = selected_nodes_under_parent[_i];
- this.select_node_handler.removeFromSelection(n);
+ if (this.select_node_handler) {
+ selected_nodes_under_parent = this.select_node_handler.getSelectedNodesUnder(parent_node);
+ for (_i = 0, _len = selected_nodes_under_parent.length; _i < _len; _i++) {
+ n = selected_nodes_under_parent[_i];
+ this.select_node_handler.removeFromSelection(n);
+ }
}
parent_node.loadFromData(data);
parent_node.load_on_demand = false;
@@ -1358,7 +1089,7 @@
};
JqTreeWidget.prototype.appendNode = function(new_node_info, parent_node) {
- var is_already_folder_node, node;
+ var is_already_folder_node;
if (!parent_node) {
parent_node = this.tree;
}
@@ -1373,7 +1104,6 @@
};
JqTreeWidget.prototype.prependNode = function(new_node_info, parent_node) {
- var node;
if (!parent_node) {
parent_node = this.tree;
}
@@ -1459,23 +1189,23 @@
this.mouse_delay = 300;
this.is_initialized = false;
this.renderer = new ElementsRenderer(this);
- if (typeof SaveStateHandler !== "undefined" && SaveStateHandler !== null) {
+ if (SaveStateHandler != null) {
this.save_state_handler = new SaveStateHandler(this);
} else {
this.options.saveState = false;
}
- if (typeof SelectNodeHandler !== "undefined" && SelectNodeHandler !== null) {
+ if (SelectNodeHandler != null) {
this.select_node_handler = new SelectNodeHandler(this);
}
- if (typeof DragAndDropHandler !== "undefined" && DragAndDropHandler !== null) {
+ if (DragAndDropHandler != null) {
this.dnd_handler = new DragAndDropHandler(this);
} else {
this.options.dragAndDrop = false;
}
- if (typeof ScrollHandler !== "undefined" && ScrollHandler !== null) {
+ if (ScrollHandler != null) {
this.scroll_handler = new ScrollHandler(this);
}
- if ((typeof KeyHandler !== "undefined" && KeyHandler !== null) && (typeof SelectNodeHandler !== "undefined" && SelectNodeHandler !== null)) {
+ if ((KeyHandler != null) && (SelectNodeHandler != null)) {
this.key_handler = new KeyHandler(this);
}
this._initData();
@@ -1489,7 +1219,9 @@
JqTreeWidget.prototype._deinit = function() {
this.element.empty();
this.element.unbind();
- this.key_handler.deinit();
+ if (this.key_handler) {
+ this.key_handler.deinit();
+ }
this.tree = null;
return JqTreeWidget.__super__._deinit.call(this);
};
@@ -1590,7 +1322,7 @@
};
JqTreeWidget.prototype._click = function(e) {
- var click_target, event, node;
+ var click_target, event;
click_target = this._getClickTarget(e.target);
if (click_target) {
if (click_target.type === 'button') {
@@ -1622,7 +1354,7 @@
};
JqTreeWidget.prototype._getClickTarget = function(element) {
- var $button, $el, $target, node;
+ var $button, $el, $target;
$target = $(element);
$button = $target.closest('.jqtree-toggler');
if ($button.length) {
@@ -1667,7 +1399,6 @@
};
JqTreeWidget.prototype._getNodeElement = function($element) {
- var node;
node = this._getNode($element);
if (node) {
return this._getNodeElementForNode(node);
@@ -1677,7 +1408,7 @@
};
JqTreeWidget.prototype._contextmenu = function(e) {
- var $div, node;
+ var $div;
$div = $(e.target).closest('ul.jqtree-tree .jqtree-element');
if ($div.length) {
node = this._getNode($div);
@@ -1751,7 +1482,6 @@
};
JqTreeWidget.prototype._selectCurrentNode = function() {
- var node, node_element;
node = this.getSelectedNode();
if (node) {
node_element = this._getNodeElementForNode(node);
@@ -1762,7 +1492,6 @@
};
JqTreeWidget.prototype._deselectCurrentNode = function() {
- var node;
node = this.getSelectedNode();
if (node) {
return this.removeFromSelection(node);
@@ -1775,1307 +1504,1729 @@
SimpleWidget.register(JqTreeWidget, 'tree');
- NodeElement = (function() {
- function NodeElement(node, tree_widget) {
- this.init(node, tree_widget);
- }
-
- NodeElement.prototype.init = function(node, tree_widget) {
- this.node = node;
- this.tree_widget = tree_widget;
- if (!node.element) {
- node.element = this.tree_widget.element;
- }
- return this.$element = $(node.element);
- };
-
- NodeElement.prototype.getUl = function() {
- return this.$element.children('ul:first');
- };
-
- NodeElement.prototype.getSpan = function() {
- return this.$element.children('.jqtree-element').find('span.jqtree-title');
- };
-
- NodeElement.prototype.getLi = function() {
- return this.$element;
- };
+}).call(this);
- NodeElement.prototype.addDropHint = function(position) {
- if (position === Position.INSIDE) {
- return new BorderDropHint(this.$element);
- } else {
- return new GhostDropHint(this.node, this.$element, position);
- }
- };
+},{"./drag_and_drop_handler":1,"./elements_renderer":2,"./key_handler":4,"./mouse.widget":5,"./node":6,"./node_element":7,"./save_state_handler":8,"./scroll_handler":9,"./select_node_handler":10,"./simple.widget":11,"./version":13}],4:[function(require,module,exports){
+(function() {
+ var KeyHandler;
- NodeElement.prototype.select = function() {
- return this.getLi().addClass('jqtree-selected');
- };
+ KeyHandler = (function() {
+ var DOWN, LEFT, RIGHT, UP;
- NodeElement.prototype.deselect = function() {
- return this.getLi().removeClass('jqtree-selected');
- };
+ LEFT = 37;
- return NodeElement;
+ UP = 38;
- })();
+ RIGHT = 39;
- FolderElement = (function(_super) {
- __extends(FolderElement, _super);
+ DOWN = 40;
- function FolderElement() {
- return FolderElement.__super__.constructor.apply(this, arguments);
+ function KeyHandler(tree_widget) {
+ this.tree_widget = tree_widget;
+ if (tree_widget.options.keyboardSupport) {
+ $(document).bind('keydown.jqtree', $.proxy(this.handleKeyDown, this));
+ }
}
- FolderElement.prototype.open = function(on_finished, slide) {
- var $button, doOpen;
- if (slide == null) {
- slide = true;
+ KeyHandler.prototype.deinit = function() {
+ return $(document).unbind('keydown.jqtree');
+ };
+
+ KeyHandler.prototype.handleKeyDown = function(e) {
+ var current_node, key, moveDown, moveLeft, moveRight, moveUp, selectNode;
+ if (!this.tree_widget.options.keyboardSupport) {
+ return;
}
- if (!this.node.is_open) {
- this.node.is_open = true;
- $button = this.getButton();
- $button.removeClass('jqtree-closed');
- $button.html('');
- $button.append(this.tree_widget.renderer.opened_icon_element.cloneNode());
- doOpen = (function(_this) {
- return function() {
- _this.getLi().removeClass('jqtree-closed');
- if (on_finished) {
- on_finished();
+ if ($(document.activeElement).is('textarea,input,select')) {
+ return true;
+ }
+ current_node = this.tree_widget.getSelectedNode();
+ selectNode = (function(_this) {
+ return function(node) {
+ if (node) {
+ _this.tree_widget.selectNode(node);
+ if (_this.tree_widget.scroll_handler && (!_this.tree_widget.scroll_handler.isScrolledIntoView($(node.element).find('.jqtree-element')))) {
+ _this.tree_widget.scrollToNode(node);
}
- return _this.tree_widget._triggerEvent('tree.open', {
- node: _this.node
- });
- };
- })(this);
- if (slide) {
- return this.getUl().slideDown('fast', doOpen);
- } else {
- this.getUl().show();
- return doOpen();
+ return false;
+ } else {
+ return true;
+ }
+ };
+ })(this);
+ moveDown = (function(_this) {
+ return function() {
+ return selectNode(_this.getNextNode(current_node));
+ };
+ })(this);
+ moveUp = (function(_this) {
+ return function() {
+ return selectNode(_this.getPreviousNode(current_node));
+ };
+ })(this);
+ moveRight = (function(_this) {
+ return function() {
+ if (current_node.isFolder() && !current_node.is_open) {
+ _this.tree_widget.openNode(current_node);
+ return false;
+ } else {
+ return true;
+ }
+ };
+ })(this);
+ moveLeft = (function(_this) {
+ return function() {
+ if (current_node.isFolder() && current_node.is_open) {
+ _this.tree_widget.closeNode(current_node);
+ return false;
+ } else {
+ return true;
+ }
+ };
+ })(this);
+ if (!current_node) {
+ return true;
+ } else {
+ key = e.which;
+ switch (key) {
+ case DOWN:
+ return moveDown();
+ case UP:
+ return moveUp();
+ case RIGHT:
+ return moveRight();
+ case LEFT:
+ return moveLeft();
}
}
};
- FolderElement.prototype.close = function(slide) {
- var $button, doClose;
- if (slide == null) {
- slide = true;
+ KeyHandler.prototype.getNextNode = function(node, include_children) {
+ var next_sibling;
+ if (include_children == null) {
+ include_children = true;
}
- if (this.node.is_open) {
- this.node.is_open = false;
- $button = this.getButton();
- $button.addClass('jqtree-closed');
- $button.html('');
- $button.append(this.tree_widget.renderer.closed_icon_element.cloneNode());
- doClose = (function(_this) {
- return function() {
- _this.getLi().addClass('jqtree-closed');
- return _this.tree_widget._triggerEvent('tree.close', {
- node: _this.node
- });
- };
- })(this);
- if (slide) {
- return this.getUl().slideUp('fast', doClose);
+ if (include_children && node.hasChildren() && node.is_open) {
+ return node.children[0];
+ } else {
+ if (!node.parent) {
+ return null;
} else {
- this.getUl().hide();
- return doClose();
+ next_sibling = node.getNextSibling();
+ if (next_sibling) {
+ return next_sibling;
+ } else {
+ return this.getNextNode(node.parent, false);
+ }
}
}
};
- FolderElement.prototype.getButton = function() {
- return this.$element.children('.jqtree-element').find('a.jqtree-toggler');
+ KeyHandler.prototype.getPreviousNode = function(node) {
+ var previous_sibling;
+ if (!node.parent) {
+ return null;
+ } else {
+ previous_sibling = node.getPreviousSibling();
+ if (previous_sibling) {
+ if (!previous_sibling.hasChildren() || !previous_sibling.is_open) {
+ return previous_sibling;
+ } else {
+ return this.getLastChild(previous_sibling);
+ }
+ } else {
+ if (node.parent.parent) {
+ return node.parent;
+ } else {
+ return null;
+ }
+ }
+ }
};
- FolderElement.prototype.addDropHint = function(position) {
- if (!this.node.is_open && position === Position.INSIDE) {
- return new BorderDropHint(this.$element);
+ KeyHandler.prototype.getLastChild = function(node) {
+ var last_child;
+ if (!node.hasChildren()) {
+ return null;
} else {
- return new GhostDropHint(this.node, this.$element, position);
+ last_child = node.children[node.children.length - 1];
+ if (!last_child.hasChildren() || !last_child.is_open) {
+ return last_child;
+ } else {
+ return this.getLastChild(last_child);
+ }
}
};
- return FolderElement;
-
- })(NodeElement);
+ return KeyHandler;
- html_escape = function(string) {
- return ('' + string).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g, '/');
- };
+ })();
- _indexOf = function(array, item) {
- var i, value, _i, _len;
- for (i = _i = 0, _len = array.length; _i < _len; i = ++_i) {
- value = array[i];
- if (value === item) {
- return i;
- }
- }
- return -1;
- };
+ module.exports = KeyHandler;
- indexOf = function(array, item) {
- if (array.indexOf) {
- return array.indexOf(item);
- } else {
- return _indexOf(array, item);
- }
- };
+}).call(this);
- this.Tree.indexOf = indexOf;
+},{}],5:[function(require,module,exports){
- this.Tree._indexOf = _indexOf;
+/*
+This widget does the same a the mouse widget in jqueryui.
+ */
- isInt = function(n) {
- return typeof n === 'number' && n % 1 === 0;
- };
+(function() {
+ var MouseWidget, SimpleWidget,
+ __hasProp = {}.hasOwnProperty,
+ __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; };
- get_json_stringify_function = function() {
- var json_escapable, json_meta, json_quote, json_str, stringify;
- json_escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
- json_meta = {
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"': '\\"',
- '\\': '\\\\'
- };
- json_quote = function(string) {
- json_escapable.lastIndex = 0;
- if (json_escapable.test(string)) {
- return '"' + string.replace(json_escapable, function(a) {
- var c;
- c = json_meta[a];
- return (typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4));
- }) + '"';
- } else {
- return '"' + string + '"';
- }
- };
- json_str = function(key, holder) {
- var i, k, partial, v, value, _i, _len;
- value = holder[key];
- switch (typeof value) {
- case 'string':
- return json_quote(value);
- case 'number':
- if (isFinite(value)) {
- return String(value);
- } else {
- return 'null';
- }
- case 'boolean':
- case 'null':
- return String(value);
- case 'object':
- if (!value) {
- return 'null';
- }
- partial = [];
- if (Object.prototype.toString.apply(value) === '[object Array]') {
- for (i = _i = 0, _len = value.length; _i < _len; i = ++_i) {
- v = value[i];
- partial[i] = json_str(i, value) || 'null';
- }
- return (partial.length === 0 ? '[]' : '[' + partial.join(',') + ']');
- }
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = json_str(k, value);
- if (v) {
- partial.push(json_quote(k) + ':' + v);
- }
- }
- }
- return (partial.length === 0 ? '{}' : '{' + partial.join(',') + '}');
- }
- };
- stringify = function(value) {
- return json_str('', {
- '': value
- });
- };
- return stringify;
- };
+ SimpleWidget = require('./simple.widget');
- this.Tree.get_json_stringify_function = get_json_stringify_function;
+ MouseWidget = (function(_super) {
+ __extends(MouseWidget, _super);
- if (!((this.JSON != null) && (this.JSON.stringify != null) && typeof this.JSON.stringify === 'function')) {
- if (this.JSON == null) {
- this.JSON = {};
+ function MouseWidget() {
+ return MouseWidget.__super__.constructor.apply(this, arguments);
}
- this.JSON.stringify = get_json_stringify_function();
- }
- SaveStateHandler = (function() {
- function SaveStateHandler(tree_widget) {
- this.tree_widget = tree_widget;
- }
+ MouseWidget.is_mouse_handled = false;
- SaveStateHandler.prototype.saveState = function() {
- var state;
- state = JSON.stringify(this.getState());
- if (this.tree_widget.options.onSetStateFromStorage) {
- return this.tree_widget.options.onSetStateFromStorage(state);
- } else if (this.supportsLocalStorage()) {
- return localStorage.setItem(this.getCookieName(), state);
- } else if ($.cookie) {
- $.cookie.raw = true;
- return $.cookie(this.getCookieName(), state, {
- path: '/'
- });
+ MouseWidget.prototype._init = function() {
+ this.$el.bind('mousedown.mousewidget', $.proxy(this._mouseDown, this));
+ this.$el.bind('touchstart.mousewidget', $.proxy(this._touchStart, this));
+ this.is_mouse_started = false;
+ this.mouse_delay = 0;
+ this._mouse_delay_timer = null;
+ this._is_mouse_delay_met = true;
+ return this.mouse_down_info = null;
+ };
+
+ MouseWidget.prototype._deinit = function() {
+ var $document;
+ this.$el.unbind('mousedown.mousewidget');
+ this.$el.unbind('touchstart.mousewidget');
+ $document = $(document);
+ $document.unbind('mousemove.mousewidget');
+ return $document.unbind('mouseup.mousewidget');
+ };
+
+ MouseWidget.prototype._mouseDown = function(e) {
+ var result;
+ if (e.which !== 1) {
+ return;
+ }
+ result = this._handleMouseDown(e, this._getPositionInfo(e));
+ if (result) {
+ e.preventDefault();
}
+ return result;
};
- SaveStateHandler.prototype.restoreState = function() {
- var state;
- state = this.getStateFromStorage();
- if (state) {
- this.setState(state);
- return true;
- } else {
- return false;
+ MouseWidget.prototype._handleMouseDown = function(e, position_info) {
+ if (MouseWidget.is_mouse_handled) {
+ return;
+ }
+ if (this.is_mouse_started) {
+ this._handleMouseUp(position_info);
+ }
+ this.mouse_down_info = position_info;
+ if (!this._mouseCapture(position_info)) {
+ return;
}
+ this._handleStartMouse();
+ this.is_mouse_handled = true;
+ return true;
};
- SaveStateHandler.prototype.getStateFromStorage = function() {
- var json_data;
- json_data = this._loadFromStorage();
- if (json_data) {
- return this._parseState(json_data);
- } else {
- return null;
+ MouseWidget.prototype._handleStartMouse = function() {
+ var $document;
+ $document = $(document);
+ $document.bind('mousemove.mousewidget', $.proxy(this._mouseMove, this));
+ $document.bind('touchmove.mousewidget', $.proxy(this._touchMove, this));
+ $document.bind('mouseup.mousewidget', $.proxy(this._mouseUp, this));
+ $document.bind('touchend.mousewidget', $.proxy(this._touchEnd, this));
+ if (this.mouse_delay) {
+ return this._startMouseDelayTimer();
}
};
- SaveStateHandler.prototype._parseState = function(json_data) {
- var state;
- state = $.parseJSON(json_data);
- if (state && state.selected_node && isInt(state.selected_node)) {
- state.selected_node = [state.selected_node];
+ MouseWidget.prototype._startMouseDelayTimer = function() {
+ if (this._mouse_delay_timer) {
+ clearTimeout(this._mouse_delay_timer);
}
- return state;
+ this._mouse_delay_timer = setTimeout((function(_this) {
+ return function() {
+ return _this._is_mouse_delay_met = true;
+ };
+ })(this), this.mouse_delay);
+ return this._is_mouse_delay_met = false;
};
- SaveStateHandler.prototype._loadFromStorage = function() {
- if (this.tree_widget.options.onGetStateFromStorage) {
- return this.tree_widget.options.onGetStateFromStorage();
- } else if (this.supportsLocalStorage()) {
- return localStorage.getItem(this.getCookieName());
- } else if ($.cookie) {
- $.cookie.raw = true;
- return $.cookie(this.getCookieName());
+ MouseWidget.prototype._mouseMove = function(e) {
+ return this._handleMouseMove(e, this._getPositionInfo(e));
+ };
+
+ MouseWidget.prototype._handleMouseMove = function(e, position_info) {
+ if (this.is_mouse_started) {
+ this._mouseDrag(position_info);
+ return e.preventDefault();
+ }
+ if (this.mouse_delay && !this._is_mouse_delay_met) {
+ return true;
+ }
+ this.is_mouse_started = this._mouseStart(this.mouse_down_info) !== false;
+ if (this.is_mouse_started) {
+ this._mouseDrag(position_info);
} else {
- return null;
+ this._handleMouseUp(position_info);
}
+ return !this.is_mouse_started;
};
- SaveStateHandler.prototype.getState = function() {
- var getOpenNodeIds, getSelectedNodeIds;
- getOpenNodeIds = (function(_this) {
- return function() {
- var open_nodes;
- open_nodes = [];
- _this.tree_widget.tree.iterate(function(node) {
- if (node.is_open && node.id && node.hasChildren()) {
- open_nodes.push(node.id);
- }
- return true;
- });
- return open_nodes;
- };
- })(this);
- getSelectedNodeIds = (function(_this) {
- return function() {
- var n;
- return (function() {
- var _i, _len, _ref, _results;
- _ref = this.tree_widget.getSelectedNodes();
- _results = [];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- n = _ref[_i];
- _results.push(n.id);
- }
- return _results;
- }).call(_this);
- };
- })(this);
+ MouseWidget.prototype._getPositionInfo = function(e) {
return {
- open_nodes: getOpenNodeIds(),
- selected_node: getSelectedNodeIds()
+ page_x: e.pageX,
+ page_y: e.pageY,
+ target: e.target,
+ original_event: e
};
};
- SaveStateHandler.prototype.setState = function(state) {
- var node_id, open_nodes, selected_node, selected_node_ids, _i, _len, _results;
- if (state) {
- open_nodes = state.open_nodes;
- selected_node_ids = state.selected_node;
- this.tree_widget.tree.iterate((function(_this) {
- return function(node) {
- node.is_open = node.id && node.hasChildren() && (indexOf(open_nodes, node.id) >= 0);
- return true;
- };
- })(this));
- if (selected_node_ids && this.tree_widget.select_node_handler) {
- this.tree_widget.select_node_handler.clear();
- _results = [];
- for (_i = 0, _len = selected_node_ids.length; _i < _len; _i++) {
- node_id = selected_node_ids[_i];
- selected_node = this.tree_widget.getNodeById(node_id);
- if (selected_node) {
- _results.push(this.tree_widget.select_node_handler.addToSelection(selected_node));
- } else {
- _results.push(void 0);
- }
- }
- return _results;
- }
- }
+ MouseWidget.prototype._mouseUp = function(e) {
+ return this._handleMouseUp(this._getPositionInfo(e));
};
- SaveStateHandler.prototype.getCookieName = function() {
- if (typeof this.tree_widget.options.saveState === 'string') {
- return this.tree_widget.options.saveState;
- } else {
- return 'tree';
+ MouseWidget.prototype._handleMouseUp = function(position_info) {
+ var $document;
+ $document = $(document);
+ $document.unbind('mousemove.mousewidget');
+ $document.unbind('touchmove.mousewidget');
+ $document.unbind('mouseup.mousewidget');
+ $document.unbind('touchend.mousewidget');
+ if (this.is_mouse_started) {
+ this.is_mouse_started = false;
+ this._mouseStop(position_info);
}
};
- SaveStateHandler.prototype.supportsLocalStorage = function() {
- var testSupport;
- testSupport = function() {
- var error, key;
- if (typeof localStorage === "undefined" || localStorage === null) {
- return false;
- } else {
- try {
- key = '_storage_test';
- sessionStorage.setItem(key, true);
- sessionStorage.removeItem(key);
- } catch (_error) {
- error = _error;
- return false;
- }
- return true;
- }
- };
- if (this._supportsLocalStorage == null) {
- this._supportsLocalStorage = testSupport();
- }
- return this._supportsLocalStorage;
+ MouseWidget.prototype._mouseCapture = function(position_info) {
+ return true;
};
- SaveStateHandler.prototype.getNodeIdToBeSelected = function() {
- var state;
- state = this.getStateFromStorage();
- if (state && state.selected_node) {
- return state.selected_node[0];
- } else {
- return null;
- }
+ MouseWidget.prototype._mouseStart = function(position_info) {
+ return null;
};
- return SaveStateHandler;
-
- })();
+ MouseWidget.prototype._mouseDrag = function(position_info) {
+ return null;
+ };
- SelectNodeHandler = (function() {
- function SelectNodeHandler(tree_widget) {
- this.tree_widget = tree_widget;
- this.clear();
- }
+ MouseWidget.prototype._mouseStop = function(position_info) {
+ return null;
+ };
- SelectNodeHandler.prototype.getSelectedNode = function() {
- var selected_nodes;
- selected_nodes = this.getSelectedNodes();
- if (selected_nodes.length) {
- return selected_nodes[0];
- } else {
- return false;
- }
+ MouseWidget.prototype.setMouseDelay = function(mouse_delay) {
+ return this.mouse_delay = mouse_delay;
};
- SelectNodeHandler.prototype.getSelectedNodes = function() {
- var id, node, selected_nodes;
- if (this.selected_single_node) {
- return [this.selected_single_node];
- } else {
- selected_nodes = [];
- for (id in this.selected_nodes) {
- node = this.tree_widget.getNodeById(id);
- if (node) {
- selected_nodes.push(node);
- }
- }
- return selected_nodes;
+ MouseWidget.prototype._touchStart = function(e) {
+ var touch;
+ if (e.originalEvent.touches.length > 1) {
+ return;
}
+ touch = e.originalEvent.changedTouches[0];
+ return this._handleMouseDown(e, this._getPositionInfo(touch));
};
- SelectNodeHandler.prototype.getSelectedNodesUnder = function(parent) {
- var id, node, selected_nodes;
- if (this.selected_single_node) {
- if (parent.isParentOf(this.selected_single_node)) {
- return [this.selected_single_node];
- } else {
- return [];
- }
- } else {
- selected_nodes = [];
- for (id in this.selected_nodes) {
- node = this.tree_widget.getNodeById(id);
- if (node && parent.isParentOf(node)) {
- selected_nodes.push(node);
- }
- }
- return selected_nodes;
+ MouseWidget.prototype._touchMove = function(e) {
+ var touch;
+ if (e.originalEvent.touches.length > 1) {
+ return;
}
+ touch = e.originalEvent.changedTouches[0];
+ return this._handleMouseMove(e, this._getPositionInfo(touch));
};
- SelectNodeHandler.prototype.isNodeSelected = function(node) {
- if (node.id) {
- return this.selected_nodes[node.id];
- } else if (this.selected_single_node) {
- return this.selected_single_node.element === node.element;
- } else {
- return false;
+ MouseWidget.prototype._touchEnd = function(e) {
+ var touch;
+ if (e.originalEvent.touches.length > 1) {
+ return;
}
+ touch = e.originalEvent.changedTouches[0];
+ return this._handleMouseUp(this._getPositionInfo(touch));
};
- SelectNodeHandler.prototype.clear = function() {
- this.selected_nodes = {};
- return this.selected_single_node = null;
- };
+ return MouseWidget;
- SelectNodeHandler.prototype.removeFromSelection = function(node, include_children) {
- if (include_children == null) {
- include_children = false;
- }
- if (!node.id) {
- if (this.selected_single_node && node.element === this.selected_single_node.element) {
- return this.selected_single_node = null;
- }
- } else {
- delete this.selected_nodes[node.id];
- if (include_children) {
- return node.iterate((function(_this) {
- return function(n) {
- delete _this.selected_nodes[node.id];
- return true;
- };
- })(this));
+ })(SimpleWidget);
+
+ module.exports = MouseWidget;
+
+}).call(this);
+
+},{"./simple.widget":11}],6:[function(require,module,exports){
+(function() {
+ var Node, Position;
+
+ Position = {
+ getName: function(position) {
+ return Position.strings[position - 1];
+ },
+ nameToIndex: function(name) {
+ var i, _i, _ref;
+ for (i = _i = 1, _ref = Position.strings.length; 1 <= _ref ? _i <= _ref : _i >= _ref; i = 1 <= _ref ? ++_i : --_i) {
+ if (Position.strings[i - 1] === name) {
+ return i;
}
}
- };
+ return 0;
+ }
+ };
- SelectNodeHandler.prototype.addToSelection = function(node) {
- if (node.id) {
- return this.selected_nodes[node.id] = true;
- } else {
- return this.selected_single_node = node;
- }
- };
+ Position.BEFORE = 1;
- return SelectNodeHandler;
+ Position.AFTER = 2;
- })();
+ Position.INSIDE = 3;
- DragAndDropHandler = (function() {
- function DragAndDropHandler(tree_widget) {
- this.tree_widget = tree_widget;
- this.hovered_area = null;
- this.$ghost = null;
- this.hit_areas = [];
- this.is_dragging = false;
- this.current_item = null;
- }
+ Position.NONE = 4;
- DragAndDropHandler.prototype.mouseCapture = function(position_info) {
- var $element, node_element;
- $element = $(position_info.target);
- if (!this.mustCaptureElement($element)) {
- return null;
- }
- if (this.tree_widget.options.onIsMoveHandle && !this.tree_widget.options.onIsMoveHandle($element)) {
- return null;
+ Position.strings = ['before', 'after', 'inside', 'none'];
+
+ Node = (function() {
+ function Node(o, is_root, node_class) {
+ if (is_root == null) {
+ is_root = false;
}
- node_element = this.tree_widget._getNodeElement($element);
- if (node_element && this.tree_widget.options.onCanMove) {
- if (!this.tree_widget.options.onCanMove(node_element.node)) {
- node_element = null;
- }
+ if (node_class == null) {
+ node_class = Node;
}
- this.current_item = node_element;
- return this.current_item !== null;
- };
-
- DragAndDropHandler.prototype.mouseStart = function(position_info) {
- var offset;
- this.refresh();
- offset = $(position_info.target).offset();
- 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);
- this.is_dragging = true;
- this.current_item.$element.addClass('jqtree-moving');
- return true;
- };
+ this.setData(o);
+ this.children = [];
+ this.parent = null;
+ if (is_root) {
+ this.id_mapping = {};
+ this.tree = this;
+ this.node_class = node_class;
+ }
+ }
- DragAndDropHandler.prototype.mouseDrag = function(position_info) {
- var area, can_move_to;
- this.drag_element.move(position_info.page_x, position_info.page_y);
- area = this.findHoveredArea(position_info.page_x, position_info.page_y);
- can_move_to = this.canMoveToArea(area);
- if (can_move_to && area) {
- if (!area.node.isFolder()) {
- this.stopOpenFolderTimer();
- }
- if (this.hovered_area !== area) {
- this.hovered_area = area;
- if (this.mustOpenFolderTimer(area)) {
- this.startOpenFolderTimer(area.node);
+ Node.prototype.setData = function(o) {
+ var key, value, _results;
+ if (typeof o !== 'object') {
+ return this.name = o;
+ } else {
+ _results = [];
+ for (key in o) {
+ value = o[key];
+ if (key === 'label') {
+ _results.push(this.name = value);
} else {
- this.stopOpenFolderTimer();
+ _results.push(this[key] = value);
}
- this.updateDropHint();
}
- } else {
- this.removeHover();
- this.removeDropHint();
- this.stopOpenFolderTimer();
+ return _results;
}
- return true;
};
- DragAndDropHandler.prototype.mustCaptureElement = function($element) {
- return !$element.is('input,select');
+ Node.prototype.initFromData = function(data) {
+ var addChildren, addNode;
+ addNode = (function(_this) {
+ return function(node_data) {
+ _this.setData(node_data);
+ if (node_data.children) {
+ return addChildren(node_data.children);
+ }
+ };
+ })(this);
+ addChildren = (function(_this) {
+ return function(children_data) {
+ var child, node, _i, _len;
+ for (_i = 0, _len = children_data.length; _i < _len; _i++) {
+ child = children_data[_i];
+ node = new _this.tree.node_class('');
+ node.initFromData(child);
+ _this.addChild(node);
+ }
+ return null;
+ };
+ })(this);
+ addNode(data);
+ return null;
};
- DragAndDropHandler.prototype.canMoveToArea = function(area) {
- var position_name;
- if (!area) {
- return false;
- } else if (this.tree_widget.options.onCanMoveTo) {
- position_name = Position.getName(area.position);
- return this.tree_widget.options.onCanMoveTo(this.current_item.node, area.node, position_name);
- } else {
- return true;
- }
- };
- DragAndDropHandler.prototype.mouseStop = function(position_info) {
- this.moveItem(position_info);
- this.clear();
- this.removeHover();
- this.removeDropHint();
- this.removeHitAreas();
- if (this.current_item) {
- this.current_item.$element.removeClass('jqtree-moving');
- this.current_item = null;
- }
- this.is_dragging = false;
- return false;
- };
+ /*
+ Create tree from data.
+
+ Structure of data is:
+ [
+ {
+ label: 'node1',
+ children: [
+ { label: 'child1' },
+ { label: 'child2' }
+ ]
+ },
+ {
+ label: 'node2'
+ }
+ ]
+ */
- DragAndDropHandler.prototype.refresh = function() {
- this.removeHitAreas();
- if (this.current_item) {
- this.generateHitAreas();
- this.current_item = this.tree_widget._getNodeElementForNode(this.current_item.node);
- if (this.is_dragging) {
- return this.current_item.$element.addClass('jqtree-moving');
+ Node.prototype.loadFromData = function(data) {
+ var node, o, _i, _len;
+ this.removeChildren();
+ for (_i = 0, _len = data.length; _i < _len; _i++) {
+ o = data[_i];
+ node = new this.tree.node_class(o);
+ this.addChild(node);
+ if (typeof o === 'object' && o.children) {
+ node.loadFromData(o.children);
}
}
+ return null;
};
- DragAndDropHandler.prototype.removeHitAreas = function() {
- return this.hit_areas = [];
- };
- DragAndDropHandler.prototype.clear = function() {
- this.drag_element.remove();
- return this.drag_element = null;
- };
+ /*
+ Add child.
+
+ tree.addChild(
+ new Node('child1')
+ );
+ */
- DragAndDropHandler.prototype.removeDropHint = function() {
- if (this.previous_ghost) {
- return this.previous_ghost.remove();
- }
+ Node.prototype.addChild = function(node) {
+ this.children.push(node);
+ return node._setParent(this);
};
- DragAndDropHandler.prototype.removeHover = function() {
- return this.hovered_area = null;
- };
- DragAndDropHandler.prototype.generateHitAreas = function() {
- var hit_areas_generator;
- hit_areas_generator = new HitAreasGenerator(this.tree_widget.tree, this.current_item.node, this.getTreeDimensions().bottom);
- return this.hit_areas = hit_areas_generator.generate();
- };
+ /*
+ Add child at position. Index starts at 0.
+
+ tree.addChildAtPosition(
+ new Node('abc'),
+ 1
+ );
+ */
- DragAndDropHandler.prototype.findHoveredArea = function(x, y) {
- var area, dimensions, high, low, mid;
- dimensions = this.getTreeDimensions();
- if (x < dimensions.left || y < dimensions.top || x > dimensions.right || y > dimensions.bottom) {
- return null;
- }
- low = 0;
- high = this.hit_areas.length;
- while (low < high) {
- mid = (low + high) >> 1;
- area = this.hit_areas[mid];
- if (y < area.top) {
- high = mid;
- } else if (y > area.bottom) {
- low = mid + 1;
- } else {
- return area;
- }
- }
- return null;
+ Node.prototype.addChildAtPosition = function(node, index) {
+ this.children.splice(index, 0, node);
+ return node._setParent(this);
};
- DragAndDropHandler.prototype.mustOpenFolderTimer = function(area) {
- var node;
- node = area.node;
- return node.isFolder() && !node.is_open && area.position === Position.INSIDE;
+ Node.prototype._setParent = function(parent) {
+ this.parent = parent;
+ this.tree = parent.tree;
+ return this.tree.addNodeToIndex(this);
};
- DragAndDropHandler.prototype.updateDropHint = function() {
- var node_element;
- if (!this.hovered_area) {
- return;
- }
- this.removeDropHint();
- node_element = this.tree_widget._getNodeElementForNode(this.hovered_area.node);
- return this.previous_ghost = node_element.addDropHint(this.hovered_area.position);
- };
- DragAndDropHandler.prototype.startOpenFolderTimer = function(folder) {
- var openFolder;
- openFolder = (function(_this) {
- return function() {
- return _this.tree_widget._openNode(folder, _this.tree_widget.options.slide, function() {
- _this.refresh();
- return _this.updateDropHint();
- });
- };
- })(this);
- this.stopOpenFolderTimer();
- return this.open_folder_timer = setTimeout(openFolder, this.tree_widget.options.openFolderDelay);
- };
+ /*
+ Remove child. This also removes the children of the node.
+
+ tree.removeChild(tree.children[0]);
+ */
- DragAndDropHandler.prototype.stopOpenFolderTimer = function() {
- if (this.open_folder_timer) {
- clearTimeout(this.open_folder_timer);
- return this.open_folder_timer = null;
- }
+ Node.prototype.removeChild = function(node) {
+ node.removeChildren();
+ return this._removeChild(node);
};
- DragAndDropHandler.prototype.moveItem = function(position_info) {
- var doMove, event, moved_node, position, previous_parent, target_node;
- if (this.hovered_area && this.hovered_area.position !== Position.NONE && this.canMoveToArea(this.hovered_area)) {
- moved_node = this.current_item.node;
- target_node = this.hovered_area.node;
- position = this.hovered_area.position;
- previous_parent = moved_node.parent;
- if (position === Position.INSIDE) {
- this.hovered_area.node.is_open = true;
- }
- doMove = (function(_this) {
- return function() {
- _this.tree_widget.tree.moveNode(moved_node, target_node, position);
- _this.tree_widget.element.empty();
- return _this.tree_widget._refreshElements();
- };
- })(this);
- event = this.tree_widget._triggerEvent('tree.move', {
- move_info: {
- moved_node: moved_node,
- target_node: target_node,
- position: Position.getName(position),
- previous_parent: previous_parent,
- do_move: doMove,
- original_event: position_info.original_event
- }
- });
- if (!event.isDefaultPrevented()) {
- return doMove();
- }
- }
+ Node.prototype._removeChild = function(node) {
+ this.children.splice(this.getChildIndex(node), 1);
+ return this.tree.removeNodeFromIndex(node);
};
- DragAndDropHandler.prototype.getTreeDimensions = function() {
- var offset;
- offset = this.tree_widget.element.offset();
- return {
- left: offset.left,
- top: offset.top,
- right: offset.left + this.tree_widget.element.width(),
- bottom: offset.top + this.tree_widget.element.height() + 16
- };
- };
- return DragAndDropHandler;
+ /*
+ Get child index.
+
+ var index = getChildIndex(node);
+ */
- })();
+ Node.prototype.getChildIndex = function(node) {
+ return $.inArray(node, this.children);
+ };
- VisibleNodeIterator = (function() {
- function VisibleNodeIterator(tree) {
- this.tree = tree;
+
+ /*
+ Does the tree have children?
+
+ if (tree.hasChildren()) {
+ //
}
+ */
- VisibleNodeIterator.prototype.iterate = function() {
- var is_first_node, _iterateNode;
- is_first_node = true;
- _iterateNode = (function(_this) {
- return function(node, next_node) {
- var $element, child, children_length, i, must_iterate_inside, _i, _len, _ref;
- must_iterate_inside = (node.is_open || !node.element) && node.hasChildren();
- if (node.element) {
- $element = $(node.element);
- if (!$element.is(':visible')) {
- return;
- }
- if (is_first_node) {
- _this.handleFirstNode(node, $element);
- is_first_node = false;
- }
- if (!node.hasChildren()) {
- _this.handleNode(node, next_node, $element);
- } else if (node.is_open) {
- if (!_this.handleOpenFolder(node, $element)) {
- must_iterate_inside = false;
- }
- } else {
- _this.handleClosedFolder(node, next_node, $element);
- }
- }
- if (must_iterate_inside) {
- children_length = node.children.length;
+ Node.prototype.hasChildren = function() {
+ return this.children.length !== 0;
+ };
+
+ Node.prototype.isFolder = function() {
+ return this.hasChildren() || this.load_on_demand;
+ };
+
+
+ /*
+ Iterate over all the nodes in the tree.
+
+ Calls callback with (node, level).
+
+ The callback must return true to continue the iteration on current node.
+
+ tree.iterate(
+ function(node, level) {
+ console.log(node.name);
+
+ // stop iteration after level 2
+ return (level <= 2);
+ }
+ );
+ */
+
+ Node.prototype.iterate = function(callback) {
+ var _iterate;
+ _iterate = (function(_this) {
+ return function(node, level) {
+ var child, result, _i, _len, _ref;
+ if (node.children) {
_ref = node.children;
- for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
- child = _ref[i];
- if (i === (children_length - 1)) {
- _iterateNode(node.children[i], null);
- } else {
- _iterateNode(node.children[i], node.children[i + 1]);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ child = _ref[_i];
+ result = callback(child, level);
+ if (_this.hasChildren() && result) {
+ _iterate(child, level + 1);
}
}
- if (node.is_open) {
- return _this.handleAfterOpenFolder(node, next_node, $element);
- }
+ return null;
}
};
})(this);
- return _iterateNode(this.tree, null);
+ _iterate(this, 0);
+ return null;
};
- VisibleNodeIterator.prototype.handleNode = function(node, next_node, $element) {};
-
- VisibleNodeIterator.prototype.handleOpenFolder = function(node, $element) {};
-
- VisibleNodeIterator.prototype.handleClosedFolder = function(node, next_node, $element) {};
-
- VisibleNodeIterator.prototype.handleAfterOpenFolder = function(node, next_node, $element) {};
-
- VisibleNodeIterator.prototype.handleFirstNode = function(node, $element) {};
-
- return VisibleNodeIterator;
- })();
+ /*
+ Move node relative to another node.
+
+ Argument position: Position.BEFORE, Position.AFTER or Position.Inside
+
+ // move node1 after node2
+ tree.moveNode(node1, node2, Position.AFTER);
+ */
- HitAreasGenerator = (function(_super) {
- __extends(HitAreasGenerator, _super);
+ Node.prototype.moveNode = function(moved_node, target_node, position) {
+ if (moved_node.isParentOf(target_node)) {
+ return;
+ }
+ moved_node.parent._removeChild(moved_node);
+ if (position === Position.AFTER) {
+ return target_node.parent.addChildAtPosition(moved_node, target_node.parent.getChildIndex(target_node) + 1);
+ } else if (position === Position.BEFORE) {
+ return target_node.parent.addChildAtPosition(moved_node, target_node.parent.getChildIndex(target_node));
+ } else if (position === Position.INSIDE) {
+ return target_node.addChildAtPosition(moved_node, 0);
+ }
+ };
- function HitAreasGenerator(tree, current_node, tree_bottom) {
- HitAreasGenerator.__super__.constructor.call(this, tree);
- this.current_node = current_node;
- this.tree_bottom = tree_bottom;
- }
- HitAreasGenerator.prototype.generate = function() {
- this.positions = [];
- this.last_top = 0;
- this.iterate();
- return this.generateHitAreas(this.positions);
- };
+ /*
+ Get the tree as data.
+ */
- HitAreasGenerator.prototype.getTop = function($element) {
- return $element.offset().top;
+ Node.prototype.getData = function() {
+ var getDataFromNodes;
+ getDataFromNodes = (function(_this) {
+ return function(nodes) {
+ var data, k, node, tmp_node, v, _i, _len;
+ data = [];
+ for (_i = 0, _len = nodes.length; _i < _len; _i++) {
+ node = nodes[_i];
+ tmp_node = {};
+ for (k in node) {
+ v = node[k];
+ if ((k !== 'parent' && k !== 'children' && k !== 'element' && k !== 'tree') && Object.prototype.hasOwnProperty.call(node, k)) {
+ tmp_node[k] = v;
+ }
+ }
+ if (node.hasChildren()) {
+ tmp_node.children = getDataFromNodes(node.children);
+ }
+ data.push(tmp_node);
+ }
+ return data;
+ };
+ })(this);
+ return getDataFromNodes(this.children);
};
- HitAreasGenerator.prototype.addPosition = function(node, position, top) {
- var area;
- area = {
- top: top,
- node: node,
- position: position
- };
- this.positions.push(area);
- return this.last_top = top;
+ Node.prototype.getNodeByName = function(name) {
+ var result;
+ result = null;
+ this.iterate(function(node) {
+ if (node.name === name) {
+ result = node;
+ return false;
+ } else {
+ return true;
+ }
+ });
+ return result;
};
- HitAreasGenerator.prototype.handleNode = function(node, next_node, $element) {
- var top;
- top = this.getTop($element);
- if (node === this.current_node) {
- this.addPosition(node, Position.NONE, top);
- } else {
- this.addPosition(node, Position.INSIDE, top);
- }
- if (next_node === this.current_node || node === this.current_node) {
- return this.addPosition(node, Position.NONE, top);
+ Node.prototype.addAfter = function(node_info) {
+ var child_index, node;
+ if (!this.parent) {
+ return null;
} else {
- return this.addPosition(node, Position.AFTER, top);
+ node = new this.tree.node_class(node_info);
+ child_index = this.parent.getChildIndex(this);
+ this.parent.addChildAtPosition(node, child_index + 1);
+ return node;
}
};
- HitAreasGenerator.prototype.handleOpenFolder = function(node, $element) {
- if (node === this.current_node) {
- return false;
- }
- if (node.children[0] !== this.current_node) {
- this.addPosition(node, Position.INSIDE, this.getTop($element));
+ Node.prototype.addBefore = function(node_info) {
+ var child_index, node;
+ if (!this.parent) {
+ return null;
+ } else {
+ node = new this.tree.node_class(node_info);
+ child_index = this.parent.getChildIndex(this);
+ this.parent.addChildAtPosition(node, child_index);
+ return node;
}
- return true;
};
- HitAreasGenerator.prototype.handleClosedFolder = function(node, next_node, $element) {
- var top;
- top = this.getTop($element);
- if (node === this.current_node) {
- return this.addPosition(node, Position.NONE, top);
+ Node.prototype.addParent = function(node_info) {
+ var child, new_parent, original_parent, _i, _len, _ref;
+ if (!this.parent) {
+ return null;
} else {
- this.addPosition(node, Position.INSIDE, top);
- if (next_node !== this.current_node) {
- return this.addPosition(node, Position.AFTER, top);
+ new_parent = new this.tree.node_class(node_info);
+ new_parent._setParent(this.tree);
+ original_parent = this.parent;
+ _ref = original_parent.children;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ child = _ref[_i];
+ new_parent.addChild(child);
}
+ original_parent.children = [];
+ original_parent.addChild(new_parent);
+ return new_parent;
}
};
- HitAreasGenerator.prototype.handleFirstNode = function(node, $element) {
- if (node !== this.current_node) {
- return this.addPosition(node, Position.BEFORE, this.getTop($(node.element)));
+ Node.prototype.remove = function() {
+ if (this.parent) {
+ this.parent.removeChild(this);
+ return this.parent = null;
}
};
- HitAreasGenerator.prototype.handleAfterOpenFolder = function(node, next_node, $element) {
- if (node === this.current_node.node || next_node === this.current_node.node) {
- return this.addPosition(node, Position.NONE, this.last_top);
- } else {
- return this.addPosition(node, Position.AFTER, this.last_top);
- }
+ Node.prototype.append = function(node_info) {
+ var node;
+ node = new this.tree.node_class(node_info);
+ this.addChild(node);
+ return node;
};
- HitAreasGenerator.prototype.generateHitAreas = function(positions) {
- var group, hit_areas, position, previous_top, _i, _len;
- previous_top = -1;
- group = [];
- hit_areas = [];
- for (_i = 0, _len = positions.length; _i < _len; _i++) {
- position = positions[_i];
- if (position.top !== previous_top && group.length) {
- if (group.length) {
- this.generateHitAreasForGroup(hit_areas, group, previous_top, position.top);
- }
- previous_top = position.top;
- group = [];
+ Node.prototype.prepend = function(node_info) {
+ var node;
+ node = new this.tree.node_class(node_info);
+ this.addChildAtPosition(node, 0);
+ return node;
+ };
+
+ Node.prototype.isParentOf = function(node) {
+ var parent;
+ parent = node.parent;
+ while (parent) {
+ if (parent === this) {
+ return true;
}
- group.push(position);
+ parent = parent.parent;
}
- this.generateHitAreasForGroup(hit_areas, group, previous_top, this.tree_bottom);
- return hit_areas;
+ return false;
};
- HitAreasGenerator.prototype.generateHitAreasForGroup = function(hit_areas, positions_in_group, top, bottom) {
- var area_height, area_top, i, position, position_count;
- position_count = Math.min(positions_in_group.length, 4);
- area_height = Math.round((bottom - top) / position_count);
- area_top = top;
- i = 0;
- while (i < position_count) {
- position = positions_in_group[i];
- hit_areas.push({
- top: area_top,
- bottom: area_top + area_height,
- node: position.node,
- position: position.position
- });
- area_top += area_height;
- i += 1;
+ Node.prototype.getLevel = function() {
+ var level, node;
+ level = 0;
+ node = this;
+ while (node.parent) {
+ level += 1;
+ node = node.parent;
}
- return null;
+ return level;
};
- return HitAreasGenerator;
-
- })(VisibleNodeIterator);
-
- DragElement = (function() {
- function DragElement(node, offset_x, offset_y, $tree) {
- this.offset_x = offset_x;
- this.offset_y = offset_y;
- this.$element = $("" + node.name + "");
- this.$element.css("position", "absolute");
- $tree.append(this.$element);
- }
-
- DragElement.prototype.move = function(page_x, page_y) {
- return this.$element.offset({
- left: page_x - this.offset_x,
- top: page_y - this.offset_y
- });
+ Node.prototype.getNodeById = function(node_id) {
+ return this.id_mapping[node_id];
};
- DragElement.prototype.remove = function() {
- return this.$element.remove();
+ Node.prototype.addNodeToIndex = function(node) {
+ if (node.id != null) {
+ return this.id_mapping[node.id] = node;
+ }
};
- return DragElement;
+ Node.prototype.removeNodeFromIndex = function(node) {
+ if (node.id != null) {
+ return delete this.id_mapping[node.id];
+ }
+ };
- })();
+ Node.prototype.removeChildren = function() {
+ this.iterate((function(_this) {
+ return function(child) {
+ _this.tree.removeNodeFromIndex(child);
+ return true;
+ };
+ })(this));
+ return this.children = [];
+ };
- GhostDropHint = (function() {
- function GhostDropHint(node, $element, position) {
- this.$element = $element;
- this.node = node;
- this.$ghost = $('');
- if (position === Position.AFTER) {
- this.moveAfter();
- } else if (position === Position.BEFORE) {
- this.moveBefore();
- } else if (position === Position.INSIDE) {
- if (node.isFolder() && node.is_open) {
- this.moveInsideOpenFolder();
+ Node.prototype.getPreviousSibling = function() {
+ var previous_index;
+ if (!this.parent) {
+ return null;
+ } else {
+ previous_index = this.parent.getChildIndex(this) - 1;
+ if (previous_index >= 0) {
+ return this.parent.children[previous_index];
} else {
- this.moveInside();
+ return null;
}
}
- }
-
- GhostDropHint.prototype.remove = function() {
- return this.$ghost.remove();
- };
-
- GhostDropHint.prototype.moveAfter = function() {
- return this.$element.after(this.$ghost);
};
- GhostDropHint.prototype.moveBefore = function() {
- return this.$element.before(this.$ghost);
+ Node.prototype.getNextSibling = function() {
+ var next_index;
+ if (!this.parent) {
+ return null;
+ } else {
+ next_index = this.parent.getChildIndex(this) + 1;
+ if (next_index < this.parent.children.length) {
+ return this.parent.children[next_index];
+ } else {
+ return null;
+ }
+ }
};
- GhostDropHint.prototype.moveInsideOpenFolder = function() {
- return $(this.node.children[0].element).before(this.$ghost);
+ Node.prototype.getNodesByProperty = function(key, value) {
+ return this.filter(function(node) {
+ return node[key] === value;
+ });
};
- GhostDropHint.prototype.moveInside = function() {
- this.$element.after(this.$ghost);
- return this.$ghost.addClass('jqtree-inside');
+ Node.prototype.filter = function(f) {
+ var result;
+ result = [];
+ this.iterate(function(node) {
+ if (f(node)) {
+ result.push(node);
+ }
+ return true;
+ });
+ return result;
};
- return GhostDropHint;
+ return Node;
})();
- BorderDropHint = (function() {
- function BorderDropHint($element) {
- var $div, width;
- $div = $element.children('.jqtree-element');
- width = $element.width() - 4;
- this.$hint = $('');
- $div.append(this.$hint);
- this.$hint.css({
- width: width,
- height: $div.height() - 4
- });
- }
+ module.exports = {
+ Node: Node,
+ Position: Position
+ };
- BorderDropHint.prototype.remove = function() {
- return this.$hint.remove();
- };
+}).call(this);
- return BorderDropHint;
+},{}],7:[function(require,module,exports){
+(function() {
+ var BorderDropHint, FolderElement, GhostDropHint, NodeElement, Position, node,
+ __hasProp = {}.hasOwnProperty,
+ __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; };
- })();
+ node = require('./node');
- ScrollHandler = (function() {
- function ScrollHandler(tree_widget) {
- this.tree_widget = tree_widget;
- this.previous_top = -1;
- this._initScrollParent();
+ Position = node.Position;
+
+ NodeElement = (function() {
+ function NodeElement(node, tree_widget) {
+ this.init(node, tree_widget);
}
- ScrollHandler.prototype._initScrollParent = function() {
- var $scroll_parent, getParentWithOverflow, setDocumentAsScrollParent;
- getParentWithOverflow = (function(_this) {
- return function() {
- var css_values, el, hasOverFlow, _i, _len, _ref;
- css_values = ['overflow', 'overflow-y'];
- hasOverFlow = function(el) {
- var css_value, _i, _len, _ref;
- for (_i = 0, _len = css_values.length; _i < _len; _i++) {
- css_value = css_values[_i];
- if ((_ref = $.css(el, css_value)) === 'auto' || _ref === 'scroll') {
- return true;
- }
- }
- return false;
- };
- if (hasOverFlow(_this.tree_widget.$el[0])) {
- return _this.tree_widget.$el;
- }
- _ref = _this.tree_widget.$el.parents();
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- el = _ref[_i];
- if (hasOverFlow(el)) {
- return $(el);
- }
- }
- return null;
- };
- })(this);
- setDocumentAsScrollParent = (function(_this) {
- return function() {
- _this.scroll_parent_top = 0;
- return _this.$scroll_parent = null;
- };
- })(this);
- if (this.tree_widget.$el.css('position') === 'fixed') {
- setDocumentAsScrollParent();
+ NodeElement.prototype.init = function(node, tree_widget) {
+ this.node = node;
+ this.tree_widget = tree_widget;
+ if (!node.element) {
+ node.element = this.tree_widget.element;
}
- $scroll_parent = getParentWithOverflow();
- if ($scroll_parent && $scroll_parent.length && $scroll_parent[0].tagName !== 'HTML') {
- this.$scroll_parent = $scroll_parent;
- return this.scroll_parent_top = this.$scroll_parent.offset().top;
+ return this.$element = $(node.element);
+ };
+
+ NodeElement.prototype.getUl = function() {
+ return this.$element.children('ul:first');
+ };
+
+ NodeElement.prototype.getSpan = function() {
+ return this.$element.children('.jqtree-element').find('span.jqtree-title');
+ };
+
+ NodeElement.prototype.getLi = function() {
+ return this.$element;
+ };
+
+ NodeElement.prototype.addDropHint = function(position) {
+ if (position === Position.INSIDE) {
+ return new BorderDropHint(this.$element);
} else {
- return setDocumentAsScrollParent();
+ return new GhostDropHint(this.node, this.$element, position);
}
};
- ScrollHandler.prototype.checkScrolling = function() {
- var hovered_area;
- hovered_area = this.tree_widget.dnd_handler.hovered_area;
- if (hovered_area && hovered_area.top !== this.previous_top) {
- this.previous_top = hovered_area.top;
- if (this.$scroll_parent) {
- return this._handleScrollingWithScrollParent(hovered_area);
+ NodeElement.prototype.select = function() {
+ return this.getLi().addClass('jqtree-selected');
+ };
+
+ NodeElement.prototype.deselect = function() {
+ return this.getLi().removeClass('jqtree-selected');
+ };
+
+ return NodeElement;
+
+ })();
+
+ FolderElement = (function(_super) {
+ __extends(FolderElement, _super);
+
+ function FolderElement() {
+ return FolderElement.__super__.constructor.apply(this, arguments);
+ }
+
+ FolderElement.prototype.open = function(on_finished, slide) {
+ var $button, doOpen;
+ if (slide == null) {
+ slide = true;
+ }
+ if (!this.node.is_open) {
+ this.node.is_open = true;
+ $button = this.getButton();
+ $button.removeClass('jqtree-closed');
+ $button.html('');
+ $button.append(this.tree_widget.renderer.opened_icon_element.cloneNode());
+ doOpen = (function(_this) {
+ return function() {
+ _this.getLi().removeClass('jqtree-closed');
+ if (on_finished) {
+ on_finished();
+ }
+ return _this.tree_widget._triggerEvent('tree.open', {
+ node: _this.node
+ });
+ };
+ })(this);
+ if (slide) {
+ return this.getUl().slideDown('fast', doOpen);
} else {
- return this._handleScrollingWithDocument(hovered_area);
+ this.getUl().show();
+ return doOpen();
}
}
};
- ScrollHandler.prototype._handleScrollingWithScrollParent = function(area) {
- var distance_bottom;
- distance_bottom = this.scroll_parent_top + this.$scroll_parent[0].offsetHeight - area.bottom;
- if (distance_bottom < 20) {
- this.$scroll_parent[0].scrollTop += 20;
- this.tree_widget.refreshHitAreas();
- return this.previous_top = -1;
- } else if ((area.top - this.scroll_parent_top) < 20) {
- this.$scroll_parent[0].scrollTop -= 20;
- this.tree_widget.refreshHitAreas();
- return this.previous_top = -1;
+ FolderElement.prototype.close = function(slide) {
+ var $button, doClose;
+ if (slide == null) {
+ slide = true;
}
- };
-
- ScrollHandler.prototype._handleScrollingWithDocument = function(area) {
- var distance_top;
- distance_top = area.top - $(document).scrollTop();
- if (distance_top < 20) {
- return $(document).scrollTop($(document).scrollTop() - 20);
- } else if ($(window).height() - (area.bottom - $(document).scrollTop()) < 20) {
- return $(document).scrollTop($(document).scrollTop() + 20);
+ if (this.node.is_open) {
+ this.node.is_open = false;
+ $button = this.getButton();
+ $button.addClass('jqtree-closed');
+ $button.html('');
+ $button.append(this.tree_widget.renderer.closed_icon_element.cloneNode());
+ doClose = (function(_this) {
+ return function() {
+ _this.getLi().addClass('jqtree-closed');
+ return _this.tree_widget._triggerEvent('tree.close', {
+ node: _this.node
+ });
+ };
+ })(this);
+ if (slide) {
+ return this.getUl().slideUp('fast', doClose);
+ } else {
+ this.getUl().hide();
+ return doClose();
+ }
}
};
- ScrollHandler.prototype.scrollTo = function(top) {
- var tree_top;
- if (this.$scroll_parent) {
- return this.$scroll_parent[0].scrollTop = top;
- } else {
- tree_top = this.tree_widget.$el.offset().top;
- return $(document).scrollTop(top + tree_top);
- }
+ FolderElement.prototype.getButton = function() {
+ return this.$element.children('.jqtree-element').find('a.jqtree-toggler');
};
- ScrollHandler.prototype.isScrolledIntoView = function(element) {
- var $element, element_bottom, element_top, view_bottom, view_top;
- $element = $(element);
- if (this.$scroll_parent) {
- view_top = 0;
- view_bottom = this.$scroll_parent.height();
- element_top = $element.offset().top - this.scroll_parent_top;
- element_bottom = element_top + $element.height();
+ FolderElement.prototype.addDropHint = function(position) {
+ if (!this.node.is_open && position === Position.INSIDE) {
+ return new BorderDropHint(this.$element);
} else {
- view_top = $(window).scrollTop();
- view_bottom = view_top + $(window).height();
- element_top = $element.offset().top;
- element_bottom = element_top + $element.height();
+ return new GhostDropHint(this.node, this.$element, position);
}
- return (element_bottom <= view_bottom) && (element_top >= view_top);
};
- return ScrollHandler;
-
- })();
+ return FolderElement;
- KeyHandler = (function() {
- var DOWN, LEFT, RIGHT, UP;
+ })(NodeElement);
- LEFT = 37;
+ BorderDropHint = (function() {
+ function BorderDropHint($element) {
+ var $div, width;
+ $div = $element.children('.jqtree-element');
+ width = $element.width() - 4;
+ this.$hint = $('');
+ $div.append(this.$hint);
+ this.$hint.css({
+ width: width,
+ height: $div.height() - 4
+ });
+ }
- UP = 38;
+ BorderDropHint.prototype.remove = function() {
+ return this.$hint.remove();
+ };
- RIGHT = 39;
+ return BorderDropHint;
- DOWN = 40;
+ })();
- function KeyHandler(tree_widget) {
- this.tree_widget = tree_widget;
- if (tree_widget.options.keyboardSupport) {
- $(document).bind('keydown.jqtree', $.proxy(this.handleKeyDown, this));
+ GhostDropHint = (function() {
+ function GhostDropHint(node, $element, position) {
+ this.$element = $element;
+ this.node = node;
+ this.$ghost = $('');
+ if (position === Position.AFTER) {
+ this.moveAfter();
+ } else if (position === Position.BEFORE) {
+ this.moveBefore();
+ } else if (position === Position.INSIDE) {
+ if (node.isFolder() && node.is_open) {
+ this.moveInsideOpenFolder();
+ } else {
+ this.moveInside();
+ }
}
}
- KeyHandler.prototype.deinit = function() {
- return $(document).unbind('keydown.jqtree');
+ GhostDropHint.prototype.remove = function() {
+ return this.$ghost.remove();
};
- KeyHandler.prototype.handleKeyDown = function(e) {
- var current_node, key, moveDown, moveLeft, moveRight, moveUp, selectNode;
- if (!this.tree_widget.options.keyboardSupport) {
- return;
- }
- if ($(document.activeElement).is('textarea,input,select')) {
- return true;
- }
- current_node = this.tree_widget.getSelectedNode();
- selectNode = (function(_this) {
- return function(node) {
- if (node) {
- _this.tree_widget.selectNode(node);
- if (_this.tree_widget.scroll_handler && (!_this.tree_widget.scroll_handler.isScrolledIntoView($(node.element).find('.jqtree-element')))) {
- _this.tree_widget.scrollToNode(node);
- }
- return false;
- } else {
- return true;
- }
- };
- })(this);
- moveDown = (function(_this) {
- return function() {
- return selectNode(_this.getNextNode(current_node));
- };
- })(this);
- moveUp = (function(_this) {
+ GhostDropHint.prototype.moveAfter = function() {
+ return this.$element.after(this.$ghost);
+ };
+
+ GhostDropHint.prototype.moveBefore = function() {
+ return this.$element.before(this.$ghost);
+ };
+
+ GhostDropHint.prototype.moveInsideOpenFolder = function() {
+ return $(this.node.children[0].element).before(this.$ghost);
+ };
+
+ GhostDropHint.prototype.moveInside = function() {
+ this.$element.after(this.$ghost);
+ return this.$ghost.addClass('jqtree-inside');
+ };
+
+ return GhostDropHint;
+
+ })();
+
+ module.exports = {
+ FolderElement: FolderElement,
+ NodeElement: NodeElement
+ };
+
+}).call(this);
+
+},{"./node":6}],8:[function(require,module,exports){
+(function() {
+ var SaveStateHandler, indexOf, isInt, util;
+
+ util = require('./util');
+
+ indexOf = util.indexOf;
+
+ isInt = util.isInt;
+
+ SaveStateHandler = (function() {
+ function SaveStateHandler(tree_widget) {
+ this.tree_widget = tree_widget;
+ }
+
+ SaveStateHandler.prototype.saveState = function() {
+ var state;
+ state = JSON.stringify(this.getState());
+ if (this.tree_widget.options.onSetStateFromStorage) {
+ return this.tree_widget.options.onSetStateFromStorage(state);
+ } else if (this.supportsLocalStorage()) {
+ return localStorage.setItem(this.getCookieName(), state);
+ } else if ($.cookie) {
+ $.cookie.raw = true;
+ return $.cookie(this.getCookieName(), state, {
+ path: '/'
+ });
+ }
+ };
+
+ SaveStateHandler.prototype.restoreState = function() {
+ var state;
+ state = this.getStateFromStorage();
+ if (state) {
+ this.setState(state);
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ SaveStateHandler.prototype.getStateFromStorage = function() {
+ var json_data;
+ json_data = this._loadFromStorage();
+ if (json_data) {
+ return this._parseState(json_data);
+ } else {
+ return null;
+ }
+ };
+
+ SaveStateHandler.prototype._parseState = function(json_data) {
+ var state;
+ state = $.parseJSON(json_data);
+ if (state && state.selected_node && isInt(state.selected_node)) {
+ state.selected_node = [state.selected_node];
+ }
+ return state;
+ };
+
+ SaveStateHandler.prototype._loadFromStorage = function() {
+ if (this.tree_widget.options.onGetStateFromStorage) {
+ return this.tree_widget.options.onGetStateFromStorage();
+ } else if (this.supportsLocalStorage()) {
+ return localStorage.getItem(this.getCookieName());
+ } else if ($.cookie) {
+ $.cookie.raw = true;
+ return $.cookie(this.getCookieName());
+ } else {
+ return null;
+ }
+ };
+
+ SaveStateHandler.prototype.getState = function() {
+ var getOpenNodeIds, getSelectedNodeIds;
+ getOpenNodeIds = (function(_this) {
return function() {
- return selectNode(_this.getPreviousNode(current_node));
+ var open_nodes;
+ open_nodes = [];
+ _this.tree_widget.tree.iterate(function(node) {
+ if (node.is_open && node.id && node.hasChildren()) {
+ open_nodes.push(node.id);
+ }
+ return true;
+ });
+ return open_nodes;
};
})(this);
- moveRight = (function(_this) {
+ getSelectedNodeIds = (function(_this) {
return function() {
- if (current_node.isFolder() && !current_node.is_open) {
- _this.tree_widget.openNode(current_node);
- return false;
- } else {
- return true;
- }
+ var n;
+ return (function() {
+ var _i, _len, _ref, _results;
+ _ref = this.tree_widget.getSelectedNodes();
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ n = _ref[_i];
+ _results.push(n.id);
+ }
+ return _results;
+ }).call(_this);
};
})(this);
- moveLeft = (function(_this) {
- return function() {
- if (current_node.isFolder() && current_node.is_open) {
- _this.tree_widget.closeNode(current_node);
- return false;
- } else {
+ return {
+ open_nodes: getOpenNodeIds(),
+ selected_node: getSelectedNodeIds()
+ };
+ };
+
+ SaveStateHandler.prototype.setState = function(state) {
+ var node_id, open_nodes, selected_node, selected_node_ids, _i, _len, _results;
+ if (state) {
+ open_nodes = state.open_nodes;
+ selected_node_ids = state.selected_node;
+ this.tree_widget.tree.iterate((function(_this) {
+ return function(node) {
+ node.is_open = node.id && node.hasChildren() && (indexOf(open_nodes, node.id) >= 0);
return true;
+ };
+ })(this));
+ if (selected_node_ids && this.tree_widget.select_node_handler) {
+ this.tree_widget.select_node_handler.clear();
+ _results = [];
+ for (_i = 0, _len = selected_node_ids.length; _i < _len; _i++) {
+ node_id = selected_node_ids[_i];
+ selected_node = this.tree_widget.getNodeById(node_id);
+ if (selected_node) {
+ _results.push(this.tree_widget.select_node_handler.addToSelection(selected_node));
+ } else {
+ _results.push(void 0);
+ }
}
- };
- })(this);
- if (!current_node) {
- return true;
- } else {
- key = e.which;
- switch (key) {
- case DOWN:
- return moveDown();
- case UP:
- return moveUp();
- case RIGHT:
- return moveRight();
- case LEFT:
- return moveLeft();
+ return _results;
}
}
};
- KeyHandler.prototype.getNextNode = function(node, include_children) {
- var next_sibling;
- if (include_children == null) {
- include_children = true;
- }
- if (include_children && node.hasChildren() && node.is_open) {
- return node.children[0];
+ SaveStateHandler.prototype.getCookieName = function() {
+ if (typeof this.tree_widget.options.saveState === 'string') {
+ return this.tree_widget.options.saveState;
} else {
- if (!node.parent) {
- return null;
- } else {
- next_sibling = node.getNextSibling();
- if (next_sibling) {
- return next_sibling;
- } else {
- return this.getNextNode(node.parent, false);
- }
- }
+ return 'tree';
}
};
- KeyHandler.prototype.getPreviousNode = function(node) {
- var previous_sibling;
- if (!node.parent) {
- return null;
- } else {
- previous_sibling = node.getPreviousSibling();
- if (previous_sibling) {
- if (!previous_sibling.hasChildren() || !previous_sibling.is_open) {
- return previous_sibling;
- } else {
- return this.getLastChild(previous_sibling);
- }
+ SaveStateHandler.prototype.supportsLocalStorage = function() {
+ var testSupport;
+ testSupport = function() {
+ var error, key;
+ if (typeof localStorage === "undefined" || localStorage === null) {
+ return false;
} else {
- if (node.parent.parent) {
- return node.parent;
- } else {
- return null;
+ try {
+ key = '_storage_test';
+ sessionStorage.setItem(key, true);
+ sessionStorage.removeItem(key);
+ } catch (_error) {
+ error = _error;
+ return false;
}
+ return true;
}
+ };
+ if (this._supportsLocalStorage == null) {
+ this._supportsLocalStorage = testSupport();
}
+ return this._supportsLocalStorage;
};
- KeyHandler.prototype.getLastChild = function(node) {
- var last_child;
- if (!node.hasChildren()) {
- return null;
+ SaveStateHandler.prototype.getNodeIdToBeSelected = function() {
+ var state;
+ state = this.getStateFromStorage();
+ if (state && state.selected_node) {
+ return state.selected_node[0];
} else {
- last_child = node.children[node.children.length - 1];
- if (!last_child.hasChildren() || !last_child.is_open) {
- return last_child;
- } else {
- return this.getLastChild(last_child);
- }
+ return null;
}
};
- return KeyHandler;
+ return SaveStateHandler;
})();
+ module.exports = SaveStateHandler;
+
}).call(this);
+
+},{"./util":12}],9:[function(require,module,exports){
+(function() {
+ var ScrollHandler;
+
+ ScrollHandler = (function() {
+ function ScrollHandler(tree_widget) {
+ this.tree_widget = tree_widget;
+ this.previous_top = -1;
+ this._initScrollParent();
+ }
+
+ ScrollHandler.prototype._initScrollParent = function() {
+ var $scroll_parent, getParentWithOverflow, setDocumentAsScrollParent;
+ getParentWithOverflow = (function(_this) {
+ return function() {
+ var css_values, el, hasOverFlow, _i, _len, _ref;
+ css_values = ['overflow', 'overflow-y'];
+ hasOverFlow = function(el) {
+ var css_value, _i, _len, _ref;
+ for (_i = 0, _len = css_values.length; _i < _len; _i++) {
+ css_value = css_values[_i];
+ if ((_ref = $.css(el, css_value)) === 'auto' || _ref === 'scroll') {
+ return true;
+ }
+ }
+ return false;
+ };
+ if (hasOverFlow(_this.tree_widget.$el[0])) {
+ return _this.tree_widget.$el;
+ }
+ _ref = _this.tree_widget.$el.parents();
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ el = _ref[_i];
+ if (hasOverFlow(el)) {
+ return $(el);
+ }
+ }
+ return null;
+ };
+ })(this);
+ setDocumentAsScrollParent = (function(_this) {
+ return function() {
+ _this.scroll_parent_top = 0;
+ return _this.$scroll_parent = null;
+ };
+ })(this);
+ if (this.tree_widget.$el.css('position') === 'fixed') {
+ setDocumentAsScrollParent();
+ }
+ $scroll_parent = getParentWithOverflow();
+ if ($scroll_parent && $scroll_parent.length && $scroll_parent[0].tagName !== 'HTML') {
+ this.$scroll_parent = $scroll_parent;
+ return this.scroll_parent_top = this.$scroll_parent.offset().top;
+ } else {
+ return setDocumentAsScrollParent();
+ }
+ };
+
+ ScrollHandler.prototype.checkScrolling = function() {
+ var hovered_area;
+ hovered_area = this.tree_widget.dnd_handler.hovered_area;
+ if (hovered_area && hovered_area.top !== this.previous_top) {
+ this.previous_top = hovered_area.top;
+ if (this.$scroll_parent) {
+ return this._handleScrollingWithScrollParent(hovered_area);
+ } else {
+ return this._handleScrollingWithDocument(hovered_area);
+ }
+ }
+ };
+
+ ScrollHandler.prototype._handleScrollingWithScrollParent = function(area) {
+ var distance_bottom;
+ distance_bottom = this.scroll_parent_top + this.$scroll_parent[0].offsetHeight - area.bottom;
+ if (distance_bottom < 20) {
+ this.$scroll_parent[0].scrollTop += 20;
+ this.tree_widget.refreshHitAreas();
+ return this.previous_top = -1;
+ } else if ((area.top - this.scroll_parent_top) < 20) {
+ this.$scroll_parent[0].scrollTop -= 20;
+ this.tree_widget.refreshHitAreas();
+ return this.previous_top = -1;
+ }
+ };
+
+ ScrollHandler.prototype._handleScrollingWithDocument = function(area) {
+ var distance_top;
+ distance_top = area.top - $(document).scrollTop();
+ if (distance_top < 20) {
+ return $(document).scrollTop($(document).scrollTop() - 20);
+ } else if ($(window).height() - (area.bottom - $(document).scrollTop()) < 20) {
+ return $(document).scrollTop($(document).scrollTop() + 20);
+ }
+ };
+
+ ScrollHandler.prototype.scrollTo = function(top) {
+ var tree_top;
+ if (this.$scroll_parent) {
+ return this.$scroll_parent[0].scrollTop = top;
+ } else {
+ tree_top = this.tree_widget.$el.offset().top;
+ return $(document).scrollTop(top + tree_top);
+ }
+ };
+
+ ScrollHandler.prototype.isScrolledIntoView = function(element) {
+ var $element, element_bottom, element_top, view_bottom, view_top;
+ $element = $(element);
+ if (this.$scroll_parent) {
+ view_top = 0;
+ view_bottom = this.$scroll_parent.height();
+ element_top = $element.offset().top - this.scroll_parent_top;
+ element_bottom = element_top + $element.height();
+ } else {
+ view_top = $(window).scrollTop();
+ view_bottom = view_top + $(window).height();
+ element_top = $element.offset().top;
+ element_bottom = element_top + $element.height();
+ }
+ return (element_bottom <= view_bottom) && (element_top >= view_top);
+ };
+
+ return ScrollHandler;
+
+ })();
+
+ module.exports = ScrollHandler;
+
+}).call(this);
+
+},{}],10:[function(require,module,exports){
+(function() {
+ var SelectNodeHandler;
+
+ SelectNodeHandler = (function() {
+ function SelectNodeHandler(tree_widget) {
+ this.tree_widget = tree_widget;
+ this.clear();
+ }
+
+ SelectNodeHandler.prototype.getSelectedNode = function() {
+ var selected_nodes;
+ selected_nodes = this.getSelectedNodes();
+ if (selected_nodes.length) {
+ return selected_nodes[0];
+ } else {
+ return false;
+ }
+ };
+
+ SelectNodeHandler.prototype.getSelectedNodes = function() {
+ var id, node, selected_nodes;
+ if (this.selected_single_node) {
+ return [this.selected_single_node];
+ } else {
+ selected_nodes = [];
+ for (id in this.selected_nodes) {
+ node = this.tree_widget.getNodeById(id);
+ if (node) {
+ selected_nodes.push(node);
+ }
+ }
+ return selected_nodes;
+ }
+ };
+
+ SelectNodeHandler.prototype.getSelectedNodesUnder = function(parent) {
+ var id, node, selected_nodes;
+ if (this.selected_single_node) {
+ if (parent.isParentOf(this.selected_single_node)) {
+ return [this.selected_single_node];
+ } else {
+ return [];
+ }
+ } else {
+ selected_nodes = [];
+ for (id in this.selected_nodes) {
+ node = this.tree_widget.getNodeById(id);
+ if (node && parent.isParentOf(node)) {
+ selected_nodes.push(node);
+ }
+ }
+ return selected_nodes;
+ }
+ };
+
+ SelectNodeHandler.prototype.isNodeSelected = function(node) {
+ if (node.id) {
+ return this.selected_nodes[node.id];
+ } else if (this.selected_single_node) {
+ return this.selected_single_node.element === node.element;
+ } else {
+ return false;
+ }
+ };
+
+ SelectNodeHandler.prototype.clear = function() {
+ this.selected_nodes = {};
+ return this.selected_single_node = null;
+ };
+
+ SelectNodeHandler.prototype.removeFromSelection = function(node, include_children) {
+ if (include_children == null) {
+ include_children = false;
+ }
+ if (!node.id) {
+ if (this.selected_single_node && node.element === this.selected_single_node.element) {
+ return this.selected_single_node = null;
+ }
+ } else {
+ delete this.selected_nodes[node.id];
+ if (include_children) {
+ return node.iterate((function(_this) {
+ return function(n) {
+ delete _this.selected_nodes[node.id];
+ return true;
+ };
+ })(this));
+ }
+ }
+ };
+
+ SelectNodeHandler.prototype.addToSelection = function(node) {
+ if (node.id) {
+ return this.selected_nodes[node.id] = true;
+ } else {
+ return this.selected_single_node = node;
+ }
+ };
+
+ return SelectNodeHandler;
+
+ })();
+
+ module.exports = SelectNodeHandler;
+
+}).call(this);
+
+},{}],11:[function(require,module,exports){
+
+/*
+Copyright 2013 Marco Braak
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+(function() {
+ var SimpleWidget,
+ __slice = [].slice;
+
+ SimpleWidget = (function() {
+ SimpleWidget.prototype.defaults = {};
+
+ function SimpleWidget(el, options) {
+ this.$el = $(el);
+ this.options = $.extend({}, this.defaults, options);
+ }
+
+ SimpleWidget.prototype.destroy = function() {
+ return this._deinit();
+ };
+
+ SimpleWidget.prototype._init = function() {
+ return null;
+ };
+
+ SimpleWidget.prototype._deinit = function() {
+ return null;
+ };
+
+ SimpleWidget.register = function(widget_class, widget_name) {
+ var callFunction, createWidget, destroyWidget, getDataKey, getWidgetData;
+ getDataKey = function() {
+ return "simple_widget_" + widget_name;
+ };
+ getWidgetData = function(el, data_key) {
+ var widget;
+ widget = $.data(el, data_key);
+ if (widget && (widget instanceof SimpleWidget)) {
+ return widget;
+ } else {
+ return null;
+ }
+ };
+ createWidget = function($el, options) {
+ var data_key, el, existing_widget, widget, _i, _len;
+ data_key = getDataKey();
+ for (_i = 0, _len = $el.length; _i < _len; _i++) {
+ el = $el[_i];
+ existing_widget = getWidgetData(el, data_key);
+ if (!existing_widget) {
+ widget = new widget_class(el, options);
+ if (!$.data(el, data_key)) {
+ $.data(el, data_key, widget);
+ }
+ widget._init();
+ }
+ }
+ return $el;
+ };
+ destroyWidget = function($el) {
+ var data_key, el, widget, _i, _len, _results;
+ data_key = getDataKey();
+ _results = [];
+ for (_i = 0, _len = $el.length; _i < _len; _i++) {
+ el = $el[_i];
+ widget = getWidgetData(el, data_key);
+ if (widget) {
+ widget.destroy();
+ }
+ _results.push($.removeData(el, data_key));
+ }
+ return _results;
+ };
+ callFunction = function($el, function_name, args) {
+ var el, result, widget, widget_function, _i, _len;
+ result = null;
+ for (_i = 0, _len = $el.length; _i < _len; _i++) {
+ el = $el[_i];
+ widget = $.data(el, getDataKey());
+ if (widget && (widget instanceof SimpleWidget)) {
+ widget_function = widget[function_name];
+ if (widget_function && (typeof widget_function === 'function')) {
+ result = widget_function.apply(widget, args);
+ }
+ }
+ }
+ return result;
+ };
+ return $.fn[widget_name] = function() {
+ var $el, args, argument1, function_name, options;
+ argument1 = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
+ $el = this;
+ if (argument1 === void 0 || typeof argument1 === 'object') {
+ options = argument1;
+ return createWidget($el, options);
+ } else if (typeof argument1 === 'string' && argument1[0] !== '_') {
+ function_name = argument1;
+ if (function_name === 'destroy') {
+ return destroyWidget($el);
+ } else {
+ return callFunction($el, function_name, args);
+ }
+ }
+ };
+ };
+
+ return SimpleWidget;
+
+ })();
+
+ module.exports = SimpleWidget;
+
+}).call(this);
+
+},{}],12:[function(require,module,exports){
+(function() {
+ var get_json_stringify_function, html_escape, indexOf, isInt, _indexOf;
+
+ _indexOf = function(array, item) {
+ var i, value, _i, _len;
+ for (i = _i = 0, _len = array.length; _i < _len; i = ++_i) {
+ value = array[i];
+ if (value === item) {
+ return i;
+ }
+ }
+ return -1;
+ };
+
+ indexOf = function(array, item) {
+ if (array.indexOf) {
+ return array.indexOf(item);
+ } else {
+ return _indexOf(array, item);
+ }
+ };
+
+ isInt = function(n) {
+ return typeof n === 'number' && n % 1 === 0;
+ };
+
+ get_json_stringify_function = function() {
+ var json_escapable, json_meta, json_quote, json_str, stringify;
+ json_escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+ json_meta = {
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"': '\\"',
+ '\\': '\\\\'
+ };
+ json_quote = function(string) {
+ json_escapable.lastIndex = 0;
+ if (json_escapable.test(string)) {
+ return '"' + string.replace(json_escapable, function(a) {
+ var c;
+ c = json_meta[a];
+ return (typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4));
+ }) + '"';
+ } else {
+ return '"' + string + '"';
+ }
+ };
+ json_str = function(key, holder) {
+ var i, k, partial, v, value, _i, _len;
+ value = holder[key];
+ switch (typeof value) {
+ case 'string':
+ return json_quote(value);
+ case 'number':
+ if (isFinite(value)) {
+ return String(value);
+ } else {
+ return 'null';
+ }
+ case 'boolean':
+ case 'null':
+ return String(value);
+ case 'object':
+ if (!value) {
+ return 'null';
+ }
+ partial = [];
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
+ for (i = _i = 0, _len = value.length; _i < _len; i = ++_i) {
+ v = value[i];
+ partial[i] = json_str(i, value) || 'null';
+ }
+ return (partial.length === 0 ? '[]' : '[' + partial.join(',') + ']');
+ }
+ for (k in value) {
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
+ v = json_str(k, value);
+ if (v) {
+ partial.push(json_quote(k) + ':' + v);
+ }
+ }
+ }
+ return (partial.length === 0 ? '{}' : '{' + partial.join(',') + '}');
+ }
+ };
+ stringify = function(value) {
+ return json_str('', {
+ '': value
+ });
+ };
+ return stringify;
+ };
+
+ if (!((this.JSON != null) && (this.JSON.stringify != null) && typeof this.JSON.stringify === 'function')) {
+ if (this.JSON == null) {
+ this.JSON = {};
+ }
+ this.JSON.stringify = get_json_stringify_function();
+ }
+
+ html_escape = function(string) {
+ return ('' + string).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g, '/');
+ };
+
+ module.exports = {
+ _indexOf: _indexOf,
+ get_json_stringify_function: get_json_stringify_function,
+ html_escape: html_escape,
+ indexOf: indexOf,
+ isInt: isInt
+ };
+
+}).call(this);
+
+},{}],13:[function(require,module,exports){
+(function() {
+ module.exports = '0.22.0';
+
+}).call(this);
+
+},{}]},{},[3])
\ No newline at end of file