jqtree 1.7.4 → 1.8.0
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/.eslintrc +5 -1
- package/bower.json +1 -1
- package/config/babel.config.json +1 -1
- package/config/production +2 -0
- package/devserver/devserver_scroll.js +8 -0
- package/devserver/test_scroll.html +28 -0
- package/devserver/test_scroll_container.html +39 -0
- package/docs/_config.yml +1 -1
- package/docs/_entries/general/changelog.md +12 -0
- package/docs/package.json +1 -1
- package/docs/pnpm-lock.yaml +30 -30
- package/package.json +31 -27
- package/src/dataLoader.ts +44 -19
- package/src/dragAndDropHandler/dragElement.ts +42 -0
- package/src/dragAndDropHandler/hitAreasGenerator.ts +175 -0
- package/src/dragAndDropHandler/index.ts +470 -0
- package/src/dragAndDropHandler/types.ts +12 -0
- package/src/dragAndDropHandler/visibleNodeIterator.ts +97 -0
- package/src/elementsRenderer.ts +75 -40
- package/src/jqtreeMethodTypes.ts +40 -0
- package/src/jqtreeOptions.ts +43 -25
- package/src/keyHandler.ts +59 -38
- package/src/mouse.widget.ts +3 -3
- package/src/mouseWidgetTypes.ts +6 -0
- package/src/node.ts +32 -48
- package/src/nodeElement/borderDropHint.ts +32 -0
- package/src/nodeElement/folderElement.ts +133 -0
- package/src/nodeElement/ghostDropHint.ts +68 -0
- package/src/nodeElement/index.ts +101 -0
- package/src/nodeUtils.ts +10 -0
- package/src/playwright/coverage.ts +1 -4
- package/src/playwright/playwright.test.ts +203 -15
- package/src/playwright/testUtils.ts +23 -15
- package/src/saveStateHandler.ts +75 -26
- package/src/scrollHandler/containerScrollParent.ts +177 -0
- package/src/scrollHandler/createScrollParent.ts +50 -0
- package/src/scrollHandler/documentScrollParent.ts +182 -0
- package/src/scrollHandler/types.ts +7 -0
- package/src/scrollHandler.ts +36 -248
- package/src/selectNodeHandler.ts +10 -16
- package/src/test/jqTree/keyboard.test.ts +18 -23
- package/src/test/jqTree/loadOnDemand.test.ts +2 -3
- package/src/test/jqTree/methods.test.ts +33 -4
- package/src/test/jqTree/options.test.ts +15 -4
- package/src/test/node.test.ts +85 -26
- package/src/test/nodeUtils.test.ts +21 -0
- package/src/tree.jquery.ts +262 -83
- package/src/util.ts +3 -0
- package/src/version.ts +1 -1
- package/tree.jquery.debug.js +1922 -2608
- package/tree.jquery.debug.js.map +1 -1
- package/tree.jquery.js +2 -2
- package/tree.jquery.js.map +1 -1
- package/lib/dataLoader.js +0 -124
- package/lib/dragAndDropHandler.js +0 -596
- package/lib/elementsRenderer.js +0 -268
- package/lib/jqtreeOptions.js +0 -1
- package/lib/keyHandler.js +0 -115
- package/lib/mouse.widget.js +0 -256
- package/lib/node.js +0 -717
- package/lib/nodeElement.js +0 -277
- package/lib/playwright/coverage.js +0 -96
- package/lib/playwright/playwright.test.js +0 -228
- package/lib/playwright/testUtils.js +0 -184
- package/lib/saveStateHandler.js +0 -278
- package/lib/scrollHandler.js +0 -250
- package/lib/selectNodeHandler.js +0 -129
- package/lib/simple.widget.js +0 -159
- package/lib/test/global.d.js +0 -3
- package/lib/test/jqTree/accessibility.test.js +0 -37
- package/lib/test/jqTree/create.test.js +0 -48
- package/lib/test/jqTree/events.test.js +0 -210
- package/lib/test/jqTree/keyboard.test.js +0 -225
- package/lib/test/jqTree/loadOnDemand.test.js +0 -218
- package/lib/test/jqTree/methods.test.js +0 -1347
- package/lib/test/jqTree/options.test.js +0 -548
- package/lib/test/node.test.js +0 -1160
- package/lib/test/nodeUtil.test.js +0 -27
- package/lib/test/support/exampleData.js +0 -36
- package/lib/test/support/jqTreeMatchers.js +0 -70
- package/lib/test/support/matchers.d.js +0 -1
- package/lib/test/support/setupTests.js +0 -7
- package/lib/test/support/testUtil.js +0 -32
- package/lib/test/support/treeStructure.js +0 -39
- package/lib/test/util.test.js +0 -26
- package/lib/tree.jquery.d.js +0 -1
- package/lib/tree.jquery.js +0 -1106
- package/lib/types.js +0 -1
- package/lib/typings.d.js +0 -2
- package/lib/util.js +0 -18
- package/lib/version.js +0 -9
- package/src/dragAndDropHandler.ts +0 -719
- package/src/nodeElement.ts +0 -272
- package/src/types.ts +0 -19
|
@@ -3,17 +3,12 @@ import {
|
|
|
3
3
|
dragAndDrop,
|
|
4
4
|
findNodeElement,
|
|
5
5
|
getTreeStructure,
|
|
6
|
+
moveMouseToNode,
|
|
6
7
|
selectNode,
|
|
7
8
|
} from "./testUtils";
|
|
8
9
|
import { initCoverage, saveCoverage } from "./coverage";
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
baseURL?: string;
|
|
12
|
-
dragAndDrop: boolean;
|
|
13
|
-
page: Page;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const initPage = async ({ baseURL, dragAndDrop, page }: InitPageParameters) => {
|
|
11
|
+
const initPage = async (page: Page, baseURL: string | undefined) => {
|
|
17
12
|
if (!baseURL) {
|
|
18
13
|
throw new Error("Missing baseURL");
|
|
19
14
|
}
|
|
@@ -22,22 +17,28 @@ const initPage = async ({ baseURL, dragAndDrop, page }: InitPageParameters) => {
|
|
|
22
17
|
await page.waitForLoadState("domcontentloaded");
|
|
23
18
|
|
|
24
19
|
page.on("console", (msg) => console.log(`console: ${msg.text()}`));
|
|
20
|
+
};
|
|
25
21
|
|
|
22
|
+
interface InitTreeOptions {
|
|
23
|
+
autoOpen?: number;
|
|
24
|
+
dragAndDrop?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const initTree = async (
|
|
28
|
+
page: Page,
|
|
29
|
+
{ autoOpen, dragAndDrop }: InitTreeOptions,
|
|
30
|
+
) => {
|
|
26
31
|
await page.evaluate(`
|
|
27
32
|
const $tree = jQuery("#tree1");
|
|
28
33
|
|
|
29
34
|
$tree.tree({
|
|
30
35
|
animationSpeed: 0,
|
|
31
|
-
autoOpen: 0,
|
|
36
|
+
autoOpen: ${autoOpen || 0},
|
|
32
37
|
data: ExampleData.exampleData,
|
|
33
|
-
dragAndDrop: ${dragAndDrop},
|
|
38
|
+
dragAndDrop: ${dragAndDrop || false},
|
|
34
39
|
startDndDelay: 100,
|
|
35
40
|
});
|
|
36
41
|
`);
|
|
37
|
-
|
|
38
|
-
await page.evaluate(`
|
|
39
|
-
console.log(window.__coverage__ ? 'Coverage enabled' : 'Coverage not enabled');
|
|
40
|
-
`);
|
|
41
42
|
};
|
|
42
43
|
|
|
43
44
|
test.beforeEach(async ({ context }) => {
|
|
@@ -50,7 +51,8 @@ test.afterEach(async ({ context }) => {
|
|
|
50
51
|
|
|
51
52
|
test.describe("without dragAndDrop", () => {
|
|
52
53
|
test.beforeEach(async ({ baseURL, page }) => {
|
|
53
|
-
await initPage(
|
|
54
|
+
await initPage(page, baseURL);
|
|
55
|
+
await initTree(page, { dragAndDrop: false });
|
|
54
56
|
});
|
|
55
57
|
|
|
56
58
|
test("displays a tree", async ({ page }) => {
|
|
@@ -75,7 +77,8 @@ test.describe("without dragAndDrop", () => {
|
|
|
75
77
|
|
|
76
78
|
test.describe("with dragAndDrop", () => {
|
|
77
79
|
test.beforeEach(async ({ baseURL, page }) => {
|
|
78
|
-
await initPage(
|
|
80
|
+
await initPage(page, baseURL);
|
|
81
|
+
await initTree(page, { dragAndDrop: true });
|
|
79
82
|
});
|
|
80
83
|
|
|
81
84
|
test("moves a node", async ({ page }) => {
|
|
@@ -110,3 +113,188 @@ test.describe("with dragAndDrop", () => {
|
|
|
110
113
|
expect(screenshot).toMatchSnapshot();
|
|
111
114
|
});
|
|
112
115
|
});
|
|
116
|
+
|
|
117
|
+
test.describe("autoscroll when the window is scrollable", () => {
|
|
118
|
+
test("it scrolls vertically when the users drags an element to the bottom ", async ({
|
|
119
|
+
baseURL,
|
|
120
|
+
page,
|
|
121
|
+
}) => {
|
|
122
|
+
await page.setViewportSize({ width: 200, height: 100 });
|
|
123
|
+
await initPage(page, baseURL);
|
|
124
|
+
await initTree(page, { autoOpen: 3, dragAndDrop: true });
|
|
125
|
+
|
|
126
|
+
expect(
|
|
127
|
+
await page
|
|
128
|
+
.getByRole("document")
|
|
129
|
+
.evaluate((element) => element.scrollTop),
|
|
130
|
+
).toEqual(0);
|
|
131
|
+
|
|
132
|
+
await moveMouseToNode(page, "Saurischia");
|
|
133
|
+
await page.mouse.down();
|
|
134
|
+
|
|
135
|
+
// eslint-disable-next-line playwright/no-wait-for-timeout
|
|
136
|
+
await page.waitForTimeout(200);
|
|
137
|
+
|
|
138
|
+
await page.mouse.move(20, 190);
|
|
139
|
+
// eslint-disable-next-line playwright/no-wait-for-timeout
|
|
140
|
+
await page.waitForTimeout(50);
|
|
141
|
+
|
|
142
|
+
expect(
|
|
143
|
+
await page
|
|
144
|
+
.getByRole("document")
|
|
145
|
+
.evaluate((element) => element.scrollTop),
|
|
146
|
+
).toBeGreaterThan(0);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test("it scrolls horizontally when the users drags an element to the right", async ({
|
|
150
|
+
baseURL,
|
|
151
|
+
page,
|
|
152
|
+
}) => {
|
|
153
|
+
await page.setViewportSize({ width: 60, height: 400 });
|
|
154
|
+
await initPage(page, baseURL);
|
|
155
|
+
await initTree(page, { autoOpen: 3, dragAndDrop: true });
|
|
156
|
+
|
|
157
|
+
expect(
|
|
158
|
+
await page
|
|
159
|
+
.getByRole("document")
|
|
160
|
+
.evaluate((element) => element.scrollLeft),
|
|
161
|
+
).toEqual(0);
|
|
162
|
+
|
|
163
|
+
await moveMouseToNode(page, "Saurischia");
|
|
164
|
+
await page.mouse.down();
|
|
165
|
+
|
|
166
|
+
// eslint-disable-next-line playwright/no-wait-for-timeout
|
|
167
|
+
await page.waitForTimeout(200);
|
|
168
|
+
|
|
169
|
+
await page.mouse.move(55, 10);
|
|
170
|
+
// eslint-disable-next-line playwright/no-wait-for-timeout
|
|
171
|
+
await page.waitForTimeout(50);
|
|
172
|
+
|
|
173
|
+
expect(
|
|
174
|
+
await page
|
|
175
|
+
.getByRole("document")
|
|
176
|
+
.evaluate((element) => element.scrollLeft),
|
|
177
|
+
).toBeGreaterThan(0);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test("scrollToNode scrolls to a node", async ({ baseURL, page }) => {
|
|
181
|
+
await page.setViewportSize({ width: 200, height: 100 });
|
|
182
|
+
await initPage(page, baseURL);
|
|
183
|
+
await initTree(page, { autoOpen: 3, dragAndDrop: true });
|
|
184
|
+
|
|
185
|
+
expect(
|
|
186
|
+
await page
|
|
187
|
+
.getByRole("document")
|
|
188
|
+
.evaluate((element) => element.scrollTop),
|
|
189
|
+
).toEqual(0);
|
|
190
|
+
|
|
191
|
+
await page.evaluate(`
|
|
192
|
+
const $tree = jQuery("#tree1");
|
|
193
|
+
const node = $tree.tree("getNodeByName", "Sauropodomorphs");
|
|
194
|
+
$tree.tree("scrollToNode",node);
|
|
195
|
+
`);
|
|
196
|
+
|
|
197
|
+
expect(
|
|
198
|
+
await page
|
|
199
|
+
.getByRole("document")
|
|
200
|
+
.evaluate((element) => element.scrollTop),
|
|
201
|
+
).toBeGreaterThan(0);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test.describe("autoscroll when the container is scrollable", () => {
|
|
206
|
+
test.beforeEach(async ({ page, baseURL }) => {
|
|
207
|
+
await initPage(page, baseURL);
|
|
208
|
+
|
|
209
|
+
// Add a container and make it the parent of the tree element
|
|
210
|
+
await page.evaluate(`
|
|
211
|
+
document.body.style.marginLeft = "40px";
|
|
212
|
+
document.body.style.marginTop = "40px";
|
|
213
|
+
|
|
214
|
+
const treeElement = document.querySelector("#tree1");
|
|
215
|
+
|
|
216
|
+
const container = document.createElement("div");
|
|
217
|
+
container.id = "container";
|
|
218
|
+
container.style.height = "200px";
|
|
219
|
+
container.style.width = "60px";
|
|
220
|
+
container.style.overflowY = "scroll";
|
|
221
|
+
|
|
222
|
+
document.body.replaceChild(container, treeElement);
|
|
223
|
+
container.appendChild(treeElement);
|
|
224
|
+
`);
|
|
225
|
+
|
|
226
|
+
await initTree(page, { autoOpen: 3, dragAndDrop: true });
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
test("it scrolls vertically when the users drags an element to the bottom", async ({
|
|
230
|
+
page,
|
|
231
|
+
}) => {
|
|
232
|
+
expect(
|
|
233
|
+
await page
|
|
234
|
+
.locator("#container")
|
|
235
|
+
.evaluate((element) => element.scrollTop),
|
|
236
|
+
).toEqual(0);
|
|
237
|
+
|
|
238
|
+
await moveMouseToNode(page, "Saurischia");
|
|
239
|
+
await page.mouse.down();
|
|
240
|
+
|
|
241
|
+
// eslint-disable-next-line playwright/no-wait-for-timeout
|
|
242
|
+
await page.waitForTimeout(200);
|
|
243
|
+
|
|
244
|
+
await page.mouse.move(20, 245);
|
|
245
|
+
// eslint-disable-next-line playwright/no-wait-for-timeout
|
|
246
|
+
await page.waitForTimeout(50);
|
|
247
|
+
|
|
248
|
+
expect(
|
|
249
|
+
await page
|
|
250
|
+
.locator("#container")
|
|
251
|
+
.evaluate((element) => element.scrollTop),
|
|
252
|
+
).toBeGreaterThan(0);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
test("it scrolls horizontally when the users drags an element to the right", async ({
|
|
256
|
+
page,
|
|
257
|
+
}) => {
|
|
258
|
+
expect(
|
|
259
|
+
await page
|
|
260
|
+
.locator("#container")
|
|
261
|
+
.evaluate((element) => element.scrollLeft),
|
|
262
|
+
).toEqual(0);
|
|
263
|
+
|
|
264
|
+
await moveMouseToNode(page, "Saurischia");
|
|
265
|
+
await page.mouse.down();
|
|
266
|
+
|
|
267
|
+
// eslint-disable-next-line playwright/no-wait-for-timeout
|
|
268
|
+
await page.waitForTimeout(200);
|
|
269
|
+
|
|
270
|
+
await page.mouse.move(100, 50);
|
|
271
|
+
// eslint-disable-next-line playwright/no-wait-for-timeout
|
|
272
|
+
await page.waitForTimeout(50);
|
|
273
|
+
|
|
274
|
+
expect(
|
|
275
|
+
await page
|
|
276
|
+
.locator("#container")
|
|
277
|
+
.evaluate((element) => element.scrollLeft),
|
|
278
|
+
).toBeGreaterThan(0);
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
test("scrollToNode scrolls to a node", async ({ page }) => {
|
|
282
|
+
expect(
|
|
283
|
+
await page
|
|
284
|
+
.locator("#container")
|
|
285
|
+
.evaluate((element) => element.scrollTop),
|
|
286
|
+
).toEqual(0);
|
|
287
|
+
|
|
288
|
+
await page.evaluate(`
|
|
289
|
+
const $tree = jQuery("#tree1");
|
|
290
|
+
const node = $tree.tree("getNodeByName", "Sauropodomorphs");
|
|
291
|
+
$tree.tree("scrollToNode",node);
|
|
292
|
+
`);
|
|
293
|
+
|
|
294
|
+
expect(
|
|
295
|
+
await page
|
|
296
|
+
.locator("#container")
|
|
297
|
+
.evaluate((element) => element.scrollTop),
|
|
298
|
+
).toBeGreaterThan(0);
|
|
299
|
+
});
|
|
300
|
+
});
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { Page, ElementHandle } from "@playwright/test";
|
|
2
2
|
|
|
3
|
+
interface BoundingBox {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
const locateTitle = (page: Page, title: string) =>
|
|
4
11
|
page.locator(".jqtree-title", {
|
|
5
12
|
hasText: title,
|
|
@@ -35,7 +42,9 @@ export const selectNode = async (nodeElement: ElementHandle) => {
|
|
|
35
42
|
await titleHandle.click();
|
|
36
43
|
};
|
|
37
44
|
|
|
38
|
-
const getRect = async (
|
|
45
|
+
const getRect = async (
|
|
46
|
+
elementHandle: ElementHandle<HTMLElement>,
|
|
47
|
+
): Promise<BoundingBox> => {
|
|
39
48
|
const boundingBox = await elementHandle.boundingBox();
|
|
40
49
|
|
|
41
50
|
if (!boundingBox) {
|
|
@@ -88,7 +97,7 @@ export const getTreeStructure = async (page: Page) => {
|
|
|
88
97
|
return JSON.parse(structure) as JQTreeMatchers.TreeStructure;
|
|
89
98
|
};
|
|
90
99
|
|
|
91
|
-
const getNodeRect = async (page: Page, title: string) => {
|
|
100
|
+
const getNodeRect = async (page: Page, title: string): Promise<BoundingBox> => {
|
|
92
101
|
const titleElement = await locateTitle(page, title).elementHandle();
|
|
93
102
|
|
|
94
103
|
if (!titleElement) {
|
|
@@ -99,24 +108,23 @@ const getNodeRect = async (page: Page, title: string) => {
|
|
|
99
108
|
return rect;
|
|
100
109
|
};
|
|
101
110
|
|
|
111
|
+
export const moveMouseToNode = async (page: Page, title: string) => {
|
|
112
|
+
const rect = await getNodeRect(page, title);
|
|
113
|
+
|
|
114
|
+
await page.mouse.move(rect.x + 10, rect.y + rect.height / 2);
|
|
115
|
+
};
|
|
116
|
+
|
|
102
117
|
export const dragAndDrop = async (
|
|
103
118
|
page: Page,
|
|
104
|
-
|
|
105
|
-
|
|
119
|
+
fromTitle: string,
|
|
120
|
+
toTitle: string,
|
|
106
121
|
): Promise<void> => {
|
|
107
|
-
|
|
108
|
-
const toRect = await getNodeRect(page, to);
|
|
109
|
-
|
|
110
|
-
await page.mouse.move(
|
|
111
|
-
fromRect.x + fromRect.width / 2,
|
|
112
|
-
fromRect.y + fromRect.height / 2
|
|
113
|
-
);
|
|
122
|
+
await moveMouseToNode(page, fromTitle);
|
|
114
123
|
await page.mouse.down();
|
|
124
|
+
|
|
115
125
|
// eslint-disable-next-line playwright/no-wait-for-timeout
|
|
116
126
|
await page.waitForTimeout(200);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
toRect.y + toRect.height / 2
|
|
120
|
-
);
|
|
127
|
+
|
|
128
|
+
await moveMouseToNode(page, toTitle);
|
|
121
129
|
await page.mouse.up();
|
|
122
130
|
};
|
package/src/saveStateHandler.ts
CHANGED
|
@@ -1,25 +1,76 @@
|
|
|
1
1
|
import { isInt } from "./util";
|
|
2
|
-
import { JqTreeWidget } from "./tree.jquery";
|
|
3
2
|
import { Node } from "./node";
|
|
3
|
+
import { OnGetStateFromStorage, OnSetStateFromStorage } from "./jqtreeOptions";
|
|
4
|
+
import {
|
|
5
|
+
AddToSelection,
|
|
6
|
+
GetNodeById,
|
|
7
|
+
GetSelectedNodes,
|
|
8
|
+
GetTree,
|
|
9
|
+
OpenNode,
|
|
10
|
+
RefreshElements,
|
|
11
|
+
RemoveFromSelection,
|
|
12
|
+
} from "./jqtreeMethodTypes";
|
|
4
13
|
|
|
5
14
|
export interface SavedState {
|
|
6
15
|
open_nodes: NodeId[];
|
|
7
16
|
selected_node: NodeId[];
|
|
8
17
|
}
|
|
9
18
|
|
|
19
|
+
interface SaveStateHandlerParams {
|
|
20
|
+
addToSelection: AddToSelection;
|
|
21
|
+
getNodeById: GetNodeById;
|
|
22
|
+
getSelectedNodes: GetSelectedNodes;
|
|
23
|
+
getTree: GetTree;
|
|
24
|
+
onGetStateFromStorage?: OnGetStateFromStorage;
|
|
25
|
+
onSetStateFromStorage?: OnSetStateFromStorage;
|
|
26
|
+
openNode: OpenNode;
|
|
27
|
+
refreshElements: RefreshElements;
|
|
28
|
+
removeFromSelection: RemoveFromSelection;
|
|
29
|
+
saveState: boolean | string;
|
|
30
|
+
}
|
|
31
|
+
|
|
10
32
|
export default class SaveStateHandler {
|
|
11
|
-
private
|
|
33
|
+
private addToSelection: AddToSelection;
|
|
34
|
+
private getNodeById: GetNodeById;
|
|
35
|
+
private getSelectedNodes: GetSelectedNodes;
|
|
36
|
+
private getTree: GetTree;
|
|
37
|
+
private onGetStateFromStorage?: OnGetStateFromStorage;
|
|
38
|
+
private onSetStateFromStorage?: OnSetStateFromStorage;
|
|
39
|
+
private openNode: OpenNode;
|
|
40
|
+
private refreshElements: RefreshElements;
|
|
41
|
+
private removeFromSelection: RemoveFromSelection;
|
|
42
|
+
private saveStateOption: boolean | string;
|
|
12
43
|
private _supportsLocalStorage: boolean | null;
|
|
13
44
|
|
|
14
|
-
constructor(
|
|
15
|
-
|
|
45
|
+
constructor({
|
|
46
|
+
addToSelection,
|
|
47
|
+
getNodeById,
|
|
48
|
+
getSelectedNodes,
|
|
49
|
+
getTree,
|
|
50
|
+
onGetStateFromStorage,
|
|
51
|
+
onSetStateFromStorage,
|
|
52
|
+
openNode,
|
|
53
|
+
refreshElements,
|
|
54
|
+
removeFromSelection,
|
|
55
|
+
saveState,
|
|
56
|
+
}: SaveStateHandlerParams) {
|
|
57
|
+
this.addToSelection = addToSelection;
|
|
58
|
+
this.getNodeById = getNodeById;
|
|
59
|
+
this.getSelectedNodes = getSelectedNodes;
|
|
60
|
+
this.getTree = getTree;
|
|
61
|
+
this.onGetStateFromStorage = onGetStateFromStorage;
|
|
62
|
+
this.onSetStateFromStorage = onSetStateFromStorage;
|
|
63
|
+
this.openNode = openNode;
|
|
64
|
+
this.refreshElements = refreshElements;
|
|
65
|
+
this.removeFromSelection = removeFromSelection;
|
|
66
|
+
this.saveStateOption = saveState;
|
|
16
67
|
}
|
|
17
68
|
|
|
18
69
|
public saveState(): void {
|
|
19
70
|
const state = JSON.stringify(this.getState());
|
|
20
71
|
|
|
21
|
-
if (this.
|
|
22
|
-
this.
|
|
72
|
+
if (this.onSetStateFromStorage) {
|
|
73
|
+
this.onSetStateFromStorage(state);
|
|
23
74
|
} else if (this.supportsLocalStorage()) {
|
|
24
75
|
localStorage.setItem(this.getKeyName(), state);
|
|
25
76
|
}
|
|
@@ -39,7 +90,7 @@ export default class SaveStateHandler {
|
|
|
39
90
|
const getOpenNodeIds = (): NodeId[] => {
|
|
40
91
|
const openNodes: NodeId[] = [];
|
|
41
92
|
|
|
42
|
-
this.
|
|
93
|
+
this.getTree()?.iterate((node: Node) => {
|
|
43
94
|
if (node.is_open && node.id && node.hasChildren()) {
|
|
44
95
|
openNodes.push(node.id);
|
|
45
96
|
}
|
|
@@ -52,7 +103,7 @@ export default class SaveStateHandler {
|
|
|
52
103
|
const getSelectedNodeIds = (): NodeId[] => {
|
|
53
104
|
const selectedNodeIds: NodeId[] = [];
|
|
54
105
|
|
|
55
|
-
this.
|
|
106
|
+
this.getSelectedNodes().forEach((node) => {
|
|
56
107
|
if (node.id != null) {
|
|
57
108
|
selectedNodeIds.push(node.id);
|
|
58
109
|
}
|
|
@@ -94,13 +145,13 @@ export default class SaveStateHandler {
|
|
|
94
145
|
|
|
95
146
|
public setInitialStateOnDemand(
|
|
96
147
|
state: SavedState,
|
|
97
|
-
cbFinished: () => void
|
|
148
|
+
cbFinished: () => void,
|
|
98
149
|
): void {
|
|
99
150
|
if (state) {
|
|
100
151
|
this.doSetInitialStateOnDemand(
|
|
101
152
|
state.open_nodes,
|
|
102
153
|
state.selected_node,
|
|
103
|
-
cbFinished
|
|
154
|
+
cbFinished,
|
|
104
155
|
);
|
|
105
156
|
} else {
|
|
106
157
|
cbFinished();
|
|
@@ -130,8 +181,8 @@ export default class SaveStateHandler {
|
|
|
130
181
|
}
|
|
131
182
|
|
|
132
183
|
private loadFromStorage(): string | null {
|
|
133
|
-
if (this.
|
|
134
|
-
return this.
|
|
184
|
+
if (this.onGetStateFromStorage) {
|
|
185
|
+
return this.onGetStateFromStorage();
|
|
135
186
|
} else if (this.supportsLocalStorage()) {
|
|
136
187
|
return localStorage.getItem(this.getKeyName());
|
|
137
188
|
} else {
|
|
@@ -143,7 +194,7 @@ export default class SaveStateHandler {
|
|
|
143
194
|
let mustLoadOnDemand = false;
|
|
144
195
|
|
|
145
196
|
for (const nodeId of nodeIds) {
|
|
146
|
-
const node = this.
|
|
197
|
+
const node = this.getNodeById(nodeId);
|
|
147
198
|
|
|
148
199
|
if (node) {
|
|
149
200
|
if (!node.load_on_demand) {
|
|
@@ -161,12 +212,12 @@ export default class SaveStateHandler {
|
|
|
161
212
|
let selectCount = 0;
|
|
162
213
|
|
|
163
214
|
for (const nodeId of nodeIds) {
|
|
164
|
-
const node = this.
|
|
215
|
+
const node = this.getNodeById(nodeId);
|
|
165
216
|
|
|
166
217
|
if (node) {
|
|
167
218
|
selectCount += 1;
|
|
168
219
|
|
|
169
|
-
this.
|
|
220
|
+
this.addToSelection(node);
|
|
170
221
|
}
|
|
171
222
|
}
|
|
172
223
|
|
|
@@ -174,19 +225,17 @@ export default class SaveStateHandler {
|
|
|
174
225
|
}
|
|
175
226
|
|
|
176
227
|
private resetSelection(): void {
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
const selectedNodes = selectNodeHandler.getSelectedNodes();
|
|
228
|
+
const selectedNodes = this.getSelectedNodes();
|
|
180
229
|
|
|
181
230
|
selectedNodes.forEach((node) => {
|
|
182
|
-
|
|
231
|
+
this.removeFromSelection(node);
|
|
183
232
|
});
|
|
184
233
|
}
|
|
185
234
|
|
|
186
235
|
private doSetInitialStateOnDemand(
|
|
187
236
|
nodeIdsParam: NodeId[],
|
|
188
237
|
selectedNodes: NodeId[],
|
|
189
|
-
cbFinished: () => void
|
|
238
|
+
cbFinished: () => void,
|
|
190
239
|
): void {
|
|
191
240
|
let loadingCount = 0;
|
|
192
241
|
let nodeIds = nodeIdsParam;
|
|
@@ -195,7 +244,7 @@ export default class SaveStateHandler {
|
|
|
195
244
|
const newNodesIds = [];
|
|
196
245
|
|
|
197
246
|
for (const nodeId of nodeIds) {
|
|
198
|
-
const node = this.
|
|
247
|
+
const node = this.getNodeById(nodeId);
|
|
199
248
|
|
|
200
249
|
if (!node) {
|
|
201
250
|
newNodesIds.push(nodeId);
|
|
@@ -204,7 +253,7 @@ export default class SaveStateHandler {
|
|
|
204
253
|
if (node.load_on_demand) {
|
|
205
254
|
loadAndOpenNode(node);
|
|
206
255
|
} else {
|
|
207
|
-
this.
|
|
256
|
+
this.openNode(node, false);
|
|
208
257
|
}
|
|
209
258
|
}
|
|
210
259
|
}
|
|
@@ -213,7 +262,7 @@ export default class SaveStateHandler {
|
|
|
213
262
|
nodeIds = newNodesIds;
|
|
214
263
|
|
|
215
264
|
if (this.selectInitialNodes(selectedNodes)) {
|
|
216
|
-
this.
|
|
265
|
+
this.refreshElements(null);
|
|
217
266
|
}
|
|
218
267
|
|
|
219
268
|
if (loadingCount === 0) {
|
|
@@ -223,7 +272,7 @@ export default class SaveStateHandler {
|
|
|
223
272
|
|
|
224
273
|
const loadAndOpenNode = (node: Node): void => {
|
|
225
274
|
loadingCount += 1;
|
|
226
|
-
this.
|
|
275
|
+
this.openNode(node, false, () => {
|
|
227
276
|
loadingCount -= 1;
|
|
228
277
|
openNodes();
|
|
229
278
|
});
|
|
@@ -233,8 +282,8 @@ export default class SaveStateHandler {
|
|
|
233
282
|
}
|
|
234
283
|
|
|
235
284
|
private getKeyName(): string {
|
|
236
|
-
if (typeof this.
|
|
237
|
-
return this.
|
|
285
|
+
if (typeof this.saveStateOption === "string") {
|
|
286
|
+
return this.saveStateOption;
|
|
238
287
|
} else {
|
|
239
288
|
return "tree";
|
|
240
289
|
}
|