diff --git a/src/dragAndDropHandler/generateHitAreas.ts b/src/dragAndDropHandler/generateHitAreas.ts index 6e426674..ec9bfda7 100644 --- a/src/dragAndDropHandler/generateHitAreas.ts +++ b/src/dragAndDropHandler/generateHitAreas.ts @@ -1,12 +1,11 @@ -import { Node } from "../node"; -import { Position } from "../position"; +import { Node, Position } from "../node"; import { getOffsetTop } from "../util"; import iterateVisibleNodes from "./iterateVisibleNodes"; import { HitArea } from "./types"; interface HitPosition { node: Node; - position: Position; + position: null | Position; top: number; } @@ -17,7 +16,11 @@ export const generateHitPositions = ( const hitPositions: HitPosition[] = []; let lastTop = 0; - const addHitPosition = (node: Node, position: number, top: number) => { + const addHitPosition = ( + node: Node, + position: null | Position, + top: number, + ) => { hitPositions.push({ node, position, @@ -29,9 +32,9 @@ export const generateHitPositions = ( const handleAfterOpenFolder = (node: Node, nextNode: Node | null) => { if (node === currentNode || nextNode === currentNode) { // Cannot move before or after current item - addHitPosition(node, Position.None, lastTop); + addHitPosition(node, null, lastTop); } else { - addHitPosition(node, Position.After, lastTop); + addHitPosition(node, "after", lastTop); } }; @@ -44,20 +47,20 @@ export const generateHitPositions = ( if (node === currentNode) { // Cannot move after current item - addHitPosition(node, Position.None, top); + addHitPosition(node, null, top); } else { - addHitPosition(node, Position.Inside, top); + addHitPosition(node, "inside", top); // Cannot move before current item if (nextNode !== currentNode) { - addHitPosition(node, Position.After, top); + addHitPosition(node, "after", top); } } }; const handleFirstNode = (node: Node) => { if (node !== currentNode && node.element) { - addHitPosition(node, Position.Before, getOffsetTop(node.element)); + addHitPosition(node, "before", getOffsetTop(node.element)); } }; @@ -70,16 +73,16 @@ export const generateHitPositions = ( if (node === currentNode) { // Cannot move inside current item - addHitPosition(node, Position.None, top); + addHitPosition(node, null, top); } else { - addHitPosition(node, Position.Inside, top); + addHitPosition(node, "inside", top); } if (nextNode === currentNode || node === currentNode) { // Cannot move before or after current item - addHitPosition(node, Position.None, top); + addHitPosition(node, null, top); } else { - addHitPosition(node, Position.After, top); + addHitPosition(node, "after", top); } }; @@ -90,11 +93,11 @@ export const generateHitPositions = ( // Dnd over the current element is not possible: add a position with type None for the top and the bottom. const top = getOffsetTop(element); const height = element.clientHeight; - addHitPosition(node, Position.None, top); + addHitPosition(node, null, top); if (height > 5) { // Subtract 5 pixels to allow more space for the next element. - addHitPosition(node, Position.None, top + height - 5); + addHitPosition(node, null, top + height - 5); } // Stop iterating @@ -103,7 +106,7 @@ export const generateHitPositions = ( // Cannot move before current item if (node.children[0] !== currentNode) { - addHitPosition(node, Position.Inside, getOffsetTop(element)); + addHitPosition(node, "inside", getOffsetTop(element)); } // Continue iterating @@ -136,7 +139,7 @@ export const generateHitAreasForGroup = ( for (let i = 0; i < positionCount; i++) { const position = positionsInGroup[i] as HitPosition; - if (position.position !== Position.None) { + if (position.position) { hitAreas.push({ bottom: areaTop + areaHeight, node: position.node, diff --git a/src/dragAndDropHandler/index.ts b/src/dragAndDropHandler/index.ts index 7e57daa6..b74f6a2e 100644 --- a/src/dragAndDropHandler/index.ts +++ b/src/dragAndDropHandler/index.ts @@ -14,7 +14,6 @@ import { import { PositionInfo } from "../mouseUtils"; import { Node } from "../node"; import NodeElement from "../nodeElement"; -import { getPositionName, Position } from "../position"; import { getElementPosition } from "../util"; import binarySearch from "./binarySearch"; import DragElement from "./dragElement"; @@ -254,9 +253,7 @@ export class DragAndDropHandler { return true; } - const positionName = getPositionName(area.position); - - return this.onCanMoveTo(currentItem.node, area.node, positionName); + return this.onCanMoveTo(currentItem.node, area.node, area.position); } private clear(): void { @@ -322,8 +319,7 @@ export class DragAndDropHandler { private moveItem(positionInfo: PositionInfo): void { if ( this.currentItem && - this.hoveredArea && - this.hoveredArea.position !== Position.None && + this.hoveredArea?.position && this.canMoveToArea(this.hoveredArea, this.currentItem) ) { const movedNode = this.currentItem.node; @@ -331,7 +327,7 @@ export class DragAndDropHandler { const position = this.hoveredArea.position; const previousParent = movedNode.parent; - if (position === Position.Inside) { + if (position === "inside") { this.hoveredArea.node.is_open = true; } @@ -351,7 +347,7 @@ export class DragAndDropHandler { do_move: doMove, moved_node: movedNode, original_event: positionInfo.originalEvent, - position: getPositionName(position), + position, previous_parent: previousParent, target_node: targetNode, }, @@ -376,11 +372,7 @@ export class DragAndDropHandler { private mustOpenFolderTimer(area: HitArea): boolean { const node = area.node; - return ( - node.isFolder() && - !node.is_open && - area.position === Position.Inside - ); + return node.isFolder() && !node.is_open && area.position === "inside"; } private removeDropHint(): void { diff --git a/src/dragAndDropHandler/types.ts b/src/dragAndDropHandler/types.ts index fde1bb7f..11bafe2d 100644 --- a/src/dragAndDropHandler/types.ts +++ b/src/dragAndDropHandler/types.ts @@ -1,5 +1,4 @@ -import { Node } from "../node"; -import { Position } from "../position"; +import { Node, Position } from "../node"; export interface DropHint { remove: () => void; diff --git a/src/node.ts b/src/node.ts index dae880cf..064d3f4e 100644 --- a/src/node.ts +++ b/src/node.ts @@ -1,5 +1,6 @@ import { isNodeRecordWithChildren } from "./nodeUtils"; -import { Position } from "./position"; + +export type Position = "after" | "before" | "inside"; type IterateCallback = (node: Node, level: number) => boolean; @@ -514,7 +515,7 @@ export class Node implements INode { movedNode.parent.doRemoveChild(movedNode); switch (position) { - case Position.After: { + case "after": { if (targetNode.parent) { targetNode.parent.addChildAtPosition( movedNode, @@ -525,7 +526,7 @@ export class Node implements INode { return false; } - case Position.Before: { + case "before": { if (targetNode.parent) { targetNode.parent.addChildAtPosition( movedNode, @@ -536,14 +537,11 @@ export class Node implements INode { return false; } - case Position.Inside: { + case "inside": { // move inside as first child targetNode.addChildAtPosition(movedNode, 0); return true; } - - default: - return false; } } } diff --git a/src/nodeElement/folderElement.ts b/src/nodeElement/folderElement.ts index 78d5ec2f..89c4bdb5 100644 --- a/src/nodeElement/folderElement.ts +++ b/src/nodeElement/folderElement.ts @@ -1,5 +1,5 @@ import { OnFinishOpenNode, TriggerEvent } from "../jqtreeMethodTypes"; -import { Position } from "../position"; +import { Position } from "../node"; import NodeElement, { NodeElementParams } from "./index"; interface FolderElementParams extends NodeElementParams { @@ -117,7 +117,7 @@ class FolderElement extends NodeElement { } protected mustShowBorderDropHint(position: Position): boolean { - return !this.node.is_open && position === Position.Inside; + return !this.node.is_open && position === "inside"; } private getButton(): HTMLLinkElement { diff --git a/src/nodeElement/ghostDropHint.ts b/src/nodeElement/ghostDropHint.ts index 009f5d77..e23cb28c 100644 --- a/src/nodeElement/ghostDropHint.ts +++ b/src/nodeElement/ghostDropHint.ts @@ -1,6 +1,5 @@ import { DropHint } from "../dragAndDropHandler/types"; -import { Node } from "../node"; -import { Position } from "../position"; +import { Node, Position } from "../node"; class GhostDropHint implements DropHint { private element: HTMLElement; @@ -13,15 +12,15 @@ class GhostDropHint implements DropHint { this.ghost = this.createGhostElement(); switch (position) { - case Position.After: + case "after": this.moveAfter(); break; - case Position.Before: + case "before": this.moveBefore(); break; - case Position.Inside: { + case "inside": { if (node.isFolder() && node.is_open) { this.moveInsideOpenFolder(); } else { diff --git a/src/nodeElement/index.ts b/src/nodeElement/index.ts index 98ad4ab6..1a855c2e 100644 --- a/src/nodeElement/index.ts +++ b/src/nodeElement/index.ts @@ -1,7 +1,6 @@ import { DropHint } from "../dragAndDropHandler/types"; import { GetScrollLeft } from "../jqtreeMethodTypes"; -import { Node } from "../node"; -import { Position } from "../position"; +import { Node, Position } from "../node"; import BorderDropHint from "./borderDropHint"; import GhostDropHint from "./ghostDropHint"; @@ -32,7 +31,7 @@ class NodeElement { this.init(node); } - public addDropHint(position: number): DropHint { + public addDropHint(position: Position): DropHint { if (this.mustShowBorderDropHint(position)) { return new BorderDropHint(this.element, this.getScrollLeft()); } else { @@ -89,7 +88,7 @@ class NodeElement { } protected mustShowBorderDropHint(position: Position): boolean { - return position === Position.Inside; + return position === "inside"; } } diff --git a/src/position.ts b/src/position.ts deleted file mode 100644 index 6e2994d5..00000000 --- a/src/position.ts +++ /dev/null @@ -1,28 +0,0 @@ -export enum Position { - Before = 1, - After, - Inside, - None, -} - -const positionNames: Record = { - after: Position.After, - before: Position.Before, - inside: Position.Inside, - none: Position.None, -}; - -export const getPositionName = (position: Position): string => { - for (const name in positionNames) { - if (Object.prototype.hasOwnProperty.call(positionNames, name)) { - if (positionNames[name] === position) { - return name; - } - } - } - - return ""; -}; - -export const getPosition = (name: string): Position | undefined => - positionNames[name]; diff --git a/src/test/dragAndDropHandler/generateHitAreas.test.ts b/src/test/dragAndDropHandler/generateHitAreas.test.ts index 87eca6f7..65114552 100644 --- a/src/test/dragAndDropHandler/generateHitAreas.test.ts +++ b/src/test/dragAndDropHandler/generateHitAreas.test.ts @@ -4,8 +4,7 @@ import { generateHitPositions, } from "../../dragAndDropHandler/generateHitAreas"; import { HitArea } from "../../dragAndDropHandler/types"; -import { Node } from "../../node"; -import { Position } from "../../position"; +import { Node, Position } from "../../node"; const mockHtmlElement = (y: number) => ({ @@ -29,7 +28,7 @@ describe("generateHitAreasForGroup", () => { const node = new Node(null); const hitPosition = { node, - position: Position.Inside, + position: "inside" as Position, top: 0, }; @@ -40,17 +39,17 @@ describe("generateHitAreasForGroup", () => { expect.objectContaining({ bottom: 100, node, - position: Position.Inside, + position: "inside", top: 40, }), ]); }); - it("doesn't add a hit area when the position is Position.None", () => { + it("doesn't add a hit area when the position is none", () => { const node = new Node(null); const hitPosition = { node, - position: Position.None, + position: null, top: 0, }; @@ -65,12 +64,12 @@ describe("generateHitAreasForGroup", () => { const hitPositions = [ { node, - position: Position.Before, + position: "before" as Position, top: 0, }, { node, - position: Position.Inside, + position: "inside" as Position, top: 0, }, ]; @@ -82,13 +81,13 @@ describe("generateHitAreasForGroup", () => { expect.objectContaining({ bottom: 70, node, - position: Position.Before, + position: "before", top: 40, }), expect.objectContaining({ bottom: 100, node, - position: Position.Inside, + position: "inside", top: 70, }), ]); @@ -104,7 +103,7 @@ describe("generateHitAreasFromPositions", () => { const node = new Node(null); const hitPosition = { node, - position: Position.Inside, + position: "inside" as Position, top: 100, }; @@ -112,7 +111,7 @@ describe("generateHitAreasFromPositions", () => { expect.objectContaining({ bottom: 140, node, - position: Position.Inside, + position: "inside", top: 100, }), ]); @@ -123,12 +122,12 @@ describe("generateHitAreasFromPositions", () => { const hitPositions = [ { node, - position: Position.Before, + position: "before" as Position, top: 100, }, { node, - position: Position.Inside, + position: "inside" as Position, top: 100, }, ]; @@ -137,13 +136,13 @@ describe("generateHitAreasFromPositions", () => { expect.objectContaining({ bottom: 120, node, - position: Position.Before, + position: "before", top: 100, }), expect.objectContaining({ bottom: 140, node, - position: Position.Inside, + position: "inside", top: 120, }), ]); @@ -155,12 +154,12 @@ describe("generateHitAreasFromPositions", () => { const hitPositions = [ { node: node1, - position: Position.Inside, + position: "inside" as Position, top: 100, }, { node: node2, - position: Position.After, + position: "after" as Position, top: 125, }, ]; @@ -169,13 +168,13 @@ describe("generateHitAreasFromPositions", () => { expect.objectContaining({ bottom: 125, node: node1, - position: Position.Inside, + position: "inside", top: 100, }), expect.objectContaining({ bottom: 140, node: node2, - position: Position.After, + position: "after", top: 125, }), ]); @@ -204,22 +203,22 @@ describe("generatePositions", () => { expect(generateHitPositions(tree, node1)).toEqual([ expect.objectContaining({ node: node1, - position: Position.None, + position: null, top: 100, }), expect.objectContaining({ node: node1, - position: Position.None, + position: null, top: 100, }), expect.objectContaining({ node: node2, - position: Position.Inside, + position: "inside", top: 120, }), expect.objectContaining({ node: node2, - position: Position.After, + position: "after", top: 120, }), ]); @@ -244,32 +243,32 @@ describe("generatePositions", () => { expect(generateHitPositions(tree, node1)).toEqual([ expect.objectContaining({ node: node1, - position: Position.None, + position: null, top: 100, }), expect.objectContaining({ node: node1, - position: Position.None, + position: null, top: 100, }), expect.objectContaining({ node: node2, - position: Position.Inside, + position: "inside", top: 120, }), expect.objectContaining({ node: child1, - position: Position.Inside, + position: "inside", top: 140, }), expect.objectContaining({ node: child1, - position: Position.After, + position: "after", top: 140, }), expect.objectContaining({ node: node2, - position: Position.After, + position: "after", top: 140, }), ]); @@ -294,27 +293,27 @@ describe("generatePositions", () => { expect(generateHitPositions(tree, node2)).toEqual([ expect.objectContaining({ node: node1, - position: Position.Before, + position: "before", top: 100, }), expect.objectContaining({ node: node1, - position: Position.Inside, + position: "inside", top: 100, }), expect.objectContaining({ node: node1, - position: Position.None, + position: null, top: 100, }), expect.objectContaining({ node: node2, - position: Position.None, + position: null, top: 120, }), expect.objectContaining({ node: node2, - position: Position.None, + position: null, top: 135, }), ]); diff --git a/src/test/dragAndDropHandler/index.test.ts b/src/test/dragAndDropHandler/index.test.ts index 6ce7efeb..b8f80fad 100644 --- a/src/test/dragAndDropHandler/index.test.ts +++ b/src/test/dragAndDropHandler/index.test.ts @@ -3,7 +3,6 @@ import { GetTree } from "../../jqtreeMethodTypes"; import { DragMethod, OnIsMoveHandle } from "../../jqtreeOptions"; import { Node } from "../../node"; import NodeElement from "../../nodeElement"; -import { Position } from "../../position"; import { generateHtmlElementsForTree } from "../support/testUtil"; interface CreateDragAndDropHandlerParams { @@ -399,7 +398,7 @@ describe(".mouseDrag", () => { expect.objectContaining({ bottom: 38, node: node2, - position: Position.Inside, + position: "inside", top: 20, }), ); @@ -529,13 +528,13 @@ describe(".refresh", () => { expect.objectContaining({ bottom: 38, node: node2, - position: Position.Inside, + position: "inside", top: 20, }), expect.objectContaining({ bottom: 56, node: node2, - position: Position.After, + position: "after", top: 38, }), ]); diff --git a/src/test/node.test.ts b/src/test/node.test.ts index 38be121b..812df762 100644 --- a/src/test/node.test.ts +++ b/src/test/node.test.ts @@ -2,7 +2,6 @@ import getGiven from "givens"; import "jest-extended"; import { Node } from "../node"; -import { Position } from "../position"; import exampleData from "./support/exampleData"; const context = describe; @@ -1174,7 +1173,7 @@ describe("moveNode", () => { context("when moving after a node", () => { it("moves the node", () => { expect( - given.tree.moveNode(given.child2, given.node2, Position.After), + given.tree.moveNode(given.child2, given.node2, "after"), ).toBe(true); expect(given.tree).toMatchObject({ @@ -1193,11 +1192,7 @@ describe("moveNode", () => { context("when the target is the root node", () => { it("returns false", () => { expect( - given.tree.moveNode( - given.child2, - given.tree, - Position.After, - ), + given.tree.moveNode(given.child2, given.tree, "after"), ).toBe(false); }); }); @@ -1206,7 +1201,7 @@ describe("moveNode", () => { context("when moving inside a node", () => { it("moves the node", () => { expect( - given.tree.moveNode(given.child1, given.node2, Position.Inside), + given.tree.moveNode(given.child1, given.node2, "inside"), ).toBe(true); expect(given.tree).toMatchObject({ @@ -1231,11 +1226,7 @@ describe("moveNode", () => { context("when moving before a node", () => { it("moves the node", () => { expect( - given.tree.moveNode( - given.child2, - given.child1, - Position.Before, - ), + given.tree.moveNode(given.child2, given.child1, "before"), ).toBe(true); expect(given.tree).toMatchObject({ @@ -1256,11 +1247,7 @@ describe("moveNode", () => { context("when the target is the root node", () => { it("returns false", () => { expect( - given.tree.moveNode( - given.child2, - given.tree, - Position.Before, - ), + given.tree.moveNode(given.child2, given.tree, "before"), ).toBe(false); }); }); @@ -1269,7 +1256,7 @@ describe("moveNode", () => { context("when the moved node is a parent of the target node", () => { it("doesn't move the node", () => { expect( - given.tree.moveNode(given.node1, given.child1, Position.Before), + given.tree.moveNode(given.node1, given.child1, "before"), ).toBe(false); expect(given.tree).toMatchObject({ @@ -1286,14 +1273,6 @@ describe("moveNode", () => { }); }); }); - - context("with position None", () => { - it("returns false", () => { - expect( - given.tree.moveNode(given.child2, given.node2, Position.None), - ).toBe(false); - }); - }); }); describe("prepend", () => { diff --git a/src/test/nodeElement/ghostDropHint.test.ts b/src/test/nodeElement/ghostDropHint.test.ts index 8987ac08..14edcb33 100644 --- a/src/test/nodeElement/ghostDropHint.test.ts +++ b/src/test/nodeElement/ghostDropHint.test.ts @@ -1,6 +1,5 @@ import { Node } from "../../node"; import GhostDropHint from "../../nodeElement/ghostDropHint"; -import { Position } from "../../position"; beforeEach(() => { document.body.innerHTML = ""; @@ -11,7 +10,7 @@ it("creates a hint element after the node element when the position is After", ( document.body.append(nodeElement); const node = new Node(); - new GhostDropHint(node, nodeElement, Position.After); + new GhostDropHint(node, nodeElement, "after"); expect(nodeElement.nextSibling).toHaveClass("jqtree-ghost"); expect(nodeElement.previousSibling).toBeNull(); @@ -23,7 +22,7 @@ it("creates a hint element after the node element when the position is Before", document.body.append(nodeElement); const node = new Node(); - new GhostDropHint(node, nodeElement, Position.Before); + new GhostDropHint(node, nodeElement, "before"); expect(nodeElement.previousSibling).toHaveClass("jqtree-ghost"); expect(nodeElement.nextSibling).toBeNull(); @@ -42,7 +41,7 @@ it("creates a hint element after the node element when the position is Inside an childNode.element = childElement; node.addChild(childNode); - new GhostDropHint(node, nodeElement, Position.Inside); + new GhostDropHint(node, nodeElement, "inside"); expect(nodeElement.previousSibling).toBeNull(); expect(nodeElement.nextSibling).toBeNull(); @@ -57,7 +56,7 @@ it("creates a hint element after the node element when the position is Inside an const node = new Node(); node.addChild(new Node()); - new GhostDropHint(node, nodeElement, Position.Inside); + new GhostDropHint(node, nodeElement, "inside"); expect(nodeElement.nextSibling).toHaveClass("jqtree-ghost"); expect(nodeElement.previousSibling).toBeNull(); diff --git a/src/test/position.test.ts b/src/test/position.test.ts deleted file mode 100644 index d83006b0..00000000 --- a/src/test/position.test.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { getPosition, getPositionName, Position } from "../position"; - -const context = describe; - -describe("getPosition", () => { - it("returns the position", () => { - expect(getPosition("inside")).toBe(Position.Inside); - }); - - context("with an unknown position", () => { - it("returns undefined", () => { - expect(getPosition("unknown")).toBeUndefined(); - }); - }); -}); - -describe("getPositionName", () => { - it("returns the name of the position", () => { - expect(getPositionName(Position.After)).toBe("after"); - expect(getPositionName(Position.Before)).toBe("before"); - expect(getPositionName(Position.Inside)).toBe("inside"); - expect(getPositionName(Position.None)).toBe("none"); - }); - - context("with an unknown position", () => { - it("returns an empty string", () => { - expect(getPositionName(10 as Position)).toBe(""); - }); - }); -}); diff --git a/src/tree.jquery.d.ts b/src/tree.jquery.d.ts index d29f9c49..7807a019 100644 --- a/src/tree.jquery.d.ts +++ b/src/tree.jquery.d.ts @@ -92,7 +92,7 @@ interface IJQTreePlugin { behavior: "moveNode", node: INode, targetNode: INode, - position: string, + position: "after" | "before" | "inside", ): JQuery; (behavior: "moveUp"): JQuery; (behavior: "openNode", node: INode): JQuery; diff --git a/src/tree.jquery.ts b/src/tree.jquery.ts index 21c51716..db177a75 100644 --- a/src/tree.jquery.ts +++ b/src/tree.jquery.ts @@ -6,10 +6,9 @@ import { JQTreeOptions } from "./jqtreeOptions"; import KeyHandler from "./keyHandler"; import MouseHandler from "./mouseHandler"; import { PositionInfo } from "./mouseUtils"; -import { Node } from "./node"; +import { Node, Position } from "./node"; import NodeElement from "./nodeElement"; import FolderElement from "./nodeElement/folderElement"; -import { getPosition } from "./position"; import SaveStateHandler, { SavedState } from "./saveStateHandler"; import ScrollHandler from "./scrollHandler"; import SelectNodeHandler from "./selectNodeHandler"; @@ -321,7 +320,11 @@ export class JqTreeWidget extends SimpleWidget { return this.element; } - public moveNode(node?: Node, targetNode?: Node, position?: string): JQuery { + public moveNode( + node?: Node, + targetNode?: Node, + position?: Position, + ): JQuery { if (!node) { throw Error(NODE_PARAM_IS_EMPTY); } @@ -334,12 +337,8 @@ export class JqTreeWidget extends SimpleWidget { throw Error(PARAM_IS_EMPTY + "position"); } - const positionIndex = getPosition(position); - - if (positionIndex !== undefined) { - this.tree.moveNode(node, targetNode, positionIndex); - this.refreshElements(null); - } + this.tree.moveNode(node, targetNode, position); + this.refreshElements(null); return this.element; }