jqtree 1.8.7 → 1.8.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bower.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jqTree",
3
- "version": "1.8.7",
3
+ "version": "1.8.9",
4
4
  "main": [
5
5
  "jqtree.css",
6
6
  "jqtree-circle.png",
package/eslint.config.mjs CHANGED
@@ -5,6 +5,7 @@ import jestPlugin from "eslint-plugin-jest";
5
5
  import jestDomPlugin from "eslint-plugin-jest-dom";
6
6
  import perfectionistPlugin from "eslint-plugin-perfectionist";
7
7
  import playwrightPlugin from "eslint-plugin-playwright";
8
+ import testingLibraryPlugin from "eslint-plugin-testing-library";
8
9
 
9
10
  export default [
10
11
  eslint.configs.recommended,
@@ -59,7 +60,11 @@ export default [
59
60
  },
60
61
  },
61
62
  {
62
- files: ["src/test/jqTree/**/*.ts"],
63
+ files: ["src/test/**/*.ts"],
64
+ ...testingLibraryPlugin.configs["flat/dom"],
65
+ },
66
+ {
67
+ files: ["src/test/**/*.ts"],
63
68
  ...jestDomPlugin.configs["flat/recommended"],
64
69
  },
65
70
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jqtree",
3
- "version": "1.8.7",
3
+ "version": "1.8.9",
4
4
  "description": "Tree widget for jQuery",
5
5
  "keywords": [
6
6
  "jquery-plugin",
@@ -35,51 +35,52 @@
35
35
  "jquery": "^3"
36
36
  },
37
37
  "devDependencies": {
38
- "@babel/cli": "^7.25.7",
39
- "@babel/core": "^7.25.7",
40
- "@babel/preset-env": "^7.25.7",
41
- "@babel/preset-typescript": "^7.25.7",
42
- "@playwright/test": "^1.47.2",
38
+ "@babel/cli": "^7.26.4",
39
+ "@babel/core": "^7.26.0",
40
+ "@babel/preset-env": "^7.26.0",
41
+ "@babel/preset-typescript": "^7.26.0",
42
+ "@playwright/test": "^1.49.1",
43
43
  "@rollup/plugin-babel": "^6.0.4",
44
- "@rollup/plugin-node-resolve": "^15.3.0",
44
+ "@rollup/plugin-node-resolve": "^16.0.0",
45
45
  "@rollup/plugin-terser": "^0.4.4",
46
46
  "@testing-library/dom": "^10.4.0",
47
- "@testing-library/jest-dom": "^6.6.2",
47
+ "@testing-library/jest-dom": "^6.6.3",
48
48
  "@testing-library/user-event": "^14.5.2",
49
49
  "@types/debug": "^4.1.12",
50
- "@types/jest": "^29.5.13",
50
+ "@types/jest": "^29.5.14",
51
51
  "@types/jest-axe": "^3.5.9",
52
- "@types/jquery": "^3.5.31",
53
- "@types/node": "^22.7.4",
52
+ "@types/jquery": "^3.5.32",
53
+ "@types/node": "^22.10.2",
54
54
  "autoprefixer": "^10.4.20",
55
55
  "babel-jest": "^29.7.0",
56
56
  "babel-plugin-istanbul": "^7.0.0",
57
- "eslint": "^9",
57
+ "eslint": "^9.17.0",
58
58
  "eslint-plugin-import": "^2.31.0",
59
- "eslint-plugin-jest": "^28.8.3",
60
- "eslint-plugin-jest-dom": "^5.4.0",
61
- "eslint-plugin-perfectionist": "^3.8.0",
62
- "eslint-plugin-playwright": "^1.6.2",
59
+ "eslint-plugin-jest": "^28.10.0",
60
+ "eslint-plugin-jest-dom": "^5.5.0",
61
+ "eslint-plugin-perfectionist": "^4.4.0",
62
+ "eslint-plugin-playwright": "^2.1.0",
63
+ "eslint-plugin-testing-library": "^7",
63
64
  "givens": "^1.3.9",
64
- "graphql": "^16.9.0",
65
+ "graphql": "^16.10.0",
65
66
  "jest": "^29.7.0",
66
67
  "jest-axe": "^9.0.0",
67
68
  "jest-extended": "^4.0.2",
68
- "jest-fixed-jsdom": "^0.0.4",
69
+ "jest-fixed-jsdom": "^0.0.9",
70
+ "jsdom-testing-mocks": "^1.13.1",
69
71
  "jsonfile": "^6.1.0",
70
72
  "lodash": "^4.17.21",
71
- "msw": "^2.4.9",
72
- "postcss": "^8.4.47",
73
+ "msw": "^2.7.0",
74
+ "postcss": "^8.4.49",
73
75
  "postcss-cli": "^11.0.0",
74
76
  "postcss-import": "^16.1.0",
75
77
  "postcss-load-config": "^6.0.1",
76
- "postcss-nested": "^6.2.0",
77
- "prettier": "^3.3.3",
78
- "rollup": "^4.24.0",
78
+ "postcss-nested": "^7.0.2",
79
+ "prettier": "^3.4.2",
80
+ "rollup": "^4.29.1",
79
81
  "rollup-plugin-serve": "^3.0.0",
80
- "tslib": "^2.7.0",
81
- "typescript": "^5.6.2",
82
- "typescript-eslint": "^8.8.0",
83
- "undici": "^5.28.4"
82
+ "tslib": "^2.8.1",
83
+ "typescript": "^5.7.2",
84
+ "typescript-eslint": "^8.18.1"
84
85
  }
85
86
  }
