-
Notifications
You must be signed in to change notification settings - Fork 177
/
Copy pathtree.jquery.js.map
1 lines (1 loc) · 206 KB
/
tree.jquery.js.map
1
{"version":3,"file":"tree.jquery.js","sources":["src/dataLoader.ts","src/util.ts","src/dragAndDropHandler/dragElement.ts","src/dragAndDropHandler/iterateVisibleNodes.ts","src/dragAndDropHandler/generateHitAreas.ts","src/dragAndDropHandler/index.ts","src/dragAndDropHandler/binarySearch.ts","src/elementsRenderer.ts","src/keyHandler.ts","src/mouseUtils.ts","src/mouseHandler.ts","src/nodeUtils.ts","src/node.ts","src/nodeElement/borderDropHint.ts","src/nodeElement/ghostDropHint.ts","src/nodeElement/index.ts","src/nodeElement/folderElement.ts","src/saveStateHandler.ts","src/scrollHandler/containerScrollParent.ts","src/scrollHandler/documentScrollParent.ts","src/scrollHandler/createScrollParent.ts","src/scrollHandler.ts","src/selectNodeHandler.ts","src/simple.widget.ts","src/version.ts","src/tree.jquery.ts"],"sourcesContent":["import { LoadData, TriggerEvent } from \"./jqtreeMethodTypes\";\nimport { DataFilter, OnLoadFailed, OnLoading } from \"./jqtreeOptions\";\nimport { Node } from \"./node\";\n\nexport type HandleFinishedLoading = () => void;\n\ninterface DataLoaderParams {\n dataFilter?: DataFilter;\n loadData: LoadData;\n onLoadFailed?: OnLoadFailed;\n onLoading?: OnLoading;\n treeElement: HTMLElement;\n triggerEvent: TriggerEvent;\n}\n\nexport default class DataLoader {\n private dataFilter?: DataFilter;\n private loadData: LoadData;\n private onLoadFailed?: OnLoadFailed;\n private onLoading?: OnLoading;\n private treeElement: HTMLElement;\n private triggerEvent: TriggerEvent;\n\n constructor({\n dataFilter,\n loadData,\n onLoadFailed,\n onLoading,\n treeElement,\n triggerEvent,\n }: DataLoaderParams) {\n this.dataFilter = dataFilter;\n this.loadData = loadData;\n this.onLoadFailed = onLoadFailed;\n this.onLoading = onLoading;\n this.treeElement = treeElement;\n this.triggerEvent = triggerEvent;\n }\n\n public loadFromUrl(\n urlInfo: JQuery.AjaxSettings | null | string,\n parentNode: Node | null,\n onFinished: HandleFinishedLoading | null,\n ): void {\n if (!urlInfo) {\n return;\n }\n\n const element = this.getDomElement(parentNode);\n this.addLoadingClass(element);\n this.notifyLoading(true, parentNode, element);\n\n const stopLoading = (): void => {\n this.removeLoadingClass(element);\n this.notifyLoading(false, parentNode, element);\n };\n\n const handleSuccess = (data: NodeData[] | string): void => {\n stopLoading();\n this.loadData(this.parseData(data), parentNode);\n\n if (onFinished && typeof onFinished === \"function\") {\n onFinished();\n }\n };\n\n const handleError = (jqXHR: JQuery.jqXHR): void => {\n stopLoading();\n\n if (this.onLoadFailed) {\n this.onLoadFailed(jqXHR);\n }\n };\n\n this.submitRequest(urlInfo, handleSuccess, handleError);\n }\n\n private addLoadingClass(element: HTMLElement): void {\n element.classList.add(\"jqtree-loading\");\n }\n\n private getDomElement(parentNode: Node | null): HTMLElement {\n if (parentNode?.element) {\n return parentNode.element;\n } else {\n return this.treeElement;\n }\n }\n\n private notifyLoading(\n isLoading: boolean,\n node: Node | null,\n element: HTMLElement,\n ): void {\n const $el = jQuery(element);\n\n if (this.onLoading) {\n this.onLoading(isLoading, node, $el);\n }\n\n this.triggerEvent(\"tree.loading_data\", {\n $el,\n isLoading,\n node,\n });\n }\n\n private parseData(data: NodeData[] | string): NodeData[] {\n const getParsedData = () => {\n if (typeof data === \"string\") {\n return JSON.parse(data) as NodeData[];\n } else {\n return data;\n }\n };\n\n const parsedData = getParsedData();\n\n if (this.dataFilter) {\n return this.dataFilter(parsedData);\n } else {\n return parsedData;\n }\n }\n\n private removeLoadingClass(element: HTMLElement): void {\n element.classList.remove(\"jqtree-loading\");\n }\n\n private submitRequest(\n urlInfoInput: JQuery.AjaxSettings | string,\n handleSuccess: JQuery.Ajax.SuccessCallback<any>,\n handleError: JQuery.Ajax.ErrorCallback<any>,\n ): void {\n const urlInfo =\n typeof urlInfoInput === \"string\"\n ? { url: urlInfoInput }\n : urlInfoInput;\n\n const ajaxSettings: JQuery.AjaxSettings = {\n cache: false,\n dataType: \"json\",\n error: handleError,\n method: \"GET\",\n success: handleSuccess,\n ...urlInfo,\n };\n\n ajaxSettings.method = ajaxSettings.method?.toUpperCase() ?? \"GET\";\n\n void jQuery.ajax(ajaxSettings);\n }\n}\n","export const isInt = (n: unknown): boolean =>\n typeof n === \"number\" && n % 1 === 0;\n\nexport const isFunction = (v: unknown): boolean => typeof v === \"function\";\n\nexport const getBoolString = (value: unknown): string =>\n value ? \"true\" : \"false\";\n\nexport const getOffsetTop = (element: HTMLElement) =>\n getElementPosition(element).top;\n\nexport const getElementPosition = (element: HTMLElement) => {\n const rect = element.getBoundingClientRect();\n\n return {\n left: rect.x + window.scrollX,\n top: rect.y + window.scrollY,\n };\n};\n","interface DragElementParams {\n autoEscape: boolean;\n nodeName: string;\n offsetX: number;\n offsetY: number;\n treeElement: HTMLElement;\n}\n\nclass DragElement {\n private element: HTMLElement;\n private offsetX: number;\n private offsetY: number;\n\n constructor({\n autoEscape,\n nodeName,\n offsetX,\n offsetY,\n treeElement,\n }: DragElementParams) {\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n\n this.element = this.createElement(nodeName, autoEscape);\n\n treeElement.appendChild(this.element);\n }\n\n public move(pageX: number, pageY: number): void {\n this.element.style.left = `${pageX - this.offsetX}px`;\n this.element.style.top = `${pageY - this.offsetY}px`;\n }\n\n public remove(): void {\n this.element.remove();\n }\n\n private createElement(nodeName: string, autoEscape: boolean) {\n const element = document.createElement(\"span\");\n element.classList.add(\"jqtree-title\", \"jqtree-dragging\");\n\n if (autoEscape) {\n element.textContent = nodeName;\n } else {\n element.innerHTML = nodeName;\n }\n\n element.style.position = \"absolute\";\n\n return element;\n }\n}\n\nexport default DragElement;\n","import { Node } from \"../node\";\n\ninterface Options {\n handleAfterOpenFolder: (node: Node, nextNode: Node | null) => void;\n handleClosedFolder: (\n node: Node,\n nextNode: Node | null,\n element: HTMLElement,\n ) => void;\n handleFirstNode: (node: Node) => void;\n handleNode: (\n node: Node,\n nextNode: Node | null,\n element: HTMLElement,\n ) => void;\n\n /*\n override\n return\n - true: continue iterating\n - false: stop iterating\n */\n handleOpenFolder: (node: Node, element: HTMLElement) => boolean;\n}\n\nconst iterateVisibleNodes = (\n tree: Node,\n {\n handleAfterOpenFolder,\n handleClosedFolder,\n handleFirstNode,\n handleNode,\n handleOpenFolder,\n }: Options,\n) => {\n let isFirstNode = true;\n\n const iterate = (node: Node, nextNode: Node | null): void => {\n let mustIterateInside =\n (node.is_open || !node.element) && node.hasChildren();\n\n let element: HTMLElement | null = null;\n\n // Is the element visible?\n if (node.element?.offsetParent) {\n element = node.element;\n\n if (isFirstNode) {\n handleFirstNode(node);\n isFirstNode = false;\n }\n\n if (!node.hasChildren()) {\n handleNode(node, nextNode, node.element);\n } else if (node.is_open) {\n if (!handleOpenFolder(node, node.element)) {\n mustIterateInside = false;\n }\n } else {\n handleClosedFolder(node, nextNode, element);\n }\n }\n\n if (mustIterateInside) {\n const childrenLength = node.children.length;\n node.children.forEach((_, i) => {\n const child = node.children[i];\n\n if (child) {\n if (i === childrenLength - 1) {\n iterate(child, null);\n } else {\n const nextChild = node.children[i + 1];\n\n if (nextChild) {\n iterate(child, nextChild);\n }\n }\n }\n });\n\n if (node.is_open && element) {\n handleAfterOpenFolder(node, nextNode);\n }\n }\n };\n\n iterate(tree, null);\n};\n\nexport default iterateVisibleNodes;\n","import { Node, Position } from \"../node\";\nimport { getOffsetTop } from \"../util\";\nimport iterateVisibleNodes from \"./iterateVisibleNodes\";\nimport { HitArea } from \"./types\";\n\ninterface HitPosition {\n node: Node;\n position: null | Position;\n top: number;\n}\n\nexport const generateHitPositions = (\n tree: Node,\n currentNode: Node,\n): HitPosition[] => {\n const hitPositions: HitPosition[] = [];\n let lastTop = 0;\n\n const addHitPosition = (\n node: Node,\n position: null | Position,\n top: number,\n ) => {\n hitPositions.push({\n node,\n position,\n top,\n });\n lastTop = top;\n };\n\n const handleAfterOpenFolder = (node: Node, nextNode: Node | null) => {\n if (node === currentNode || nextNode === currentNode) {\n // Cannot move before or after current item\n addHitPosition(node, null, lastTop);\n } else {\n addHitPosition(node, \"after\", lastTop);\n }\n };\n\n const handleClosedFolder = (\n node: Node,\n nextNode: Node | null,\n element: HTMLElement,\n ) => {\n const top = getOffsetTop(element);\n\n if (node === currentNode) {\n // Cannot move after current item\n addHitPosition(node, null, top);\n } else {\n addHitPosition(node, \"inside\", top);\n\n // Cannot move before current item\n if (nextNode !== currentNode) {\n addHitPosition(node, \"after\", top);\n }\n }\n };\n\n const handleFirstNode = (node: Node) => {\n if (node !== currentNode && node.element) {\n addHitPosition(node, \"before\", getOffsetTop(node.element));\n }\n };\n\n const handleNode = (\n node: Node,\n nextNode: Node | null,\n element: HTMLElement,\n ) => {\n const top = getOffsetTop(element);\n\n if (node === currentNode) {\n // Cannot move inside current item\n addHitPosition(node, null, top);\n } else {\n addHitPosition(node, \"inside\", top);\n }\n\n if (nextNode === currentNode || node === currentNode) {\n // Cannot move before or after current item\n addHitPosition(node, null, top);\n } else {\n addHitPosition(node, \"after\", top);\n }\n };\n\n const handleOpenFolder = (node: Node, element: HTMLElement) => {\n if (node === currentNode) {\n // Cannot move inside current item\n\n // Dnd over the current element is not possible: add a position with type None for the top and the bottom.\n const top = getOffsetTop(element);\n const height = element.clientHeight;\n addHitPosition(node, null, top);\n\n if (height > 5) {\n // Subtract 5 pixels to allow more space for the next element.\n addHitPosition(node, null, top + height - 5);\n }\n\n // Stop iterating\n return false;\n }\n\n // Cannot move before current item\n if (node.children[0] !== currentNode) {\n addHitPosition(node, \"inside\", getOffsetTop(element));\n }\n\n // Continue iterating\n return true;\n };\n\n iterateVisibleNodes(tree, {\n handleAfterOpenFolder,\n handleClosedFolder,\n handleFirstNode,\n handleNode,\n handleOpenFolder,\n });\n\n return hitPositions;\n};\n\nexport const generateHitAreasForGroup = (\n hitAreas: HitArea[],\n positionsInGroup: HitPosition[],\n top: number,\n bottom: number,\n) => {\n // limit positions in group\n const positionCount = Math.min(positionsInGroup.length, 4);\n\n const areaHeight = Math.round((bottom - top) / positionCount);\n let areaTop = top;\n\n for (let i = 0; i < positionCount; i++) {\n const position = positionsInGroup[i] as HitPosition;\n\n if (position.position) {\n hitAreas.push({\n bottom: areaTop + areaHeight,\n node: position.node,\n position: position.position,\n top: areaTop,\n });\n }\n\n areaTop += areaHeight;\n }\n};\n\nexport const generateHitAreasFromPositions = (\n hitPositions: HitPosition[],\n treeBottom: number,\n): HitArea[] => {\n if (!hitPositions.length) {\n return [];\n }\n\n let previousTop = (hitPositions[0] as HitPosition).top;\n let group: HitPosition[] = [];\n const hitAreas: HitArea[] = [];\n\n for (const position of hitPositions) {\n if (position.top !== previousTop && group.length) {\n generateHitAreasForGroup(\n hitAreas,\n group,\n previousTop,\n position.top,\n );\n\n previousTop = position.top;\n group = [];\n }\n\n group.push(position);\n }\n\n generateHitAreasForGroup(hitAreas, group, previousTop, treeBottom);\n\n return hitAreas;\n};\n\nconst generateHitAreas = (tree: Node, currentNode: Node, treeBottom: number) =>\n generateHitAreasFromPositions(\n generateHitPositions(tree, currentNode),\n treeBottom,\n );\n\nexport default generateHitAreas;\n","import {\n GetScrollLeft,\n GetTree,\n OpenNode,\n RefreshElements,\n TriggerEvent,\n} from \"../jqtreeMethodTypes\";\nimport {\n DragMethod,\n OnCanMove,\n OnCanMoveTo,\n OnIsMoveHandle,\n} from \"../jqtreeOptions\";\nimport { PositionInfo } from \"../mouseUtils\";\nimport { Node } from \"../node\";\nimport NodeElement from \"../nodeElement\";\nimport { getElementPosition } from \"../util\";\nimport binarySearch from \"./binarySearch\";\nimport DragElement from \"./dragElement\";\nimport generateHitAreas from \"./generateHitAreas\";\nimport { DropHint, HitArea } from \"./types\";\n\ninterface Dimensions {\n bottom: number;\n left: number;\n right: number;\n top: number;\n}\n\ninterface DragAndDropHandlerParams {\n autoEscape?: boolean;\n getNodeElement: GetNodeElement;\n getNodeElementForNode: GetNodeElementForNode;\n getScrollLeft: GetScrollLeft;\n getTree: GetTree;\n onCanMove?: OnCanMove;\n onCanMoveTo?: OnCanMoveTo;\n onDragMove?: DragMethod;\n onDragStop?: DragMethod;\n onIsMoveHandle?: OnIsMoveHandle;\n openFolderDelay: false | number;\n openNode: OpenNode;\n refreshElements: RefreshElements;\n slide: boolean;\n treeElement: HTMLElement;\n triggerEvent: TriggerEvent;\n}\ntype GetNodeElement = (element: HTMLElement) => NodeElement | null;\n\ntype GetNodeElementForNode = (node: Node) => NodeElement;\n\nexport class DragAndDropHandler {\n public currentItem: NodeElement | null;\n public hitAreas: HitArea[];\n public hoveredArea: HitArea | null;\n public isDragging: boolean;\n\n private autoEscape?: boolean;\n private dragElement: DragElement | null;\n private getNodeElement: GetNodeElement;\n private getNodeElementForNode: GetNodeElementForNode;\n private getScrollLeft: GetScrollLeft;\n private getTree: GetTree;\n private onCanMove?: OnCanMove;\n private onCanMoveTo?: OnCanMoveTo;\n private onDragMove?: DragMethod;\n private onDragStop?: DragMethod;\n private onIsMoveHandle?: OnIsMoveHandle;\n private openFolderDelay: false | number;\n private openFolderTimer: null | number;\n private openNode: OpenNode;\n private previousGhost: DropHint | null;\n private refreshElements: RefreshElements;\n private slide: boolean;\n private treeElement: HTMLElement;\n private triggerEvent: TriggerEvent;\n\n constructor({\n autoEscape,\n getNodeElement,\n getNodeElementForNode,\n getScrollLeft,\n getTree,\n onCanMove,\n onCanMoveTo,\n onDragMove,\n onDragStop,\n onIsMoveHandle,\n openFolderDelay,\n openNode,\n refreshElements,\n slide,\n treeElement,\n triggerEvent,\n }: DragAndDropHandlerParams) {\n this.autoEscape = autoEscape;\n this.getNodeElement = getNodeElement;\n this.getNodeElementForNode = getNodeElementForNode;\n this.getScrollLeft = getScrollLeft;\n this.getTree = getTree;\n this.onCanMove = onCanMove;\n this.onCanMoveTo = onCanMoveTo;\n this.onDragMove = onDragMove;\n this.onDragStop = onDragStop;\n this.onIsMoveHandle = onIsMoveHandle;\n this.openFolderDelay = openFolderDelay;\n this.openNode = openNode;\n this.refreshElements = refreshElements;\n this.slide = slide;\n this.treeElement = treeElement;\n this.triggerEvent = triggerEvent;\n\n this.hoveredArea = null;\n this.hitAreas = [];\n this.isDragging = false;\n this.currentItem = null;\n }\n\n public mouseCapture(positionInfo: PositionInfo): boolean | null {\n const element = positionInfo.target;\n\n if (!this.mustCaptureElement(element)) {\n return null;\n }\n\n if (this.onIsMoveHandle && !this.onIsMoveHandle(jQuery(element))) {\n return null;\n }\n\n let nodeElement = this.getNodeElement(element);\n\n if (nodeElement && this.onCanMove) {\n if (!this.onCanMove(nodeElement.node)) {\n nodeElement = null;\n }\n }\n\n this.currentItem = nodeElement;\n return this.currentItem != null;\n }\n\n public mouseDrag(positionInfo: PositionInfo): boolean {\n if (!this.currentItem || !this.dragElement) {\n return false;\n }\n\n this.dragElement.move(positionInfo.pageX, positionInfo.pageY);\n\n const area = this.findHoveredArea(\n positionInfo.pageX,\n positionInfo.pageY,\n );\n\n if (area && this.canMoveToArea(area, this.currentItem)) {\n if (!area.node.isFolder()) {\n this.stopOpenFolderTimer();\n }\n\n if (this.hoveredArea !== area) {\n this.hoveredArea = area;\n\n // If this is a closed folder, start timer to open it\n if (this.mustOpenFolderTimer(area)) {\n this.startOpenFolderTimer(area.node);\n } else {\n this.stopOpenFolderTimer();\n }\n\n this.updateDropHint();\n }\n } else {\n this.removeDropHint();\n this.stopOpenFolderTimer();\n this.hoveredArea = area;\n }\n\n if (!area) {\n if (this.onDragMove) {\n this.onDragMove(\n this.currentItem.node,\n positionInfo.originalEvent,\n );\n }\n }\n\n return true;\n }\n\n public mouseStart(positionInfo: PositionInfo): boolean {\n if (!this.currentItem) {\n return false;\n }\n\n this.refresh();\n\n const { left, top } = getElementPosition(positionInfo.target);\n\n const node = this.currentItem.node;\n\n this.dragElement = new DragElement({\n autoEscape: this.autoEscape ?? true,\n nodeName: node.name,\n offsetX: positionInfo.pageX - left,\n offsetY: positionInfo.pageY - top,\n treeElement: this.treeElement,\n });\n\n this.isDragging = true;\n this.currentItem.element.classList.add(\"jqtree-moving\");\n\n return true;\n }\n\n public mouseStop(positionInfo: PositionInfo): boolean {\n this.moveItem(positionInfo);\n this.clear();\n this.removeHover();\n this.removeDropHint();\n this.removeHitAreas();\n\n const currentItem = this.currentItem;\n\n if (this.currentItem) {\n this.currentItem.element.classList.remove(\"jqtree-moving\");\n this.currentItem = null;\n }\n\n this.isDragging = false;\n\n if (!this.hoveredArea && currentItem) {\n if (this.onDragStop) {\n this.onDragStop(currentItem.node, positionInfo.originalEvent);\n }\n }\n\n return false;\n }\n\n public refresh(): void {\n this.removeHitAreas();\n\n if (this.currentItem) {\n const currentNode = this.currentItem.node;\n this.generateHitAreas(currentNode);\n this.currentItem = this.getNodeElementForNode(currentNode);\n\n if (this.isDragging) {\n this.currentItem.element.classList.add(\"jqtree-moving\");\n }\n }\n }\n\n private canMoveToArea(area: HitArea, currentItem: NodeElement): boolean {\n if (!this.onCanMoveTo) {\n return true;\n }\n\n return this.onCanMoveTo(currentItem.node, area.node, area.position);\n }\n\n private clear(): void {\n if (this.dragElement) {\n this.dragElement.remove();\n this.dragElement = null;\n }\n }\n\n private findHoveredArea(x: number, y: number): HitArea | null {\n const dimensions = this.getTreeDimensions();\n\n if (\n x < dimensions.left ||\n y < dimensions.top ||\n x > dimensions.right ||\n y > dimensions.bottom\n ) {\n return null;\n }\n\n return binarySearch<HitArea>(this.hitAreas, (area) => {\n if (y < area.top) {\n return 1;\n } else if (y > area.bottom) {\n return -1;\n } else {\n return 0;\n }\n });\n }\n\n private generateHitAreas(currentNode: Node): void {\n const tree = this.getTree();\n\n if (!tree) {\n this.hitAreas = [];\n } else {\n this.hitAreas = generateHitAreas(\n tree,\n currentNode,\n this.getTreeDimensions().bottom,\n );\n }\n }\n\n private getTreeDimensions(): Dimensions {\n // Return the dimensions of the tree. Add a margin to the bottom to allow\n // to drag-and-drop after the last element.\n const treePosition = getElementPosition(this.treeElement);\n const left = treePosition.left + this.getScrollLeft();\n const top = treePosition.top;\n\n return {\n bottom: top + this.treeElement.clientHeight + 16,\n left,\n right: left + this.treeElement.clientWidth,\n top,\n };\n }\n\n /* Move the dragged node to the selected position in the tree. */\n private moveItem(positionInfo: PositionInfo): void {\n if (\n this.currentItem &&\n this.hoveredArea?.position &&\n this.canMoveToArea(this.hoveredArea, this.currentItem)\n ) {\n const movedNode = this.currentItem.node;\n const targetNode = this.hoveredArea.node;\n const position = this.hoveredArea.position;\n const previousParent = movedNode.parent;\n\n if (position === \"inside\") {\n this.hoveredArea.node.is_open = true;\n }\n\n const doMove = (): void => {\n const tree = this.getTree();\n\n if (tree) {\n tree.moveNode(movedNode, targetNode, position);\n\n this.treeElement.textContent = \"\";\n this.refreshElements(null);\n }\n };\n\n const event = this.triggerEvent(\"tree.move\", {\n move_info: {\n do_move: doMove,\n moved_node: movedNode,\n original_event: positionInfo.originalEvent,\n position,\n previous_parent: previousParent,\n target_node: targetNode,\n },\n });\n\n if (!event.isDefaultPrevented()) {\n doMove();\n }\n }\n }\n\n private mustCaptureElement(element: HTMLElement): boolean {\n const nodeName = element.nodeName;\n\n return (\n nodeName !== \"INPUT\" &&\n nodeName !== \"SELECT\" &&\n nodeName !== \"TEXTAREA\"\n );\n }\n\n private mustOpenFolderTimer(area: HitArea): boolean {\n const node = area.node;\n\n return node.isFolder() && !node.is_open && area.position === \"inside\";\n }\n\n private removeDropHint(): void {\n if (this.previousGhost) {\n this.previousGhost.remove();\n }\n }\n\n private removeHitAreas(): void {\n this.hitAreas = [];\n }\n\n private removeHover(): void {\n this.hoveredArea = null;\n }\n\n private startOpenFolderTimer(folder: Node): void {\n const openFolder = (): void => {\n this.openNode(folder, this.slide, () => {\n this.refresh();\n this.updateDropHint();\n });\n };\n\n this.stopOpenFolderTimer();\n\n const openFolderDelay = this.openFolderDelay;\n\n if (openFolderDelay !== false) {\n this.openFolderTimer = window.setTimeout(\n openFolder,\n openFolderDelay,\n );\n }\n }\n\n private stopOpenFolderTimer(): void {\n if (this.openFolderTimer) {\n clearTimeout(this.openFolderTimer);\n this.openFolderTimer = null;\n }\n }\n\n private updateDropHint(): void {\n if (!this.hoveredArea) {\n return;\n }\n\n // remove previous drop hint\n this.removeDropHint();\n\n // add new drop hint\n const nodeElement = this.getNodeElementForNode(this.hoveredArea.node);\n this.previousGhost = nodeElement.addDropHint(this.hoveredArea.position);\n }\n}\n","function binarySearch<T>(items: T[], compareFn: (a: T) => number): null | T {\n let low = 0;\n let high = items.length;\n\n while (low < high) {\n const mid = (low + high) >> 1;\n const item = items[mid];\n\n if (item === undefined) {\n return null;\n }\n\n const compareResult = compareFn(item);\n\n if (compareResult > 0) {\n high = mid;\n } else if (compareResult < 0) {\n low = mid + 1;\n } else {\n return item;\n }\n }\n\n return null;\n}\n\nexport default binarySearch;\n","import { GetTree, IsNodeSelected } from \"./jqtreeMethodTypes\";\nimport { IconElement, OnCreateLi } from \"./jqtreeOptions\";\nimport { Node } from \"./node\";\nimport { getBoolString } from \"./util\";\n\ninterface ElementsRendererParams {\n $element: JQuery;\n autoEscape: boolean;\n buttonLeft: boolean;\n closedIcon?: IconElement;\n dragAndDrop: boolean;\n getTree: GetTree;\n isNodeSelected: IsNodeSelected;\n onCreateLi?: OnCreateLi;\n openedIcon?: IconElement;\n rtl?: boolean;\n showEmptyFolder: boolean;\n tabIndex?: number;\n}\n\nexport default class ElementsRenderer {\n public closedIconElement?: HTMLElement | Text;\n public openedIconElement?: HTMLElement | Text;\n private $element: JQuery;\n private autoEscape: boolean;\n private buttonLeft: boolean;\n private dragAndDrop: boolean;\n private getTree: GetTree;\n private isNodeSelected: IsNodeSelected;\n private onCreateLi?: OnCreateLi;\n private rtl?: boolean;\n\n private showEmptyFolder: boolean;\n private tabIndex?: number;\n\n constructor({\n $element,\n autoEscape,\n buttonLeft,\n closedIcon,\n dragAndDrop,\n getTree,\n isNodeSelected,\n onCreateLi,\n openedIcon,\n rtl,\n showEmptyFolder,\n tabIndex,\n }: ElementsRendererParams) {\n this.autoEscape = autoEscape;\n this.buttonLeft = buttonLeft;\n this.dragAndDrop = dragAndDrop;\n this.$element = $element;\n this.getTree = getTree;\n this.isNodeSelected = isNodeSelected;\n this.onCreateLi = onCreateLi;\n this.rtl = rtl;\n this.showEmptyFolder = showEmptyFolder;\n this.tabIndex = tabIndex;\n this.openedIconElement = this.createButtonElement(openedIcon ?? \"+\");\n this.closedIconElement = this.createButtonElement(closedIcon ?? \"-\");\n }\n\n public render(fromNode: Node | null): void {\n if (fromNode?.parent) {\n this.renderFromNode(fromNode);\n } else {\n this.renderFromRoot();\n }\n }\n\n public renderFromNode(node: Node): void {\n if (!node.element) {\n return;\n }\n\n // remember current li\n const $previousLi = jQuery(node.element);\n\n // create element\n const li = this.createLi(node, node.getLevel());\n\n // add element to dom\n $previousLi.after(li);\n\n // remove previous li\n $previousLi.remove();\n\n // create children\n this.createDomElements(li, node.children, false, node.getLevel() + 1);\n }\n\n public renderFromRoot(): void {\n this.$element.empty();\n\n const tree = this.getTree();\n\n if (this.$element[0] && tree) {\n this.createDomElements(this.$element[0], tree.children, true, 1);\n }\n }\n\n private attachNodeData(node: Node, li: HTMLElement): void {\n node.element = li;\n jQuery(li).data(\"node\", node);\n }\n\n private createButtonElement(\n value: IconElement,\n ): HTMLElement | Text | undefined {\n if (typeof value === \"string\") {\n // convert value to html\n const div = document.createElement(\"div\");\n div.innerHTML = value;\n\n return document.createTextNode(div.innerHTML);\n } else if ((value as HTMLElement).nodeType) {\n return value as HTMLElement;\n } else {\n return jQuery(value)[0];\n }\n }\n\n private createDomElements(\n element: Element,\n children: Node[],\n isRootNode: boolean,\n level: number,\n ): void {\n const ul = this.createUl(isRootNode);\n element.appendChild(ul);\n\n for (const child of children) {\n const li = this.createLi(child, level);\n ul.appendChild(li);\n\n if (child.hasChildren()) {\n this.createDomElements(li, child.children, false, level + 1);\n }\n }\n }\n\n private createFolderLi(\n node: Node,\n level: number,\n isSelected: boolean,\n ): HTMLLIElement {\n const buttonClasses = this.getButtonClasses(node);\n const folderClasses = this.getFolderClasses(node, isSelected);\n\n const iconElement = node.is_open\n ? this.openedIconElement\n : this.closedIconElement;\n\n // li\n const li = document.createElement(\"li\");\n li.className = `jqtree_common ${folderClasses}`;\n li.setAttribute(\"role\", \"none\");\n\n // div\n const div = document.createElement(\"div\");\n div.className = \"jqtree-element jqtree_common\";\n div.setAttribute(\"role\", \"none\");\n\n li.appendChild(div);\n\n // button link\n const buttonLink = document.createElement(\"a\");\n buttonLink.className = buttonClasses;\n\n if (iconElement) {\n buttonLink.appendChild(iconElement.cloneNode(true));\n }\n\n if (this.buttonLeft) {\n div.appendChild(buttonLink);\n }\n\n // title span\n const titleSpan = this.createTitleSpan(\n node.name,\n isSelected,\n true,\n level,\n );\n titleSpan.setAttribute(\"aria-expanded\", getBoolString(node.is_open));\n div.appendChild(titleSpan);\n\n if (!this.buttonLeft) {\n div.appendChild(buttonLink);\n }\n\n return li;\n }\n\n /* Create the <li> element\n * Attach it to node.element.\n * Call onCreateLi\n */\n private createLi(node: Node, level: number): HTMLLIElement {\n const isSelected = Boolean(this.isNodeSelected(node));\n\n const mustShowFolder =\n node.isFolder() || (node.isEmptyFolder && this.showEmptyFolder);\n\n const li = mustShowFolder\n ? this.createFolderLi(node, level, isSelected)\n : this.createNodeLi(node, level, isSelected);\n\n this.attachNodeData(node, li);\n\n if (this.onCreateLi) {\n this.onCreateLi(node, jQuery(li), isSelected);\n }\n\n return li;\n }\n\n private createNodeLi(\n node: Node,\n level: number,\n isSelected: boolean,\n ): HTMLLIElement {\n const liClasses = [\"jqtree_common\"];\n\n if (isSelected) {\n liClasses.push(\"jqtree-selected\");\n }\n\n const classString = liClasses.join(\" \");\n\n // li\n const li = document.createElement(\"li\");\n li.className = classString;\n li.setAttribute(\"role\", \"none\");\n\n // div\n const div = document.createElement(\"div\");\n div.className = \"jqtree-element jqtree_common\";\n div.setAttribute(\"role\", \"none\");\n\n li.appendChild(div);\n\n // title span\n const titleSpan = this.createTitleSpan(\n node.name,\n isSelected,\n false,\n level,\n );\n div.appendChild(titleSpan);\n\n return li;\n }\n\n private createTitleSpan(\n nodeName: string,\n isSelected: boolean,\n isFolder: boolean,\n level: number,\n ): HTMLSpanElement {\n const titleSpan = document.createElement(\"span\");\n\n let classes = \"jqtree-title jqtree_common\";\n\n if (isFolder) {\n classes += \" jqtree-title-folder\";\n }\n\n classes += ` jqtree-title-button-${this.buttonLeft ? \"left\" : \"right\"}`;\n\n titleSpan.className = classes;\n\n if (isSelected) {\n const tabIndex = this.tabIndex;\n\n if (tabIndex !== undefined) {\n titleSpan.setAttribute(\"tabindex\", `${tabIndex}`);\n }\n }\n\n this.setTreeItemAriaAttributes(titleSpan, nodeName, level, isSelected);\n\n if (this.autoEscape) {\n titleSpan.textContent = nodeName;\n } else {\n titleSpan.innerHTML = nodeName;\n }\n\n return titleSpan;\n }\n\n private createUl(isRootNode: boolean): HTMLUListElement {\n let classString;\n let role;\n\n if (!isRootNode) {\n classString = \"\";\n role = \"group\";\n } else {\n classString = \"jqtree-tree\";\n role = \"tree\";\n\n if (this.rtl) {\n classString += \" jqtree-rtl\";\n }\n }\n\n if (this.dragAndDrop) {\n classString += \" jqtree-dnd\";\n }\n\n const ul = document.createElement(\"ul\");\n ul.className = `jqtree_common ${classString}`;\n\n ul.setAttribute(\"role\", role);\n\n return ul;\n }\n\n private getButtonClasses(node: Node): string {\n const classes = [\"jqtree-toggler\", \"jqtree_common\"];\n\n if (!node.is_open) {\n classes.push(\"jqtree-closed\");\n }\n\n if (this.buttonLeft) {\n classes.push(\"jqtree-toggler-left\");\n } else {\n classes.push(\"jqtree-toggler-right\");\n }\n\n return classes.join(\" \");\n }\n\n private getFolderClasses(node: Node, isSelected: boolean): string {\n const classes = [\"jqtree-folder\"];\n\n if (!node.is_open) {\n classes.push(\"jqtree-closed\");\n }\n\n if (isSelected) {\n classes.push(\"jqtree-selected\");\n }\n\n if (node.is_loading) {\n classes.push(\"jqtree-loading\");\n }\n\n return classes.join(\" \");\n }\n\n private setTreeItemAriaAttributes(\n element: HTMLElement,\n name: string,\n level: number,\n isSelected: boolean,\n ) {\n element.setAttribute(\"aria-label\", name);\n element.setAttribute(\"aria-level\", `${level}`);\n element.setAttribute(\"aria-selected\", getBoolString(isSelected));\n element.setAttribute(\"role\", \"treeitem\");\n }\n}\n","import {\n CloseNode,\n GetSelectedNode,\n IsFocusOnTree,\n OpenNode,\n SelectNode,\n} from \"./jqtreeMethodTypes\";\nimport { Node } from \"./node\";\n\ninterface KeyHandlerParams {\n closeNode: CloseNode;\n getSelectedNode: GetSelectedNode;\n isFocusOnTree: IsFocusOnTree;\n keyboardSupport: boolean;\n openNode: OpenNode;\n selectNode: SelectNode;\n}\n\nexport default class KeyHandler {\n private closeNode: CloseNode;\n private getSelectedNode: GetSelectedNode;\n\n private isFocusOnTree: IsFocusOnTree;\n\n private keyboardSupport: boolean;\n private openNode: OpenNode;\n private originalSelectNode: SelectNode;\n constructor({\n closeNode,\n getSelectedNode,\n isFocusOnTree,\n keyboardSupport,\n openNode,\n selectNode,\n }: KeyHandlerParams) {\n this.closeNode = closeNode;\n this.getSelectedNode = getSelectedNode;\n this.isFocusOnTree = isFocusOnTree;\n this.keyboardSupport = keyboardSupport;\n this.openNode = openNode;\n this.originalSelectNode = selectNode;\n\n if (keyboardSupport) {\n document.addEventListener(\"keydown\", this.handleKeyDown);\n }\n }\n\n public deinit(): void {\n if (this.keyboardSupport) {\n document.removeEventListener(\"keydown\", this.handleKeyDown);\n }\n }\n\n public moveDown(selectedNode: Node): boolean {\n return this.selectNode(selectedNode.getNextVisibleNode());\n }\n\n public moveUp(selectedNode: Node): boolean {\n return this.selectNode(selectedNode.getPreviousVisibleNode());\n }\n\n private canHandleKeyboard(): boolean {\n return this.keyboardSupport && this.isFocusOnTree();\n }\n\n private handleKeyDown = (e: KeyboardEvent): void => {\n if (!this.canHandleKeyboard()) {\n return;\n }\n\n let isKeyHandled = false;\n\n const selectedNode = this.getSelectedNode();\n if (selectedNode) {\n switch (e.key) {\n case \"ArrowDown\":\n isKeyHandled = this.moveDown(selectedNode);\n break;\n\n case \"ArrowLeft\":\n isKeyHandled = this.moveLeft(selectedNode);\n break;\n\n case \"ArrowRight\":\n isKeyHandled = this.moveRight(selectedNode);\n break;\n\n case \"ArrowUp\":\n isKeyHandled = this.moveUp(selectedNode);\n break;\n }\n }\n\n if (isKeyHandled) {\n e.preventDefault();\n }\n };\n\n private moveLeft(selectedNode: Node): boolean {\n if (selectedNode.isFolder() && selectedNode.is_open) {\n // Left on an open node closes the node\n this.closeNode(selectedNode);\n return true;\n } else {\n // Left on a closed or end node moves focus to the node's parent\n return this.selectNode(selectedNode.getParent());\n }\n }\n\n private moveRight(selectedNode: Node): boolean {\n if (!selectedNode.isFolder()) {\n return false;\n } else {\n // folder node\n if (selectedNode.is_open) {\n // Right moves to the first child of an open node\n return this.selectNode(selectedNode.getNextVisibleNode());\n } else {\n // Right expands a closed node\n this.openNode(selectedNode);\n return true;\n }\n }\n }\n\n /* Select the node.\n * Don't do anything if the node is null.\n * Result: a different node was selected.\n */\n private selectNode(node: Node | null): boolean {\n if (!node) {\n return false;\n } else {\n this.originalSelectNode(node);\n\n return true;\n }\n }\n}\n","export interface PositionInfo {\n originalEvent: Event;\n pageX: number;\n pageY: number;\n target: HTMLElement;\n}\n\nexport const getPositionInfoFromMouseEvent = (e: MouseEvent): PositionInfo => ({\n originalEvent: e,\n pageX: e.pageX,\n pageY: e.pageY,\n target: e.target as HTMLElement,\n});\n\nexport const getPositionInfoFromTouch = (\n touch: Touch,\n e: TouchEvent,\n): PositionInfo => ({\n originalEvent: e,\n pageX: touch.pageX,\n pageY: touch.pageY,\n target: touch.target as HTMLElement,\n});\n","import { TriggerEvent } from \"./jqtreeMethodTypes\";\nimport {\n getPositionInfoFromMouseEvent,\n getPositionInfoFromTouch,\n PositionInfo,\n} from \"./mouseUtils\";\nimport { Node } from \"./node\";\n\ninterface ClickTarget {\n node: Node;\n type: \"button\" | \"label\";\n}\n\ntype GetNode = (element: HTMLElement) => Node | null;\n\ninterface MouseHandlerParams {\n element: HTMLElement;\n getMouseDelay: () => number;\n getNode: GetNode;\n onClickButton: (node: Node) => void;\n onClickTitle: (node: Node) => void;\n onMouseCapture: (positionInfo: PositionInfo) => boolean | null;\n onMouseDrag: (positionInfo: PositionInfo) => void;\n onMouseStart: (positionInfo: PositionInfo) => boolean;\n onMouseStop: (positionInfo: PositionInfo) => void;\n triggerEvent: TriggerEvent;\n useContextMenu: boolean;\n}\n\nclass MouseHandler {\n private element: HTMLElement;\n private getMouseDelay: () => number;\n private getNode: GetNode;\n\n private isMouseDelayMet: boolean;\n\n private isMouseStarted: boolean;\n\n private mouseDelayTimer: null | number;\n\n private mouseDownInfo: null | PositionInfo;\n private onClickButton: (node: Node) => void;\n private onClickTitle: (node: Node) => void;\n\n private onMouseCapture: (positionInfo: PositionInfo) => boolean | null;\n\n private onMouseDrag: (positionInfo: PositionInfo) => void;\n\n private onMouseStart: (positionInfo: PositionInfo) => boolean;\n\n private onMouseStop: (positionInfo: PositionInfo) => void;\n\n private triggerEvent: TriggerEvent;\n private useContextMenu: boolean;\n constructor({\n element,\n getMouseDelay,\n getNode,\n onClickButton,\n onClickTitle,\n onMouseCapture,\n onMouseDrag,\n onMouseStart,\n onMouseStop,\n triggerEvent,\n useContextMenu,\n }: MouseHandlerParams) {\n this.element = element;\n this.getMouseDelay = getMouseDelay;\n this.getNode = getNode;\n this.onClickButton = onClickButton;\n this.onClickTitle = onClickTitle;\n this.onMouseCapture = onMouseCapture;\n this.onMouseDrag = onMouseDrag;\n this.onMouseStart = onMouseStart;\n this.onMouseStop = onMouseStop;\n this.triggerEvent = triggerEvent;\n this.useContextMenu = useContextMenu;\n\n element.addEventListener(\"click\", this.handleClick);\n element.addEventListener(\"dblclick\", this.handleDblclick);\n element.addEventListener(\"mousedown\", this.mouseDown, {\n passive: false,\n });\n element.addEventListener(\"touchstart\", this.touchStart, {\n passive: false,\n });\n\n if (useContextMenu) {\n element.addEventListener(\"contextmenu\", this.handleContextmenu);\n }\n\n this.isMouseStarted = false;\n this.mouseDelayTimer = null;\n this.isMouseDelayMet = false;\n this.mouseDownInfo = null;\n }\n public deinit(): void {\n this.element.removeEventListener(\"click\", this.handleClick);\n this.element.removeEventListener(\"dblclick\", this.handleDblclick);\n\n if (this.useContextMenu) {\n this.element.removeEventListener(\n \"contextmenu\",\n this.handleContextmenu,\n );\n }\n\n this.element.removeEventListener(\"mousedown\", this.mouseDown);\n this.element.removeEventListener(\"touchstart\", this.touchStart);\n this.removeMouseMoveEventListeners();\n }\n private getClickTarget(element: HTMLElement): ClickTarget | null {\n const button = element.closest<HTMLElement>(\".jqtree-toggler\");\n\n if (button) {\n const node = this.getNode(button);\n\n if (node) {\n return {\n node,\n type: \"button\",\n };\n }\n } else {\n const jqTreeElement =\n element.closest<HTMLElement>(\".jqtree-element\");\n\n if (jqTreeElement) {\n const node = this.getNode(jqTreeElement);\n if (node) {\n return {\n node,\n type: \"label\",\n };\n }\n }\n }\n\n return null;\n }\n private handleClick = (e: MouseEvent): void => {\n if (!e.target) {\n return;\n }\n\n const clickTarget = this.getClickTarget(e.target as HTMLElement);\n\n if (!clickTarget) {\n return;\n }\n\n switch (clickTarget.type) {\n case \"button\":\n this.onClickButton(clickTarget.node);\n\n e.preventDefault();\n e.stopPropagation();\n break;\n\n case \"label\": {\n const event = this.triggerEvent(\"tree.click\", {\n click_event: e,\n node: clickTarget.node,\n });\n\n if (!event.isDefaultPrevented()) {\n this.onClickTitle(clickTarget.node);\n }\n break;\n }\n }\n };\n\n private handleContextmenu = (e: MouseEvent) => {\n if (!e.target) {\n return;\n }\n\n const div = (e.target as HTMLElement).closest<HTMLElement>(\n \"ul.jqtree-tree .jqtree-element\",\n );\n\n if (div) {\n const node = this.getNode(div);\n if (node) {\n e.preventDefault();\n e.stopPropagation();\n\n this.triggerEvent(\"tree.contextmenu\", {\n click_event: e,\n node,\n });\n return false;\n }\n }\n\n return null;\n };\n\n private handleDblclick = (e: MouseEvent): void => {\n if (!e.target) {\n return;\n }\n\n const clickTarget = this.getClickTarget(e.target as HTMLElement);\n\n if (clickTarget?.type === \"label\") {\n this.triggerEvent(\"tree.dblclick\", {\n click_event: e,\n node: clickTarget.node,\n });\n }\n };\n\n private handleMouseDown(positionInfo: PositionInfo): boolean {\n // We may have missed mouseup (out of window)\n if (this.isMouseStarted) {\n this.handleMouseUp(positionInfo);\n }\n\n this.mouseDownInfo = positionInfo;\n\n if (!this.onMouseCapture(positionInfo)) {\n return false;\n }\n\n this.handleStartMouse();\n\n return true;\n }\n\n private handleMouseMove(\n e: MouseEvent | TouchEvent,\n positionInfo: PositionInfo,\n ): void {\n if (this.isMouseStarted) {\n this.onMouseDrag(positionInfo);\n\n if (e.cancelable) {\n e.preventDefault();\n }\n return;\n }\n\n if (!this.isMouseDelayMet) {\n return;\n }\n\n if (this.mouseDownInfo) {\n this.isMouseStarted = this.onMouseStart(this.mouseDownInfo);\n }\n\n if (this.isMouseStarted) {\n this.onMouseDrag(positionInfo);\n\n if (e.cancelable) {\n e.preventDefault();\n }\n } else {\n this.handleMouseUp(positionInfo);\n }\n }\n private handleMouseUp(positionInfo: PositionInfo): void {\n this.removeMouseMoveEventListeners();\n this.isMouseDelayMet = false;\n this.mouseDownInfo = null;\n\n if (this.isMouseStarted) {\n this.isMouseStarted = false;\n this.onMouseStop(positionInfo);\n }\n }\n\n private handleStartMouse(): void {\n document.addEventListener(\"mousemove\", this.mouseMove, {\n passive: false,\n });\n document.addEventListener(\"touchmove\", this.touchMove, {\n passive: false,\n });\n document.addEventListener(\"mouseup\", this.mouseUp, { passive: false });\n document.addEventListener(\"touchend\", this.touchEnd, {\n passive: false,\n });\n\n const mouseDelay = this.getMouseDelay();\n\n if (mouseDelay) {\n this.startMouseDelayTimer(mouseDelay);\n } else {\n this.isMouseDelayMet = true;\n }\n }\n\n private mouseDown = (e: MouseEvent): void => {\n // Left mouse button?\n if (e.button !== 0) {\n return;\n }\n\n const result = this.handleMouseDown(getPositionInfoFromMouseEvent(e));\n\n if (result && e.cancelable) {\n e.preventDefault();\n }\n };\n\n private mouseMove = (e: MouseEvent): void => {\n this.handleMouseMove(e, getPositionInfoFromMouseEvent(e));\n };\n\n private mouseUp = (e: MouseEvent): void => {\n this.handleMouseUp(getPositionInfoFromMouseEvent(e));\n };\n\n private removeMouseMoveEventListeners() {\n document.removeEventListener(\"mousemove\", this.mouseMove);\n document.removeEventListener(\"touchmove\", this.touchMove);\n document.removeEventListener(\"mouseup\", this.mouseUp);\n document.removeEventListener(\"touchend\", this.touchEnd);\n }\n\n private startMouseDelayTimer(mouseDelay: number): void {\n if (this.mouseDelayTimer) {\n clearTimeout(this.mouseDelayTimer);\n }\n\n this.mouseDelayTimer = window.setTimeout(() => {\n if (this.mouseDownInfo) {\n this.isMouseDelayMet = true;\n }\n }, mouseDelay);\n\n this.isMouseDelayMet = false;\n }\n\n private touchEnd = (e: TouchEvent): void => {\n if (e.touches.length > 1) {\n return;\n }\n\n const touch = e.touches[0];\n\n if (!touch) {\n return;\n }\n\n this.handleMouseUp(getPositionInfoFromTouch(touch, e));\n };\n\n private touchMove = (e: TouchEvent): void => {\n if (e.touches.length > 1) {\n return;\n }\n\n const touch = e.touches[0];\n\n if (!touch) {\n return;\n }\n\n this.handleMouseMove(e, getPositionInfoFromTouch(touch, e));\n };\n\n private touchStart = (e: TouchEvent): void => {\n if (e.touches.length > 1) {\n return;\n }\n\n const touch = e.touches[0];\n\n if (!touch) {\n return;\n }\n\n this.handleMouseDown(getPositionInfoFromTouch(touch, e));\n };\n}\n\nexport default MouseHandler;\n","interface NodeRecordWithChildren extends NodeRecord {\n children: NodeData[];\n}\n\nexport const isNodeRecordWithChildren = (\n data: NodeData,\n): data is NodeRecordWithChildren =>\n typeof data === \"object\" &&\n \"children\" in data &&\n data.children instanceof Array;\n","import { isNodeRecordWithChildren } from \"./nodeUtils\";\n\nexport type Position = \"after\" | \"before\" | \"inside\";\n\ntype IterateCallback = (node: Node, level: number) => boolean;\n\nexport class Node implements INode {\n [key: string]: unknown;\n\n public children: Node[];\n public element?: HTMLElement;\n public id?: NodeId;\n public idMapping: Map<NodeId, Node>;\n public is_loading: boolean;\n public is_open: boolean;\n public isEmptyFolder: boolean;\n public load_on_demand: boolean;\n public name: string;\n public nodeClass?: typeof Node;\n public parent: Node | null;\n public tree?: Node;\n\n constructor(\n nodeData: NodeData | null = null,\n isRoot = false,\n nodeClass = Node,\n ) {\n this.name = \"\";\n this.load_on_demand = false;\n\n this.isEmptyFolder =\n nodeData != null &&\n isNodeRecordWithChildren(nodeData) &&\n nodeData.children.length === 0;\n\n this.setData(nodeData);\n\n this.children = [];\n this.parent = null;\n\n if (isRoot) {\n this.idMapping = new Map<NodeId, Node>();\n this.tree = this;\n this.nodeClass = nodeClass;\n }\n }\n\n public addAfter(nodeInfo: NodeData): Node | null {\n if (!this.parent) {\n return null;\n } else {\n const node = this.createNode(nodeInfo);\n\n const childIndex = this.parent.getChildIndex(this);\n this.parent.addChildAtPosition(node, childIndex + 1);\n\n node.loadChildrenFromData(nodeInfo);\n return node;\n }\n }\n\n public addBefore(nodeInfo: NodeData): Node | null {\n if (!this.parent) {\n return null;\n } else {\n const node = this.createNode(nodeInfo);\n\n const childIndex = this.parent.getChildIndex(this);\n this.parent.addChildAtPosition(node, childIndex);\n\n node.loadChildrenFromData(nodeInfo);\n return node;\n }\n }\n\n /*\n Add child.\n\n tree.addChild(\n new Node('child1')\n );\n */\n public addChild(node: Node): void {\n this.children.push(node);\n node.setParent(this);\n }\n\n /*\n Add child at position. Index starts at 0.\n\n tree.addChildAtPosition(\n new Node('abc'),\n 1\n );\n */\n public addChildAtPosition(node: Node, index: number): void {\n this.children.splice(index, 0, node);\n node.setParent(this);\n }\n\n public addNodeToIndex(node: Node): void {\n if (node.id != null) {\n this.idMapping.set(node.id, node);\n }\n }\n\n public addParent(nodeInfo: NodeData): Node | null {\n if (!this.parent) {\n return null;\n } else {\n const newParent = this.createNode(nodeInfo);\n\n if (this.tree) {\n newParent.setParent(this.tree);\n }\n const originalParent = this.parent;\n\n for (const child of originalParent.children) {\n newParent.addChild(child);\n }\n\n originalParent.children = [];\n originalParent.addChild(newParent);\n return newParent;\n }\n }\n\n public append(nodeInfo: NodeData): Node {\n const node = this.createNode(nodeInfo);\n this.addChild(node);\n\n node.loadChildrenFromData(nodeInfo);\n return node;\n }\n\n public filter(f: (node: Node) => boolean): Node[] {\n const result: Node[] = [];\n\n this.iterate((node: Node) => {\n if (f(node)) {\n result.push(node);\n }\n\n return true;\n });\n\n return result;\n }\n\n /*\n Get child index.\n\n var index = getChildIndex(node);\n */\n public getChildIndex(node: Node): number {\n return this.children.indexOf(node);\n }\n\n /*\n Get the tree as data.\n */\n public getData(includeParent = false): NodeRecord[] {\n const getDataFromNodes = (nodes: Node[]): Record<string, unknown>[] => {\n return nodes.map((node) => {\n const tmpNode: Record<string, unknown> = {};\n\n for (const k in node) {\n if (\n [\n \"parent\",\n \"children\",\n \"element\",\n \"idMapping\",\n \"load_on_demand\",\n \"nodeClass\",\n \"tree\",\n \"isEmptyFolder\",\n ].indexOf(k) === -1 &&\n Object.prototype.hasOwnProperty.call(node, k)\n ) {\n const v = node[k];\n tmpNode[k] = v;\n }\n }\n\n if (node.hasChildren()) {\n tmpNode.children = getDataFromNodes(node.children);\n }\n\n return tmpNode;\n });\n };\n\n if (includeParent) {\n return getDataFromNodes([this]);\n } else {\n return getDataFromNodes(this.children);\n }\n }\n\n public getLastChild(): Node | null {\n if (!this.hasChildren()) {\n return null;\n } else {\n const lastChild = this.children[this.children.length - 1];\n\n if (!lastChild) {\n return null;\n }\n\n if (!(lastChild.hasChildren() && lastChild.is_open)) {\n return lastChild;\n } else {\n return lastChild.getLastChild();\n }\n }\n }\n\n public getLevel(): number {\n let level = 0;\n let node: Node = this; // eslint-disable-line @typescript-eslint/no-this-alias\n\n while (node.parent) {\n level += 1;\n node = node.parent;\n }\n\n return level;\n }\n\n public getNextNode(includeChildren = true): Node | null {\n if (includeChildren && this.hasChildren()) {\n return this.children[0] ?? null;\n } else if (!this.parent) {\n return null;\n } else {\n const nextSibling = this.getNextSibling();\n\n if (nextSibling) {\n return nextSibling;\n } else {\n return this.parent.getNextNode(false);\n }\n }\n }\n\n public getNextSibling(): Node | null {\n if (!this.parent) {\n return null;\n } else {\n const nextIndex = this.parent.getChildIndex(this) + 1;\n if (nextIndex < this.parent.children.length) {\n return this.parent.children[nextIndex] ?? null;\n } else {\n return null;\n }\n }\n }\n\n public getNextVisibleNode(): Node | null {\n if (this.hasChildren() && this.is_open) {\n // First child\n return this.children[0] ?? null;\n } else {\n if (!this.parent) {\n return null;\n } else {\n const nextSibling = this.getNextSibling();\n if (nextSibling) {\n // Next sibling\n return nextSibling;\n } else {\n // Next node of parent\n return this.parent.getNextNode(false);\n }\n }\n }\n }\n\n public getNodeByCallback(callback: (node: Node) => boolean): Node | null {\n let result: Node | null = null;\n\n this.iterate((node: Node) => {\n if (result) {\n return false;\n } else if (callback(node)) {\n result = node;\n return false;\n } else {\n return true;\n }\n });\n\n return result;\n }\n\n public getNodeById(nodeId: NodeId): Node | null {\n return this.idMapping.get(nodeId) ?? null;\n }\n\n public getNodeByName(name: string): Node | null {\n return this.getNodeByCallback((node: Node) => node.name === name);\n }\n\n public getNodeByNameMustExist(name: string): Node {\n const node = this.getNodeByCallback((n: Node) => n.name === name);\n\n if (!node) {\n throw new Error(`Node with name ${name} not found`);\n }\n\n return node;\n }\n\n public getNodesByProperty(key: string, value: unknown): Node[] {\n return this.filter((node: Node) => node[key] === value);\n }\n\n public getParent(): Node | null {\n // Return parent except if it is the root node\n if (!this.parent) {\n return null;\n } else if (!this.parent.parent) {\n // Root node -> null\n return null;\n } else {\n return this.parent;\n }\n }\n\n public getPreviousNode(): Node | null {\n if (!this.parent) {\n return null;\n } else {\n const previousSibling = this.getPreviousSibling();\n\n if (!previousSibling) {\n return this.getParent();\n } else if (previousSibling.hasChildren()) {\n return previousSibling.getLastChild();\n } else {\n return previousSibling;\n }\n }\n }\n\n public getPreviousSibling(): Node | null {\n if (!this.parent) {\n return null;\n } else {\n const previousIndex = this.parent.getChildIndex(this) - 1;\n if (previousIndex >= 0) {\n return this.parent.children[previousIndex] ?? null;\n } else {\n return null;\n }\n }\n }\n\n public getPreviousVisibleNode(): Node | null {\n if (!this.parent) {\n return null;\n } else {\n const previousSibling = this.getPreviousSibling();\n\n if (!previousSibling) {\n return this.getParent();\n } else if (\n !previousSibling.hasChildren() ||\n !previousSibling.is_open\n ) {\n // Previous sibling\n return previousSibling;\n } else {\n // Last child of previous sibling\n return previousSibling.getLastChild();\n }\n }\n }\n\n /*\n Does the tree have children?\n\n if (tree.hasChildren()) {\n //\n }\n */\n public hasChildren(): boolean {\n return this.children.length !== 0;\n }\n\n // Init Node from data without making it the root of the tree\n public initFromData(data: NodeData): void {\n const addNode = (nodeData: NodeData): void => {\n this.setData(nodeData);\n\n if (\n isNodeRecordWithChildren(nodeData) &&\n nodeData.children.length\n ) {\n addChildren(nodeData.children);\n }\n };\n\n const addChildren = (childrenData: NodeData[]): void => {\n for (const child of childrenData) {\n const node = this.createNode();\n node.initFromData(child);\n this.addChild(node);\n }\n };\n\n addNode(data);\n }\n\n public isFolder(): boolean {\n return this.hasChildren() || this.load_on_demand;\n }\n\n public isParentOf(node: Node): boolean {\n let parent = node.parent;\n\n while (parent) {\n if (parent === this) {\n return true;\n }\n\n parent = parent.parent;\n }\n\n return false;\n }\n\n /*\n Iterate over all the nodes in the tree.\n\n Calls callback with (node, level).\n\n The callback must return true to continue the iteration on current node.\n\n tree.iterate(\n function(node, level) {\n console.log(node.name);\n\n // stop iteration after level 2\n return (level <= 2);\n }\n );\n\n */\n public iterate(callback: IterateCallback): void {\n const _iterate = (node: Node, level: number): void => {\n for (const child of node.children) {\n const result = callback(child, level);\n\n if (result && child.hasChildren()) {\n _iterate(child, level + 1);\n }\n }\n };\n\n _iterate(this, 0);\n }\n\n /*\n Create tree from data.\n\n Structure of data is:\n [\n {\n name: 'node1',\n children: [\n { name: 'child1' },\n { name: 'child2' }\n ]\n },\n {\n name: 'node2'\n }\n ]\n */\n public loadFromData(data: NodeData[]): this {\n this.removeChildren();\n\n for (const childData of data) {\n const node = this.createNode(childData);\n this.addChild(node);\n\n if (isNodeRecordWithChildren(childData)) {\n node.loadFromData(childData.children);\n }\n }\n\n return this;\n }\n\n /*\n Move node relative to another node.\n\n Argument position: Position.BEFORE, Position.AFTER or Position.Inside\n\n // move node1 after node2\n tree.moveNode(node1, node2, Position.AFTER);\n */\n public moveNode(\n movedNode: Node,\n targetNode: Node,\n position: Position,\n ): boolean {\n if (!movedNode.parent || movedNode.isParentOf(targetNode)) {\n // - Node is parent of target node\n // - Or, parent is empty\n return false;\n } else {\n movedNode.parent.doRemoveChild(movedNode);\n\n switch (position) {\n case \"after\": {\n if (targetNode.parent) {\n targetNode.parent.addChildAtPosition(\n movedNode,\n targetNode.parent.getChildIndex(targetNode) + 1,\n );\n return true;\n }\n return false;\n }\n\n case \"before\": {\n if (targetNode.parent) {\n targetNode.parent.addChildAtPosition(\n movedNode,\n targetNode.parent.getChildIndex(targetNode),\n );\n return true;\n }\n return false;\n }\n\n case \"inside\": {\n // move inside as first child\n targetNode.addChildAtPosition(movedNode, 0);\n return true;\n }\n }\n }\n }\n\n public prepend(nodeInfo: NodeData): Node {\n const node = this.createNode(nodeInfo);\n this.addChildAtPosition(node, 0);\n\n node.loadChildrenFromData(nodeInfo);\n return node;\n }\n\n public remove(): void {\n if (this.parent) {\n this.parent.removeChild(this);\n this.parent = null;\n }\n }\n\n /*\n Remove child. This also removes the children of the node.\n\n tree.removeChild(tree.children[0]);\n */\n public removeChild(node: Node): void {\n // remove children from the index\n node.removeChildren();\n\n this.doRemoveChild(node);\n }\n\n public removeChildren(): void {\n this.iterate((child: Node) => {\n this.tree?.removeNodeFromIndex(child);\n return true;\n });\n\n this.children = [];\n }\n\n public removeNodeFromIndex(node: Node): void {\n if (node.id != null) {\n this.idMapping.delete(node.id);\n }\n }\n\n /*\n Set the data of this node.\n\n setData(string): set the name of the node\n setData(object): set attributes of the node\n\n Examples:\n setData('node1')\n\n setData({ name: 'node1', id: 1});\n\n setData({ name: 'node2', id: 2, color: 'green'});\n\n * This is an internal function; it is not in the docs\n * Does not remove existing node values\n */\n public setData(o: NodeData | null): void {\n if (!o) {\n return;\n } else if (typeof o === \"string\") {\n this.name = o;\n } else if (typeof o === \"object\") {\n for (const key in o) {\n if (Object.prototype.hasOwnProperty.call(o, key)) {\n const value = o[key];\n\n if (key === \"label\" || key === \"name\") {\n // You can use the 'label' key instead of 'name'; this is a legacy feature\n if (typeof value === \"string\") {\n this.name = value;\n }\n } else if (key !== \"children\" && key !== \"parent\") {\n // You can't update the children or the parent using this function\n this[key] = value;\n }\n }\n }\n }\n }\n\n private createNode(nodeData?: NodeData): Node {\n const nodeClass = this.getNodeClass();\n return new nodeClass(nodeData);\n }\n\n private doRemoveChild(node: Node): void {\n this.children.splice(this.getChildIndex(node), 1);\n this.tree?.removeNodeFromIndex(node);\n }\n\n private getNodeClass(): typeof Node {\n return this.nodeClass ?? this.tree?.nodeClass ?? Node;\n }\n\n // Load children data from nodeInfo if it has children\n private loadChildrenFromData(nodeInfo: NodeData) {\n if (isNodeRecordWithChildren(nodeInfo) && nodeInfo.children.length) {\n this.loadFromData(nodeInfo.children);\n }\n }\n\n private setParent(parent: Node): void {\n this.parent = parent;\n this.tree = parent.tree;\n this.tree?.addNodeToIndex(this);\n }\n}\n","import { DropHint } from \"../dragAndDropHandler/types\";\n\nclass BorderDropHint implements DropHint {\n private hint?: HTMLElement;\n\n constructor(element: HTMLElement, scrollLeft: number) {\n const div = element.querySelector(\":scope > .jqtree-element\");\n\n if (!div) {\n this.hint = undefined;\n return;\n }\n\n const width = Math.max(element.offsetWidth + scrollLeft - 4, 0);\n const height = Math.max(element.clientHeight - 4, 0);\n\n const hint = document.createElement(\"span\");\n hint.className = \"jqtree-border\";\n hint.style.width = `${width}px`;\n hint.style.height = `${height}px`;\n\n this.hint = hint;\n\n div.append(this.hint);\n }\n\n public remove(): void {\n this.hint?.remove();\n }\n}\n\nexport default BorderDropHint;\n","import { DropHint } from \"../dragAndDropHandler/types\";\nimport { Node, Position } from \"../node\";\n\nclass GhostDropHint implements DropHint {\n private element: HTMLElement;\n private ghost: HTMLElement;\n private node: Node;\n\n constructor(node: Node, element: HTMLElement, position: Position) {\n this.element = element;\n this.node = node;\n this.ghost = this.createGhostElement();\n\n switch (position) {\n case \"after\":\n this.moveAfter();\n break;\n\n case \"before\":\n this.moveBefore();\n break;\n\n case \"inside\": {\n if (node.isFolder() && node.is_open) {\n this.moveInsideOpenFolder();\n } else {\n this.moveInside();\n }\n }\n }\n }\n\n public remove(): void {\n this.ghost.remove();\n }\n\n private createGhostElement() {\n const ghost = document.createElement(\"li\");\n ghost.className = \"jqtree_common jqtree-ghost\";\n\n const circleSpan = document.createElement(\"span\");\n circleSpan.className = \"jqtree_common jqtree-circle\";\n ghost.append(circleSpan);\n\n const lineSpan = document.createElement(\"span\");\n lineSpan.className = \"jqtree_common jqtree-line\";\n ghost.append(lineSpan);\n\n return ghost;\n }\n\n private moveAfter(): void {\n this.element.after(this.ghost);\n }\n\n private moveBefore(): void {\n this.element.before(this.ghost);\n }\n\n private moveInside(): void {\n this.element.after(this.ghost);\n this.ghost.classList.add(\"jqtree-inside\");\n }\n\n private moveInsideOpenFolder(): void {\n const childElement = this.node.children[0]?.element;\n\n if (childElement) {\n childElement.before(this.ghost);\n }\n }\n}\n\nexport default GhostDropHint;\n","import { DropHint } from \"../dragAndDropHandler/types\";\nimport { GetScrollLeft } from \"../jqtreeMethodTypes\";\nimport { Node, Position } from \"../node\";\nimport BorderDropHint from \"./borderDropHint\";\nimport GhostDropHint from \"./ghostDropHint\";\n\nexport interface NodeElementParams {\n getScrollLeft: GetScrollLeft;\n node: Node;\n tabIndex?: number;\n treeElement: HTMLElement;\n}\n\nclass NodeElement {\n public element: HTMLElement;\n public node: Node;\n private getScrollLeft: GetScrollLeft;\n private tabIndex?: number;\n private treeElement: HTMLElement;\n\n constructor({\n getScrollLeft,\n node,\n tabIndex,\n treeElement,\n }: NodeElementParams) {\n this.getScrollLeft = getScrollLeft;\n this.tabIndex = tabIndex;\n this.treeElement = treeElement;\n\n this.init(node);\n }\n\n public addDropHint(position: Position): DropHint {\n if (this.mustShowBorderDropHint(position)) {\n return new BorderDropHint(this.element, this.getScrollLeft());\n } else {\n return new GhostDropHint(this.node, this.element, position);\n }\n }\n\n public deselect(): void {\n this.element.classList.remove(\"jqtree-selected\");\n\n const titleSpan = this.getTitleSpan();\n titleSpan.removeAttribute(\"tabindex\");\n titleSpan.setAttribute(\"aria-selected\", \"false\");\n\n titleSpan.blur();\n }\n\n public init(node: Node): void {\n this.node = node;\n\n if (!node.element) {\n node.element = this.treeElement;\n }\n\n this.element = node.element;\n }\n\n public select(mustSetFocus: boolean): void {\n this.element.classList.add(\"jqtree-selected\");\n\n const titleSpan = this.getTitleSpan();\n const tabIndex = this.tabIndex;\n\n // Check for null or undefined\n if (tabIndex != null) {\n titleSpan.setAttribute(\"tabindex\", tabIndex.toString());\n }\n\n titleSpan.setAttribute(\"aria-selected\", \"true\");\n\n if (mustSetFocus) {\n titleSpan.focus();\n }\n }\n\n protected getTitleSpan(): HTMLSpanElement {\n return this.element.querySelector(\n \":scope > .jqtree-element > span.jqtree-title\",\n ) as HTMLSpanElement;\n }\n\n protected getUl(): HTMLUListElement {\n return this.element.querySelector(\":scope > ul\") as HTMLUListElement;\n }\n\n protected mustShowBorderDropHint(position: Position): boolean {\n return position === \"inside\";\n }\n}\n\nexport default NodeElement;\n","import { OnFinishOpenNode, TriggerEvent } from \"../jqtreeMethodTypes\";\nimport { Position } from \"../node\";\nimport NodeElement, { NodeElementParams } from \"./index\";\n\ninterface FolderElementParams extends NodeElementParams {\n closedIconElement?: HTMLElement | Text;\n openedIconElement?: HTMLElement | Text;\n triggerEvent: TriggerEvent;\n}\n\nclass FolderElement extends NodeElement {\n private closedIconElement?: HTMLElement | Text;\n private openedIconElement?: HTMLElement | Text;\n private triggerEvent: TriggerEvent;\n\n constructor({\n closedIconElement,\n getScrollLeft,\n node,\n openedIconElement,\n tabIndex,\n treeElement,\n triggerEvent,\n }: FolderElementParams) {\n super({\n getScrollLeft,\n node,\n tabIndex,\n treeElement,\n });\n\n this.closedIconElement = closedIconElement;\n this.openedIconElement = openedIconElement;\n this.triggerEvent = triggerEvent;\n }\n\n public close(slide: boolean, animationSpeed: JQuery.Duration): void {\n if (!this.node.is_open) {\n return;\n }\n\n this.node.is_open = false;\n\n const button = this.getButton();\n button.classList.add(\"jqtree-closed\");\n button.innerHTML = \"\";\n\n const closedIconElement = this.closedIconElement;\n\n if (closedIconElement) {\n const icon = closedIconElement.cloneNode(true);\n button.appendChild(icon);\n }\n\n const doClose = (): void => {\n this.element.classList.add(\"jqtree-closed\");\n\n const titleSpan = this.getTitleSpan();\n titleSpan.setAttribute(\"aria-expanded\", \"false\");\n\n this.triggerEvent(\"tree.close\", {\n node: this.node,\n });\n };\n\n if (slide) {\n jQuery(this.getUl()).slideUp(animationSpeed, doClose);\n } else {\n jQuery(this.getUl()).hide();\n doClose();\n }\n }\n\n public open(\n onFinished: OnFinishOpenNode | undefined,\n slide: boolean,\n animationSpeed: JQuery.Duration,\n ): void {\n if (this.node.is_open) {\n return;\n }\n\n this.node.is_open = true;\n\n const button = this.getButton();\n button.classList.remove(\"jqtree-closed\");\n button.innerHTML = \"\";\n\n const openedIconElement = this.openedIconElement;\n\n if (openedIconElement) {\n const icon = openedIconElement.cloneNode(true);\n button.appendChild(icon);\n }\n\n const doOpen = (): void => {\n this.element.classList.remove(\"jqtree-closed\");\n\n const titleSpan = this.getTitleSpan();\n titleSpan.setAttribute(\"aria-expanded\", \"true\");\n\n if (onFinished) {\n onFinished(this.node);\n }\n\n this.triggerEvent(\"tree.open\", {\n node: this.node,\n });\n };\n\n if (slide) {\n jQuery(this.getUl()).slideDown(animationSpeed, doOpen);\n } else {\n jQuery(this.getUl()).show();\n doOpen();\n }\n }\n\n protected mustShowBorderDropHint(position: Position): boolean {\n return !this.node.is_open && position === \"inside\";\n }\n\n private getButton(): HTMLLinkElement {\n return this.element.querySelector(\n \":scope > .jqtree-element > a.jqtree-toggler\",\n ) as HTMLLinkElement;\n }\n}\n\nexport default FolderElement;\n","import {\n AddToSelection,\n GetNodeById,\n GetSelectedNodes,\n GetTree,\n OpenNode,\n RefreshElements,\n RemoveFromSelection,\n} from \"./jqtreeMethodTypes\";\nimport { OnGetStateFromStorage, OnSetStateFromStorage } from \"./jqtreeOptions\";\nimport { Node } from \"./node\";\nimport { isInt } from \"./util\";\n\nexport interface SavedState {\n open_nodes?: NodeId[];\n selected_node?: NodeId[];\n}\n\ninterface SaveStateHandlerParams {\n addToSelection: AddToSelection;\n getNodeById: GetNodeById;\n getSelectedNodes: GetSelectedNodes;\n getTree: GetTree;\n onGetStateFromStorage?: OnGetStateFromStorage;\n onSetStateFromStorage?: OnSetStateFromStorage;\n openNode: OpenNode;\n refreshElements: RefreshElements;\n removeFromSelection: RemoveFromSelection;\n saveState: boolean | string;\n}\n\nexport default class SaveStateHandler {\n private addToSelection: AddToSelection;\n private getNodeById: GetNodeById;\n private getSelectedNodes: GetSelectedNodes;\n private getTree: GetTree;\n private onGetStateFromStorage?: OnGetStateFromStorage;\n private onSetStateFromStorage?: OnSetStateFromStorage;\n private openNode: OpenNode;\n private refreshElements: RefreshElements;\n private removeFromSelection: RemoveFromSelection;\n private saveStateOption: boolean | string;\n\n constructor({\n addToSelection,\n getNodeById,\n getSelectedNodes,\n getTree,\n onGetStateFromStorage,\n onSetStateFromStorage,\n openNode,\n refreshElements,\n removeFromSelection,\n saveState,\n }: SaveStateHandlerParams) {\n this.addToSelection = addToSelection;\n this.getNodeById = getNodeById;\n this.getSelectedNodes = getSelectedNodes;\n this.getTree = getTree;\n this.onGetStateFromStorage = onGetStateFromStorage;\n this.onSetStateFromStorage = onSetStateFromStorage;\n this.openNode = openNode;\n this.refreshElements = refreshElements;\n this.removeFromSelection = removeFromSelection;\n this.saveStateOption = saveState;\n }\n\n public getNodeIdToBeSelected(): NodeId | null {\n const state = this.getStateFromStorage();\n\n if (state?.selected_node) {\n return state.selected_node[0] ?? null;\n } else {\n return null;\n }\n }\n\n public getState(): SavedState {\n const getOpenNodeIds = (): NodeId[] => {\n const openNodes: NodeId[] = [];\n\n this.getTree()?.iterate((node: Node) => {\n if (node.is_open && node.id && node.hasChildren()) {\n openNodes.push(node.id);\n }\n return true;\n });\n\n return openNodes;\n };\n\n const getSelectedNodeIds = (): NodeId[] => {\n const selectedNodeIds: NodeId[] = [];\n\n this.getSelectedNodes().forEach((node) => {\n if (node.id != null) {\n selectedNodeIds.push(node.id);\n }\n });\n\n return selectedNodeIds;\n };\n\n return {\n open_nodes: getOpenNodeIds(),\n selected_node: getSelectedNodeIds(),\n };\n }\n\n public getStateFromStorage(): null | SavedState {\n const jsonData = this.loadFromStorage();\n\n if (jsonData) {\n return this.parseState(jsonData) as unknown as SavedState;\n } else {\n return null;\n }\n }\n\n public saveState(): void {\n const state = JSON.stringify(this.getState());\n\n if (this.onSetStateFromStorage) {\n this.onSetStateFromStorage(state);\n } else {\n localStorage.setItem(this.getKeyName(), state);\n }\n }\n\n /*\n Set initial state\n Don't handle nodes that are loaded on demand\n\n result: must load on demand (boolean)\n */\n public setInitialState(state: SavedState): boolean {\n let mustLoadOnDemand = false;\n\n if (state.open_nodes) {\n mustLoadOnDemand = this.openInitialNodes(state.open_nodes);\n }\n\n this.resetSelection();\n\n if (state.selected_node) {\n this.selectInitialNodes(state.selected_node);\n }\n\n return mustLoadOnDemand;\n }\n\n public setInitialStateOnDemand(\n state: SavedState,\n cbFinished: () => void,\n ): void {\n let loadingCount = 0;\n let nodeIds = state.open_nodes;\n\n const openNodes = (): void => {\n if (!nodeIds) {\n return;\n }\n\n const newNodesIds = [];\n\n for (const nodeId of nodeIds) {\n const node = this.getNodeById(nodeId);\n\n if (!node) {\n newNodesIds.push(nodeId);\n } else {\n if (!node.is_loading) {\n if (node.load_on_demand) {\n loadAndOpenNode(node);\n } else {\n this.openNode(node, false);\n }\n }\n }\n }\n\n nodeIds = newNodesIds;\n\n if (state.selected_node) {\n if (this.selectInitialNodes(state.selected_node)) {\n this.refreshElements(null);\n }\n }\n\n if (loadingCount === 0) {\n cbFinished();\n }\n };\n\n const loadAndOpenNode = (node: Node): void => {\n loadingCount += 1;\n this.openNode(node, false, () => {\n loadingCount -= 1;\n openNodes();\n });\n };\n\n openNodes();\n }\n\n private getKeyName(): string {\n if (typeof this.saveStateOption === \"string\") {\n return this.saveStateOption;\n } else {\n return \"tree\";\n }\n }\n\n private loadFromStorage(): null | string {\n if (this.onGetStateFromStorage) {\n return this.onGetStateFromStorage();\n } else {\n return localStorage.getItem(this.getKeyName());\n }\n }\n\n private openInitialNodes(nodeIds: NodeId[]): boolean {\n let mustLoadOnDemand = false;\n\n for (const nodeId of nodeIds) {\n const node = this.getNodeById(nodeId);\n\n if (node) {\n if (!node.load_on_demand) {\n node.is_open = true;\n } else {\n mustLoadOnDemand = true;\n }\n }\n }\n\n return mustLoadOnDemand;\n }\n\n private parseState(jsonData: string): SavedState {\n const state = JSON.parse(jsonData) as Record<string, unknown>;\n\n // Check if selected_node is an int (instead of an array)\n if (state.selected_node && isInt(state.selected_node)) {\n // Convert to array\n state.selected_node = [state.selected_node];\n }\n\n return state as unknown as SavedState;\n }\n\n private resetSelection(): void {\n const selectedNodes = this.getSelectedNodes();\n\n selectedNodes.forEach((node) => {\n this.removeFromSelection(node);\n });\n }\n\n private selectInitialNodes(nodeIds: NodeId[]): boolean {\n let selectCount = 0;\n\n for (const nodeId of nodeIds) {\n const node = this.getNodeById(nodeId);\n\n if (node) {\n selectCount += 1;\n\n this.addToSelection(node);\n }\n }\n\n return selectCount !== 0;\n }\n}\n","import type { ScrollParent } from \"./types\";\n\nimport { getElementPosition, getOffsetTop } from '../util'\n\ntype HorizontalScrollDirection = \"left\" | \"right\";\ninterface Params {\n container: HTMLElement;\n refreshHitAreas: () => void;\n}\n\ntype VerticalScrollDirection = \"bottom\" | \"top\";\n\nexport default class ContainerScrollParent implements ScrollParent {\n private container: HTMLElement;\n private horizontalScrollDirection?: HorizontalScrollDirection;\n private horizontalScrollTimeout?: number;\n private refreshHitAreas: () => void;\n private scrollParentBottom?: number;\n private scrollParentTop?: number;\n private verticalScrollDirection?: VerticalScrollDirection;\n private verticalScrollTimeout?: number;\n\n constructor({ container, refreshHitAreas }: Params) {\n this.container = container;\n this.refreshHitAreas = refreshHitAreas;\n }\n\n public checkHorizontalScrolling(pageX: number): void {\n const newHorizontalScrollDirection =\n this.getNewHorizontalScrollDirection(pageX);\n\n if (this.horizontalScrollDirection !== newHorizontalScrollDirection) {\n this.horizontalScrollDirection = newHorizontalScrollDirection;\n\n if (this.horizontalScrollTimeout != null) {\n window.clearTimeout(this.verticalScrollTimeout);\n }\n\n if (newHorizontalScrollDirection) {\n this.horizontalScrollTimeout = window.setTimeout(\n this.scrollHorizontally.bind(this),\n 40,\n );\n }\n }\n }\n\n public checkVerticalScrolling(pageY: number) {\n const newVerticalScrollDirection =\n this.getNewVerticalScrollDirection(pageY);\n\n if (this.verticalScrollDirection !== newVerticalScrollDirection) {\n this.verticalScrollDirection = newVerticalScrollDirection;\n\n if (this.verticalScrollTimeout != null) {\n window.clearTimeout(this.verticalScrollTimeout);\n this.verticalScrollTimeout = undefined;\n }\n\n if (newVerticalScrollDirection) {\n this.verticalScrollTimeout = window.setTimeout(\n this.scrollVertically.bind(this),\n 40,\n );\n }\n }\n }\n\n public getScrollLeft(): number {\n return this.container.scrollLeft;\n }\n\n public scrollToY(top: number): void {\n this.container.scrollTop = top;\n }\n\n public stopScrolling() {\n this.horizontalScrollDirection = undefined;\n this.verticalScrollDirection = undefined;\n this.scrollParentTop = undefined;\n this.scrollParentBottom = undefined;\n }\n\n private getNewHorizontalScrollDirection(\n pageX: number,\n ): HorizontalScrollDirection | undefined {\n const scrollParentOffset = getElementPosition(this.container);\n\n const rightEdge = scrollParentOffset.left + this.container.clientWidth;\n const leftEdge = scrollParentOffset.left;\n const isNearRightEdge = pageX > rightEdge - 20;\n const isNearLeftEdge = pageX < leftEdge + 20;\n\n if (isNearRightEdge) {\n return \"right\";\n } else if (isNearLeftEdge) {\n return \"left\";\n }\n\n return undefined;\n }\n\n private getNewVerticalScrollDirection(\n pageY: number,\n ): undefined | VerticalScrollDirection {\n if (pageY < this.getScrollParentTop()) {\n return \"top\";\n }\n\n if (pageY > this.getScrollParentBottom()) {\n return \"bottom\";\n }\n\n return undefined;\n }\n\n private getScrollParentBottom() {\n if (this.scrollParentBottom == null) {\n this.scrollParentBottom = this.getScrollParentTop() + this.container.clientHeight;\n }\n\n return this.scrollParentBottom;\n }\n\n private getScrollParentTop() {\n if (this.scrollParentTop == null) {\n this.scrollParentTop = getOffsetTop(this.container)\n }\n\n return this.scrollParentTop;\n }\n\n private scrollHorizontally() {\n if (!this.horizontalScrollDirection) {\n return;\n }\n\n const distance = this.horizontalScrollDirection === \"left\" ? -20 : 20;\n\n this.container.scrollBy({\n behavior: \"instant\",\n left: distance,\n top: 0,\n });\n\n this.refreshHitAreas();\n\n setTimeout(this.scrollHorizontally.bind(this), 40);\n }\n\n private scrollVertically() {\n if (!this.verticalScrollDirection) {\n return;\n }\n\n const distance = this.verticalScrollDirection === \"top\" ? -20 : 20;\n\n this.container.scrollBy({\n behavior: \"instant\",\n left: 0,\n top: distance,\n });\n\n this.refreshHitAreas();\n\n setTimeout(this.scrollVertically.bind(this), 40);\n }\n}\n","import type { ScrollParent } from \"./types\";\n\nimport { getOffsetTop } from \"../util\";\n\ntype HorizontalScrollDirection = \"left\" | \"right\";\ninterface Params {\n refreshHitAreas: () => void;\n treeElement: HTMLElement;\n}\n\ntype VerticalScrollDirection = \"bottom\" | \"top\";\n\nexport default class DocumentScrollParent implements ScrollParent {\n private documentScrollHeight?: number;\n private documentScrollWidth?: number;\n private horizontalScrollDirection?: HorizontalScrollDirection;\n private horizontalScrollTimeout?: number;\n private refreshHitAreas: () => void;\n private treeElement: HTMLElement;\n private verticalScrollDirection?: VerticalScrollDirection;\n private verticalScrollTimeout?: number;\n\n constructor({ refreshHitAreas, treeElement }: Params) {\n this.refreshHitAreas = refreshHitAreas;\n this.treeElement = treeElement;\n }\n\n public checkHorizontalScrolling(pageX: number): void {\n const newHorizontalScrollDirection =\n this.getNewHorizontalScrollDirection(pageX);\n\n if (this.horizontalScrollDirection !== newHorizontalScrollDirection) {\n this.horizontalScrollDirection = newHorizontalScrollDirection;\n\n if (this.horizontalScrollTimeout != null) {\n window.clearTimeout(this.horizontalScrollTimeout);\n }\n\n if (newHorizontalScrollDirection) {\n this.horizontalScrollTimeout = window.setTimeout(\n this.scrollHorizontally.bind(this),\n 40,\n );\n }\n }\n }\n\n public checkVerticalScrolling(pageY: number) {\n const newVerticalScrollDirection =\n this.getNewVerticalScrollDirection(pageY);\n\n if (this.verticalScrollDirection !== newVerticalScrollDirection) {\n this.verticalScrollDirection = newVerticalScrollDirection;\n\n if (this.verticalScrollTimeout != null) {\n window.clearTimeout(this.verticalScrollTimeout);\n this.verticalScrollTimeout = undefined;\n }\n\n if (newVerticalScrollDirection) {\n this.verticalScrollTimeout = window.setTimeout(\n this.scrollVertically.bind(this),\n 40,\n );\n }\n }\n }\n\n public getScrollLeft(): number {\n return document.documentElement.scrollLeft;\n }\n\n public scrollToY(top: number): void {\n const treeTop = getOffsetTop(this.treeElement);\n\n document.documentElement.scrollTop = top + treeTop;\n }\n\n public stopScrolling() {\n this.horizontalScrollDirection = undefined;\n this.verticalScrollDirection = undefined;\n this.documentScrollHeight = undefined;\n this.documentScrollWidth = undefined;\n }\n\n private canScrollDown() {\n const documentElement = document.documentElement;\n\n return (\n documentElement.scrollTop + documentElement.clientHeight <\n this.getDocumentScrollHeight()\n );\n }\n\n private canScrollRight() {\n const documentElement = document.documentElement;\n\n return (\n documentElement.scrollLeft + documentElement.clientWidth <\n this.getDocumentScrollWidth()\n );\n }\n\n private getDocumentScrollHeight() {\n // Store the original scroll height because the scroll height can increase when the drag element is moved beyond the scroll height.\n if (this.documentScrollHeight == null) {\n this.documentScrollHeight = document.documentElement.scrollHeight;\n }\n\n return this.documentScrollHeight;\n }\n\n private getDocumentScrollWidth() {\n // Store the original scroll width because the scroll width can increase when the drag element is moved beyond the scroll width.\n if (this.documentScrollWidth == null) {\n this.documentScrollWidth = document.documentElement.scrollWidth;\n }\n\n return this.documentScrollWidth;\n }\n\n private getNewHorizontalScrollDirection(\n pageX: number,\n ): HorizontalScrollDirection | undefined {\n const scrollLeft = document.documentElement.scrollLeft;\n const windowWidth = window.innerWidth;\n\n const isNearRightEdge = pageX > windowWidth - 20;\n const isNearLeftEdge = pageX - scrollLeft < 20;\n\n if (isNearRightEdge && this.canScrollRight()) {\n return \"right\";\n }\n\n if (isNearLeftEdge) {\n return \"left\";\n }\n\n return undefined;\n }\n\n private getNewVerticalScrollDirection(\n pageY: number,\n ): undefined | VerticalScrollDirection {\n const scrollTop = jQuery(document).scrollTop() ?? 0;\n const distanceTop = pageY - scrollTop;\n\n if (distanceTop < 20) {\n return \"top\";\n }\n\n const windowHeight = window.innerHeight;\n\n if (windowHeight - (pageY - scrollTop) < 20 && this.canScrollDown()) {\n return \"bottom\";\n }\n\n return undefined;\n }\n\n private scrollHorizontally() {\n if (!this.horizontalScrollDirection) {\n return;\n }\n\n const distance = this.horizontalScrollDirection === \"left\" ? -20 : 20;\n window.scrollBy({ behavior: \"instant\", left: distance, top: 0 });\n\n this.refreshHitAreas();\n\n setTimeout(this.scrollHorizontally.bind(this), 40);\n }\n\n private scrollVertically() {\n if (!this.verticalScrollDirection) {\n return;\n }\n\n const distance = this.verticalScrollDirection === \"top\" ? -20 : 20;\n window.scrollBy({ behavior: \"instant\", left: 0, top: distance });\n\n this.refreshHitAreas();\n\n setTimeout(this.scrollVertically.bind(this), 40);\n }\n}\n","import type { ScrollParent } from \"./types\";\n\nimport ContainerScrollParent from \"./containerScrollParent\";\nimport DocumentScrollParent from \"./documentScrollParent\";\n\nconst isOverflow = (overflowValue: string) =>\n overflowValue === \"auto\" || overflowValue === \"scroll\";\n\nconst hasOverFlow = (element: HTMLElement): boolean => {\n const style = getComputedStyle(element);\n\n return isOverflow(style.overflowX) || isOverflow(style.overflowY);\n};\n\nconst getParentWithOverflow = (\n treeElement: HTMLElement,\n): HTMLElement | null => {\n if (hasOverFlow(treeElement)) {\n return treeElement;\n }\n\n let parent = treeElement.parentElement;\n\n while (parent) {\n if (hasOverFlow(parent)) {\n return parent;\n }\n\n parent = parent.parentElement;\n }\n\n return null;\n};\n\nconst createScrollParent = (\n treeElement: HTMLElement,\n refreshHitAreas: () => void,\n): ScrollParent => {\n const container = getParentWithOverflow(treeElement);\n\n if (container && container.tagName !== \"HTML\") {\n return new ContainerScrollParent({\n container,\n refreshHitAreas,\n });\n } else {\n return new DocumentScrollParent({ refreshHitAreas, treeElement });\n }\n};\n\nexport default createScrollParent;\n","import { PositionInfo } from \"./mouseUtils\";\nimport createScrollParent from \"./scrollHandler/createScrollParent\";\nimport { ScrollParent } from \"./scrollHandler/types\";\n\ninterface ScrollHandlerParams {\n refreshHitAreas: () => void;\n treeElement: HTMLElement;\n}\n\nexport default class ScrollHandler {\n private refreshHitAreas: () => void;\n private scrollParent?: ScrollParent;\n private treeElement: HTMLElement;\n\n constructor({ refreshHitAreas, treeElement }: ScrollHandlerParams) {\n this.refreshHitAreas = refreshHitAreas;\n this.scrollParent = undefined;\n this.treeElement = treeElement;\n }\n\n public checkScrolling(positionInfo: PositionInfo): void {\n this.checkVerticalScrolling(positionInfo);\n this.checkHorizontalScrolling(positionInfo);\n }\n\n public getScrollLeft(): number {\n return this.getScrollParent().getScrollLeft();\n }\n\n public scrollToY(top: number): void {\n this.getScrollParent().scrollToY(top);\n }\n\n public stopScrolling() {\n this.getScrollParent().stopScrolling();\n }\n\n private checkHorizontalScrolling(positionInfo: PositionInfo): void {\n this.getScrollParent().checkHorizontalScrolling(positionInfo.pageX);\n }\n\n private checkVerticalScrolling(positionInfo: PositionInfo): void {\n this.getScrollParent().checkVerticalScrolling(positionInfo.pageY);\n }\n\n private getScrollParent(): ScrollParent {\n if (!this.scrollParent) {\n this.scrollParent = createScrollParent(\n this.treeElement,\n this.refreshHitAreas,\n );\n }\n\n return this.scrollParent;\n }\n}\n","import { GetNodeById } from \"./jqtreeMethodTypes\";\nimport { Node } from \"./node\";\n\ninterface SelectNodeHandlerParameters {\n getNodeById: GetNodeById;\n}\n\nexport default class SelectNodeHandler {\n private getNodeById: GetNodeById;\n private selectedNodes: Set<NodeId>;\n private selectedSingleNode: Node | null;\n\n constructor({ getNodeById }: SelectNodeHandlerParameters) {\n this.getNodeById = getNodeById;\n this.selectedNodes = new Set<NodeId>();\n this.clear();\n }\n\n public addToSelection(node: Node): void {\n if (node.id != null) {\n this.selectedNodes.add(node.id);\n } else {\n this.selectedSingleNode = node;\n }\n }\n\n public clear(): void {\n this.selectedNodes.clear();\n this.selectedSingleNode = null;\n }\n\n public getSelectedNode(): false | Node {\n const selectedNodes = this.getSelectedNodes();\n\n if (selectedNodes.length) {\n return selectedNodes[0] ?? false;\n } else {\n return false;\n }\n }\n\n public getSelectedNodes(): Node[] {\n if (this.selectedSingleNode) {\n return [this.selectedSingleNode];\n } else {\n const selectedNodes: Node[] = [];\n\n this.selectedNodes.forEach((id) => {\n const node = this.getNodeById(id);\n if (node) {\n selectedNodes.push(node);\n }\n });\n\n return selectedNodes;\n }\n }\n\n public getSelectedNodesUnder(parent: Node): Node[] {\n if (this.selectedSingleNode) {\n if (parent.isParentOf(this.selectedSingleNode)) {\n return [this.selectedSingleNode];\n } else {\n return [];\n }\n } else {\n const selectedNodes: Node[] = [];\n\n this.selectedNodes.forEach((id) => {\n const node = this.getNodeById(id);\n if (node && parent.isParentOf(node)) {\n selectedNodes.push(node);\n }\n });\n\n return selectedNodes;\n }\n }\n\n public isNodeSelected(node: Node): boolean {\n if (node.id != null) {\n return this.selectedNodes.has(node.id);\n } else if (this.selectedSingleNode) {\n return this.selectedSingleNode.element === node.element;\n } else {\n return false;\n }\n }\n\n public removeFromSelection(node: Node, includeChildren = false): void {\n if (node.id == null) {\n if (\n this.selectedSingleNode &&\n node.element === this.selectedSingleNode.element\n ) {\n this.selectedSingleNode = null;\n }\n } else {\n this.selectedNodes.delete(node.id);\n\n if (includeChildren) {\n node.iterate(() => {\n if (node.id != null) {\n this.selectedNodes.delete(node.id);\n }\n return true;\n });\n }\n }\n }\n}\n","const register = (widgetClass: unknown, widgetName: string): void => {\n const getDataKey = (): string => `simple_widget_${widgetName}`;\n\n const getWidgetData = (\n el: HTMLElement,\n dataKey: string,\n ): null | SimpleWidget<unknown> => {\n const widget = jQuery.data(el, dataKey) as unknown;\n\n if (widget && widget instanceof SimpleWidget) {\n return widget;\n } else {\n return null;\n }\n };\n\n const createWidget = ($el: JQuery, options: unknown): JQuery => {\n const dataKey = getDataKey();\n\n for (const el of $el.get()) {\n const existingWidget = getWidgetData(el, dataKey);\n\n if (!existingWidget) {\n const simpleWidgetClass = widgetClass as typeof SimpleWidget;\n const widget = new simpleWidgetClass(el, options);\n\n if (!jQuery.data(el, dataKey)) {\n jQuery.data(el, dataKey, widget);\n }\n\n // Call init after setting data, so we can call methods\n widget.init();\n }\n }\n\n return $el;\n };\n\n const destroyWidget = ($el: JQuery): void => {\n const dataKey = getDataKey();\n\n for (const el of $el.get()) {\n const widget = getWidgetData(el, dataKey);\n\n if (widget) {\n widget.destroy();\n }\n\n jQuery.removeData(el, dataKey);\n }\n };\n\n const callFunction = (\n $el: JQuery,\n functionName: string,\n args: unknown[],\n ): unknown => {\n let result = null;\n\n for (const el of $el.get()) {\n const widget = jQuery.data(el, getDataKey()) as unknown;\n\n if (widget && widget instanceof SimpleWidget) {\n const simpleWidget = widget as SimpleWidget<unknown>;\n const widgetFunction = simpleWidget[functionName];\n\n if (widgetFunction && typeof widgetFunction === \"function\") {\n result = widgetFunction.apply(widget, args) as unknown;\n }\n }\n }\n\n return result;\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n (jQuery.fn as any)[widgetName] = function (\n this: JQuery,\n argument1: unknown,\n ...args: unknown[]\n ) {\n if (!argument1) {\n return createWidget(this, null);\n } else if (typeof argument1 === \"object\") {\n const options = argument1 as unknown;\n return createWidget(this, options);\n } else if (typeof argument1 === \"string\" && argument1[0] !== \"_\") {\n const functionName = argument1;\n\n if (functionName === \"destroy\") {\n destroyWidget(this);\n return undefined;\n } else if (functionName === \"get_widget_class\") {\n return widgetClass;\n } else {\n return callFunction(this, functionName, args);\n }\n } else {\n return undefined;\n }\n };\n};\n\nexport default class SimpleWidget<WidgetOptions> {\n [key: string]: unknown;\n\n protected static defaults: unknown = {};\n\n public $el: JQuery;\n\n public options: WidgetOptions;\n\n constructor(el: HTMLElement, options: WidgetOptions) {\n this.$el = jQuery(el);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const defaults = (this.constructor as any).defaults as WidgetOptions;\n this.options = { ...defaults, ...options };\n }\n\n public static register(widgetClass: unknown, widgetName: string): void {\n register(widgetClass, widgetName);\n }\n\n public deinit(): void {\n //\n }\n\n public destroy(): void {\n this.deinit();\n }\n\n public init(): void {\n //\n }\n}\n","const version = \"1.8.10\";\n\nexport default version;\n","import DataLoader, { HandleFinishedLoading } from \"./dataLoader\";\nimport { DragAndDropHandler } from \"./dragAndDropHandler\";\nimport ElementsRenderer from \"./elementsRenderer\";\nimport { OnFinishOpenNode } from \"./jqtreeMethodTypes\";\nimport { JQTreeOptions } from \"./jqtreeOptions\";\nimport KeyHandler from \"./keyHandler\";\nimport MouseHandler from \"./mouseHandler\";\nimport { PositionInfo } from \"./mouseUtils\";\nimport { Node, Position } from \"./node\";\nimport NodeElement from \"./nodeElement\";\nimport FolderElement from \"./nodeElement/folderElement\";\nimport SaveStateHandler, { SavedState } from \"./saveStateHandler\";\nimport ScrollHandler from \"./scrollHandler\";\nimport SelectNodeHandler from \"./selectNodeHandler\";\nimport SimpleWidget from \"./simple.widget\";\nimport { getOffsetTop, isFunction } from \"./util\";\nimport __version__ from \"./version\";\n\ninterface SelectNodeOptions {\n mustSetFocus?: boolean;\n mustToggle?: boolean;\n}\n\nconst NODE_PARAM_IS_EMPTY = \"Node parameter is empty\";\nconst PARAM_IS_EMPTY = \"Parameter is empty: \";\n\nexport class JqTreeWidget extends SimpleWidget<JQTreeOptions> {\n protected static defaults: JQTreeOptions = {\n animationSpeed: \"fast\",\n autoEscape: true,\n autoOpen: false, // true / false / int (open n levels starting at 0)\n buttonLeft: true,\n // The symbol to use for a closed node - ► BLACK RIGHT-POINTING POINTER\n // http://www.fileformat.info/info/unicode/char/25ba/index.htm\n closedIcon: undefined,\n data: undefined,\n dataFilter: undefined,\n dataUrl: undefined,\n dragAndDrop: false,\n keyboardSupport: true,\n nodeClass: Node,\n onCanMove: undefined, // Can this node be moved?\n onCanMoveTo: undefined, // Can this node be moved to this position? function(moved_node, target_node, position)\n onCanSelectNode: undefined,\n onCreateLi: undefined,\n onDragMove: undefined,\n onDragStop: undefined,\n onGetStateFromStorage: undefined,\n onIsMoveHandle: undefined,\n onLoadFailed: undefined,\n onLoading: undefined,\n onSetStateFromStorage: undefined,\n openedIcon: \"▼\",\n openFolderDelay: 500, // The delay for opening a folder during drag and drop; the value is in milliseconds\n // The symbol to use for an open node - ▼ BLACK DOWN-POINTING TRIANGLE\n // http://www.fileformat.info/info/unicode/char/25bc/index.htm\n rtl: undefined, // right-to-left support; true / false (default)\n saveState: false, // true / false / string (cookie name)\n selectable: true,\n showEmptyFolder: false,\n slide: true, // must display slide animation?\n startDndDelay: 300, // The delay for starting dnd (in milliseconds)\n tabIndex: 0,\n useContextMenu: true,\n };\n\n private dataLoader: DataLoader;\n private dndHandler: DragAndDropHandler;\n private element: JQuery;\n\n private isInitialized: boolean;\n private keyHandler: KeyHandler;\n private mouseHandler: MouseHandler;\n private renderer: ElementsRenderer;\n private saveStateHandler: SaveStateHandler;\n private scrollHandler: ScrollHandler;\n private selectNodeHandler: SelectNodeHandler;\n private tree: Node;\n\n public addNodeAfter(\n newNodeInfo: NodeData,\n existingNode: Node,\n ): Node | null {\n const newNode = existingNode.addAfter(newNodeInfo);\n\n if (newNode) {\n this.refreshElements(existingNode.parent);\n }\n\n return newNode;\n }\n\n public addNodeBefore(\n newNodeInfo: NodeData,\n existingNode?: Node,\n ): Node | null {\n if (!existingNode) {\n throw Error(PARAM_IS_EMPTY + \"existingNode\");\n }\n\n const newNode = existingNode.addBefore(newNodeInfo);\n\n if (newNode) {\n this.refreshElements(existingNode.parent);\n }\n\n return newNode;\n }\n\n public addParentNode(\n newNodeInfo: NodeData,\n existingNode?: Node,\n ): Node | null {\n if (!existingNode) {\n throw Error(PARAM_IS_EMPTY + \"existingNode\");\n }\n\n const newNode = existingNode.addParent(newNodeInfo);\n\n if (newNode) {\n this.refreshElements(newNode.parent);\n }\n\n return newNode;\n }\n\n public addToSelection(node?: Node, mustSetFocus?: boolean): JQuery {\n if (!node) {\n throw Error(NODE_PARAM_IS_EMPTY);\n }\n\n this.selectNodeHandler.addToSelection(node);\n this.openParents(node);\n\n this.getNodeElementForNode(node).select(mustSetFocus ?? true);\n\n this.saveState();\n\n return this.element;\n }\n\n public appendNode(newNodeInfo: NodeData, parentNodeParam?: Node): Node {\n const parentNode = parentNodeParam ?? this.tree;\n\n const node = parentNode.append(newNodeInfo);\n\n this.refreshElements(parentNode);\n\n return node;\n }\n\n public closeNode(node?: Node, slideParam?: boolean | null): JQuery {\n if (!node) {\n throw Error(NODE_PARAM_IS_EMPTY);\n }\n\n const slide = slideParam ?? this.options.slide;\n\n if (node.isFolder() || node.isEmptyFolder) {\n this.createFolderElement(node).close(\n slide,\n this.options.animationSpeed,\n );\n\n this.saveState();\n }\n\n return this.element;\n }\n\n public deinit(): void {\n this.element.empty();\n this.element.off();\n\n this.keyHandler.deinit();\n this.mouseHandler.deinit();\n\n this.tree = new Node({}, true);\n\n super.deinit();\n }\n\n public getNodeByCallback(callback: (node: Node) => boolean): Node | null {\n return this.tree.getNodeByCallback(callback);\n }\n\n public getNodeByHtmlElement(\n inputElement: HTMLElement | JQuery,\n ): Node | null {\n const element =\n inputElement instanceof HTMLElement\n ? inputElement\n : inputElement[0];\n\n if (!element) {\n return null;\n }\n\n return this.getNode(element);\n }\n\n public getNodeById(nodeId: NodeId): Node | null {\n return this.tree.getNodeById(nodeId);\n }\n\n public getNodeByName(name: string): Node | null {\n return this.tree.getNodeByName(name);\n }\n\n public getNodeByNameMustExist(name: string): Node {\n return this.tree.getNodeByNameMustExist(name);\n }\n\n public getNodesByProperty(key: string, value: unknown): Node[] {\n return this.tree.getNodesByProperty(key, value);\n }\n\n public getSelectedNode(): false | Node {\n return this.selectNodeHandler.getSelectedNode();\n }\n\n public getSelectedNodes(): Node[] {\n return this.selectNodeHandler.getSelectedNodes();\n }\n\n public getState(): null | SavedState {\n return this.saveStateHandler.getState();\n }\n\n public getStateFromStorage(): null | SavedState {\n return this.saveStateHandler.getStateFromStorage();\n }\n\n public getTree(): Node {\n return this.tree;\n }\n\n public getVersion(): string {\n return __version__;\n }\n\n public init(): void {\n super.init();\n\n this.element = this.$el;\n this.isInitialized = false;\n\n this.options.rtl = this.getRtlOption();\n\n if (this.options.closedIcon == null) {\n this.options.closedIcon = this.getDefaultClosedIcon();\n }\n\n this.connectHandlers();\n\n this.initData();\n }\n\n public isDragging(): boolean {\n return this.dndHandler.isDragging;\n }\n\n public isNodeSelected(node?: Node): boolean {\n if (!node) {\n throw Error(NODE_PARAM_IS_EMPTY);\n }\n\n return this.selectNodeHandler.isNodeSelected(node);\n }\n\n public loadData(data: NodeData[], parentNode: Node | null): JQuery {\n this.doLoadData(data, parentNode);\n return this.element;\n }\n\n /*\n signatures:\n - loadDataFromUrl(url, parent_node=null, on_finished=null)\n loadDataFromUrl('/my_data');\n loadDataFromUrl('/my_data', node1);\n loadDataFromUrl('/my_data', node1, function() { console.log('finished'); });\n loadDataFromUrl('/my_data', null, function() { console.log('finished'); });\n\n - loadDataFromUrl(parent_node=null, on_finished=null)\n loadDataFromUrl();\n loadDataFromUrl(node1);\n loadDataFromUrl(null, function() { console.log('finished'); });\n loadDataFromUrl(node1, function() { console.log('finished'); });\n */\n public loadDataFromUrl(\n param1: Node | null | string,\n param2?: HandleFinishedLoading | Node | null,\n param3?: HandleFinishedLoading,\n ): JQuery {\n if (typeof param1 === \"string\") {\n // first parameter is url\n this.doLoadDataFromUrl(\n param1,\n param2 as Node | null,\n param3 ?? null,\n );\n } else {\n // first parameter is not url\n this.doLoadDataFromUrl(\n null,\n param1,\n param2 as HandleFinishedLoading | null,\n );\n }\n\n return this.element;\n }\n\n public moveDown(): JQuery {\n const selectedNode = this.getSelectedNode();\n if (selectedNode) {\n this.keyHandler.moveDown(selectedNode);\n }\n\n return this.element;\n }\n\n public moveNode(\n node?: Node,\n targetNode?: Node,\n position?: Position,\n ): JQuery {\n if (!node) {\n throw Error(NODE_PARAM_IS_EMPTY);\n }\n\n if (!targetNode) {\n throw Error(PARAM_IS_EMPTY + \"targetNode\");\n }\n\n if (!position) {\n throw Error(PARAM_IS_EMPTY + \"position\");\n }\n\n this.tree.moveNode(node, targetNode, position);\n this.refreshElements(null);\n\n return this.element;\n }\n\n public moveUp(): JQuery {\n const selectedNode = this.getSelectedNode();\n if (selectedNode) {\n this.keyHandler.moveUp(selectedNode);\n }\n\n return this.element;\n }\n\n public openNode(\n node?: Node,\n param1?: boolean | OnFinishOpenNode,\n param2?: OnFinishOpenNode,\n ): JQuery {\n if (!node) {\n throw Error(NODE_PARAM_IS_EMPTY);\n }\n\n const parseParams = (): [boolean, OnFinishOpenNode | undefined] => {\n let onFinished: null | OnFinishOpenNode;\n let slide: boolean | null;\n\n if (isFunction(param1)) {\n onFinished = param1 as OnFinishOpenNode;\n slide = null;\n } else {\n slide = param1 as boolean;\n onFinished = param2 as OnFinishOpenNode;\n }\n\n if (slide == null) {\n slide = this.options.slide;\n }\n\n return [slide, onFinished];\n };\n\n const [slide, onFinished] = parseParams();\n\n this.openNodeInternal(node, slide, onFinished);\n return this.element;\n }\n\n public prependNode(newNodeInfo: NodeData, parentNodeParam?: Node): Node {\n const parentNode = parentNodeParam ?? this.tree;\n\n const node = parentNode.prepend(newNodeInfo);\n\n this.refreshElements(parentNode);\n\n return node;\n }\n\n public refresh(): JQuery {\n this.refreshElements(null);\n return this.element;\n }\n\n public refreshHitAreas(): JQuery {\n this.dndHandler.refresh();\n return this.element;\n }\n\n public reload(onFinished: HandleFinishedLoading | null): JQuery {\n this.doLoadDataFromUrl(null, null, onFinished);\n return this.element;\n }\n\n public removeFromSelection(node?: Node): JQuery {\n if (!node) {\n throw Error(NODE_PARAM_IS_EMPTY);\n }\n\n this.selectNodeHandler.removeFromSelection(node);\n\n this.getNodeElementForNode(node).deselect();\n this.saveState();\n\n return this.element;\n }\n\n public removeNode(node?: Node): JQuery {\n if (!node) {\n throw Error(NODE_PARAM_IS_EMPTY);\n }\n\n if (!node.parent) {\n throw Error(\"Node has no parent\");\n }\n\n this.selectNodeHandler.removeFromSelection(node, true); // including children\n\n const parent = node.parent;\n node.remove();\n this.refreshElements(parent);\n\n return this.element;\n }\n\n public scrollToNode(node?: Node): JQuery {\n if (!node) {\n throw Error(NODE_PARAM_IS_EMPTY);\n }\n\n if (!node.element) {\n return this.element;\n }\n\n const top =\n getOffsetTop(node.element) -\n getOffsetTop(this.$el.get(0) as HTMLElement);\n\n this.scrollHandler.scrollToY(top);\n\n return this.element;\n }\n\n public selectNode(\n node: Node | null,\n optionsParam?: SelectNodeOptions,\n ): JQuery {\n this.doSelectNode(node, optionsParam);\n return this.element;\n }\n\n public setOption(option: string, value: unknown): JQuery {\n (this.options as unknown as Record<string, unknown>)[option] = value;\n return this.element;\n }\n\n public setState(state?: SavedState): JQuery {\n if (state) {\n this.saveStateHandler.setInitialState(state);\n this.refreshElements(null);\n }\n\n return this.element;\n }\n\n public toggle(node?: Node, slideParam: boolean | null = null): JQuery {\n if (!node) {\n throw Error(NODE_PARAM_IS_EMPTY);\n }\n\n const slide = slideParam ?? this.options.slide;\n\n if (node.is_open) {\n this.closeNode(node, slide);\n } else {\n this.openNode(node, slide);\n }\n\n return this.element;\n }\n\n public toJson(): string {\n return JSON.stringify(this.tree.getData());\n }\n\n public updateNode(node?: Node, data?: NodeData): JQuery {\n if (!node) {\n throw Error(NODE_PARAM_IS_EMPTY);\n }\n\n if (!data) {\n return this.element;\n }\n\n const idIsChanged =\n typeof data === \"object\" && data.id && data.id !== node.id;\n\n if (idIsChanged) {\n this.tree.removeNodeFromIndex(node);\n }\n\n node.setData(data);\n\n if (idIsChanged) {\n this.tree.addNodeToIndex(node);\n }\n\n if (\n typeof data === \"object\" &&\n data.children &&\n data.children instanceof Array\n ) {\n node.removeChildren();\n\n if (data.children.length) {\n node.loadFromData(data.children as Node[]);\n }\n }\n\n this.refreshElements(node);\n\n return this.element;\n }\n\n private connectHandlers() {\n const {\n autoEscape,\n buttonLeft,\n closedIcon,\n dataFilter,\n dragAndDrop,\n keyboardSupport,\n onCanMove,\n onCanMoveTo,\n onCreateLi,\n onDragMove,\n onDragStop,\n onGetStateFromStorage,\n onIsMoveHandle,\n onLoadFailed,\n onLoading,\n onSetStateFromStorage,\n openedIcon,\n openFolderDelay,\n rtl,\n saveState,\n showEmptyFolder,\n slide,\n tabIndex,\n } = this.options;\n\n const closeNode = this.closeNode.bind(this);\n const getNodeElement = this.getNodeElement.bind(this);\n const getNodeElementForNode = this.getNodeElementForNode.bind(this);\n const getNodeById = this.getNodeById.bind(this);\n const getSelectedNode = this.getSelectedNode.bind(this);\n const getTree = this.getTree.bind(this);\n const isFocusOnTree = this.isFocusOnTree.bind(this);\n const loadData = this.loadData.bind(this);\n const openNode = this.openNodeInternal.bind(this);\n const refreshElements = this.refreshElements.bind(this);\n const refreshHitAreas = this.refreshHitAreas.bind(this);\n const selectNode = this.selectNode.bind(this);\n const $treeElement = this.element;\n const treeElement = this.element.get(0) as HTMLElement;\n const triggerEvent = this.triggerEvent.bind(this);\n\n const selectNodeHandler = new SelectNodeHandler({\n getNodeById,\n });\n\n const addToSelection =\n selectNodeHandler.addToSelection.bind(selectNodeHandler);\n const getSelectedNodes =\n selectNodeHandler.getSelectedNodes.bind(selectNodeHandler);\n const isNodeSelected =\n selectNodeHandler.isNodeSelected.bind(selectNodeHandler);\n const removeFromSelection =\n selectNodeHandler.removeFromSelection.bind(selectNodeHandler);\n const getMouseDelay = () => this.options.startDndDelay ?? 0;\n\n const dataLoader = new DataLoader({\n dataFilter,\n loadData,\n onLoadFailed,\n onLoading,\n treeElement,\n triggerEvent,\n });\n\n const saveStateHandler = new SaveStateHandler({\n addToSelection,\n getNodeById,\n getSelectedNodes,\n getTree,\n onGetStateFromStorage,\n onSetStateFromStorage,\n openNode,\n refreshElements,\n removeFromSelection,\n saveState,\n });\n\n const scrollHandler = new ScrollHandler({\n refreshHitAreas,\n treeElement,\n });\n\n const getScrollLeft = scrollHandler.getScrollLeft.bind(scrollHandler);\n\n const dndHandler = new DragAndDropHandler({\n autoEscape,\n getNodeElement,\n getNodeElementForNode,\n getScrollLeft,\n getTree,\n onCanMove,\n onCanMoveTo,\n onDragMove,\n onDragStop,\n onIsMoveHandle,\n openFolderDelay,\n openNode,\n refreshElements,\n slide,\n treeElement,\n triggerEvent,\n });\n\n const keyHandler = new KeyHandler({\n closeNode,\n getSelectedNode,\n isFocusOnTree,\n keyboardSupport,\n openNode,\n selectNode,\n });\n\n const renderer = new ElementsRenderer({\n $element: $treeElement,\n autoEscape,\n buttonLeft,\n closedIcon,\n dragAndDrop,\n getTree,\n isNodeSelected,\n onCreateLi,\n openedIcon,\n rtl,\n showEmptyFolder,\n tabIndex,\n });\n\n const getNode = this.getNode.bind(this);\n const onMouseCapture = this.mouseCapture.bind(this);\n const onMouseDrag = this.mouseDrag.bind(this);\n const onMouseStart = this.mouseStart.bind(this);\n const onMouseStop = this.mouseStop.bind(this);\n\n const mouseHandler = new MouseHandler({\n element: treeElement,\n getMouseDelay,\n getNode,\n onClickButton: this.toggle.bind(this),\n onClickTitle: this.doSelectNode.bind(this),\n onMouseCapture,\n onMouseDrag,\n onMouseStart,\n onMouseStop,\n triggerEvent,\n useContextMenu: this.options.useContextMenu,\n });\n\n this.dataLoader = dataLoader;\n this.dndHandler = dndHandler;\n this.keyHandler = keyHandler;\n this.mouseHandler = mouseHandler;\n this.renderer = renderer;\n this.saveStateHandler = saveStateHandler;\n this.scrollHandler = scrollHandler;\n this.selectNodeHandler = selectNodeHandler;\n }\n\n private containsElement(element: HTMLElement): boolean {\n const node = this.getNode(element);\n\n return node != null && node.tree === this.tree;\n }\n\n private createFolderElement(node: Node) {\n const closedIconElement = this.renderer.closedIconElement;\n const getScrollLeft = this.scrollHandler.getScrollLeft.bind(\n this.scrollHandler,\n );\n const openedIconElement = this.renderer.openedIconElement;\n const tabIndex = this.options.tabIndex;\n const treeElement = this.element.get(0) as HTMLElement;\n const triggerEvent = this.triggerEvent.bind(this);\n\n return new FolderElement({\n closedIconElement,\n getScrollLeft,\n node,\n openedIconElement,\n tabIndex,\n treeElement,\n triggerEvent,\n });\n }\n\n private createNodeElement(node: Node) {\n const getScrollLeft = this.scrollHandler.getScrollLeft.bind(\n this.scrollHandler,\n );\n const tabIndex = this.options.tabIndex;\n const treeElement = this.element.get(0) as HTMLElement;\n\n return new NodeElement({\n getScrollLeft,\n node,\n tabIndex,\n treeElement,\n });\n }\n\n private deselectCurrentNode(): void {\n const node = this.getSelectedNode();\n if (node) {\n this.removeFromSelection(node);\n }\n }\n\n private deselectNodes(parentNode: Node): void {\n const selectedNodesUnderParent =\n this.selectNodeHandler.getSelectedNodesUnder(parentNode);\n for (const n of selectedNodesUnderParent) {\n this.selectNodeHandler.removeFromSelection(n);\n }\n }\n\n private doLoadData(data: NodeData[] | null, parentNode: Node | null): void {\n if (data) {\n if (parentNode) {\n this.deselectNodes(parentNode);\n this.loadSubtree(data, parentNode);\n } else {\n this.initTree(data);\n }\n\n if (this.isDragging()) {\n this.dndHandler.refresh();\n }\n }\n\n this.triggerEvent(\"tree.load_data\", {\n parent_node: parentNode,\n tree_data: data,\n });\n }\n\n private doLoadDataFromUrl(\n urlInfoParam: JQuery.AjaxSettings | null | string,\n parentNode: Node | null,\n onFinished: HandleFinishedLoading | null,\n ): void {\n const urlInfo = urlInfoParam ?? this.getDataUrlInfo(parentNode);\n\n this.dataLoader.loadFromUrl(urlInfo, parentNode, onFinished);\n }\n\n private doSelectNode(\n node: Node | null,\n optionsParam?: SelectNodeOptions,\n ): void {\n const saveState = (): void => {\n if (this.options.saveState) {\n this.saveStateHandler.saveState();\n }\n };\n\n if (!node) {\n // Called with empty node -> deselect current node\n this.deselectCurrentNode();\n saveState();\n return;\n }\n const defaultOptions = { mustSetFocus: true, mustToggle: true };\n const selectOptions = { ...defaultOptions, ...(optionsParam ?? {}) };\n\n const canSelect = (): boolean => {\n if (this.options.onCanSelectNode) {\n return (\n this.options.selectable &&\n this.options.onCanSelectNode(node)\n );\n } else {\n return this.options.selectable;\n }\n };\n\n if (!canSelect()) {\n return;\n }\n\n if (this.selectNodeHandler.isNodeSelected(node)) {\n if (selectOptions.mustToggle) {\n this.deselectCurrentNode();\n this.triggerEvent(\"tree.select\", {\n node: null,\n previous_node: node,\n });\n }\n } else {\n const deselectedNode = this.getSelectedNode() || null;\n this.deselectCurrentNode();\n this.addToSelection(node, selectOptions.mustSetFocus);\n\n this.triggerEvent(\"tree.select\", {\n deselected_node: deselectedNode,\n node,\n });\n this.openParents(node);\n }\n\n saveState();\n }\n\n private getAutoOpenMaxLevel(): number {\n if (this.options.autoOpen === true) {\n return -1;\n } else if (typeof this.options.autoOpen === \"number\") {\n return this.options.autoOpen;\n } else if (typeof this.options.autoOpen === \"string\") {\n return parseInt(this.options.autoOpen, 10);\n } else {\n return 0;\n }\n }\n\n private getDataUrlInfo(node: Node | null): JQuery.AjaxSettings | null {\n const dataUrl =\n this.options.dataUrl ?? (this.element.data(\"url\") as null | string);\n\n const getUrlFromString = (url: string): JQuery.AjaxSettings => {\n const urlInfo: JQuery.AjaxSettings = { url };\n\n setUrlInfoData(urlInfo);\n\n return urlInfo;\n };\n\n const setUrlInfoData = (urlInfo: JQuery.AjaxSettings): void => {\n if (node?.id) {\n // Load on demand of a subtree; add node parameter\n const data = { node: node.id };\n urlInfo.data = data;\n } else {\n // Add selected_node parameter\n const selectedNodeId = this.getNodeIdToBeSelected();\n if (selectedNodeId) {\n const data = { selected_node: selectedNodeId };\n urlInfo.data = data;\n }\n }\n };\n\n if (typeof dataUrl === \"function\") {\n return dataUrl(node);\n } else if (typeof dataUrl === \"string\") {\n return getUrlFromString(dataUrl);\n } else if (dataUrl && typeof dataUrl === \"object\") {\n setUrlInfoData(dataUrl);\n return dataUrl;\n } else {\n return null;\n }\n }\n\n private getDefaultClosedIcon(): string {\n if (this.options.rtl) {\n // triangle to the left\n return \"◀\";\n } else {\n // triangle to the right\n return \"►\";\n }\n }\n\n private getNode(element: HTMLElement): Node | null {\n const liElement = element.closest(\"li.jqtree_common\");\n\n if (liElement) {\n return jQuery(liElement).data(\"node\") as Node;\n } else {\n return null;\n }\n }\n\n private getNodeElement(element: HTMLElement): NodeElement | null {\n const node = this.getNode(element);\n if (node) {\n return this.getNodeElementForNode(node);\n } else {\n return null;\n }\n }\n\n private getNodeElementForNode(node: Node): NodeElement {\n if (node.isFolder()) {\n return this.createFolderElement(node);\n } else {\n return this.createNodeElement(node);\n }\n }\n\n private getNodeIdToBeSelected(): NodeId | null {\n if (this.options.saveState) {\n return this.saveStateHandler.getNodeIdToBeSelected();\n } else {\n return null;\n }\n }\n\n private getRtlOption(): boolean {\n if (this.options.rtl != null) {\n return this.options.rtl;\n } else {\n const dataRtl = this.element.data(\"rtl\") as unknown;\n\n if (\n dataRtl !== null &&\n dataRtl !== false &&\n dataRtl !== undefined\n ) {\n return true;\n } else {\n return false;\n }\n }\n }\n\n private initData(): void {\n if (this.options.data) {\n this.doLoadData(this.options.data, null);\n } else {\n const dataUrl = this.getDataUrlInfo(null);\n\n if (dataUrl) {\n this.doLoadDataFromUrl(null, null, null);\n } else {\n this.doLoadData([], null);\n }\n }\n }\n\n private initTree(data: NodeData[]): void {\n const doInit = (): void => {\n if (!this.isInitialized) {\n this.isInitialized = true;\n this.triggerEvent(\"tree.init\");\n }\n };\n\n this.tree = new this.options.nodeClass(\n null,\n true,\n this.options.nodeClass,\n );\n\n this.selectNodeHandler.clear();\n\n this.tree.loadFromData(data);\n\n const mustLoadOnDemand = this.setInitialState();\n\n this.refreshElements(null);\n\n if (!mustLoadOnDemand) {\n doInit();\n } else {\n // Load data on demand and then init the tree\n this.setInitialStateOnDemand(doInit);\n }\n }\n\n private isFocusOnTree(): boolean {\n const activeElement = document.activeElement;\n\n return Boolean(\n activeElement &&\n activeElement.tagName === \"SPAN\" &&\n this.containsElement(activeElement as HTMLElement),\n );\n }\n\n private isSelectedNodeInSubtree(subtree: Node): boolean {\n const selectedNode = this.getSelectedNode();\n\n if (!selectedNode) {\n return false;\n } else {\n return subtree === selectedNode || subtree.isParentOf(selectedNode);\n }\n }\n\n private loadFolderOnDemand(\n node: Node,\n slide = true,\n onFinished?: OnFinishOpenNode,\n ): void {\n node.is_loading = true;\n\n this.doLoadDataFromUrl(null, node, () => {\n this.openNodeInternal(node, slide, onFinished);\n });\n }\n\n private loadSubtree(data: NodeData[], parentNode: Node): void {\n parentNode.loadFromData(data);\n\n parentNode.load_on_demand = false;\n parentNode.is_loading = false;\n\n this.refreshElements(parentNode);\n }\n\n private mouseCapture(positionInfo: PositionInfo): boolean | null {\n if (this.options.dragAndDrop) {\n return this.dndHandler.mouseCapture(positionInfo);\n } else {\n return false;\n }\n }\n\n private mouseDrag(positionInfo: PositionInfo): boolean {\n if (this.options.dragAndDrop) {\n const result = this.dndHandler.mouseDrag(positionInfo);\n\n this.scrollHandler.checkScrolling(positionInfo);\n return result;\n } else {\n return false;\n }\n }\n\n private mouseStart(positionInfo: PositionInfo): boolean {\n if (this.options.dragAndDrop) {\n return this.dndHandler.mouseStart(positionInfo);\n } else {\n return false;\n }\n }\n\n private mouseStop(positionInfo: PositionInfo): boolean {\n if (this.options.dragAndDrop) {\n this.scrollHandler.stopScrolling();\n return this.dndHandler.mouseStop(positionInfo);\n } else {\n return false;\n }\n }\n\n private openNodeInternal(\n node: Node,\n slide = true,\n onFinished?: OnFinishOpenNode,\n ): void {\n const doOpenNode = (\n _node: Node,\n _slide: boolean,\n _onFinished?: OnFinishOpenNode,\n ): void => {\n if (!node.children.length) {\n return;\n }\n\n const folderElement = this.createFolderElement(_node);\n folderElement.open(\n _onFinished,\n _slide,\n this.options.animationSpeed,\n );\n };\n\n if (node.isFolder() || node.isEmptyFolder) {\n if (node.load_on_demand) {\n this.loadFolderOnDemand(node, slide, onFinished);\n } else {\n let parent = node.parent;\n\n while (parent) {\n // nb: do not open root element\n if (parent.parent) {\n doOpenNode(parent, false);\n }\n parent = parent.parent;\n }\n\n doOpenNode(node, slide, onFinished);\n this.saveState();\n }\n }\n }\n\n private openParents(node: Node) {\n const parent = node.parent;\n\n if (parent?.parent && !parent.is_open) {\n this.openNode(parent, false);\n }\n }\n\n /*\n Redraw the tree or part of the tree.\n from_node: redraw this subtree\n */\n private refreshElements(fromNode: Node | null): void {\n const mustSetFocus = this.isFocusOnTree();\n const mustSelect = fromNode\n ? this.isSelectedNodeInSubtree(fromNode)\n : false;\n\n this.renderer.render(fromNode);\n\n if (mustSelect) {\n this.selectCurrentNode(mustSetFocus);\n }\n\n this.triggerEvent(\"tree.refresh\");\n }\n\n private saveState(): void {\n if (this.options.saveState) {\n this.saveStateHandler.saveState();\n }\n }\n\n private selectCurrentNode(mustSetFocus: boolean): void {\n const node = this.getSelectedNode();\n if (node) {\n const nodeElement = this.getNodeElementForNode(node);\n nodeElement.select(mustSetFocus);\n }\n }\n\n // Set initial state, either by restoring the state or auto-opening nodes\n // result: must load nodes on demand?\n private setInitialState(): boolean {\n const restoreState = (): [boolean, boolean] => {\n // result: is state restored, must load on demand?\n if (!this.options.saveState) {\n return [false, false];\n } else {\n const state = this.saveStateHandler.getStateFromStorage();\n\n if (!state) {\n return [false, false];\n } else {\n const mustLoadOnDemand =\n this.saveStateHandler.setInitialState(state);\n\n // return true: the state is restored\n return [true, mustLoadOnDemand];\n }\n }\n };\n\n const autoOpenNodes = (): boolean => {\n // result: must load on demand?\n if (this.options.autoOpen === false) {\n return false;\n }\n\n const maxLevel = this.getAutoOpenMaxLevel();\n let mustLoadOnDemand = false;\n\n this.tree.iterate((node: Node, level: number) => {\n if (node.load_on_demand) {\n mustLoadOnDemand = true;\n return false;\n } else if (!node.hasChildren()) {\n return false;\n } else {\n node.is_open = true;\n return level !== maxLevel;\n }\n });\n\n return mustLoadOnDemand;\n };\n\n let [isRestored, mustLoadOnDemand] = restoreState(); // eslint-disable-line prefer-const\n\n if (!isRestored) {\n mustLoadOnDemand = autoOpenNodes();\n }\n\n return mustLoadOnDemand;\n }\n\n // Set the initial state for nodes that are loaded on demand\n // Call cb_finished when done\n private setInitialStateOnDemand(cbFinished: () => void): void {\n const restoreState = (): boolean => {\n if (!this.options.saveState) {\n return false;\n } else {\n const state = this.saveStateHandler.getStateFromStorage();\n\n if (!state) {\n return false;\n } else {\n this.saveStateHandler.setInitialStateOnDemand(\n state,\n cbFinished,\n );\n\n return true;\n }\n }\n };\n\n const autoOpenNodes = (): void => {\n const maxLevel = this.getAutoOpenMaxLevel();\n let loadingCount = 0;\n\n const loadAndOpenNode = (node: Node): void => {\n loadingCount += 1;\n this.openNodeInternal(node, false, () => {\n loadingCount -= 1;\n openNodes();\n });\n };\n\n const openNodes = (): void => {\n this.tree.iterate((node: Node, level: number) => {\n if (node.load_on_demand) {\n if (!node.is_loading) {\n loadAndOpenNode(node);\n }\n\n return false;\n } else {\n this.openNodeInternal(node, false);\n\n return level !== maxLevel;\n }\n });\n\n if (loadingCount === 0) {\n cbFinished();\n }\n };\n\n openNodes();\n };\n\n if (!restoreState()) {\n autoOpenNodes();\n }\n }\n\n private triggerEvent(\n eventName: string,\n values?: Record<string, unknown>,\n ): JQuery.Event {\n const event = jQuery.Event(eventName, values);\n this.element.trigger(event);\n return event;\n }\n}\n\nSimpleWidget.register(JqTreeWidget, \"tree\");\n"],"names":["DataLoader","constructor","_ref","dataFilter","loadData","onLoadFailed","onLoading","treeElement","triggerEvent","this","loadFromUrl","urlInfo","parentNode","onFinished","element","getDomElement","addLoadingClass","notifyLoading","stopLoading","removeLoadingClass","submitRequest","data","parseData","jqXHR","classList","add","isLoading","node","$el","jQuery","parsedData","JSON","parse","remove","urlInfoInput","handleSuccess","handleError","ajaxSettings","cache","dataType","error","method","success","url","toUpperCase","ajax","getBoolString","value","getOffsetTop","getElementPosition","top","rect","getBoundingClientRect","left","x","window","scrollX","y","scrollY","DragElement","autoEscape","nodeName","offsetX","offsetY","createElement","appendChild","move","pageX","pageY","style","document","textContent","innerHTML","position","generateHitAreasForGroup","hitAreas","positionsInGroup","bottom","positionCount","Math","min","length","areaHeight","round","areaTop","i","push","generateHitAreas","tree","currentNode","treeBottom","generateHitAreasFromPositions","hitPositions","previousTop","group","generateHitPositions","lastTop","addHitPosition","iterateVisibleNodes","handleAfterOpenFolder","handleClosedFolder","handleFirstNode","handleNode","handleOpenFolder","isFirstNode","iterate","nextNode","mustIterateInside","is_open","hasChildren","offsetParent","childrenLength","children","forEach","_","child","nextChild","height","clientHeight","DragAndDropHandler","getNodeElement","getNodeElementForNode","getScrollLeft","getTree","onCanMove","onCanMoveTo","onDragMove","onDragStop","onIsMoveHandle","openFolderDelay","openNode","refreshElements","slide","hoveredArea","isDragging","currentItem","mouseCapture","positionInfo","target","mustCaptureElement","nodeElement","mouseDrag","dragElement","area","findHoveredArea","canMoveToArea","isFolder","stopOpenFolderTimer","mustOpenFolderTimer","startOpenFolderTimer","updateDropHint","removeDropHint","originalEvent","mouseStart","refresh","name","mouseStop","moveItem","clear","removeHover","removeHitAreas","dimensions","getTreeDimensions","right","items","compareFn","low","high","mid","item","undefined","compareResult","binarySearch","treePosition","clientWidth","movedNode","targetNode","previousParent","parent","doMove","moveNode","move_info","do_move","moved_node","original_event","previous_parent","target_node","isDefaultPrevented","previousGhost","folder","openFolder","openFolderTimer","setTimeout","clearTimeout","addDropHint","ElementsRenderer","$element","buttonLeft","closedIcon","dragAndDrop","isNodeSelected","onCreateLi","openedIcon","rtl","showEmptyFolder","tabIndex","openedIconElement","createButtonElement","closedIconElement","render","fromNode","renderFromNode","renderFromRoot","$previousLi","li","createLi","getLevel","after","createDomElements","empty","attachNodeData","div","createTextNode","nodeType","isRootNode","level","ul","createUl","createFolderLi","isSelected","buttonClasses","getButtonClasses","folderClasses","getFolderClasses","iconElement","className","setAttribute","buttonLink","cloneNode","titleSpan","createTitleSpan","Boolean","isEmptyFolder","createNodeLi","liClasses","classString","join","classes","setTreeItemAriaAttributes","role","is_loading","KeyHandler","closeNode","getSelectedNode","isFocusOnTree","keyboardSupport","selectNode","originalSelectNode","addEventListener","handleKeyDown","deinit","removeEventListener","moveDown","selectedNode","getNextVisibleNode","moveUp","getPreviousVisibleNode","canHandleKeyboard","e","isKeyHandled","key","moveLeft","moveRight","preventDefault","getParent","getPositionInfoFromMouseEvent","getPositionInfoFromTouch","touch","MouseHandler","getMouseDelay","getNode","onClickButton","onClickTitle","onMouseCapture","onMouseDrag","onMouseStart","onMouseStop","useContextMenu","handleClick","handleDblclick","mouseDown","passive","touchStart","handleContextmenu","isMouseStarted","mouseDelayTimer","isMouseDelayMet","mouseDownInfo","removeMouseMoveEventListeners","getClickTarget","button","closest","type","jqTreeElement","clickTarget","stopPropagation","click_event","handleMouseDown","handleMouseUp","handleStartMouse","handleMouseMove","cancelable","mouseMove","touchMove","mouseUp","touchEnd","mouseDelay","startMouseDelayTimer","touches","isNodeRecordWithChildren","Array","Node","nodeData","arguments","isRoot","nodeClass","load_on_demand","setData","idMapping","Map","addAfter","nodeInfo","createNode","childIndex","getChildIndex","addChildAtPosition","loadChildrenFromData","addBefore","addChild","setParent","index","splice","addNodeToIndex","id","set","addParent","newParent","originalParent","append","filter","f","result","indexOf","getData","getDataFromNodes","nodes","map","tmpNode","k","Object","prototype","hasOwnProperty","call","v","getLastChild","lastChild","getNextNode","nextSibling","getNextSibling","nextIndex","getNodeByCallback","callback","getNodeById","nodeId","get","getNodeByName","getNodeByNameMustExist","n","Error","getNodesByProperty","getPreviousNode","previousSibling","getPreviousSibling","previousIndex","initFromData","addChildren","childrenData","addNode","isParentOf","_iterate","loadFromData","removeChildren","childData","doRemoveChild","prepend","removeChild","removeNodeFromIndex","delete","o","getNodeClass","BorderDropHint","scrollLeft","querySelector","hint","width","max","offsetWidth","GhostDropHint","ghost","createGhostElement","moveAfter","moveBefore","moveInsideOpenFolder","moveInside","circleSpan","lineSpan","before","childElement","NodeElement","init","mustShowBorderDropHint","deselect","getTitleSpan","removeAttribute","blur","select","mustSetFocus","toString","focus","getUl","FolderElement","super","close","animationSpeed","getButton","icon","doClose","slideUp","hide","open","doOpen","slideDown","show","SaveStateHandler","addToSelection","getSelectedNodes","onGetStateFromStorage","onSetStateFromStorage","removeFromSelection","saveState","saveStateOption","getNodeIdToBeSelected","state","getStateFromStorage","selected_node","getState","open_nodes","getOpenNodeIds","openNodes","getSelectedNodeIds","selectedNodeIds","jsonData","loadFromStorage","parseState","stringify","localStorage","setItem","getKeyName","setInitialState","mustLoadOnDemand","openInitialNodes","resetSelection","selectInitialNodes","setInitialStateOnDemand","cbFinished","loadingCount","nodeIds","newNodesIds","loadAndOpenNode","getItem","selectCount","ContainerScrollParent","container","refreshHitAreas","checkHorizontalScrolling","newHorizontalScrollDirection","getNewHorizontalScrollDirection","horizontalScrollDirection","horizontalScrollTimeout","verticalScrollTimeout","scrollHorizontally","bind","checkVerticalScrolling","newVerticalScrollDirection","getNewVerticalScrollDirection","verticalScrollDirection","scrollVertically","scrollToY","scrollTop","stopScrolling","scrollParentTop","scrollParentBottom","scrollParentOffset","rightEdge","leftEdge","getScrollParentTop","getScrollParentBottom","distance","scrollBy","behavior","DocumentScrollParent","documentElement","treeTop","documentScrollHeight","documentScrollWidth","canScrollDown","getDocumentScrollHeight","canScrollRight","getDocumentScrollWidth","scrollHeight","scrollWidth","isNearLeftEdge","innerWidth","innerHeight","isOverflow","overflowValue","hasOverFlow","getComputedStyle","overflowX","overflowY","createScrollParent","parentElement","getParentWithOverflow","tagName","ScrollHandler","scrollParent","checkScrolling","getScrollParent","SelectNodeHandler","selectedNodes","Set","selectedSingleNode","getSelectedNodesUnder","has","includeChildren","register","widgetClass","widgetName","getDataKey","getWidgetData","el","dataKey","widget","SimpleWidget","createWidget","options","fn","argument1","functionName","destroy","removeData","destroyWidget","_len","args","_key","callFunction","widgetFunction","apply","static","defaults","NODE_PARAM_IS_EMPTY","PARAM_IS_EMPTY","JqTreeWidget","autoOpen","dataUrl","onCanSelectNode","selectable","startDndDelay","addNodeAfter","newNodeInfo","existingNode","newNode","addNodeBefore","addParentNode","selectNodeHandler","openParents","appendNode","parentNodeParam","slideParam","createFolderElement","off","keyHandler","mouseHandler","getNodeByHtmlElement","inputElement","HTMLElement","saveStateHandler","getVersion","isInitialized","getRtlOption","getDefaultClosedIcon","connectHandlers","initData","dndHandler","doLoadData","loadDataFromUrl","param1","param2","param3","doLoadDataFromUrl","parseParams","openNodeInternal","prependNode","reload","removeNode","scrollToNode","scrollHandler","optionsParam","doSelectNode","setOption","option","setState","toggle","toJson","updateNode","idIsChanged","$treeElement","dataLoader","renderer","containsElement","createNodeElement","deselectCurrentNode","deselectNodes","selectedNodesUnderParent","loadSubtree","initTree","parent_node","tree_data","urlInfoParam","getDataUrlInfo","selectOptions","mustToggle","canSelect","previous_node","deselectedNode","deselected_node","getAutoOpenMaxLevel","parseInt","setUrlInfoData","selectedNodeId","getUrlFromString","liElement","dataRtl","doInit","activeElement","isSelectedNodeInSubtree","subtree","loadFolderOnDemand","doOpenNode","_node","_slide","_onFinished","mustSelect","selectCurrentNode","autoOpenNodes","maxLevel","isRestored","restoreState","eventName","values","event","Event","trigger"],"mappings":"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"}