diff options
Diffstat (limited to 'ecomp-portal-FE/client/bower_components/jqTree/src/node.coffee')
-rw-r--r-- | ecomp-portal-FE/client/bower_components/jqTree/src/node.coffee | 490 |
1 files changed, 490 insertions, 0 deletions
diff --git a/ecomp-portal-FE/client/bower_components/jqTree/src/node.coffee b/ecomp-portal-FE/client/bower_components/jqTree/src/node.coffee new file mode 100644 index 00000000..5af050ac --- /dev/null +++ b/ecomp-portal-FE/client/bower_components/jqTree/src/node.coffee @@ -0,0 +1,490 @@ +$ = jQuery + + +Position = + getName: (position) -> + return Position.strings[position - 1] + + nameToIndex: (name) -> + for i in [1..Position.strings.length] + 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'] + +class Node + constructor: (o, is_root=false, node_class=Node) -> + @name = '' + + @setData(o) + + @children = [] + @parent = null + + if is_root + @id_mapping = {} + @tree = this + @node_class = node_class + + setData: (o) -> + ### + Set the data of this node. + + setData(string): set the name of the node + setdata(object): set attributes of the node + + Examples: + setdata('node1') + + setData({ name: 'node1', id: 1}); + + setData({ name: 'node2', id: 2, color: 'green'}); + + * This is an internal function; it is not in the docs + * Does not remove existing node values + ### + setName = (name) => + if name != null + @name = name + + if typeof o != 'object' + setName(o) + else + for key, value of o + if key == 'label' + # You can use the 'label' key instead of 'name'; this is a legacy feature + setName(value) + else if key != 'children' + # You can't update the children using this function + @[key] = value + + return null + + # Init Node from data without making it the root of the tree + initFromData: (data) -> + addNode = (node_data) => + @setData(node_data) + + if node_data.children + addChildren(node_data.children) + + addChildren = (children_data) => + for child in children_data + node = new @tree.node_class('') + node.initFromData(child) + @addChild(node) + return null + + addNode(data) + return null + + ### + Create tree from data. + + Structure of data is: + [ + { + label: 'node1', + children: [ + { label: 'child1' }, + { label: 'child2' } + ] + }, + { + label: 'node2' + } + ] + ### + loadFromData: (data) -> + @removeChildren() + + for o in data + node = new @tree.node_class(o) + @addChild(node) + + if typeof o == 'object' and o.children + node.loadFromData(o.children) + + return null + + ### + Add child. + + tree.addChild( + new Node('child1') + ); + ### + addChild: (node) -> + @children.push(node) + node._setParent(this) + + ### + Add child at position. Index starts at 0. + + tree.addChildAtPosition( + new Node('abc'), + 1 + ); + ### + addChildAtPosition: (node, index) -> + @children.splice(index, 0, node) + node._setParent(this) + + _setParent: (parent) -> + @parent = parent + @tree = parent.tree + @tree.addNodeToIndex(this) + + ### + Remove child. This also removes the children of the node. + + tree.removeChild(tree.children[0]); + ### + removeChild: (node) -> + # remove children from the index + node.removeChildren() + + @_removeChild(node) + + _removeChild: (node) -> + @children.splice( + @getChildIndex(node), + 1 + ) + @tree.removeNodeFromIndex(node) + + ### + Get child index. + + var index = getChildIndex(node); + ### + getChildIndex: (node) -> + return $.inArray(node, @children) + + ### + Does the tree have children? + + if (tree.hasChildren()) { + // + } + ### + hasChildren: -> + return @children.length != 0 + + isFolder: -> + return @hasChildren() or @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); + } + ); + + ### + iterate: (callback) -> + _iterate = (node, level) -> + if node.children + for child in node.children + result = callback(child, level) + + if result and child.hasChildren() + _iterate(child, level + 1) + return null + + _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); + ### + moveNode: (moved_node, target_node, position) -> + if moved_node.isParentOf(target_node) + # Node is parent of target node. This is an illegal move + return + + moved_node.parent._removeChild(moved_node) + if position == Position.AFTER + target_node.parent.addChildAtPosition( + moved_node, + target_node.parent.getChildIndex(target_node) + 1 + ) + else if position == Position.BEFORE + target_node.parent.addChildAtPosition( + moved_node, + target_node.parent.getChildIndex(target_node) + ) + else if position == Position.INSIDE + # move inside as first child + target_node.addChildAtPosition(moved_node, 0) + + ### + Get the tree as data. + ### + getData: (include_parent=false) -> + getDataFromNodes = (nodes) -> + data = [] + + for node in nodes + tmp_node = {} + + for k, v of node + if ( + k not in ['parent', 'children', 'element', 'tree'] and + 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 + + if include_parent + return getDataFromNodes([this]) + else + return getDataFromNodes(@children) + + getNodeByName: (name) -> + return @getNodeByCallback( + (node) -> (node.name == name) + ) + + getNodeByCallback: (callback) -> + result = null + + @iterate( + (node) -> + if callback(node) + result = node + return false + else + return true + ) + + return result + + + addAfter: (node_info) -> + if not @parent + return null + else + node = new @tree.node_class(node_info) + + child_index = @parent.getChildIndex(this) + @parent.addChildAtPosition(node, child_index + 1) + + if typeof node_info == 'object' and node_info.children and node_info.children.length + node.loadFromData(node_info.children) + + return node + + addBefore: (node_info) -> + if not @parent + return null + else + node = new @tree.node_class(node_info) + + child_index = @parent.getChildIndex(this) + @parent.addChildAtPosition(node, child_index) + + if typeof node_info == 'object' and node_info.children and node_info.children.length + node.loadFromData(node_info.children) + + return node + + addParent: (node_info) -> + if not @parent + return null + else + new_parent = new @tree.node_class(node_info) + new_parent._setParent(@tree) + original_parent = @parent + + for child in original_parent.children + new_parent.addChild(child) + + original_parent.children = [] + original_parent.addChild(new_parent) + return new_parent + + remove: -> + if @parent + @parent.removeChild(this) + @parent = null + + append: (node_info) -> + node = new @tree.node_class(node_info) + @addChild(node) + + if typeof node_info == 'object' and node_info.children and node_info.children.length + node.loadFromData(node_info.children) + + return node + + prepend: (node_info) -> + node = new @tree.node_class(node_info) + @addChildAtPosition(node, 0) + + if typeof node_info == 'object' and node_info.children and node_info.children.length + node.loadFromData(node_info.children) + + return node + + isParentOf: (node) -> + parent = node.parent + + while parent + if parent == this + return true + + parent = parent.parent + + return false + + getLevel: -> + level = 0 + node = this + + while node.parent + level += 1 + node = node.parent + + return level + + getNodeById: (node_id) -> + return @id_mapping[node_id] + + addNodeToIndex: (node) -> + if node.id? + @id_mapping[node.id] = node + + removeNodeFromIndex: (node) -> + if node.id? + delete @id_mapping[node.id] + + removeChildren: -> + @iterate( + (child) => + @tree.removeNodeFromIndex(child) + return true + ) + + @children = [] + + getPreviousSibling: -> + if not @parent + return null + else + previous_index = @parent.getChildIndex(this) - 1 + if previous_index >= 0 + return @parent.children[previous_index] + else + return null + + getNextSibling: -> + if not @parent + return null + else + next_index = @parent.getChildIndex(this) + 1 + if next_index < @parent.children.length + return @parent.children[next_index] + else + return null + + getNodesByProperty: (key, value) -> + return @filter( + (node) -> + return node[key] == value + ) + + filter: (f) -> + result = [] + + @iterate( + (node) -> + if f(node) + result.push(node) + + return true + ) + + return result + + getNextNode: (include_children=true) -> + if include_children and @hasChildren() and @is_open + # First child + return @children[0] + else + if not @parent + return null + else + next_sibling = @getNextSibling() + if next_sibling + # Next sibling + return next_sibling + else + # Next node of parent + return @parent.getNextNode(false) + + getPreviousNode: -> + if not @parent + return null + else + previous_sibling = @getPreviousSibling() + if previous_sibling + if not previous_sibling.hasChildren() or not previous_sibling.is_open + # Previous sibling + return previous_sibling + else + # Last child of previous sibling + return previous_sibling.getLastChild() + else + return @getParent() + + getParent: -> + # Return parent except if it is the root node + if not @parent + return null + else if not @parent.parent + # Root node -> null + return null + else + return @parent + + getLastChild: -> + if not @hasChildren() + return null + else + last_child = @children[@children.length - 1] + if not last_child.hasChildren() or not last_child.is_open + return last_child + else + return last_child.getLastChild() + + +module.exports = + Node: Node + Position: Position |