package/src/dataLoader.ts CHANGED
@@ -37,6 +37,44 @@ export default class DataLoader {
37
37
  this.triggerEvent = triggerEvent;
38
38
  }
39
39
 
40
+ public loadFromUrl(
41
+ urlInfo: JQuery.AjaxSettings | null | string,
42
+ parentNode: Node | null,
43
+ onFinished: HandleFinishedLoading | null,
44
+ ): void {
45
+ if (!urlInfo) {
46
+ return;
47
+ }
48
+
49
+ const element = this.getDomElement(parentNode);
50
+ this.addLoadingClass(element);
51
+ this.notifyLoading(true, parentNode, element);
52
+
53
+ const stopLoading = (): void => {
54
+ this.removeLoadingClass(element);
55
+ this.notifyLoading(false, parentNode, element);
56
+ };
57
+
58
+ const handleSuccess = (data: NodeData[] | string): void => {
59
+ stopLoading();
60
+ this.loadData(this.parseData(data), parentNode);
61
+
62
+ if (onFinished && typeof onFinished === "function") {
63
+ onFinished();
64
+ }
65
+ };
66
+
67
+ const handleError = (jqXHR: JQuery.jqXHR): void => {
68
+ stopLoading();
69
+
70
+ if (this.onLoadFailed) {
71
+ this.onLoadFailed(jqXHR);
72
+ }
73
+ };
74
+
75
+ this.submitRequest(urlInfo, handleSuccess, handleError);
76
+ }
77
+
40
78
  private addLoadingClass(element: HTMLElement): void {
41
79
  element.classList.add("jqtree-loading");
42
80
  }
@@ -112,42 +150,4 @@ export default class DataLoader {
112
150
 
113
151
  void jQuery.ajax(ajaxSettings);
114
152
  }
115
-
116
- public loadFromUrl(
117
- urlInfo: JQuery.AjaxSettings | null | string,
118
- parentNode: Node | null,
119
- onFinished: HandleFinishedLoading | null,
120
- ): void {
121
- if (!urlInfo) {
122
- return;
123
- }
124
-
125
- const element = this.getDomElement(parentNode);
126
- this.addLoadingClass(element);
127
- this.notifyLoading(true, parentNode, element);
128
-
129
- const stopLoading = (): void => {
130
- this.removeLoadingClass(element);
131
- this.notifyLoading(false, parentNode, element);
132
- };
133
-
134
- const handleSuccess = (data: NodeData[] | string): void => {
135
- stopLoading();
136
- this.loadData(this.parseData(data), parentNode);
137
-
138
- if (onFinished && typeof onFinished === "function") {
139
- onFinished();
140
- }
141
- };
142
-
143
- const handleError = (jqXHR: JQuery.jqXHR): void => {
144
- stopLoading();
145
-
146
- if (this.onLoadFailed) {
147
- this.onLoadFailed(jqXHR);
148
- }
149
- };
150
-
151
- this.submitRequest(urlInfo, handleSuccess, handleError);
152
- }
153
153
  }
@@ -0,0 +1,27 @@
1
+ function binarySearch<T>(items: T[], compareFn: (a: T) => number): null | T {
2
+ let low = 0;
3
+ let high = items.length;
4
+
5
+ while (low < high) {
6
+ const mid = (low + high) >> 1;
7
+ const item = items[mid];
8
+
9
+ if (item === undefined) {
10
+ return null;
11
+ }
12
+
13
+ const compareResult = compareFn(item);
14
+
15
+ if (compareResult > 0) {
16
+ high = mid;
17
+ } else if (compareResult < 0) {
18
+ low = mid + 1;
19
+ } else {
20
+ return item;
21
+ }
22
+ }
23
+
24
+ return null;
25
+ }
26
+
27
+ export default binarySearch;
@@ -26,6 +26,15 @@ class DragElement {
26
26
  treeElement.appendChild(this.element);
27
27
  }
28
28
 
29
+ public move(pageX: number, pageY: number): void {
30
+ this.element.style.left = `${pageX - this.offsetX}px`;
31
+ this.element.style.top = `${pageY - this.offsetY}px`;
32
+ }
33
+
34
+ public remove(): void {
35
+ this.element.remove();
36
+ }
37
+
29
38
  private createElement(nodeName: string, autoEscape: boolean) {
30
39
  const element = document.createElement("span");
31
40
  element.classList.add("jqtree-title", "jqtree-dragging");
@@ -40,15 +49,6 @@ class DragElement {
40
49
 
41
50
  return element;
42
51
  }
43
-
44
- public move(pageX: number, pageY: number): void {
45
- this.element.style.left = `${pageX - this.offsetX}px`;
46
- this.element.style.top = `${pageY - this.offsetY}px`;
47
- }
48
-
49
- public remove(): void {
50
- this.element.remove();
51
- }
52
52
  }
