jqtree 1.8.6 → 1.8.8

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.6",
3
+ "version": "1.8.8",
4
4
  "main": [
5
5
  "jqtree.css",
6
6
  "jqtree-circle.png",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jqtree",
3
- "version": "1.8.6",
3
+ "version": "1.8.8",
4
4
  "description": "Tree widget for jQuery",
5
5
  "keywords": [
6
6
  "jquery-plugin",
@@ -35,51 +35,50 @@
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.25.9",
39
+ "@babel/core": "^7.26.0",
40
+ "@babel/preset-env": "^7.26.0",
41
+ "@babel/preset-typescript": "^7.26.0",
42
+ "@playwright/test": "^1.48.2",
43
43
  "@rollup/plugin-babel": "^6.0.4",
44
44
  "@rollup/plugin-node-resolve": "^15.3.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.9.0",
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.14.0",
58
58
  "eslint-plugin-import": "^2.31.0",
59
- "eslint-plugin-jest": "^28.8.3",
59
+ "eslint-plugin-jest": "^28.9.0",
60
60
  "eslint-plugin-jest-dom": "^5.4.0",
61
- "eslint-plugin-perfectionist": "^3.8.0",
62
- "eslint-plugin-playwright": "^1.6.2",
61
+ "eslint-plugin-perfectionist": "^3.9.1",
62
+ "eslint-plugin-playwright": "^2.0.1",
63
63
  "givens": "^1.3.9",
64
64
  "graphql": "^16.9.0",
65
65
  "jest": "^29.7.0",
66
66
  "jest-axe": "^9.0.0",
67
67
  "jest-extended": "^4.0.2",
68
- "jest-fixed-jsdom": "^0.0.4",
68
+ "jest-fixed-jsdom": "^0.0.8",
69
69
  "jsonfile": "^6.1.0",
70
70
  "lodash": "^4.17.21",
71
- "msw": "^2.4.9",
71
+ "msw": "^2.6.2",
72
72
  "postcss": "^8.4.47",
73
73
  "postcss-cli": "^11.0.0",
74
74
  "postcss-import": "^16.1.0",
75
75
  "postcss-load-config": "^6.0.1",
76
- "postcss-nested": "^6.2.0",
76
+ "postcss-nested": "^7.0.2",
77
77
  "prettier": "^3.3.3",
78
- "rollup": "^4.24.0",
78
+ "rollup": "^4.24.4",
79
79
  "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"
80
+ "tslib": "^2.8.1",
81
+ "typescript": "^5.6.3",
82
+ "typescript-eslint": "^8.13.0"
84
83
  }
85
84
  }
package/src/keyHandler.ts CHANGED
@@ -7,8 +7,6 @@ import {
7
7
  } from "./jqtreeMethodTypes";
8
8
  import { Node } from "./node";
9
9
 
10
- type KeyboardEventHandler = (event: KeyboardEvent) => boolean;
11
-
12
10
  interface KeyHandlerParams {
13
11
  closeNode: CloseNode;
14
12
  getSelectedNode: GetSelectedNode;
@@ -36,16 +34,16 @@ export default class KeyHandler {
36
34
  isKeyHandled = this.moveDown(selectedNode);
37
35
  break;
38
36
 
39
- case "ArrowUp":
40
- isKeyHandled = this.moveUp(selectedNode);
37
+ case "ArrowLeft":
38
+ isKeyHandled = this.moveLeft(selectedNode);
41
39
  break;
42
40
 
43
41
  case "ArrowRight":
44
42
  isKeyHandled = this.moveRight(selectedNode);
45
43
  break;
46
44
 
47
- case "ArrowLeft":
48
- isKeyHandled = this.moveLeft(selectedNode);
45
+ case "ArrowUp":
46
+ isKeyHandled = this.moveUp(selectedNode);
49
47
  break;
50
48
  }
51
49
  }
