jqtree 1.7.5 → 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/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 +7 -0
- package/package.json +5 -1
- 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 -30
- package/src/mouse.widget.ts +3 -3
- package/src/mouseWidgetTypes.ts +6 -0
- 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/playwright/coverage.ts +1 -4
- package/src/playwright/playwright.test.ts +0 -4
- package/src/saveStateHandler.ts +75 -26
- package/src/scrollHandler.ts +13 -7
- package/src/selectNodeHandler.ts +10 -16
- package/src/test/jqTree/keyboard.test.ts +18 -23
- package/src/test/jqTree/methods.test.ts +32 -3
- package/src/test/jqTree/options.test.ts +15 -4
- package/src/test/node.test.ts +1 -1
- package/src/tree.jquery.ts +239 -57
- package/src/util.ts +3 -0
- package/src/version.ts +1 -1
- package/tree.jquery.debug.js +1728 -2576
- 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 -123
- package/lib/dragAndDropHandler.js +0 -588
- package/lib/elementsRenderer.js +0 -267
- package/lib/jqtreeOptions.js +0 -1
- package/lib/keyHandler.js +0 -111
- package/lib/mouse.widget.js +0 -255
- package/lib/node.js +0 -708
- package/lib/nodeElement.js +0 -274
- package/lib/nodeUtils.js +0 -10
- package/lib/playwright/coverage.js +0 -99
- package/lib/playwright/playwright.test.js +0 -606
- package/lib/playwright/testUtils.js +0 -210
- package/lib/saveStateHandler.js +0 -277
- package/lib/scrollHandler/containerScrollParent.js +0 -160
- package/lib/scrollHandler/createScrollParent.js +0 -57
- package/lib/scrollHandler/documentScrollParent.js +0 -169
- package/lib/scrollHandler/scrollParent.js +0 -58
- package/lib/scrollHandler/types.js +0 -1
- package/lib/scrollHandler.js +0 -71
- package/lib/selectNodeHandler.js +0 -128
- package/lib/simple.widget.js +0 -158
- 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 -1348
- package/lib/test/jqTree/options.test.js +0 -548
- package/lib/test/jqTree/scrollHandler/containerScrollParent.test.js +0 -94
- package/lib/test/node.test.js +0 -1202
- package/lib/test/nodeUtil.test.js +0 -27
- package/lib/test/nodeUtils.test.js +0 -20
- package/lib/test/support/exampleData.js +0 -35
- 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 -29
- package/lib/test/support/treeStructure.js +0 -38
- package/lib/test/util.test.js +0 -26
- package/lib/tree.jquery.d.js +0 -1
- package/lib/tree.jquery.js +0 -1105
- package/lib/types.js +0 -1
- package/lib/typings.d.js +0 -2
- package/lib/util.js +0 -15
- package/lib/version.js +0 -8
- package/src/dragAndDropHandler.ts +0 -713
- package/src/nodeElement.ts +0 -272
- package/src/types.ts +0 -19
package/bower.json
CHANGED
package/config/babel.config.json
CHANGED
package/config/production
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>JqTree devserver</title>
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<meta
|
|
8
|
+
name="description"
|
|
9
|
+
content="JqTree is a jQuery widget for displaying a tree structure in html"
|
|
10
|
+
/>
|
|
11
|
+
<link rel="stylesheet" href="/jqtree.css" />
|
|
12
|
+
<style>
|
|
13
|
+
body {
|
|
14
|
+
font-size: 20px;
|
|
15
|
+
}
|
|
16
|
+
ul.jqtree-tree ul.jqtree_common {
|
|
17
|
+
margin-left: 128px;
|
|
18
|
+
}
|
|
19
|
+
</style>
|
|
20
|
+
</head>
|
|
21
|
+
<body>
|
|
22
|
+
<div id="tree1"></div>
|
|
23
|
+
</body>
|
|
24
|
+
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
|
|
25
|
+
<script src="/tree.jquery.js"></script>
|
|
26
|
+
<script src="/example_data.js"></script>
|
|
27
|
+
<script src="/devserver_scroll.js"></script>
|
|
28
|
+
</html>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>JqTree devserver</title>
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<meta
|
|
8
|
+
name="description"
|
|
9
|
+
content="JqTree is a jQuery widget for displaying a tree structure in html"
|
|
10
|
+
/>
|
|
11
|
+
<link rel="stylesheet" href="/jqtree.css" />
|
|
12
|
+
<style>
|
|
13
|
+
body {
|
|
14
|
+
font-size: 20px;
|
|
15
|
+
}
|
|
16
|
+
ul.jqtree-tree ul.jqtree_common {
|
|
17
|
+
margin-left: 128px;
|
|
18
|
+
}
|
|
19
|
+
#scroll-container {
|
|
20
|
+
height: 200px;
|
|
21
|
+
width: 400px;
|
|
22
|
+
overflow-y: scroll;
|
|
23
|
+
user-select: none;
|
|
24
|
+
background-color: #eee;
|
|
25
|
+
margin: 128px;
|
|
26
|
+
padding: 8px;
|
|
27
|
+
}
|
|
28
|
+
</style>
|
|
29
|
+
</head>
|
|
30
|
+
<body>
|
|
31
|
+
<div id="scroll-container">
|
|
32
|
+
<div id="tree1"></div>
|
|
33
|
+
</div>
|
|
34
|
+
</body>
|
|
35
|
+
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
|
|
36
|
+
<script src="/tree.jquery.js"></script>
|
|
37
|
+
<script src="/example_data.js"></script>
|
|
38
|
+
<script src="/devserver_scroll.js"></script>
|
|
39
|
+
</html>
|
package/docs/_config.yml
CHANGED
|
@@ -3,6 +3,13 @@ title: Changelog
|
|
|
3
3
|
name: changelog
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
#### 1.8.0 (november 26 2023)
|
|
7
|
+
|
|
8
|
+
This release drops support for very old browsers (like IE 11).
|
|
9
|
+
|
|
10
|
+
- Issue #735: compile to es6. This decreases the file size to 49K (from 62K). This is the minified (not gzipped) version.
|
|
11
|
+
- Issue #766: open parent nodes in the addToSelection method (thanks to Tmgarcia)
|
|
12
|
+
|
|
6
13
|
#### 1.7.5 (october 21 2023)
|
|
7
14
|
|
|
8
15
|
- Issue #734: fix autoscroll issue (thanks to WriterStat)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jqtree",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Tree widget for jQuery",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jquery-plugin",
|
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
"playwright": "pnpm build-with-coverage && playwright test --config config/playwright.config.js",
|
|
29
29
|
"test": "pnpm jest && pnpm playwright"
|
|
30
30
|
},
|
|
31
|
+
"browserslist": [
|
|
32
|
+
"defaults"
|
|
33
|
+
],
|
|
31
34
|
"peerDependencies": {
|
|
32
35
|
"jquery": "^3"
|
|
33
36
|
},
|
|
@@ -41,6 +44,7 @@
|
|
|
41
44
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
42
45
|
"@rollup/plugin-terser": "^0.4.4",
|
|
43
46
|
"@testing-library/dom": "^9.3.3",
|
|
47
|
+
"@testing-library/user-event": "^14.5.1",
|
|
44
48
|
"@types/debug": "^4.1.10",
|
|
45
49
|
"@types/jest": "^29.5.6",
|
|
46
50
|
"@types/jest-axe": "^3.5.7",
|
package/src/dataLoader.ts
CHANGED
|
@@ -1,19 +1,46 @@
|
|
|
1
1
|
import { Node } from "./node";
|
|
2
|
-
import {
|
|
2
|
+
import { DataFilter, OnLoadFailed, OnLoading } from "./jqtreeOptions";
|
|
3
|
+
import { LoadData, TriggerEvent } from "./jqtreeMethodTypes";
|
|
3
4
|
|
|
4
5
|
export type HandleFinishedLoading = () => void;
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
interface DataLoaderParams {
|
|
8
|
+
dataFilter?: DataFilter;
|
|
9
|
+
loadData: LoadData;
|
|
10
|
+
onLoadFailed?: OnLoadFailed;
|
|
11
|
+
onLoading?: OnLoading;
|
|
12
|
+
$treeElement: JQuery<HTMLElement>;
|
|
13
|
+
triggerEvent: TriggerEvent;
|
|
14
|
+
}
|
|
8
15
|
|
|
9
|
-
|
|
10
|
-
|
|
16
|
+
export default class DataLoader {
|
|
17
|
+
private dataFilter?: DataFilter;
|
|
18
|
+
private loadData: LoadData;
|
|
19
|
+
private onLoadFailed?: OnLoadFailed;
|
|
20
|
+
private onLoading?: OnLoading;
|
|
21
|
+
private $treeElement: JQuery<HTMLElement>;
|
|
22
|
+
private triggerEvent: TriggerEvent;
|
|
23
|
+
|
|
24
|
+
constructor({
|
|
25
|
+
dataFilter,
|
|
26
|
+
loadData,
|
|
27
|
+
onLoadFailed,
|
|
28
|
+
onLoading,
|
|
29
|
+
$treeElement,
|
|
30
|
+
triggerEvent,
|
|
31
|
+
}: DataLoaderParams) {
|
|
32
|
+
this.dataFilter = dataFilter;
|
|
33
|
+
this.loadData = loadData;
|
|
34
|
+
this.onLoadFailed = onLoadFailed;
|
|
35
|
+
this.onLoading = onLoading;
|
|
36
|
+
this.$treeElement = $treeElement;
|
|
37
|
+
this.triggerEvent = triggerEvent;
|
|
11
38
|
}
|
|
12
39
|
|
|
13
40
|
public loadFromUrl(
|
|
14
41
|
urlInfo: string | JQuery.AjaxSettings | null,
|
|
15
42
|
parentNode: Node | null,
|
|
16
|
-
onFinished: HandleFinishedLoading | null
|
|
43
|
+
onFinished: HandleFinishedLoading | null,
|
|
17
44
|
): void {
|
|
18
45
|
if (!urlInfo) {
|
|
19
46
|
return;
|
|
@@ -30,7 +57,7 @@ export default class DataLoader {
|
|
|
30
57
|
|
|
31
58
|
const handleSuccess = (data: string | NodeData[]): void => {
|
|
32
59
|
stopLoading();
|
|
33
|
-
this.
|
|
60
|
+
this.loadData(this.parseData(data), parentNode);
|
|
34
61
|
|
|
35
62
|
if (onFinished && typeof onFinished === "function") {
|
|
36
63
|
onFinished();
|
|
@@ -40,8 +67,8 @@ export default class DataLoader {
|
|
|
40
67
|
const handleError = (jqXHR: JQuery.jqXHR): void => {
|
|
41
68
|
stopLoading();
|
|
42
69
|
|
|
43
|
-
if (this.
|
|
44
|
-
this.
|
|
70
|
+
if (this.onLoadFailed) {
|
|
71
|
+
this.onLoadFailed(jqXHR);
|
|
45
72
|
}
|
|
46
73
|
};
|
|
47
74
|
|
|
@@ -64,20 +91,20 @@ export default class DataLoader {
|
|
|
64
91
|
if (parentNode) {
|
|
65
92
|
return jQuery(parentNode.element);
|
|
66
93
|
} else {
|
|
67
|
-
return this
|
|
94
|
+
return this.$treeElement;
|
|
68
95
|
}
|
|
69
96
|
}
|
|
70
97
|
|
|
71
98
|
private notifyLoading(
|
|
72
99
|
isLoading: boolean,
|
|
73
100
|
node: Node | null,
|
|
74
|
-
$el: JQuery
|
|
101
|
+
$el: JQuery,
|
|
75
102
|
): void {
|
|
76
|
-
if (this.
|
|
77
|
-
this.
|
|
103
|
+
if (this.onLoading) {
|
|
104
|
+
this.onLoading(isLoading, node, $el);
|
|
78
105
|
}
|
|
79
106
|
|
|
80
|
-
this.
|
|
107
|
+
this.triggerEvent("tree.loading_data", {
|
|
81
108
|
isLoading,
|
|
82
109
|
node,
|
|
83
110
|
$el,
|
|
@@ -87,7 +114,7 @@ export default class DataLoader {
|
|
|
87
114
|
private submitRequest(
|
|
88
115
|
urlInfoInput: string | JQuery.AjaxSettings,
|
|
89
116
|
handleSuccess: JQuery.Ajax.SuccessCallback<any>,
|
|
90
|
-
handleError: JQuery.Ajax.ErrorCallback<any
|
|
117
|
+
handleError: JQuery.Ajax.ErrorCallback<any>,
|
|
91
118
|
): void {
|
|
92
119
|
const urlInfo =
|
|
93
120
|
typeof urlInfoInput === "string"
|
|
@@ -109,8 +136,6 @@ export default class DataLoader {
|
|
|
109
136
|
}
|
|
110
137
|
|
|
111
138
|
private parseData(data: string | NodeData[]): NodeData[] {
|
|
112
|
-
const { dataFilter } = this.treeWidget.options;
|
|
113
|
-
|
|
114
139
|
const getParsedData = () => {
|
|
115
140
|
if (typeof data === "string") {
|
|
116
141
|
return JSON.parse(data) as NodeData[];
|
|
@@ -121,8 +146,8 @@ export default class DataLoader {
|
|
|
121
146
|
|
|
122
147
|
const parsedData = getParsedData();
|
|
123
148
|
|
|
124
|
-
if (dataFilter) {
|
|
125
|
-
return dataFilter(parsedData);
|
|
149
|
+
if (this.dataFilter) {
|
|
150
|
+
return this.dataFilter(parsedData);
|
|
126
151
|
} else {
|
|
127
152
|
return parsedData;
|
|
128
153
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
class DragElement {
|
|
2
|
+
private offsetX: number;
|
|
3
|
+
private offsetY: number;
|
|
4
|
+
private $element: JQuery;
|
|
5
|
+
|
|
6
|
+
constructor(
|
|
7
|
+
nodeName: string,
|
|
8
|
+
offsetX: number,
|
|
9
|
+
offsetY: number,
|
|
10
|
+
$tree: JQuery,
|
|
11
|
+
autoEscape: boolean,
|
|
12
|
+
) {
|
|
13
|
+
this.offsetX = offsetX;
|
|
14
|
+
this.offsetY = offsetY;
|
|
15
|
+
|
|
16
|
+
this.$element = jQuery("<span>").addClass(
|
|
17
|
+
"jqtree-title jqtree-dragging",
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
if (autoEscape) {
|
|
21
|
+
this.$element.text(nodeName);
|
|
22
|
+
} else {
|
|
23
|
+
this.$element.html(nodeName);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
this.$element.css("position", "absolute");
|
|
27
|
+
$tree.append(this.$element);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public move(pageX: number, pageY: number): void {
|
|
31
|
+
this.$element.offset({
|
|
32
|
+
left: pageX - this.offsetX,
|
|
33
|
+
top: pageY - this.offsetY,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public remove(): void {
|
|
38
|
+
this.$element.remove();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default DragElement;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { HitArea } from "./types";
|
|
2
|
+
import { Node, Position } from "../node";
|
|
3
|
+
import { getOffsetTop } from "../util";
|
|
4
|
+
import VisibleNodeIterator from "./visibleNodeIterator";
|
|
5
|
+
|
|
6
|
+
class HitAreasGenerator extends VisibleNodeIterator {
|
|
7
|
+
private currentNode: Node;
|
|
8
|
+
private treeBottom: number;
|
|
9
|
+
private positions: HitArea[];
|
|
10
|
+
private lastTop: number;
|
|
11
|
+
|
|
12
|
+
constructor(tree: Node, currentNode: Node, treeBottom: number) {
|
|
13
|
+
super(tree);
|
|
14
|
+
|
|
15
|
+
this.currentNode = currentNode;
|
|
16
|
+
this.treeBottom = treeBottom;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public generate(): HitArea[] {
|
|
20
|
+
this.positions = [];
|
|
21
|
+
this.lastTop = 0;
|
|
22
|
+
|
|
23
|
+
this.iterate();
|
|
24
|
+
|
|
25
|
+
return this.generateHitAreas(this.positions);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
protected generateHitAreas(positions: HitArea[]): HitArea[] {
|
|
29
|
+
let previousTop = positions[0]?.top ?? 0;
|
|
30
|
+
let group = [];
|
|
31
|
+
const hitAreas: HitArea[] = [];
|
|
32
|
+
|
|
33
|
+
for (const position of positions) {
|
|
34
|
+
if (position.top !== previousTop && group.length) {
|
|
35
|
+
this.generateHitAreasForGroup(
|
|
36
|
+
hitAreas,
|
|
37
|
+
group,
|
|
38
|
+
previousTop,
|
|
39
|
+
position.top,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
previousTop = position.top;
|
|
43
|
+
group = [];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
group.push(position);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
this.generateHitAreasForGroup(
|
|
50
|
+
hitAreas,
|
|
51
|
+
group,
|
|
52
|
+
previousTop,
|
|
53
|
+
this.treeBottom,
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
return hitAreas;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
protected handleOpenFolder(node: Node, element: HTMLElement): boolean {
|
|
60
|
+
if (node === this.currentNode) {
|
|
61
|
+
// Cannot move inside current item
|
|
62
|
+
// Stop iterating
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Cannot move before current item
|
|
67
|
+
if (node.children[0] !== this.currentNode) {
|
|
68
|
+
this.addPosition(node, Position.Inside, getOffsetTop(element));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Continue iterating
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
protected handleClosedFolder(
|
|
76
|
+
node: Node,
|
|
77
|
+
nextNode: Node,
|
|
78
|
+
element: HTMLElement,
|
|
79
|
+
): void {
|
|
80
|
+
const top = getOffsetTop(element);
|
|
81
|
+
|
|
82
|
+
if (node === this.currentNode) {
|
|
83
|
+
// Cannot move after current item
|
|
84
|
+
this.addPosition(node, Position.None, top);
|
|
85
|
+
} else {
|
|
86
|
+
this.addPosition(node, Position.Inside, top);
|
|
87
|
+
|
|
88
|
+
// Cannot move before current item
|
|
89
|
+
if (nextNode !== this.currentNode) {
|
|
90
|
+
this.addPosition(node, Position.After, top);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
protected handleFirstNode(node: Node): void {
|
|
96
|
+
if (node !== this.currentNode) {
|
|
97
|
+
this.addPosition(node, Position.Before, getOffsetTop(node.element));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
protected handleAfterOpenFolder(node: Node, nextNode: Node): void {
|
|
102
|
+
if (node === this.currentNode || nextNode === this.currentNode) {
|
|
103
|
+
// Cannot move before or after current item
|
|
104
|
+
this.addPosition(node, Position.None, this.lastTop);
|
|
105
|
+
} else {
|
|
106
|
+
this.addPosition(node, Position.After, this.lastTop);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
protected handleNode(
|
|
111
|
+
node: Node,
|
|
112
|
+
nextNode: Node,
|
|
113
|
+
element: HTMLElement,
|
|
114
|
+
): void {
|
|
115
|
+
const top = getOffsetTop(element);
|
|
116
|
+
|
|
117
|
+
if (node === this.currentNode) {
|
|
118
|
+
// Cannot move inside current item
|
|
119
|
+
this.addPosition(node, Position.None, top);
|
|
120
|
+
} else {
|
|
121
|
+
this.addPosition(node, Position.Inside, top);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (nextNode === this.currentNode || node === this.currentNode) {
|
|
125
|
+
// Cannot move before or after current item
|
|
126
|
+
this.addPosition(node, Position.None, top);
|
|
127
|
+
} else {
|
|
128
|
+
this.addPosition(node, Position.After, top);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private addPosition(node: Node, position: number, top: number): void {
|
|
133
|
+
const area = {
|
|
134
|
+
top,
|
|
135
|
+
bottom: 0,
|
|
136
|
+
node,
|
|
137
|
+
position,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
this.positions.push(area);
|
|
141
|
+
this.lastTop = top;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private generateHitAreasForGroup(
|
|
145
|
+
hitAreas: HitArea[],
|
|
146
|
+
positionsInGroup: HitArea[],
|
|
147
|
+
top: number,
|
|
148
|
+
bottom: number,
|
|
149
|
+
): void {
|
|
150
|
+
// limit positions in group
|
|
151
|
+
const positionCount = Math.min(positionsInGroup.length, 4);
|
|
152
|
+
|
|
153
|
+
const areaHeight = Math.round((bottom - top) / positionCount);
|
|
154
|
+
let areaTop = top;
|
|
155
|
+
|
|
156
|
+
let i = 0;
|
|
157
|
+
while (i < positionCount) {
|
|
158
|
+
const position = positionsInGroup[i];
|
|
159
|
+
|
|
160
|
+
if (position) {
|
|
161
|
+
hitAreas.push({
|
|
162
|
+
top: areaTop,
|
|
163
|
+
bottom: areaTop + areaHeight,
|
|
164
|
+
node: position.node,
|
|
165
|
+
position: position.position,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
areaTop += areaHeight;
|
|
170
|
+
i += 1;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export default HitAreasGenerator;
|