summaryrefslogtreecommitdiffstats
path: root/ecomp-portal-FE/client/bower_components/jqTree/src/tree.jquery.coffee
diff options
context:
space:
mode:
Diffstat (limited to 'ecomp-portal-FE/client/bower_components/jqTree/src/tree.jquery.coffee')
-rw-r--r--ecomp-portal-FE/client/bower_components/jqTree/src/tree.jquery.coffee918
1 files changed, 918 insertions, 0 deletions
diff --git a/ecomp-portal-FE/client/bower_components/jqTree/src/tree.jquery.coffee b/ecomp-portal-FE/client/bower_components/jqTree/src/tree.jquery.coffee
new file mode 100644
index 00000000..15e13e1b
--- /dev/null
+++ b/ecomp-portal-FE/client/bower_components/jqTree/src/tree.jquery.coffee
@@ -0,0 +1,918 @@
+__version__ = require './version'
+drag_and_drop_handler = 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_module = require './node'
+Node = node_module.Node
+Position = node_module.Position
+
+util_module = require './util'
+
+{isFunction} = util_module
+
+{BorderDropHint,FolderElement,GhostDropHint,NodeElement} = require './node_element'
+
+{DragAndDropHandler, DragElement, HitAreasGenerator} = drag_and_drop_handler
+
+
+$ = jQuery
+
+
+class JqTreeWidget extends MouseWidget
+ BorderDropHint: BorderDropHint
+ DragElement: DragElement
+ DragAndDropHandler: DragAndDropHandler
+ ElementsRenderer: ElementsRenderer
+ GhostDropHint: GhostDropHint
+ HitAreasGenerator: HitAreasGenerator
+ Node: Node
+ SaveStateHandler: SaveStateHandler
+ ScrollHandler: ScrollHandler
+ SelectNodeHandler: SelectNodeHandler
+
+ defaults:
+ autoOpen: false # true / false / int (open n levels starting at 0)
+ saveState: false # true / false / string (cookie name)
+ dragAndDrop: false
+ selectable: true
+ useContextMenu: true
+ onCanSelectNode: null
+ onSetStateFromStorage: null
+ onGetStateFromStorage: null
+ onCreateLi: null
+ onIsMoveHandle: null
+ onCanMove: null # Can this node be moved? function(node)
+ onCanMoveTo: null # Can this node be moved to this position? function(moved_node, target_node, position)
+ onLoadFailed: null
+ autoEscape: true
+ dataUrl: null
+ closedIcon: null # The symbol to use for a closed node - ► BLACK RIGHT-POINTING POINTER http://www.fileformat.info/info/unicode/char/25ba/index.htm
+ openedIcon: '▼' # The symbol to use for an open node - ▼ BLACK DOWN-POINTING TRIANGLE http://www.fileformat.info/info/unicode/char/25bc/index.htm
+ slide: true # must display slide animation?
+ nodeClass: Node
+ dataFilter: null
+ keyboardSupport: true
+ openFolderDelay: 500 # The delay for opening a folder during drag and drop; the value is in milliseconds
+ rtl: null # right-to-left support; true / false (default)
+ onDragMove: null
+ onDragStop: null
+ buttonLeft: true
+ onLoading: null
+
+ toggle: (node, slide=null) ->
+ if slide == null
+ slide = @options.slide
+
+ if node.is_open
+ @closeNode(node, slide)
+ else
+ @openNode(node, slide)
+
+ return @element
+
+ getTree: ->
+ return @tree
+
+ selectNode: (node) ->
+ @_selectNode(node, false)
+ return @element
+
+ _selectNode: (node, must_toggle=false) ->
+ if not @select_node_handler
+ return
+
+ canSelect = =>
+ if @options.onCanSelectNode
+ return @options.selectable and @options.onCanSelectNode(node)
+ else
+ return @options.selectable
+
+ openParents = =>
+ parent = node.parent
+
+ if parent and parent.parent and not parent.is_open
+ @openNode(parent, false)
+
+ saveState = =>
+ if @options.saveState
+ @save_state_handler.saveState()
+
+ if not node
+ # Called with empty node -> deselect current node
+ @_deselectCurrentNode()
+ saveState()
+ return
+
+ if not canSelect()
+ return
+
+ if @select_node_handler.isNodeSelected(node)
+ if must_toggle
+ @_deselectCurrentNode()
+ @_triggerEvent(
+ 'tree.select',
+ node: null,
+ previous_node: node
+ )
+ else
+ deselected_node = @getSelectedNode()
+ @_deselectCurrentNode()
+ @addToSelection(node)
+ @_triggerEvent('tree.select', node: node, deselected_node: deselected_node)
+ openParents()
+
+ saveState()
+
+ getSelectedNode: ->
+ if @select_node_handler
+ return @select_node_handler.getSelectedNode()
+ else
+ return null
+
+ toJson: ->
+ return JSON.stringify(
+ @tree.getData()
+ )
+
+ loadData: (data, parent_node) ->
+ @_loadData(data, parent_node)
+ return @element
+
+ ###
+ signatures:
+ - loadDataFromUrl(url, parent_node=null, on_finished=null)
+ loadDataFromUrl('/my_data');
+ loadDataFromUrl('/my_data', node1);
+ loadDataFromUrl('/my_data', node1, function() { console.log('finished'); });
+ loadDataFromUrl('/my_data', null, function() { console.log('finished'); });
+
+ - loadDataFromUrl(parent_node=null, on_finished=null)
+ loadDataFromUrl();
+ loadDataFromUrl(node1);
+ loadDataFromUrl(null, function() { console.log('finished'); });
+ loadDataFromUrl(node1, function() { console.log('finished'); });
+ ###
+ loadDataFromUrl: (param1, param2, param3) ->
+ if $.type(param1) == 'string'
+ # first parameter is url
+ @_loadDataFromUrl(param1, param2, param3)
+ else
+ # first parameter is not url
+ @_loadDataFromUrl(null, param1, param2)
+
+ return @element
+
+ reload: (on_finished) ->
+ @_loadDataFromUrl(null, null, on_finished)
+ return @element
+
+ _loadDataFromUrl: (url_info, parent_node, on_finished) ->
+ $el = null
+
+ addLoadingClass = =>
+ if parent_node
+ $el = $(parent_node.element)
+ else
+ $el = @element
+
+ $el.addClass('jqtree-loading')
+ @_notifyLoading(true, parent_node, $el)
+
+ removeLoadingClass = =>
+ if $el
+ $el.removeClass('jqtree-loading')
+
+ @_notifyLoading(false, parent_node, $el)
+
+ parseUrlInfo = ->
+ if $.type(url_info) == 'string'
+ return url: url_info
+
+ if not url_info.method
+ url_info.method = 'get'
+
+ return url_info
+
+ handeLoadData = (data) =>
+ removeLoadingClass()
+ @_loadData(data, parent_node)
+
+ if on_finished and $.isFunction(on_finished)
+ on_finished()
+
+ handleSuccess = (response) =>
+ if $.isArray(response) or typeof response == 'object'
+ data = response
+ else if data?
+ data = $.parseJSON(response)
+ else
+ data = []
+
+ if @options.dataFilter
+ data = @options.dataFilter(data)
+
+ handeLoadData(data)
+
+ handleError = (response) =>
+ removeLoadingClass()
+
+ if @options.onLoadFailed
+ @options.onLoadFailed(response)
+
+ loadDataFromUrlInfo = ->
+ url_info = parseUrlInfo()
+
+ $.ajax(
+ $.extend(
+ {},
+ url_info,
+ {
+ method: if url_info.method? then url_info.method.toUpperCase() else 'GET',
+ cache: false,
+ dataType: 'json',
+ success: handleSuccess,
+ error: handleError
+ }
+ )
+ )
+
+ if not url_info
+ # Generate url for node
+ url_info = @_getDataUrlInfo(parent_node)
+
+ addLoadingClass()
+
+ if not url_info
+ removeLoadingClass()
+ return
+ else if $.isArray(url_info)
+ handeLoadData(url_info)
+ return
+ else
+ loadDataFromUrlInfo()
+ return
+
+ _loadData: (data, parent_node=null) ->
+ deselectNodes = =>
+ 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)
+
+ return null
+
+ loadSubtree = =>
+ parent_node.loadFromData(data)
+
+ parent_node.load_on_demand = false
+ parent_node.is_loading = false
+
+ @_refreshElements(parent_node)
+
+ if not data
+ return
+
+ @_triggerEvent('tree.load_data', tree_data: data)
+
+ if not parent_node
+ @_initTree(data)
+ else
+ deselectNodes()
+ loadSubtree()
+
+ if @isDragging()
+ @dnd_handler.refresh()
+
+ getNodeById: (node_id) ->
+ return @tree.getNodeById(node_id)
+
+ getNodeByName: (name) ->
+ return @tree.getNodeByName(name)
+
+ getNodesByProperty: (key, value) ->
+ return @tree.getNodesByProperty(key, value)
+
+ getNodeByHtmlElement: (element) ->
+ return @_getNode($(element))
+
+ getNodeByCallback: (callback) ->
+ return @tree.getNodeByCallback(callback)
+
+ openNode: (node, slide_param=null, on_finished_param=null) ->
+ parseParams = =>
+ if isFunction(slide_param)
+ on_finished = slide_param
+ slide = null
+ else
+ slide = slide_param
+ on_finished = on_finished_param
+
+ if slide == null
+ slide = @options.slide
+
+ return [slide, on_finished]
+
+ [slide, on_finished] = parseParams()
+
+ if node
+ @_openNode(node, slide, on_finished)
+
+ return @element
+
+ _openNode: (node, slide=true, on_finished) ->
+ doOpenNode = (_node, _slide, _on_finished) =>
+ folder_element = new FolderElement(_node, this)
+ folder_element.open(_on_finished, _slide)
+
+ if node.isFolder()
+ if node.load_on_demand
+ @_loadFolderOnDemand(node, slide, on_finished)
+ else
+ parent = node.parent
+
+ while parent
+ # nb: do not open root element
+ if parent.parent
+ doOpenNode(parent, false, null)
+ parent = parent.parent
+
+ doOpenNode(node, slide, on_finished)
+ @_saveState()
+
+ _loadFolderOnDemand: (node, slide=true, on_finished) ->
+ node.is_loading = true
+
+ @_loadDataFromUrl(
+ null,
+ node,
+ =>
+ @_openNode(node, slide, on_finished)
+ )
+
+ closeNode: (node, slide=null) ->
+ if slide == null
+ slide = @options.slide
+
+ if node.isFolder()
+ new FolderElement(node, this).close(slide)
+
+ @_saveState()
+
+ return @element
+
+ isDragging: ->
+ if @dnd_handler
+ return @dnd_handler.is_dragging
+ else
+ return false
+
+ refreshHitAreas: ->
+ @dnd_handler.refresh()
+ return @element
+
+ addNodeAfter: (new_node_info, existing_node) ->
+ new_node = existing_node.addAfter(new_node_info)
+ @_refreshElements(existing_node.parent)
+ return new_node
+
+ addNodeBefore: (new_node_info, existing_node) ->
+ new_node = existing_node.addBefore(new_node_info)
+ @_refreshElements(existing_node.parent)
+ return new_node
+
+ addParentNode: (new_node_info, existing_node) ->
+ new_node = existing_node.addParent(new_node_info)
+ @_refreshElements(new_node.parent)
+ return new_node
+
+ removeNode: (node) ->
+ parent = node.parent
+ if parent
+ @select_node_handler.removeFromSelection(node, true) # including children
+
+ node.remove()
+ @_refreshElements(parent)
+
+ return @element
+
+ appendNode: (new_node_info, parent_node) ->
+ parent_node = parent_node or @tree
+
+ node = parent_node.append(new_node_info)
+
+ @_refreshElements(parent_node)
+
+ return node
+
+ prependNode: (new_node_info, parent_node) ->
+ if not parent_node
+ parent_node = @tree
+
+ node = parent_node.prepend(new_node_info)
+
+ @_refreshElements(parent_node)
+
+ return node
+
+ updateNode: (node, data) ->
+ id_is_changed = data.id and data.id != node.id
+
+ if id_is_changed
+ @tree.removeNodeFromIndex(node)
+
+ node.setData(data)
+
+ if id_is_changed
+ @tree.addNodeToIndex(node)
+
+ if typeof data == 'object' and data.children
+ node.removeChildren()
+
+ if data.children.length
+ node.loadFromData(data.children)
+
+ @renderer.renderFromNode(node)
+ @_selectCurrentNode()
+
+ return @element
+
+ moveNode: (node, target_node, position) ->
+ position_index = Position.nameToIndex(position)
+
+ @tree.moveNode(node, target_node, position_index)
+ @_refreshElements()
+ return @element
+
+ getStateFromStorage: ->
+ return @save_state_handler.getStateFromStorage()
+
+ addToSelection: (node) ->
+ if node
+ @select_node_handler.addToSelection(node)
+
+ @_getNodeElementForNode(node).select()
+ @_saveState()
+
+ return @element
+
+ getSelectedNodes: ->
+ return @select_node_handler.getSelectedNodes()
+
+ isNodeSelected: (node) ->
+ return @select_node_handler.isNodeSelected(node)
+
+ removeFromSelection: (node) ->
+ @select_node_handler.removeFromSelection(node)
+
+ @_getNodeElementForNode(node).deselect()
+ @_saveState()
+ return @element
+
+ scrollToNode: (node) ->
+ $element = $(node.element)
+ top = $element.offset().top - @$el.offset().top
+
+ @scroll_handler.scrollTo(top)
+ return @element
+
+ getState: ->
+ return @save_state_handler.getState()
+
+ setState: (state) ->
+ @save_state_handler.setInitialState(state)
+ @_refreshElements()
+ return @element
+
+ setOption: (option, value) ->
+ @options[option] = value
+ return @element
+
+ moveDown: ->
+ if @key_handler
+ @key_handler.moveDown()
+
+ return @element
+
+ moveUp: ->
+ if @key_handler
+ @key_handler.moveUp()
+
+ return @element
+
+ getVersion: ->
+ return __version__
+
+ _init: ->
+ super()
+
+ @element = @$el
+ @mouse_delay = 300
+ @is_initialized = false
+
+ @options.rtl = @_getRtlOption()
+
+ if !@options.closedIcon
+ @options.closedIcon = @_getDefaultClosedIcon()
+
+ @renderer = new ElementsRenderer(this)
+
+ if SaveStateHandler?
+ @save_state_handler = new SaveStateHandler(this)
+ else
+ @options.saveState = false
+
+ if SelectNodeHandler?
+ @select_node_handler = new SelectNodeHandler(this)
+
+ if DragAndDropHandler?
+ @dnd_handler = new DragAndDropHandler(this)
+ else
+ @options.dragAndDrop = false
+
+ if ScrollHandler?
+ @scroll_handler = new ScrollHandler(this)
+
+ if KeyHandler? and SelectNodeHandler?
+ @key_handler = new KeyHandler(this)
+
+ @_initData()
+
+ @element.click($.proxy(@_click, this))
+ @element.dblclick($.proxy(@_dblclick, this))
+
+ if @options.useContextMenu
+ @element.bind('contextmenu', $.proxy(@_contextmenu, this))
+
+ _deinit: ->
+ @element.empty()
+ @element.unbind()
+
+ if @key_handler
+ @key_handler.deinit()
+
+ @tree = null
+
+ super()
+
+ _initData: ->
+ if @options.data
+ @_loadData(@options.data)
+ else
+ data_url = @_getDataUrlInfo()
+
+ if data_url
+ @_loadDataFromUrl()
+ else
+ @_loadData([])
+
+ _getDataUrlInfo: (node) ->
+ data_url = @options.dataUrl or @element.data('url')
+
+ getUrlFromString = =>
+ url_info = url: data_url
+
+ if node and node.id
+ # Load on demand of a subtree; add node parameter
+ data = node: node.id
+ url_info['data'] = data
+ else
+ # Add selected_node parameter
+ selected_node_id = @_getNodeIdToBeSelected()
+ if selected_node_id
+ data = selected_node: selected_node_id
+ url_info['data'] = data
+
+ return url_info
+
+ if $.isFunction(data_url)
+ return data_url(node)
+ else if $.type(data_url) == 'string'
+ return getUrlFromString()
+ else
+ return data_url
+
+ _getNodeIdToBeSelected: ->
+ if @options.saveState
+ return @save_state_handler.getNodeIdToBeSelected()
+ else
+ return null
+
+ _initTree: (data) ->
+ doInit = =>
+ if not @is_initialized
+ @is_initialized = true
+ @_triggerEvent('tree.init')
+
+ @tree = new @options.nodeClass(null, true, @options.nodeClass)
+
+ if @select_node_handler
+ @select_node_handler.clear()
+
+ @tree.loadFromData(data)
+
+ must_load_on_demand = @_setInitialState()
+
+ @_refreshElements()
+
+ if not must_load_on_demand
+ doInit()
+ else
+ # Load data on demand and then init the tree
+ @_setInitialStateOnDemand(doInit)
+
+ # Set initial state, either by restoring the state or auto-opening nodes
+ # result: must load nodes on demand?
+ _setInitialState: ->
+ restoreState = =>
+ # result: is state restored, must load on demand?
+ if not (@options.saveState and @save_state_handler)
+ return [false, false]
+ else
+ state = @save_state_handler.getStateFromStorage()
+
+ if not state
+ return [false, false]
+ else
+ must_load_on_demand = @save_state_handler.setInitialState(state)
+
+ # return true: the state is restored
+ return [true, must_load_on_demand]
+
+ autoOpenNodes = =>
+ # result: must load on demand?
+ if @options.autoOpen is false
+ return false
+
+ max_level = @_getAutoOpenMaxLevel()
+ must_load_on_demand = false
+
+ @tree.iterate (node, level) ->
+ if node.load_on_demand
+ must_load_on_demand = true
+ return false
+ else if not node.hasChildren()
+ return false
+ else
+ node.is_open = true
+ return (level != max_level)
+
+ return must_load_on_demand
+
+ [is_restored, must_load_on_demand] = restoreState()
+
+ if not is_restored
+ must_load_on_demand = autoOpenNodes()
+
+ return must_load_on_demand
+
+ # Set the initial state for nodes that are loaded on demand
+ # Call cb_finished when done
+ _setInitialStateOnDemand: (cb_finished) ->
+ restoreState = =>
+ if not (@options.saveState and @save_state_handler)
+ return false
+ else
+ state = @save_state_handler.getStateFromStorage()
+
+ if not state
+ return false
+ else
+ @save_state_handler.setInitialStateOnDemand(state, cb_finished)
+
+ return true
+
+ autoOpenNodes = =>
+ max_level = @_getAutoOpenMaxLevel()
+ loading_count = 0
+
+ loadAndOpenNode = (node) =>
+ loading_count += 1
+ @_openNode(
+ node,
+ false,
+ ->
+ loading_count -= 1
+ openNodes()
+ )
+
+ openNodes = =>
+ @tree.iterate (node, level) =>
+ if node.load_on_demand
+ if not node.is_loading
+ loadAndOpenNode(node)
+
+ return false
+ else
+ @_openNode(node, false)
+
+ return (level != max_level)
+
+ if loading_count == 0
+ cb_finished()
+
+ openNodes()
+
+ if not restoreState()
+ autoOpenNodes()
+
+ _getAutoOpenMaxLevel: ->
+ if @options.autoOpen is true
+ return -1
+ else
+ return parseInt(@options.autoOpen)
+
+ ###
+ Redraw the tree or part of the tree.
+ # from_node: redraw this subtree
+ ###
+ _refreshElements: (from_node=null) ->
+ @renderer.render(from_node)
+
+ @_triggerEvent('tree.refresh')
+
+ _click: (e) ->
+ click_target = @_getClickTarget(e.target)
+
+ if click_target
+ if click_target.type == 'button'
+ @toggle(click_target.node, @options.slide)
+
+ e.preventDefault()
+ e.stopPropagation()
+ else if click_target.type == 'label'
+ node = click_target.node
+ event = @_triggerEvent(
+ 'tree.click',
+ node: node
+ click_event: e
+ )
+
+ if not event.isDefaultPrevented()
+ @_selectNode(node, true)
+
+ _dblclick: (e) ->
+ click_target = @_getClickTarget(e.target)
+
+ if click_target and click_target.type == 'label'
+ @_triggerEvent(
+ 'tree.dblclick',
+ node: click_target.node
+ click_event: e
+ )
+
+ _getClickTarget: (element) ->
+ $target = $(element)
+
+ $button = $target.closest('.jqtree-toggler')
+
+ if $button.length
+ node = @_getNode($button)
+
+ if node
+ return {
+ type: 'button',
+ node: node
+ }
+ else
+ $el = $target.closest('.jqtree-element')
+ if $el.length
+ node = @_getNode($el)
+ if node
+ return {
+ type: 'label',
+ node: node
+ }
+
+ return null
+
+ _getNode: ($element) ->
+ $li = $element.closest('li.jqtree_common')
+ if $li.length == 0
+ return null
+ else
+ return $li.data('node')
+
+ _getNodeElementForNode: (node) ->
+ if node.isFolder()
+ return new FolderElement(node, this)
+ else
+ return new NodeElement(node, this)
+
+ _getNodeElement: ($element) ->
+ node = @_getNode($element)
+ if node
+ return @_getNodeElementForNode(node)
+ else
+ return null
+
+ _contextmenu: (e) ->
+ $div = $(e.target).closest('ul.jqtree-tree .jqtree-element')
+ if $div.length
+ node = @_getNode($div)
+ if node
+ e.preventDefault()
+ e.stopPropagation()
+
+ @_triggerEvent(
+ 'tree.contextmenu',
+ node: node
+ click_event: e
+ )
+ return false
+
+ _saveState: ->
+ if @options.saveState
+ @save_state_handler.saveState()
+
+ _mouseCapture: (position_info) ->
+ if @options.dragAndDrop
+ return @dnd_handler.mouseCapture(position_info)
+ else
+ return false
+
+ _mouseStart: (position_info) ->
+ if @options.dragAndDrop
+ return @dnd_handler.mouseStart(position_info)
+ else
+ return false
+
+ _mouseDrag: (position_info) ->
+ if @options.dragAndDrop
+ result = @dnd_handler.mouseDrag(position_info)
+
+ if @scroll_handler
+ @scroll_handler.checkScrolling()
+ return result
+ else
+ return false
+
+ _mouseStop: (position_info) ->
+ if @options.dragAndDrop
+ return @dnd_handler.mouseStop(position_info)
+ else
+ return false
+
+ _triggerEvent: (event_name, values) ->
+ event = $.Event(event_name)
+ $.extend(event, values)
+
+ @element.trigger(event)
+ return event
+
+ testGenerateHitAreas: (moving_node) ->
+ @dnd_handler.current_item = @_getNodeElementForNode(moving_node)
+ @dnd_handler.generateHitAreas()
+ return @dnd_handler.hit_areas
+
+ _selectCurrentNode: ->
+ node = @getSelectedNode()
+ if node
+ node_element = @_getNodeElementForNode(node)
+ if node_element
+ node_element.select()
+
+ _deselectCurrentNode: ->
+ node = @getSelectedNode()
+ if node
+ @removeFromSelection(node)
+
+ _getDefaultClosedIcon: ->
+ if @options.rtl
+ # triangle to the left
+ return '◀'
+ else
+ # triangle to the right
+ return '►'
+
+ _getRtlOption: ->
+ if @options.rtl != null
+ return @options.rtl
+ else
+ data_rtl = @element.data('rtl')
+
+ if data_rtl? and data_rtl != false
+ return true
+ else
+ return false
+
+ _notifyLoading: (is_loading, node, $el) ->
+ if @options.onLoading
+ @options.onLoading(is_loading, node, $el)
+
+
+JqTreeWidget.getModule = (name) ->
+ modules =
+ 'node': node_module
+ 'util': util_module
+ 'drag_and_drop_handler': drag_and_drop_handler
+
+ return modules[name]
+
+
+SimpleWidget.register(JqTreeWidget, 'tree')