@@ -55,7 +53,6 @@ export default class KeyHandler {
55
53
  }
56
54
  };
57
55
 
58
- private handleKeyDownHandler?: KeyboardEventHandler;
59
56
  private isFocusOnTree: IsFocusOnTree;
60
57
  private keyboardSupport: boolean;
61
58
  private openNode: OpenNode;
@@ -127,8 +124,8 @@ export default class KeyHandler {
127
124
  }
128
125
 
129
126
  public deinit(): void {
130
- if (this.handleKeyDownHandler) {
131
- document.removeEventListener("keydown", this.handleKeyDownHandler);
127
+ if (this.keyboardSupport) {
128
+ document.removeEventListener("keydown", this.handleKeyDown);
132
129
  }
133
130
  }
134
131
 
@@ -14,19 +14,19 @@ class FolderElement extends NodeElement {
14
14
  private triggerEvent: TriggerEvent;
15
15
 
16
16
  constructor({
17
- $treeElement,
18
17
  closedIconElement,
19
18
  getScrollLeft,
20
19
  node,
21
20
  openedIconElement,
22
21
  tabIndex,
22
+ treeElement,
23
23
  triggerEvent,
24
24
  }: FolderElementParams) {
25
25
  super({
26
- $treeElement,
27
26
  getScrollLeft,
28
27
  node,
29
28
  tabIndex,
29
+ treeElement,
30
30
  });
31
31
 
32
32
  this.closedIconElement = closedIconElement;
@@ -44,10 +44,7 @@ class FolderElement extends NodeElement {
44
44
  ) as HTMLLinkElement;
45
45
  }
46
46
 
47
- public close(
48
- slide = true,
49
- animationSpeed: JQuery.Duration | undefined = "fast",
50
- ): void {
47
+ public close(slide: boolean, animationSpeed: JQuery.Duration): void {
51
48
  if (!this.node.is_open) {
52
49
  return;
53
50
  }
@@ -86,8 +83,8 @@ class FolderElement extends NodeElement {
86
83
 
87
84
  public open(
88
85
  onFinished: OnFinishOpenNode | undefined,
89
- slide = true,
90
- animationSpeed: JQuery.Duration = "fast",
86
+ slide: boolean,
87
+ animationSpeed: JQuery.Duration,
91
88
  ): void {
92
89
  if (this.node.is_open) {
93
90
  return;
@@ -1,15 +1,34 @@
1
1
  import { DropHint } from "../dragAndDropHandler/types";
2
+ import { Node } from "../node";
3
+ import { Position } from "../position";
2
4
 
3
5
  class GhostDropHint implements DropHint {
4
6
  private element: HTMLElement;
5
7
  private ghost: HTMLElement;
8
+ private node: Node;
6
9
 
7
- constructor(element: HTMLElement) {
10
+ constructor(node: Node, element: HTMLElement, position: Position) {
8
11
  this.element = element;
12
+ this.node = node;
9
13
  this.ghost = this.createGhostElement();
10
14
 
11
- this.element.after(this.ghost);
12
- this.ghost.classList.add("jqtree-inside");
15
+ switch (position) {
16
+ case Position.After:
17
+ this.moveAfter();
18
+ break;
19
+
20
+ case Position.Before:
21
+ this.moveBefore();
22
+ break;
23
+
24
+ case Position.Inside: {
25
+ if (node.isFolder() && node.is_open) {
26
+ this.moveInsideOpenFolder();
27
+ } else {
28
+ this.moveInside();
29
+ }
30
+ }
31
+ }
13
32
  }
14
33
 
15
34
  private createGhostElement() {
@@ -27,6 +46,27 @@ class GhostDropHint implements DropHint {
27
46
  return ghost;
28
47
  }
29
48
 
49
+ private moveAfter(): void {
50
+ this.element.after(this.ghost);
51
+ }
52
+
53
+ private moveBefore(): void {
54
+ this.element.before(this.ghost);
55
+ }
56
+
57
+ private moveInside(): void {
58
+ this.element.after(this.ghost);
59
+ this.ghost.classList.add("jqtree-inside");
60
+ }
61
+
62
+ private moveInsideOpenFolder(): void {
63
+ const childElement = this.node.children[0]?.element;
64
+
65
+ if (childElement) {
66
+ childElement.before(this.ghost);
67
+ }
68
+ }
69
+
30
70
  public remove(): void {
31
71
  this.ghost.remove();
32
72
  }
@@ -6,28 +6,28 @@ import BorderDropHint from "./borderDropHint";
6
6
  import GhostDropHint from "./ghostDropHint";
7
7
 
8
8
  export interface NodeElementParams {
9
- $treeElement: JQuery;
10
9
  getScrollLeft: GetScrollLeft;
11
10
  node: Node;
12
11
  tabIndex?: number;
12
+ treeElement: HTMLElement;
13
13
  }
14
14
 
15
15
  class NodeElement {
16
- private $treeElement: JQuery;
17
16
  private getScrollLeft: GetScrollLeft;
18
17
  private tabIndex?: number;
18
+ private treeElement: HTMLElement;
19
19
  public element: HTMLElement;
20
20
  public node: Node;
21
21
 
22
22
  constructor({
23
- $treeElement,
24
23
  getScrollLeft,
25
24
  node,
26
25
  tabIndex,
26
+ treeElement,
27
27
  }: NodeElementParams) {
28
28
  this.getScrollLeft = getScrollLeft;
29
29
  this.tabIndex = tabIndex;
30
- this.$treeElement = $treeElement;
30
+ this.treeElement = treeElement;
31
31
 
32
32
  this.init(node);
33
33
  }
@@ -50,7 +50,7 @@ class NodeElement {
50
50
  if (this.mustShowBorderDropHint(position)) {
51
51
  return new BorderDropHint(this.element, this.getScrollLeft());
52
52
  } else {
53
- return new GhostDropHint(this.element);
53
+ return new GhostDropHint(this.node, this.element, position);
54
54
  }
55
55
  }
56
56
 
@@ -68,16 +68,10 @@ class NodeElement {
68
68
  this.node = node;
69
69
 
70
70
  if (!node.element) {
71
- const element = this.$treeElement.get(0);
72
-
73
- if (element) {
74
- node.element = element;
75
- }
71
+ node.element = this.treeElement;
76
72
  }
77
73
 
78
- if (node.element) {
79
- this.element = node.element;
80
- }
74
+ this.element = node.element;
81
75
  }
82
76
 
83
77
  public select(mustSetFocus: boolean): void {
@@ -30,7 +30,6 @@ interface SaveStateHandlerParams {
30
30
  }
31
31
 
32
32
  export default class SaveStateHandler {
33
- private _supportsLocalStorage: boolean | null;
34
33
  private addToSelection: AddToSelection;
35
34
  private getNodeById: GetNodeById;
36
35
  private getSelectedNodes: GetSelectedNodes;
@@ -77,10 +76,8 @@ export default class SaveStateHandler {
77
76
  private loadFromStorage(): null | string {
78
77
  if (this.onGetStateFromStorage) {
79
78
  return this.onGetStateFromStorage();
80
- } else if (this.supportsLocalStorage()) {
81
- return localStorage.getItem(this.getKeyName());
82
79
  } else {
83
- return null;
80
+ return localStorage.getItem(this.getKeyName());
84
81
  }
85
82
  }
86
83
 
@@ -138,27 +135,6 @@ export default class SaveStateHandler {
138
135
  return selectCount !== 0;
139
136
  }
140
137
 
141
- private supportsLocalStorage(): boolean {
142
- const testSupport = (): boolean => {
143
- // Check if it's possible to store an item. Safari does not allow this in private browsing mode.
144
- try {
145
- const key = "_storage_test";
146
- sessionStorage.setItem(key, "value");
147
- sessionStorage.removeItem(key);
148
- } catch {
149
- return false;
150
- }
151
-
152
- return true;
153
- };
154
-
155
- if (this._supportsLocalStorage == null) {
156
- this._supportsLocalStorage = testSupport();
157
- }
158
-
159
- return this._supportsLocalStorage;
160
- }
161
-
162
138
  public getNodeIdToBeSelected(): NodeId | null {
163
139
  const state = this.getStateFromStorage();
164
140
 
@@ -216,7 +192,7 @@ export default class SaveStateHandler {
216
192
 
217
193
  if (this.onSetStateFromStorage) {
218
194
  this.onSetStateFromStorage(state);
219
- } else if (this.supportsLocalStorage()) {
195
+ } else {
220
196
  localStorage.setItem(this.getKeyName(), state);
221
197
  }
222
198
  }
@@ -225,7 +201,7 @@ export default class SaveStateHandler {
225
201
  Set initial state
226
202
  Don't handle nodes that are loaded on demand
227
203
 
228
- result: must load on demand
204
+ result: must load on demand (boolean)
229
205
  */
230
206
  public setInitialState(state: SavedState): boolean {
231
207
  let mustLoadOnDemand = false;
@@ -64,18 +64,14 @@ export default class SelectNodeHandler {
64
64
  return [];
65
65
  }
66
66
  } else {
67
- const selectedNodes = [];
68
-
69
- for (const id in this.selectedNodes) {
70
- if (
71
- Object.prototype.hasOwnProperty.call(this.selectedNodes, id)
72
- ) {
73
- const node = this.getNodeById(id);
74
- if (node && parent.isParentOf(node)) {
75
- selectedNodes.push(node);
76
- }
67
+ const selectedNodes: Node[] = [];
68
+
69
+ this.selectedNodes.forEach((id) => {
70
+ const node = this.getNodeById(id);
71
+ if (node && parent.isParentOf(node)) {
72
+ selectedNodes.push(node);
77
73
  }
78
- }
74
+ });
79
75
 
80
76
  return selectedNodes;
81
77
  }
@@ -250,16 +250,16 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
250
250
  );
251
251
  const openedIconElement = this.renderer.openedIconElement;
252
252
  const tabIndex = this.options.tabIndex;
253
- const $treeElement = this.element;
253
+ const treeElement = this.element.get(0) as HTMLElement;
254
254
  const triggerEvent = this.triggerEvent.bind(this);
255
255
 
256
256
  return new FolderElement({
257
- $treeElement,
258
257
  closedIconElement,
259
258
  getScrollLeft,
260
259
  node,
261
260
  openedIconElement,
262
261
  tabIndex,
262
+ treeElement,
263
263
  triggerEvent,
264
264
  });
265
265
  }
@@ -269,13 +269,13 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
269
269
  this.scrollHandler,
270
270
  );
271
271
  const tabIndex = this.options.tabIndex;
272
- const $treeElement = this.element;
272
+ const treeElement = this.element.get(0) as HTMLElement;
273
273
 
274
274
  return new NodeElement({
275
- $treeElement,
276
275
  getScrollLeft,
277
276
  node,
278
277
  tabIndex,
278
+ treeElement,
279
279
  });
280
280
  }
281
281
 
@@ -626,6 +626,10 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
626
626
  _slide: boolean,
627
627
  _onFinished?: OnFinishOpenNode,
628
628
  ): void => {
629
+ if (!node.children.length) {
630
+ return;
631
+ }
632
+
629
633
  const folderElement = this.createFolderElement(_node);
630
634
  folderElement.open(
631
635
  _onFinished,
package/src/version.ts CHANGED
@@ -1,3 +1,3 @@
1
- const version = "1.8.6";
1
+ const version = "1.8.8";
2
2
 
3
3
  export default version;