jqtree 1.7.0 → 1.7.2
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/.github/workflows/ci.yml +2 -15
- package/.github/workflows/codeql-analysis.yml +2 -2
- package/.github/workflows/size.yml +24 -0
- package/README.md +1 -1
- package/bower.json +1 -1
- package/docs/Gemfile.lock +39 -40
- package/docs/_config.yml +1 -1
- package/docs/_entries/03_features.md +1 -1
- package/docs/_entries/10_changelog.md +9 -0
- package/docs/_entries/16_closedicon.md +17 -3
- package/docs/_entries/31_openedicon.md +17 -3
- package/docs/package.json +7 -7
- package/docs/pnpm-lock.yaml +378 -284
- package/docs/static/bower.json +2 -2
- package/docs/static/bower_components/fontawesome/css/all.min.css +6 -2
- package/docs/static/bower_components/fontawesome/webfonts/fa-brands-400.ttf +0 -0
- package/docs/static/bower_components/fontawesome/webfonts/fa-brands-400.woff2 +0 -0
- package/docs/static/bower_components/fontawesome/webfonts/fa-regular-400.ttf +0 -0
- package/docs/static/bower_components/fontawesome/webfonts/fa-regular-400.woff2 +0 -0
- package/docs/static/bower_components/fontawesome/webfonts/fa-solid-900.ttf +0 -0
- package/docs/static/bower_components/fontawesome/webfonts/fa-solid-900.woff2 +0 -0
- package/docs/static/bower_components/fontawesome/webfonts/fa-v4compatibility.ttf +0 -0
- package/docs/static/bower_components/fontawesome/webfonts/fa-v4compatibility.woff2 +0 -0
- package/docs/static/bower_components/jquery/dist/jquery.js +813 -1102
- package/docs/static/bower_components/jquery/dist/jquery.min.js +2 -2
- package/docs/static/documentation.css +104 -222
- package/docs/static/examples/autoescape.js +15 -17
- package/docs/static/examples/autoscroll.js +5 -7
- package/docs/static/examples/button-on-right.js +4 -6
- package/docs/static/examples/custom_html.js +22 -24
- package/docs/static/examples/drag-outside.js +23 -25
- package/docs/static/examples/drag_and_drop.js +4 -6
- package/docs/static/examples/icon_buttons.js +3 -5
- package/docs/static/examples/load_json_data.js +14 -16
- package/docs/static/examples/load_json_data_from_server.js +1 -3
- package/docs/static/examples/load_on_demand.js +3 -5
- package/docs/static/examples/multiple_select.js +19 -21
- package/docs/static/examples/right-to-left.js +2 -4
- package/docs/static/examples/save_state.js +2 -4
- package/docs/tree.jquery.js +3 -3
- package/lib/dataLoader.js +3 -3
- package/lib/dragAndDropHandler.js +22 -11
- package/lib/elementsRenderer.js +26 -16
- package/lib/keyHandler.js +1 -1
- package/lib/mouse.widget.js +13 -2
- package/lib/node.js +17 -14
- package/lib/nodeElement.js +20 -13
- package/lib/playwright/coverage.js +11 -16
- package/lib/playwright/playwright.test.js +37 -58
- package/lib/playwright/testUtils.js +27 -44
- package/lib/saveStateHandler.js +2 -2
- package/lib/scrollHandler.js +8 -4
- package/lib/selectNodeHandler.js +2 -2
- package/lib/simple.widget.js +5 -3
- package/lib/test/jqTree/accessibility.test.js +37 -0
- package/lib/test/jqTree/events.test.js +73 -77
- package/lib/test/jqTree/loadOnDemand.test.js +5 -4
- package/lib/test/jqTree/methods.test.js +2 -2
- package/lib/test/jqTree/options.test.js +43 -2
- package/lib/test/node.test.js +7 -4
- package/lib/tree.jquery.js +5 -5
- package/lib/version.js +1 -1
- package/package.json +37 -41
- package/src/dragAndDropHandler.ts +24 -10
- package/src/elementsRenderer.ts +57 -50
- package/src/jqtreeOptions.ts +5 -5
- package/src/mouse.widget.ts +12 -0
- package/src/node.ts +10 -5
- package/src/nodeElement.ts +27 -21
- package/src/saveStateHandler.ts +1 -1
- package/src/scrollHandler.ts +6 -2
- package/src/selectNodeHandler.ts +1 -1
- package/src/simple.widget.ts +2 -0
- package/src/test/.eslintrc +2 -1
- package/src/test/jqTree/accessibility.test.ts +25 -0
- package/src/test/jqTree/events.test.ts +79 -93
- package/src/test/jqTree/loadOnDemand.test.ts +6 -5
- package/src/test/jqTree/methods.test.ts +27 -27
- package/src/test/jqTree/options.test.ts +61 -8
- package/src/test/node.test.ts +6 -4
- package/src/test/nodeUtil.test.ts +1 -1
- package/src/tree.jquery.d.ts +20 -11
- package/src/tree.jquery.ts +1 -1
- package/src/version.ts +1 -1
- package/tree.jquery.debug.js +143 -97
- package/tree.jquery.debug.js.map +1 -1
- package/tree.jquery.js +3 -3
- package/tree.jquery.js.map +1 -1
- package/tsconfig.json +1 -0
- package/.tool-versions +0 -1
- package/docs/static/bower_components/fontawesome/webfonts/fa-brands-400.eot +0 -0
- package/docs/static/bower_components/fontawesome/webfonts/fa-brands-400.svg +0 -3717
- package/docs/static/bower_components/fontawesome/webfonts/fa-brands-400.woff +0 -0
- package/docs/static/bower_components/fontawesome/webfonts/fa-regular-400.eot +0 -0
- package/docs/static/bower_components/fontawesome/webfonts/fa-regular-400.svg +0 -801
- package/docs/static/bower_components/fontawesome/webfonts/fa-regular-400.woff +0 -0
- package/docs/static/bower_components/fontawesome/webfonts/fa-solid-900.eot +0 -0
- package/docs/static/bower_components/fontawesome/webfonts/fa-solid-900.svg +0 -5028
- package/docs/static/bower_components/fontawesome/webfonts/fa-solid-900.woff +0 -0
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jqtree",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "Tree widget for jQuery",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jquery-plugin",
|
|
7
7
|
"tree"
|
|
8
8
|
],
|
|
9
9
|
"license": "Apache-2.0",
|
|
10
|
-
"
|
|
10
|
+
"browser": "./tree.jquery.js",
|
|
11
11
|
"types": "./src/tree.jquery.d.ts",
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
@@ -23,60 +23,56 @@
|
|
|
23
23
|
"devserver-with-coverage": "COVERAGE=true SERVE=true rollup --config config/rollup.config.mjs",
|
|
24
24
|
"build-with-coverage": "COVERAGE=true rollup --config config/rollup.config.mjs",
|
|
25
25
|
"prettier": "prettier src/*.ts --write --tab-width 4",
|
|
26
|
-
"write-coverage": "nyc report --reporter=text-lcov > lcov.info",
|
|
27
26
|
"tsc": "tsc --noEmit --project tsconfig.json",
|
|
28
|
-
"merge-coverage": "cp jest-coverage/coverage-final.json .nyc_output/coverage_jsdom.json",
|
|
29
|
-
"clean-coverage": "rm -rf .nyc_output && jest --clearCache",
|
|
30
|
-
"print-coverage": "nyc report",
|
|
31
27
|
"playwright": "pnpm build-with-coverage && playwright test --config config/playwright.config.js",
|
|
32
28
|
"test": "pnpm jest && pnpm playwright"
|
|
33
29
|
},
|
|
34
30
|
"dependencies": {
|
|
35
|
-
"jquery": "^3.
|
|
31
|
+
"jquery": "^3.7.1"
|
|
36
32
|
},
|
|
37
33
|
"devDependencies": {
|
|
38
|
-
"@babel/cli": "^7.
|
|
39
|
-
"@babel/core": "^7.
|
|
40
|
-
"@babel/preset-env": "^7.
|
|
41
|
-
"@babel/preset-typescript": "^7.
|
|
42
|
-
"@playwright/test": "^1.
|
|
34
|
+
"@babel/cli": "^7.22.15",
|
|
35
|
+
"@babel/core": "^7.22.17",
|
|
36
|
+
"@babel/preset-env": "^7.22.15",
|
|
37
|
+
"@babel/preset-typescript": "^7.22.15",
|
|
38
|
+
"@playwright/test": "^1.38.0",
|
|
43
39
|
"@rollup/plugin-babel": "^6.0.3",
|
|
44
|
-
"@rollup/plugin-node-resolve": "^15.
|
|
45
|
-
"@rollup/plugin-terser": "^0.
|
|
46
|
-
"@testing-library/dom": "^
|
|
47
|
-
"@types/debug": "^4.1.
|
|
48
|
-
"@types/jest": "^29.
|
|
49
|
-
"@types/
|
|
50
|
-
"@types/
|
|
51
|
-
"@
|
|
52
|
-
"@typescript-eslint/
|
|
53
|
-
"
|
|
54
|
-
"
|
|
40
|
+
"@rollup/plugin-node-resolve": "^15.2.1",
|
|
41
|
+
"@rollup/plugin-terser": "^0.4.3",
|
|
42
|
+
"@testing-library/dom": "^9.3.1",
|
|
43
|
+
"@types/debug": "^4.1.8",
|
|
44
|
+
"@types/jest": "^29.5.4",
|
|
45
|
+
"@types/jest-axe": "^3.5.5",
|
|
46
|
+
"@types/jquery": "^3.5.18",
|
|
47
|
+
"@types/node": "^20.6.0",
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "^6.7.0",
|
|
49
|
+
"@typescript-eslint/parser": "^6.7.0",
|
|
50
|
+
"autoprefixer": "^10.4.15",
|
|
51
|
+
"babel-jest": "^29.7.0",
|
|
55
52
|
"babel-plugin-istanbul": "^6.1.1",
|
|
56
|
-
"eslint": "^8.
|
|
57
|
-
"eslint-plugin-import": "^2.
|
|
58
|
-
"eslint-plugin-jest": "^27.
|
|
59
|
-
"eslint-plugin-playwright": "^0.
|
|
60
|
-
"eslint-plugin-testing-library": "^
|
|
53
|
+
"eslint": "^8.49.0",
|
|
54
|
+
"eslint-plugin-import": "^2.28.1",
|
|
55
|
+
"eslint-plugin-jest": "^27.2.3",
|
|
56
|
+
"eslint-plugin-playwright": "^0.16.0",
|
|
57
|
+
"eslint-plugin-testing-library": "^6.0.1",
|
|
61
58
|
"givens": "^1.3.9",
|
|
62
|
-
"graphql": "^16.
|
|
63
|
-
"jest": "^29.
|
|
64
|
-
"jest-
|
|
65
|
-
"jest-
|
|
59
|
+
"graphql": "^16.8.0",
|
|
60
|
+
"jest": "^29.7.0",
|
|
61
|
+
"jest-axe": "^8.0.0",
|
|
62
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
63
|
+
"jest-extended": "^4.0.1",
|
|
66
64
|
"jsonfile": "^6.1.0",
|
|
67
65
|
"lodash.template": "^4.5.0",
|
|
68
|
-
"msw": "^
|
|
69
|
-
"
|
|
70
|
-
"playwright": "^1.29.1",
|
|
71
|
-
"postcss": "^8.4.20",
|
|
66
|
+
"msw": "^1.3.1",
|
|
67
|
+
"postcss": "^8.4.29",
|
|
72
68
|
"postcss-cli": "^10.1.0",
|
|
73
69
|
"postcss-import": "^15.1.0",
|
|
74
70
|
"postcss-load-config": "^4.0.1",
|
|
75
|
-
"postcss-nested": "^6.0.
|
|
76
|
-
"prettier": "^
|
|
77
|
-
"rollup": "^3.
|
|
71
|
+
"postcss-nested": "^6.0.1",
|
|
72
|
+
"prettier": "^3.0.3",
|
|
73
|
+
"rollup": "^3.29.1",
|
|
78
74
|
"rollup-plugin-serve": "^2.0.2",
|
|
79
|
-
"tslib": "^2.
|
|
80
|
-
"typescript": "
|
|
75
|
+
"tslib": "^2.6.2",
|
|
76
|
+
"typescript": "^5.2.2"
|
|
81
77
|
}
|
|
82
78
|
}
|
|
@@ -261,6 +261,10 @@ export class DragAndDropHandler {
|
|
|
261
261
|
const mid = (low + high) >> 1;
|
|
262
262
|
const area = this.hitAreas[mid];
|
|
263
263
|
|
|
264
|
+
if (!area) {
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
|
|
264
268
|
if (y < area.top) {
|
|
265
269
|
high = mid;
|
|
266
270
|
} else if (y > area.bottom) {
|
|
@@ -433,10 +437,18 @@ abstract class VisibleNodeIterator {
|
|
|
433
437
|
if (mustIterateInside) {
|
|
434
438
|
const childrenLength = node.children.length;
|
|
435
439
|
node.children.forEach((_, i) => {
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
+
const child = node.children[i];
|
|
441
|
+
|
|
442
|
+
if (child) {
|
|
443
|
+
if (i === childrenLength - 1) {
|
|
444
|
+
_iterateNode(child, null);
|
|
445
|
+
} else {
|
|
446
|
+
const nextChild = node.children[i + 1];
|
|
447
|
+
|
|
448
|
+
if (nextChild) {
|
|
449
|
+
_iterateNode(child, nextChild);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
440
452
|
}
|
|
441
453
|
});
|
|
442
454
|
|
|
@@ -639,12 +651,14 @@ export class HitAreasGenerator extends VisibleNodeIterator {
|
|
|
639
651
|
while (i < positionCount) {
|
|
640
652
|
const position = positionsInGroup[i];
|
|
641
653
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
654
|
+
if (position) {
|
|
655
|
+
hitAreas.push({
|
|
656
|
+
top: areaTop,
|
|
657
|
+
bottom: areaTop + areaHeight,
|
|
658
|
+
node: position.node,
|
|
659
|
+
position: position.position,
|
|
660
|
+
});
|
|
661
|
+
}
|
|
648
662
|
|
|
649
663
|
areaTop += areaHeight;
|
|
650
664
|
i += 1;
|
package/src/elementsRenderer.ts
CHANGED
|
@@ -2,21 +2,21 @@ import { getBoolString } from "./util";
|
|
|
2
2
|
import { Node } from "./node";
|
|
3
3
|
import { JqTreeWidget } from "./tree.jquery";
|
|
4
4
|
|
|
5
|
-
type IconElement =
|
|
5
|
+
type IconElement = string | HTMLElement | JQuery<HTMLElement>;
|
|
6
6
|
|
|
7
7
|
export default class ElementsRenderer {
|
|
8
|
-
public openedIconElement
|
|
9
|
-
public closedIconElement
|
|
8
|
+
public openedIconElement?: HTMLElement | Text;
|
|
9
|
+
public closedIconElement?: HTMLElement | Text;
|
|
10
10
|
private treeWidget: JqTreeWidget;
|
|
11
11
|
|
|
12
12
|
constructor(treeWidget: JqTreeWidget) {
|
|
13
13
|
this.treeWidget = treeWidget;
|
|
14
14
|
|
|
15
15
|
this.openedIconElement = this.createButtonElement(
|
|
16
|
-
treeWidget.options.openedIcon || "+"
|
|
16
|
+
treeWidget.options.openedIcon || "+",
|
|
17
17
|
);
|
|
18
18
|
this.closedIconElement = this.createButtonElement(
|
|
19
|
-
treeWidget.options.closedIcon || "-"
|
|
19
|
+
treeWidget.options.closedIcon || "-",
|
|
20
20
|
);
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -32,12 +32,14 @@ export default class ElementsRenderer {
|
|
|
32
32
|
const $element = this.treeWidget.element;
|
|
33
33
|
$element.empty();
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
if ($element[0]) {
|
|
36
|
+
this.createDomElements(
|
|
37
|
+
$element[0],
|
|
38
|
+
this.treeWidget.tree.children,
|
|
39
|
+
true,
|
|
40
|
+
1,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
public renderFromNode(node: Node): void {
|
|
@@ -60,7 +62,7 @@ export default class ElementsRenderer {
|
|
|
60
62
|
li,
|
|
61
63
|
node.children,
|
|
62
64
|
false,
|
|
63
|
-
node.getLevel() + 1
|
|
65
|
+
node.getLevel() + 1,
|
|
64
66
|
);
|
|
65
67
|
}
|
|
66
68
|
}
|
|
@@ -69,7 +71,7 @@ export default class ElementsRenderer {
|
|
|
69
71
|
element: Element,
|
|
70
72
|
children: Node[],
|
|
71
73
|
isRootNode: boolean,
|
|
72
|
-
level: number
|
|
74
|
+
level: number,
|
|
73
75
|
): void {
|
|
74
76
|
const ul = this.createUl(isRootNode);
|
|
75
77
|
element.appendChild(ul);
|
|
@@ -121,7 +123,7 @@ export default class ElementsRenderer {
|
|
|
121
123
|
|
|
122
124
|
private createLi(node: Node, level: number): HTMLLIElement {
|
|
123
125
|
const isSelected = Boolean(
|
|
124
|
-
this.treeWidget.selectNodeHandler.isNodeSelected(node)
|
|
126
|
+
this.treeWidget.selectNodeHandler.isNodeSelected(node),
|
|
125
127
|
);
|
|
126
128
|
|
|
127
129
|
const mustShowFolder =
|
|
@@ -139,10 +141,22 @@ export default class ElementsRenderer {
|
|
|
139
141
|
return li;
|
|
140
142
|
}
|
|
141
143
|
|
|
144
|
+
private setTreeItemAriaAttributes(
|
|
145
|
+
element: HTMLElement,
|
|
146
|
+
name: string,
|
|
147
|
+
level: number,
|
|
148
|
+
isSelected: boolean,
|
|
149
|
+
) {
|
|
150
|
+
element.setAttribute("aria-label", name);
|
|
151
|
+
element.setAttribute("aria-level", `${level}`);
|
|
152
|
+
element.setAttribute("aria-selected", getBoolString(isSelected));
|
|
153
|
+
element.setAttribute("role", "treeitem");
|
|
154
|
+
}
|
|
155
|
+
|
|
142
156
|
private createFolderLi(
|
|
143
157
|
node: Node,
|
|
144
158
|
level: number,
|
|
145
|
-
isSelected: boolean
|
|
159
|
+
isSelected: boolean,
|
|
146
160
|
): HTMLLIElement {
|
|
147
161
|
const buttonClasses = this.getButtonClasses(node);
|
|
148
162
|
const folderClasses = this.getFolderClasses(node, isSelected);
|
|
@@ -154,12 +168,12 @@ export default class ElementsRenderer {
|
|
|
154
168
|
// li
|
|
155
169
|
const li = document.createElement("li");
|
|
156
170
|
li.className = `jqtree_common ${folderClasses}`;
|
|
157
|
-
li.setAttribute("role", "
|
|
171
|
+
li.setAttribute("role", "none");
|
|
158
172
|
|
|
159
173
|
// div
|
|
160
174
|
const div = document.createElement("div");
|
|
161
175
|
div.className = "jqtree-element jqtree_common";
|
|
162
|
-
div.setAttribute("role", "
|
|
176
|
+
div.setAttribute("role", "none");
|
|
163
177
|
|
|
164
178
|
li.appendChild(div);
|
|
165
179
|
|
|
@@ -167,25 +181,23 @@ export default class ElementsRenderer {
|
|
|
167
181
|
const buttonLink = document.createElement("a");
|
|
168
182
|
buttonLink.className = buttonClasses;
|
|
169
183
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
buttonLink.setAttribute("aria-hidden", "true");
|
|
184
|
+
if (iconElement) {
|
|
185
|
+
buttonLink.appendChild(iconElement.cloneNode(true));
|
|
186
|
+
}
|
|
174
187
|
|
|
175
188
|
if (this.treeWidget.options.buttonLeft) {
|
|
176
189
|
div.appendChild(buttonLink);
|
|
177
190
|
}
|
|
178
191
|
|
|
179
192
|
// title span
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
node.is_open,
|
|
186
|
-
true
|
|
187
|
-
)
|
|
193
|
+
const titleSpan = this.createTitleSpan(
|
|
194
|
+
node.name,
|
|
195
|
+
isSelected,
|
|
196
|
+
true,
|
|
197
|
+
level,
|
|
188
198
|
);
|
|
199
|
+
titleSpan.setAttribute("aria-expanded", getBoolString(node.is_open));
|
|
200
|
+
div.appendChild(titleSpan);
|
|
189
201
|
|
|
190
202
|
if (!this.treeWidget.options.buttonLeft) {
|
|
191
203
|
div.appendChild(buttonLink);
|
|
@@ -197,7 +209,7 @@ export default class ElementsRenderer {
|
|
|
197
209
|
private createNodeLi(
|
|
198
210
|
node: Node,
|
|
199
211
|
level: number,
|
|
200
|
-
isSelected: boolean
|
|
212
|
+
isSelected: boolean,
|
|
201
213
|
): HTMLLIElement {
|
|
202
214
|
const liClasses = ["jqtree_common"];
|
|
203
215
|
|
|
@@ -210,35 +222,32 @@ export default class ElementsRenderer {
|
|
|
210
222
|
// li
|
|
211
223
|
const li = document.createElement("li");
|
|
212
224
|
li.className = classString;
|
|
213
|
-
li.setAttribute("role", "
|
|
225
|
+
li.setAttribute("role", "none");
|
|
214
226
|
|
|
215
227
|
// div
|
|
216
228
|
const div = document.createElement("div");
|
|
217
229
|
div.className = "jqtree-element jqtree_common";
|
|
218
|
-
div.setAttribute("role", "
|
|
230
|
+
div.setAttribute("role", "none");
|
|
219
231
|
|
|
220
232
|
li.appendChild(div);
|
|
221
233
|
|
|
222
234
|
// title span
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
node.is_open,
|
|
229
|
-
false
|
|
230
|
-
)
|
|
235
|
+
const titleSpan = this.createTitleSpan(
|
|
236
|
+
node.name,
|
|
237
|
+
isSelected,
|
|
238
|
+
false,
|
|
239
|
+
level,
|
|
231
240
|
);
|
|
241
|
+
div.appendChild(titleSpan);
|
|
232
242
|
|
|
233
243
|
return li;
|
|
234
244
|
}
|
|
235
245
|
|
|
236
246
|
private createTitleSpan(
|
|
237
247
|
nodeName: string,
|
|
238
|
-
level: number,
|
|
239
248
|
isSelected: boolean,
|
|
240
|
-
|
|
241
|
-
|
|
249
|
+
isFolder: boolean,
|
|
250
|
+
level: number,
|
|
242
251
|
): HTMLSpanElement {
|
|
243
252
|
const titleSpan = document.createElement("span");
|
|
244
253
|
|
|
@@ -254,12 +263,6 @@ export default class ElementsRenderer {
|
|
|
254
263
|
|
|
255
264
|
titleSpan.className = classes;
|
|
256
265
|
|
|
257
|
-
titleSpan.setAttribute("role", "treeitem");
|
|
258
|
-
titleSpan.setAttribute("aria-level", `${level}`);
|
|
259
|
-
|
|
260
|
-
titleSpan.setAttribute("aria-selected", getBoolString(isSelected));
|
|
261
|
-
titleSpan.setAttribute("aria-expanded", getBoolString(isOpen));
|
|
262
|
-
|
|
263
266
|
if (isSelected) {
|
|
264
267
|
const tabIndex = this.treeWidget.options.tabIndex;
|
|
265
268
|
|
|
@@ -268,6 +271,8 @@ export default class ElementsRenderer {
|
|
|
268
271
|
}
|
|
269
272
|
}
|
|
270
273
|
|
|
274
|
+
this.setTreeItemAriaAttributes(titleSpan, nodeName, level, isSelected);
|
|
275
|
+
|
|
271
276
|
if (this.treeWidget.options.autoEscape) {
|
|
272
277
|
titleSpan.textContent = nodeName;
|
|
273
278
|
} else {
|
|
@@ -311,7 +316,9 @@ export default class ElementsRenderer {
|
|
|
311
316
|
return classes.join(" ");
|
|
312
317
|
}
|
|
313
318
|
|
|
314
|
-
private createButtonElement(
|
|
319
|
+
private createButtonElement(
|
|
320
|
+
value: IconElement,
|
|
321
|
+
): HTMLElement | Text | undefined {
|
|
315
322
|
if (typeof value === "string") {
|
|
316
323
|
// convert value to html
|
|
317
324
|
const div = document.createElement("div");
|
package/src/jqtreeOptions.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Node } from "./node";
|
|
|
3
3
|
type CanMoveNodeTo = (
|
|
4
4
|
node: Node,
|
|
5
5
|
targetNode: Node,
|
|
6
|
-
positionName: string
|
|
6
|
+
positionName: string,
|
|
7
7
|
) => boolean;
|
|
8
8
|
type CreateLi = (node: Node, el: JQuery, isSelected: boolean) => void;
|
|
9
9
|
type DataFilter = (data: unknown) => NodeData[];
|
|
@@ -13,15 +13,15 @@ type DragMethod = (node: Node, event: Event | Touch) => void;
|
|
|
13
13
|
type HandleLoadingMethod = (
|
|
14
14
|
isLoading: boolean,
|
|
15
15
|
node: Node | null,
|
|
16
|
-
$el: JQuery
|
|
16
|
+
$el: JQuery,
|
|
17
17
|
) => void;
|
|
18
18
|
|
|
19
19
|
export interface JQTreeOptions {
|
|
20
|
-
animationSpeed:
|
|
20
|
+
animationSpeed: JQuery.Duration;
|
|
21
21
|
autoEscape: boolean;
|
|
22
22
|
autoOpen: boolean | number;
|
|
23
23
|
buttonLeft: boolean;
|
|
24
|
-
closedIcon
|
|
24
|
+
closedIcon?: string | HTMLElement | JQuery<HTMLElement>;
|
|
25
25
|
data: NodeData[] | undefined;
|
|
26
26
|
dataFilter: DataFilter | undefined;
|
|
27
27
|
dataUrl: DataUrl | undefined;
|
|
@@ -39,7 +39,7 @@ export interface JQTreeOptions {
|
|
|
39
39
|
onLoadFailed: ((response: JQuery.jqXHR) => void) | undefined;
|
|
40
40
|
onLoading: HandleLoadingMethod | undefined;
|
|
41
41
|
onSetStateFromStorage: ((data: string) => void) | undefined;
|
|
42
|
-
openedIcon
|
|
42
|
+
openedIcon?: string | HTMLElement | JQuery<HTMLElement>;
|
|
43
43
|
openFolderDelay: number | false;
|
|
44
44
|
rtl: boolean | undefined;
|
|
45
45
|
selectable: boolean;
|
package/src/mouse.widget.ts
CHANGED
|
@@ -219,6 +219,10 @@ abstract class MouseWidget<WidgetOptions> extends SimpleWidget<WidgetOptions> {
|
|
|
219
219
|
|
|
220
220
|
const touch = e.changedTouches[0];
|
|
221
221
|
|
|
222
|
+
if (!touch) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
222
226
|
this.handleMouseDown(getPositionInfoFromTouch(touch, e));
|
|
223
227
|
};
|
|
224
228
|
|
|
@@ -233,6 +237,10 @@ abstract class MouseWidget<WidgetOptions> extends SimpleWidget<WidgetOptions> {
|
|
|
233
237
|
|
|
234
238
|
const touch = e.changedTouches[0];
|
|
235
239
|
|
|
240
|
+
if (!touch) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
236
244
|
this.handleMouseMove(e, getPositionInfoFromTouch(touch, e));
|
|
237
245
|
};
|
|
238
246
|
|
|
@@ -247,6 +255,10 @@ abstract class MouseWidget<WidgetOptions> extends SimpleWidget<WidgetOptions> {
|
|
|
247
255
|
|
|
248
256
|
const touch = e.changedTouches[0];
|
|
249
257
|
|
|
258
|
+
if (!touch) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
250
262
|
this.handleMouseUp(getPositionInfoFromTouch(touch, e));
|
|
251
263
|
};
|
|
252
264
|
}
|
package/src/node.ts
CHANGED
|
@@ -518,7 +518,7 @@ export class Node implements INode {
|
|
|
518
518
|
} else {
|
|
519
519
|
const previousIndex = this.parent.getChildIndex(this) - 1;
|
|
520
520
|
if (previousIndex >= 0) {
|
|
521
|
-
return this.parent.children[previousIndex];
|
|
521
|
+
return this.parent.children[previousIndex] || null;
|
|
522
522
|
} else {
|
|
523
523
|
return null;
|
|
524
524
|
}
|
|
@@ -531,7 +531,7 @@ export class Node implements INode {
|
|
|
531
531
|
} else {
|
|
532
532
|
const nextIndex = this.parent.getChildIndex(this) + 1;
|
|
533
533
|
if (nextIndex < this.parent.children.length) {
|
|
534
|
-
return this.parent.children[nextIndex];
|
|
534
|
+
return this.parent.children[nextIndex] || null;
|
|
535
535
|
} else {
|
|
536
536
|
return null;
|
|
537
537
|
}
|
|
@@ -558,7 +558,7 @@ export class Node implements INode {
|
|
|
558
558
|
|
|
559
559
|
public getNextNode(includeChildren = true): Node | null {
|
|
560
560
|
if (includeChildren && this.hasChildren()) {
|
|
561
|
-
return this.children[0];
|
|
561
|
+
return this.children[0] || null;
|
|
562
562
|
} else if (!this.parent) {
|
|
563
563
|
return null;
|
|
564
564
|
} else {
|
|
@@ -575,7 +575,7 @@ export class Node implements INode {
|
|
|
575
575
|
public getNextVisibleNode(): Node | null {
|
|
576
576
|
if (this.hasChildren() && this.is_open) {
|
|
577
577
|
// First child
|
|
578
|
-
return this.children[0];
|
|
578
|
+
return this.children[0] || null;
|
|
579
579
|
} else {
|
|
580
580
|
if (!this.parent) {
|
|
581
581
|
return null;
|
|
@@ -646,10 +646,15 @@ export class Node implements INode {
|
|
|
646
646
|
return null;
|
|
647
647
|
} else {
|
|
648
648
|
const lastChild = this.children[this.children.length - 1];
|
|
649
|
+
|
|
650
|
+
if (!lastChild) {
|
|
651
|
+
return null;
|
|
652
|
+
}
|
|
653
|
+
|
|
649
654
|
if (!(lastChild.hasChildren() && lastChild.is_open)) {
|
|
650
655
|
return lastChild;
|
|
651
656
|
} else {
|
|
652
|
-
return lastChild
|
|
657
|
+
return lastChild?.getLastChild();
|
|
653
658
|
}
|
|
654
659
|
}
|
|
655
660
|
}
|
package/src/nodeElement.ts
CHANGED
|
@@ -34,7 +34,7 @@ export class NodeElement {
|
|
|
34
34
|
if (this.mustShowBorderDropHint(position)) {
|
|
35
35
|
return new BorderDropHint(
|
|
36
36
|
this.$element,
|
|
37
|
-
this.treeWidget._getScrollLeft()
|
|
37
|
+
this.treeWidget._getScrollLeft(),
|
|
38
38
|
);
|
|
39
39
|
} else {
|
|
40
40
|
return new GhostDropHint(this.node, this.$element, position);
|
|
@@ -45,10 +45,10 @@ export class NodeElement {
|
|
|
45
45
|
const $li = this.getLi();
|
|
46
46
|
|
|
47
47
|
$li.addClass("jqtree-selected");
|
|
48
|
-
$li.attr("aria-selected", "true");
|
|
49
48
|
|
|
50
49
|
const $span = this.getSpan();
|
|
51
50
|
$span.attr("tabindex", this.treeWidget.options.tabIndex ?? null);
|
|
51
|
+
$span.attr("aria-selected", "true");
|
|
52
52
|
|
|
53
53
|
if (mustSetFocus) {
|
|
54
54
|
$span.trigger("focus");
|
|
@@ -59,12 +59,12 @@ export class NodeElement {
|
|
|
59
59
|
const $li = this.getLi();
|
|
60
60
|
|
|
61
61
|
$li.removeClass("jqtree-selected");
|
|
62
|
-
$li.attr("aria-selected", "false");
|
|
63
62
|
|
|
64
63
|
const $span = this.getSpan();
|
|
65
64
|
$span.removeAttr("tabindex");
|
|
65
|
+
$span.attr("aria-selected", "false");
|
|
66
66
|
|
|
67
|
-
$span.blur
|
|
67
|
+
$span.trigger("blur");
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
protected getUl(): JQuery<HTMLElement> {
|
|
@@ -81,7 +81,7 @@ export class NodeElement {
|
|
|
81
81
|
return this.$element;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
protected mustShowBorderDropHint(position:
|
|
84
|
+
protected mustShowBorderDropHint(position: Position): boolean {
|
|
85
85
|
return position === Position.Inside;
|
|
86
86
|
}
|
|
87
87
|
}
|
|
@@ -90,7 +90,7 @@ export class FolderElement extends NodeElement {
|
|
|
90
90
|
public open(
|
|
91
91
|
onFinished: OnFinishOpenNode | null,
|
|
92
92
|
slide = true,
|
|
93
|
-
animationSpeed: JQuery.Duration
|
|
93
|
+
animationSpeed: JQuery.Duration = "fast",
|
|
94
94
|
): void {
|
|
95
95
|
if (this.node.is_open) {
|
|
96
96
|
return;
|
|
@@ -105,18 +105,21 @@ export class FolderElement extends NodeElement {
|
|
|
105
105
|
const buttonEl = $button.get(0);
|
|
106
106
|
|
|
107
107
|
if (buttonEl) {
|
|
108
|
-
const
|
|
109
|
-
this.treeWidget.renderer.openedIconElement
|
|
108
|
+
const openedIconElement =
|
|
109
|
+
this.treeWidget.renderer.openedIconElement;
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
if (openedIconElement) {
|
|
112
|
+
const icon = openedIconElement.cloneNode(true);
|
|
113
|
+
buttonEl.appendChild(icon);
|
|
114
|
+
}
|
|
112
115
|
}
|
|
113
116
|
|
|
114
117
|
const doOpen = (): void => {
|
|
115
118
|
const $li = this.getLi();
|
|
116
119
|
$li.removeClass("jqtree-closed");
|
|
117
120
|
|
|
118
|
-
const $
|
|
119
|
-
$
|
|
121
|
+
const $titleSpan = this.getSpan();
|
|
122
|
+
$titleSpan.attr("aria-expanded", "true");
|
|
120
123
|
|
|
121
124
|
if (onFinished) {
|
|
122
125
|
onFinished(this.node);
|
|
@@ -137,7 +140,7 @@ export class FolderElement extends NodeElement {
|
|
|
137
140
|
|
|
138
141
|
public close(
|
|
139
142
|
slide = true,
|
|
140
|
-
animationSpeed: JQuery.Duration |
|
|
143
|
+
animationSpeed: JQuery.Duration | undefined = "fast",
|
|
141
144
|
): void {
|
|
142
145
|
if (!this.node.is_open) {
|
|
143
146
|
return;
|
|
@@ -152,18 +155,21 @@ export class FolderElement extends NodeElement {
|
|
|
152
155
|
const buttonEl = $button.get(0);
|
|
153
156
|
|
|
154
157
|
if (buttonEl) {
|
|
155
|
-
const
|
|
156
|
-
this.treeWidget.renderer.closedIconElement
|
|
158
|
+
const closedIconElement =
|
|
159
|
+
this.treeWidget.renderer.closedIconElement;
|
|
157
160
|
|
|
158
|
-
|
|
161
|
+
if (closedIconElement) {
|
|
162
|
+
const icon = closedIconElement.cloneNode(true);
|
|
163
|
+
buttonEl.appendChild(icon);
|
|
164
|
+
}
|
|
159
165
|
}
|
|
160
166
|
|
|
161
167
|
const doClose = (): void => {
|
|
162
168
|
const $li = this.getLi();
|
|
163
169
|
$li.addClass("jqtree-closed");
|
|
164
170
|
|
|
165
|
-
const $
|
|
166
|
-
$
|
|
171
|
+
const $titleSpan = this.getSpan();
|
|
172
|
+
$titleSpan.attr("aria-expanded", "false");
|
|
167
173
|
|
|
168
174
|
this.treeWidget._triggerEvent("tree.close", {
|
|
169
175
|
node: this.node,
|
|
@@ -178,7 +184,7 @@ export class FolderElement extends NodeElement {
|
|
|
178
184
|
}
|
|
179
185
|
}
|
|
180
186
|
|
|
181
|
-
protected mustShowBorderDropHint(position:
|
|
187
|
+
protected mustShowBorderDropHint(position: Position): boolean {
|
|
182
188
|
return !this.node.is_open && position === Position.Inside;
|
|
183
189
|
}
|
|
184
190
|
|
|
@@ -217,13 +223,13 @@ class GhostDropHint implements DropHint {
|
|
|
217
223
|
private node: Node;
|
|
218
224
|
private $ghost: JQuery;
|
|
219
225
|
|
|
220
|
-
constructor(node: Node, $element: JQuery<Element>, position:
|
|
226
|
+
constructor(node: Node, $element: JQuery<Element>, position: Position) {
|
|
221
227
|
this.$element = $element;
|
|
222
228
|
|
|
223
229
|
this.node = node;
|
|
224
230
|
this.$ghost = jQuery(
|
|
225
231
|
`<li class="jqtree_common jqtree-ghost"><span class="jqtree_common jqtree-circle"></span>
|
|
226
|
-
<span class="jqtree_common jqtree-line"></span></li
|
|
232
|
+
<span class="jqtree_common jqtree-line"></span></li>`,
|
|
227
233
|
);
|
|
228
234
|
|
|
229
235
|
if (position === Position.After) {
|
|
@@ -252,7 +258,7 @@ class GhostDropHint implements DropHint {
|
|
|
252
258
|
}
|
|
253
259
|
|
|
254
260
|
public moveInsideOpenFolder(): void {
|
|
255
|
-
const childElement = this.node.children[0]
|
|
261
|
+
const childElement = this.node.children[0]?.element;
|
|
256
262
|
|
|
257
263
|
if (childElement) {
|
|
258
264
|
jQuery(childElement).before(this.$ghost);
|