jqtree 1.8.4 → 1.8.6

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/.tool-versions ADDED
@@ -0,0 +1,2 @@
1
+ nodejs 20.18.0
2
+ ruby 3.3.5
package/README.md CHANGED
@@ -15,7 +15,7 @@ JqTree is a tree widget. Read more in the [documentation](https://mbraak.github.
15
15
  - Works on all modern browsers
16
16
  - Written in Typescript
17
17
 
18
- The project is hosted on [github](https://github.com/mbraak/jqTree), has a [test suite](http://mbraak.github.io/jqTree/test/test.html).
18
+ The project is hosted on [github](https://github.com/mbraak/jqTree).
19
19
 
20
20
  ## Examples
21
21
 
package/bower.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jqTree",
3
- "version": "1.8.4",
3
+ "version": "1.8.6",
4
4
  "main": [
5
5
  "jqtree.css",
6
6
  "jqtree-circle.png",
@@ -0,0 +1,69 @@
1
+ import eslint from "@eslint/js";
2
+ import tseslint from "typescript-eslint";
3
+ import importPlugin from "eslint-plugin-import";
4
+ import jestPlugin from "eslint-plugin-jest";
5
+ import jestDomPlugin from "eslint-plugin-jest-dom";
6
+ import perfectionistPlugin from "eslint-plugin-perfectionist";
7
+ import playwrightPlugin from "eslint-plugin-playwright";
8
+
9
+ export default [
10
+ eslint.configs.recommended,
11
+ ...tseslint.configs.strictTypeChecked,
12
+ ...tseslint.configs.stylisticTypeChecked,
13
+ importPlugin.flatConfigs.recommended,
14
+ importPlugin.flatConfigs.typescript,
15
+ perfectionistPlugin.configs["recommended-natural"],
16
+ {
17
+ languageOptions: {
18
+ parserOptions: {
19
+ projectService: true,
20
+ tsconfigRootDir: import.meta.dirname,
21
+ },
22
+ },
23
+ rules: {
24
+ "@typescript-eslint/explicit-function-return-type": "off",
25
+ "@typescript-eslint/interface-name-prefix": "off",
26
+ "@typescript-eslint/no-explicit-any": "off",
27
+ "@typescript-eslint/no-use-before-define": "off",
28
+ "@typescript-eslint/no-unused-vars": [
29
+ "error",
30
+ {
31
+ argsIgnorePattern: "^_",
32
+ varsIgnorePattern: "^_",
33
+ },
34
+ ],
35
+ "@typescript-eslint/non-nullable-type-assertion-style": "off",
36
+ "@typescript-eslint/prefer-includes": "off",
37
+ "@typescript-eslint/triple-slash-reference": "off",
38
+ "@typescript-eslint/prefer-string-starts-ends-with": "off",
39
+ "@typescript-eslint/restrict-template-expressions": [
40
+ "error",
41
+ {
42
+ allowNumber: true,
43
+ allowBoolean: true,
44
+ allowAny: false,
45
+ allowNullish: false,
46
+ },
47
+ ],
48
+ "@typescript-eslint/unified-signatures": "off",
49
+ },
50
+ },
51
+ {
52
+ files: ["src/test/**/*.ts"],
53
+ ...jestPlugin.configs["flat/recommended"],
54
+ },
55
+ {
56
+ files: ["src/test/**/*.ts"],
57
+ rules: {
58
+ "jest/no-identical-title": "off",
59
+ },
60
+ },
61
+ {
62
+ files: ["src/test/jqTree/**/*.ts"],
63
+ ...jestDomPlugin.configs["flat/recommended"],
64
+ },
65
+ {
66
+ files: ["src/playwright/**/*.ts"],
67
+ ...playwrightPlugin.configs["flat/recommended"],
68
+ },
69
+ ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jqtree",
3
- "version": "1.8.4",
3
+ "version": "1.8.6",
4
4
  "description": "Tree widget for jQuery",
5
5
  "keywords": [
6
6
  "jquery-plugin",
@@ -18,7 +18,7 @@
18
18
  "ci": "pnpm lint && pnpm tsc && pnpm test",
19
19
  "jest": "jest --coverage --no-cache --verbose --config ./config/jest.config.js",
20
20
  "jest-watch": "jest --watch --config ./config/jest.config.js",
21
- "lint": "eslint src/ --ext .ts,.tsx",
21
+ "lint": "eslint src",
22
22
  "production": "./config/production",
23
23
  "devserver": "SERVE=true rollup --config config/rollup.config.mjs --watch",
24
24
  "devserver-with-coverage": "COVERAGE=true SERVE=true rollup --config config/rollup.config.mjs",
@@ -35,53 +35,51 @@
35
35
  "jquery": "^3"
36
36
  },
37
37
  "devDependencies": {
38
- "@babel/cli": "^7.24.8",
39
- "@babel/core": "^7.24.9",
40
- "@babel/preset-env": "^7.24.8",
41
- "@babel/preset-typescript": "^7.24.7",
42
- "@codecov/rollup-plugin": "0.0.1-beta.10",
43
- "@playwright/test": "^1.45.2",
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",
44
43
  "@rollup/plugin-babel": "^6.0.4",
45
- "@rollup/plugin-node-resolve": "^15.2.3",
44
+ "@rollup/plugin-node-resolve": "^15.3.0",
46
45
  "@rollup/plugin-terser": "^0.4.4",
47
- "@testing-library/dom": "^10.3.2",
46
+ "@testing-library/dom": "^10.4.0",
47
+ "@testing-library/jest-dom": "^6.6.2",
48
48
  "@testing-library/user-event": "^14.5.2",
49
49
  "@types/debug": "^4.1.12",
50
- "@types/jest": "^29.5.12",
50
+ "@types/jest": "^29.5.13",
51
51
  "@types/jest-axe": "^3.5.9",
52
- "@types/jquery": "^3.5.30",
53
- "@types/node": "^20.14.11",
54
- "@typescript-eslint/eslint-plugin": "^7.16.1",
55
- "@typescript-eslint/parser": "^7.16.1",
56
- "autoprefixer": "^10.4.19",
52
+ "@types/jquery": "^3.5.31",
53
+ "@types/node": "^22.7.4",
54
+ "autoprefixer": "^10.4.20",
57
55
  "babel-jest": "^29.7.0",
58
56
  "babel-plugin-istanbul": "^7.0.0",
59
- "eslint": "^8.57.0",
60
- "eslint-import-resolver-typescript": "^3.6.1",
61
- "eslint-plugin-deprecation": "^3.0.0",
62
- "eslint-plugin-import": "^2.29.1",
63
- "eslint-plugin-jest": "^28.6.0",
57
+ "eslint": "^9",
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",
64
62
  "eslint-plugin-playwright": "^1.6.2",
65
- "eslint-plugin-testing-library": "^6.2.2",
66
63
  "givens": "^1.3.9",
67
64
  "graphql": "^16.9.0",
68
65
  "jest": "^29.7.0",
69
66
  "jest-axe": "^9.0.0",
70
- "jest-environment-jsdom": "^29.7.0",
71
67
  "jest-extended": "^4.0.2",
68
+ "jest-fixed-jsdom": "^0.0.4",
72
69
  "jsonfile": "^6.1.0",
73
70
  "lodash": "^4.17.21",
74
- "msw": "^2.3.2",
75
- "postcss": "^8.4.39",
71
+ "msw": "^2.4.9",
72
+ "postcss": "^8.4.47",
76
73
  "postcss-cli": "^11.0.0",
77
74
  "postcss-import": "^16.1.0",
78
75
  "postcss-load-config": "^6.0.1",
79
- "postcss-nested": "^6.0.1",
76
+ "postcss-nested": "^6.2.0",
80
77
  "prettier": "^3.3.3",
81
- "rollup": "^4.18.1",
78
+ "rollup": "^4.24.0",
82
79
  "rollup-plugin-serve": "^3.0.0",
83
- "tslib": "^2.6.3",
84
- "typescript": "^5.5.3",
80
+ "tslib": "^2.7.0",
81
+ "typescript": "^5.6.2",
82
+ "typescript-eslint": "^8.8.0",
85
83
  "undici": "^5.28.4"
86
84
  }
87
85
  }
package/src/dataLoader.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { Node } from "./node";
2
- import { DataFilter, OnLoadFailed, OnLoading } from "./jqtreeOptions";
3
1
  import { LoadData, TriggerEvent } from "./jqtreeMethodTypes";
2
+ import { DataFilter, OnLoadFailed, OnLoading } from "./jqtreeOptions";
3
+ import { Node } from "./node";
4
4
 
5
5
  export type HandleFinishedLoading = () => void;
6
6
 
@@ -37,54 +37,12 @@ export default class DataLoader {
37
37
  this.triggerEvent = triggerEvent;
38
38
  }
39
39
 
40
- public loadFromUrl(
41
- urlInfo: string | JQuery.AjaxSettings | null,
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: string | NodeData[]): 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
-
78
40
  private addLoadingClass(element: HTMLElement): void {
79
41
  element.classList.add("jqtree-loading");
80
42
  }
81
43
 
82
- private removeLoadingClass(element: HTMLElement): void {
83
- element.classList.remove("jqtree-loading");
84
- }
85
-
86
44
  private getDomElement(parentNode: Node | null): HTMLElement {
87
- if (parentNode) {
45
+ if (parentNode?.element) {
88
46
  return parentNode.element;
89
47
  } else {
90
48
  return this.treeElement;
@@ -103,14 +61,36 @@ export default class DataLoader {
103
61
  }
104
62
 
105
63
  this.triggerEvent("tree.loading_data", {
64
+ $el,
106
65
  isLoading,
107
66
  node,
108
- $el,
109
67
  });
110
68
  }
111
69
 
70
+ private parseData(data: NodeData[] | string): NodeData[] {
71
+ const getParsedData = () => {
72
+ if (typeof data === "string") {
73
+ return JSON.parse(data) as NodeData[];
74
+ } else {
75
+ return data;
76
+ }
77
+ };
78
+
79
+ const parsedData = getParsedData();
80
+
81
+ if (this.dataFilter) {
82
+ return this.dataFilter(parsedData);
83
+ } else {
84
+ return parsedData;
85
+ }
86
+ }
87
+
88
+ private removeLoadingClass(element: HTMLElement): void {
89
+ element.classList.remove("jqtree-loading");
90
+ }
91
+
112
92
  private submitRequest(
113
- urlInfoInput: string | JQuery.AjaxSettings,
93
+ urlInfoInput: JQuery.AjaxSettings | string,
114
94
  handleSuccess: JQuery.Ajax.SuccessCallback<any>,
115
95
  handleError: JQuery.Ajax.ErrorCallback<any>,
116
96
  ): void {
@@ -120,34 +100,54 @@ export default class DataLoader {
120
100
  : urlInfoInput;
121
101
 
122
102
  const ajaxSettings: JQuery.AjaxSettings = {
123
- method: "GET",
124
103
  cache: false,
125
104
  dataType: "json",
126
- success: handleSuccess,
127
105
  error: handleError,
106
+ method: "GET",
107
+ success: handleSuccess,
128
108
  ...urlInfo,
129
109
  };
130
110
 
131
- ajaxSettings.method = ajaxSettings.method?.toUpperCase() || "GET";
111
+ ajaxSettings.method = ajaxSettings.method?.toUpperCase() ?? "GET";
132
112
 
133
113
  void jQuery.ajax(ajaxSettings);
134
114
  }
135
115
 
136
- private parseData(data: string | NodeData[]): NodeData[] {
137
- const getParsedData = () => {
138
- if (typeof data === "string") {
139
- return JSON.parse(data) as NodeData[];
140
- } else {
141
- return data;
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();
142
140
  }
143
141
  };
144
142
 
145
- const parsedData = getParsedData();
143
+ const handleError = (jqXHR: JQuery.jqXHR): void => {
144
+ stopLoading();
146
145
 
147
- if (this.dataFilter) {
148
- return this.dataFilter(parsedData);
149
- } else {
150
- return parsedData;
151
- }
146
+ if (this.onLoadFailed) {
147
+ this.onLoadFailed(jqXHR);
148
+ }
149
+ };
150
+
151
+ this.submitRequest(urlInfo, handleSuccess, handleError);
152
152
  }
153
153
  }
@@ -7,9 +7,9 @@ interface DragElementParams {
7
7
  }
8
8
 
9
9
  class DragElement {
10
+ private element: HTMLElement;
10
11
  private offsetX: number;
11
12
  private offsetY: number;
12
- private element: HTMLElement;
13
13
 
14
14
  constructor({
15
15
  autoEscape,
@@ -26,15 +26,6 @@ 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
-
38
29
  private createElement(nodeName: string, autoEscape: boolean) {
39
30
  const element = document.createElement("span");
40
31
  element.classList.add("jqtree-title", "jqtree-dragging");
@@ -49,6 +40,15 @@ class DragElement {
49
40
 
50
41
  return element;
51
42
  }
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,13 +1,13 @@
1
- import { HitArea } from "./types";
2
1
  import { Node } from "../node";
3
2
  import { Position } from "../position";
4
3
  import { getOffsetTop } from "../util";
5
4
  import iterateVisibleNodes from "./iterateVisibleNodes";
5
+ import { HitArea } from "./types";
6
6
 
7
7
  interface HitPosition {
8
- top: number;
9
8
  node: Node;
10
9
  position: Position;
10
+ top: number;
11
11
  }
12
12
 
13
13
  export const generateHitPositions = (
@@ -19,9 +19,9 @@ export const generateHitPositions = (
19
19
 
20
20
  const addHitPosition = (node: Node, position: number, top: number) => {
21
21
  hitPositions.push({
22
- top,
23
22
  node,
24
23
  position,
24
+ top,
25
25
  });
26
26
  lastTop = top;
27
27
  };
@@ -56,7 +56,7 @@ export const generateHitPositions = (
56
56
  };
57
57
 
58
58
  const handleFirstNode = (node: Node) => {
59
- if (node !== currentNode) {
59
+ if (node !== currentNode && node.element) {
60
60
  addHitPosition(node, Position.Before, getOffsetTop(node.element));
61
61
  }
62
62
  };
@@ -138,10 +138,10 @@ export const generateHitAreasForGroup = (
138
138
 
139
139
  if (position.position !== Position.None) {
140
140
  hitAreas.push({
141
- top: areaTop,
142
141
  bottom: areaTop + areaHeight,
143
142
  node: position.node,
144
143
  position: position.position,
144
+ top: areaTop,
145
145
  });
146
146
  }
147
147