53
53
 
54
54
  export default DragElement;
@@ -1,12 +1,11 @@
1
- import { Node } from "../node";
2
- import { Position } from "../position";
1
+ import { Node, Position } from "../node";
3
2
  import { getOffsetTop } from "../util";
4
3
  import iterateVisibleNodes from "./iterateVisibleNodes";
5
4
  import { HitArea } from "./types";
6
5
 
7
6
  interface HitPosition {
8
7
  node: Node;
9
- position: Position;
8
+ position: null | Position;
10
9
  top: number;
11
10
  }
12
11
 
@@ -17,7 +16,11 @@ export const generateHitPositions = (
17
16
  const hitPositions: HitPosition[] = [];
18
17
  let lastTop = 0;
19
18
 
20
- const addHitPosition = (node: Node, position: number, top: number) => {
19
+ const addHitPosition = (
20
+ node: Node,
21
+ position: null | Position,
22
+ top: number,
23
+ ) => {
21
24
  hitPositions.push({
22
25
  node,
23
26
  position,
@@ -29,9 +32,9 @@ export const generateHitPositions = (
29
32
  const handleAfterOpenFolder = (node: Node, nextNode: Node | null) => {
30
33
  if (node === currentNode || nextNode === currentNode) {
31
34
  // Cannot move before or after current item
32
- addHitPosition(node, Position.None, lastTop);
35
+ addHitPosition(node, null, lastTop);
33
36
  } else {
34
- addHitPosition(node, Position.After, lastTop);
37
+ addHitPosition(node, "after", lastTop);
35
38
  }
36
39
  };
37
40
 
@@ -44,20 +47,20 @@ export const generateHitPositions = (
44
47
 
45
48
  if (node === currentNode) {
46
49
  // Cannot move after current item
47
- addHitPosition(node, Position.None, top);
50
+ addHitPosition(node, null, top);
48
51
  } else {
49
- addHitPosition(node, Position.Inside, top);
52
+ addHitPosition(node, "inside", top);
50
53
 
51
54
  // Cannot move before current item
52
55
  if (nextNode !== currentNode) {
53
- addHitPosition(node, Position.After, top);
56
+ addHitPosition(node, "after", top);
54
57
  }
55
58
  }
56
59
  };
57
60
 
58
61
  const handleFirstNode = (node: Node) => {
59
62
  if (node !== currentNode && node.element) {
60
- addHitPosition(node, Position.Before, getOffsetTop(node.element));
63
+ addHitPosition(node, "before", getOffsetTop(node.element));
61
64
  }
62
65
  };
63
66
 
@@ -70,16 +73,16 @@ export const generateHitPositions = (
70
73
 
71
74
  if (node === currentNode) {
72
75
  // Cannot move inside current item
73
- addHitPosition(node, Position.None, top);
76
+ addHitPosition(node, null, top);
74
77
  } else {
75
- addHitPosition(node, Position.Inside, top);
78
+ addHitPosition(node, "inside", top);
76
79
  }
77
80
 
78
81
  if (nextNode === currentNode || node === currentNode) {
79
82
  // Cannot move before or after current item
80
- addHitPosition(node, Position.None, top);
83
+ addHitPosition(node, null, top);
81
84
  } else {
82
- addHitPosition(node, Position.After, top);
85
+ addHitPosition(node, "after", top);
83
86
  }
84
87
  };
85
88
 
@@ -90,11 +93,11 @@ export const generateHitPositions = (
90
93
  // Dnd over the current element is not possible: add a position with type None for the top and the bottom.
91
94
  const top = getOffsetTop(element);
92
95
  const height = element.clientHeight;
93
- addHitPosition(node, Position.None, top);
96
+ addHitPosition(node, null, top);
94
97
 
95
98
  if (height > 5) {
96
99
  // Subtract 5 pixels to allow more space for the next element.
97
- addHitPosition(node, Position.None, top + height - 5);
100
+ addHitPosition(node, null, top + height - 5);
98
101
  }
99
102
 
100
103
  // Stop iterating
@@ -103,7 +106,7 @@ export const generateHitPositions = (
103
106
 
104
107
  // Cannot move before current item
105
108
  if (node.children[0] !== currentNode) {
106
- addHitPosition(node, Position.Inside, getOffsetTop(element));
109
+ addHitPosition(node, "inside", getOffsetTop(element));
107
110
  }
108
111
 
109
112
  // Continue iterating
@@ -136,7 +139,7 @@ export const generateHitAreasForGroup = (
136
139
  for (let i = 0; i < positionCount; i++) {
137
140
  const position = positionsInGroup[i] as HitPosition;
138
141
 
139
- if (position.position !== Position.None) {
142
+ if (position.position) {
140
143
  hitAreas.push({
141
144
  bottom: areaTop + areaHeight,
142
145
  node: position.node,