jqtree 1.7.3 → 1.7.5

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.
Files changed (170) hide show
  1. package/.eslintrc +5 -1
  2. package/.github/workflows/static.yml +57 -0
  3. package/bower.json +1 -1
  4. package/css/jqtree.postcss +4 -0
  5. package/docs/.ruby-version +1 -0
  6. package/docs/Gemfile +5 -2
  7. package/docs/Gemfile.lock +30 -210
  8. package/docs/_config.yml +110 -10
  9. package/docs/_entries/{10_changelog.md → general/changelog.md} +11 -1
  10. package/docs/_entries/multiple_selection/get-selected-nodes.md +10 -0
  11. package/docs/package.json +1 -1
  12. package/docs/pnpm-lock.yaml +30 -30
  13. package/jqtree.css +4 -0
  14. package/lib/dataLoader.js +2 -3
  15. package/lib/dragAndDropHandler.js +16 -14
  16. package/lib/elementsRenderer.js +2 -3
  17. package/lib/keyHandler.js +1 -5
  18. package/lib/mouse.widget.js +1 -2
  19. package/lib/node.js +30 -39
  20. package/lib/nodeElement.js +3 -6
  21. package/lib/nodeUtils.js +10 -0
  22. package/lib/playwright/coverage.js +14 -11
  23. package/lib/playwright/playwright.test.js +482 -104
  24. package/lib/playwright/testUtils.js +75 -49
  25. package/lib/saveStateHandler.js +2 -3
  26. package/lib/scrollHandler/containerScrollParent.js +160 -0
  27. package/lib/scrollHandler/createScrollParent.js +57 -0
  28. package/lib/scrollHandler/documentScrollParent.js +169 -0
  29. package/lib/scrollHandler/scrollParent.js +58 -0
  30. package/lib/scrollHandler/types.js +1 -0
  31. package/lib/scrollHandler.js +28 -207
  32. package/lib/selectNodeHandler.js +2 -3
  33. package/lib/simple.widget.js +1 -2
  34. package/lib/test/jqTree/loadOnDemand.test.js +3 -3
  35. package/lib/test/jqTree/methods.test.js +2 -1
  36. package/lib/test/jqTree/scrollHandler/containerScrollParent.test.js +94 -0
  37. package/lib/test/node.test.js +49 -7
  38. package/lib/test/nodeUtils.test.js +20 -0
  39. package/lib/test/support/exampleData.js +1 -2
  40. package/lib/test/support/testUtil.js +3 -6
  41. package/lib/test/support/treeStructure.js +1 -2
  42. package/lib/tree.jquery.js +6 -7
  43. package/lib/util.js +4 -7
  44. package/lib/version.js +2 -3
  45. package/package.json +27 -27
  46. package/src/dragAndDropHandler.ts +39 -34
  47. package/src/keyHandler.ts +0 -8
  48. package/src/node.ts +32 -48
  49. package/src/nodeUtils.ts +10 -0
  50. package/src/playwright/playwright.test.ts +207 -15
  51. package/src/playwright/testUtils.ts +23 -15
  52. package/src/scrollHandler/containerScrollParent.ts +177 -0
  53. package/src/scrollHandler/createScrollParent.ts +50 -0
  54. package/src/scrollHandler/documentScrollParent.ts +182 -0
  55. package/src/scrollHandler/types.ts +7 -0
  56. package/src/scrollHandler.ts +25 -243
  57. package/src/test/jqTree/loadOnDemand.test.ts +2 -3
  58. package/src/test/jqTree/methods.test.ts +1 -1
  59. package/src/test/node.test.ts +84 -25
  60. package/src/test/nodeUtils.test.ts +21 -0
  61. package/src/tree.jquery.ts +27 -30
  62. package/src/version.ts +1 -1
  63. package/tree.jquery.debug.js +402 -230
  64. package/tree.jquery.debug.js.map +1 -1
  65. package/tree.jquery.js +2 -2
  66. package/tree.jquery.js.map +1 -1
  67. package/docs/_entries/insert.py +0 -46
  68. package/docs/_entries/renumber.py +0 -38
  69. package/docs/jqtree.css +0 -189
  70. package/docs/static/documentation.css +0 -1335
  71. package/docs/static/example.css +0 -63
  72. package/docs/tree.jquery.js +0 -21
  73. /package/docs/_entries/{72_events.md → events/index.md} +0 -0
  74. /package/docs/_entries/{73_tree-click.md → events/tree-click.md} +0 -0
  75. /package/docs/_entries/{74_tree-close.md → events/tree-close.md} +0 -0
  76. /package/docs/_entries/{75_tree-contextmenu.md → events/tree-contextmenu.md} +0 -0
  77. /package/docs/_entries/{76_tree-dblclick.md → events/tree-dblclick.md} +0 -0
  78. /package/docs/_entries/{77_tree-init.md → events/tree-init.md} +0 -0
  79. /package/docs/_entries/{78_tree-load-data.md → events/tree-load-data.md} +0 -0
  80. /package/docs/_entries/{79_tree-loading-data.md → events/tree-loading-data.md} +0 -0
  81. /package/docs/_entries/{80_tree-move.md → events/tree-move.md} +0 -0
  82. /package/docs/_entries/{82_tree-open.md → events/tree-open.md} +0 -0
  83. /package/docs/_entries/{81_tree-refresh.md → events/tree-refresh.md} +0 -0
  84. /package/docs/_entries/{83_tree-select.md → events/tree-select.md} +0 -0
  85. /package/docs/_entries/{43_addnodeafter.md → functions/addnodeafter.md} +0 -0
  86. /package/docs/_entries/{44_addnodebefore.md → functions/addnodebefore.md} +0 -0
  87. /package/docs/_entries/{42_addparentnode.md → functions/addparentnode.md} +0 -0
  88. /package/docs/_entries/{45_appendnode.md → functions/appendnode.md} +0 -0
  89. /package/docs/_entries/{46_closenode.md → functions/closenode.md} +0 -0
  90. /package/docs/_entries/{47_destroy.md → functions/destroy.md} +0 -0
  91. /package/docs/_entries/{86_get-selected-nodes.md → functions/get-selected-nodes.md} +0 -0
  92. /package/docs/_entries/{48_getnodebycallback.md → functions/getnodebycallback.md} +0 -0
  93. /package/docs/_entries/{50_getnodebyhtmlelement.md → functions/getnodebyhtmlelement.md} +0 -0
  94. /package/docs/_entries/{49_getnodebyid.md → functions/getnodebyid.md} +0 -0
  95. /package/docs/_entries/{51_getselectednode.md → functions/getselectednode.md} +0 -0
  96. /package/docs/_entries/{52_getstate.md → functions/getstate.md} +0 -0
  97. /package/docs/_entries/{53_gettree.md → functions/gettree.md} +0 -0
  98. /package/docs/_entries/{41_functions.md → functions/index.md} +0 -0
  99. /package/docs/_entries/{87_is-node-selected.md → functions/is-node-selected.md} +0 -0
  100. /package/docs/_entries/{54_isdragging.md → functions/isdragging.md} +0 -0
  101. /package/docs/_entries/{55_loaddata.md → functions/loaddata.md} +0 -0
  102. /package/docs/_entries/{56_loaddatafromurl.md → functions/loaddatafromurl.md} +0 -0
  103. /package/docs/_entries/{57_movedown.md → functions/movedown.md} +0 -0
  104. /package/docs/_entries/{58_movenode.md → functions/movenode.md} +0 -0
  105. /package/docs/_entries/{59_moveup.md → functions/moveup.md} +0 -0
  106. /package/docs/_entries/{60_opennode.md → functions/opennode.md} +0 -0
  107. /package/docs/_entries/{61_prependnode.md → functions/prependnode.md} +0 -0
  108. /package/docs/_entries/{62_refresh.md → functions/refresh.md} +0 -0
  109. /package/docs/_entries/{63_reload.md → functions/reload.md} +0 -0
  110. /package/docs/_entries/{64_removenode.md → functions/removenode.md} +0 -0
  111. /package/docs/_entries/{66_scrolltonode.md → functions/scrolltonode.md} +0 -0
  112. /package/docs/_entries/{65_selectnode.md → functions/selectnode.md} +0 -0
  113. /package/docs/_entries/{67_setoption.md → functions/setoption.md} +0 -0
  114. /package/docs/_entries/{68_setstate.md → functions/setstate.md} +0 -0
  115. /package/docs/_entries/{69_toggle.md → functions/toggle.md} +0 -0
  116. /package/docs/_entries/{70_tojson.md → functions/tojson.md} +0 -0
  117. /package/docs/_entries/{71_updatenode.md → functions/updatenode.md} +0 -0
  118. /package/docs/_entries/{04_demo.html → general/demo.html} +0 -0
  119. /package/docs/_entries/{06_downloads.md → general/downloads.md} +0 -0
  120. /package/docs/_entries/{08_examples.md → general/examples.md} +0 -0
  121. /package/docs/_entries/{03_features.md → general/features.md} +0 -0
  122. /package/docs/_entries/{01_general.md → general/index.md} +0 -0
  123. /package/docs/_entries/{02_introduction.md → general/introduction.md} +0 -0
  124. /package/docs/_entries/{05_requirements.md → general/requirements.md} +0 -0
  125. /package/docs/_entries/{07_tutorial.md → general/tutorial.md} +0 -0
  126. /package/docs/_entries/{09_usecases.md → general/usecases.md} +0 -0
  127. /package/docs/_entries/{85_add-to-selection.md → multiple_selection/add-to-selection.md} +0 -0
  128. /package/docs/_entries/{84_multiple-selection.md → multiple_selection/index.md} +0 -0
  129. /package/docs/_entries/{88_remove-from-selection.md → multiple_selection/remove-from-selection.md} +0 -0
  130. /package/docs/_entries/{90_children.md → node/children.md} +0 -0
  131. /package/docs/_entries/{91_getdata.md → node/getdata.md} +0 -0
  132. /package/docs/_entries/{92_getlevel.md → node/getlevel.md} +0 -0
  133. /package/docs/_entries/{93_getnextnode.md → node/getnextnode.md} +0 -0
  134. /package/docs/_entries/{94_getnextsibling.md → node/getnextsibling.md} +0 -0
  135. /package/docs/_entries/{95_getnextvisiblenode.md → node/getnextvisiblenode.md} +0 -0
  136. /package/docs/_entries/{96_getpreviousnode.md → node/getpreviousnode.md} +0 -0
  137. /package/docs/_entries/{97_getprevioussibling.md → node/getprevioussibling.md} +0 -0
  138. /package/docs/_entries/{98_getpreviousvisiblenode.md → node/getpreviousvisiblenode.md} +0 -0
  139. /package/docs/_entries/{89_node-functions.md → node/index.md} +0 -0
  140. /package/docs/_entries/{99_parent.md → node/parent.md} +0 -0
  141. /package/docs/_entries/{12_animationspeed.md → options/animationspeed.md} +0 -0
  142. /package/docs/_entries/{13_autoescape.md → options/autoescape.md} +0 -0
  143. /package/docs/_entries/{14_autoopen.md → options/autoopen.md} +0 -0
  144. /package/docs/_entries/{15_buttonleft.md → options/buttonleft.md} +0 -0
  145. /package/docs/_entries/{16_closedicon.md → options/closedicon.md} +0 -0
  146. /package/docs/_entries/{19_data-url.md → options/data-url.md} +0 -0
  147. /package/docs/_entries/{17_data.md → options/data.md} +0 -0
  148. /package/docs/_entries/{18_datafilter.md → options/datafilter.md} +0 -0
  149. /package/docs/_entries/{20_draganddrop.md → options/draganddrop.md} +0 -0
  150. /package/docs/_entries/{11_options.md → options/index.md} +0 -0
  151. /package/docs/_entries/{21_keyboardsupport.md → options/keyboardsupport.md} +0 -0
  152. /package/docs/_entries/{22_oncanmove.md → options/oncanmove.md} +0 -0
  153. /package/docs/_entries/{23_oncanmoveto.md → options/oncanmoveto.md} +0 -0
  154. /package/docs/_entries/{24_oncanselectnode.md → options/oncanselectnode.md} +0 -0
  155. /package/docs/_entries/{25_oncreateli.md → options/oncreateli.md} +0 -0
  156. /package/docs/_entries/{26_ondragmove.md → options/ondragmove.md} +0 -0
  157. /package/docs/_entries/{27_ondragstop.md → options/ondragstop.md} +0 -0
  158. /package/docs/_entries/{28_onismovehandle.md → options/onismovehandle.md} +0 -0
  159. /package/docs/_entries/{29_onloadfailed.md → options/onloadfailed.md} +0 -0
  160. /package/docs/_entries/{30_onloading.md → options/onloading.md} +0 -0
  161. /package/docs/_entries/{31_openedicon.md → options/openedicon.md} +0 -0
  162. /package/docs/_entries/{32_openfolderdelay.md → options/openfolderdelay.md} +0 -0
  163. /package/docs/_entries/{33_rtl.md → options/rtl.md} +0 -0
  164. /package/docs/_entries/{34_savestate.md → options/savestate.md} +0 -0
  165. /package/docs/_entries/{35_selectable.md → options/selectable.md} +0 -0
  166. /package/docs/_entries/{36_showemptyfolder.md → options/showemptyfolder.md} +0 -0
  167. /package/docs/_entries/{37_slide.md → options/slide.md} +0 -0
  168. /package/docs/_entries/{38_start_dnd_delay.md → options/start_dnd_delay.md} +0 -0
  169. /package/docs/_entries/{39_tabindex.md → options/tabindex.md} +0 -0
  170. /package/docs/_entries/{40_usecontextmenu.md → options/usecontextmenu.md} +0 -0
@@ -0,0 +1,182 @@
1
+ import type { ScrollParent } from "./types";
2
+
3
+ type HorizontalScrollDirection = "left" | "right";
4
+ type VerticalScrollDirection = "bottom" | "top";
5
+
6
+ export default class DocumentScrollParent implements ScrollParent {
7
+ private $element: JQuery<HTMLElement>;
8
+ private horizontalScrollDirection?: HorizontalScrollDirection;
9
+ private horizontalScrollTimeout?: number;
10
+ private refreshHitAreas: () => void;
11
+ private verticalScrollDirection?: VerticalScrollDirection;
12
+ private verticalScrollTimeout?: number;
13
+ private documentScrollHeight?: number;
14
+ private documentScrollWidth?: number;
15
+
16
+ constructor($element: JQuery<HTMLElement>, refreshHitAreas: () => void) {
17
+ this.$element = $element;
18
+ this.refreshHitAreas = refreshHitAreas;
19
+ }
20
+
21
+ public checkHorizontalScrolling(pageX: number): void {
22
+ const newHorizontalScrollDirection =
23
+ this.getNewHorizontalScrollDirection(pageX);
24
+
25
+ if (this.horizontalScrollDirection !== newHorizontalScrollDirection) {
26
+ this.horizontalScrollDirection = newHorizontalScrollDirection;
27
+
28
+ if (this.horizontalScrollTimeout != null) {
29
+ window.clearTimeout(this.horizontalScrollTimeout);
30
+ }
31
+
32
+ if (newHorizontalScrollDirection) {
33
+ this.horizontalScrollTimeout = window.setTimeout(
34
+ this.scrollHorizontally.bind(this),
35
+ 40,
36
+ );
37
+ }
38
+ }
39
+ }
40
+
41
+ public checkVerticalScrolling(pageY: number) {
42
+ const newVerticalScrollDirection =
43
+ this.getNewVerticalScrollDirection(pageY);
44
+
45
+ if (this.verticalScrollDirection !== newVerticalScrollDirection) {
46
+ this.verticalScrollDirection = newVerticalScrollDirection;
47
+
48
+ if (this.verticalScrollTimeout != null) {
49
+ window.clearTimeout(this.verticalScrollTimeout);
50
+ this.verticalScrollTimeout = undefined;
51
+ }
52
+
53
+ if (newVerticalScrollDirection) {
54
+ this.verticalScrollTimeout = window.setTimeout(
55
+ this.scrollVertically.bind(this),
56
+ 40,
57
+ );
58
+ }
59
+ }
60
+ }
61
+
62
+ public getScrollLeft(): number {
63
+ return document.documentElement.scrollLeft;
64
+ }
65
+
66
+ public scrollToY(top: number): void {
67
+ const offset = this.$element.offset();
68
+ const treeTop = offset ? offset.top : 0;
69
+
70
+ jQuery(document).scrollTop(top + treeTop);
71
+ }
72
+
73
+ public stopScrolling() {
74
+ this.horizontalScrollDirection = undefined;
75
+ this.verticalScrollDirection = undefined;
76
+ this.documentScrollHeight = undefined;
77
+ this.documentScrollWidth = undefined;
78
+ }
79
+
80
+ private getNewHorizontalScrollDirection(
81
+ pageX: number,
82
+ ): HorizontalScrollDirection | undefined {
83
+ const $document = jQuery(document);
84
+
85
+ const scrollLeft = $document.scrollLeft() || 0;
86
+ const windowWidth = jQuery(window).width() || 0;
87
+
88
+ const isNearRightEdge = pageX > windowWidth - 20;
89
+ const isNearLeftEdge = pageX - scrollLeft < 20;
90
+
91
+ if (isNearRightEdge && this.canScrollRight()) {
92
+ return "right";
93
+ }
94
+
95
+ if (isNearLeftEdge) {
96
+ return "left";
97
+ }
98
+
99
+ return undefined;
100
+ }
101
+
102
+ private canScrollRight() {
103
+ const documentElement = document.documentElement;
104
+
105
+ return (
106
+ documentElement.scrollLeft + documentElement.clientWidth <
107
+ this.getDocumentScrollWidth()
108
+ );
109
+ }
110
+
111
+ private canScrollDown() {
112
+ const documentElement = document.documentElement;
113
+
114
+ return (
115
+ documentElement.scrollTop + documentElement.clientHeight <
116
+ this.getDocumentScrollHeight()
117
+ );
118
+ }
119
+
120
+ private getDocumentScrollHeight() {
121
+ // Store the original scroll height because the scroll height can increase when the drag element is moved beyond the scroll height.
122
+ if (this.documentScrollHeight == null) {
123
+ this.documentScrollHeight = document.documentElement.scrollHeight;
124
+ }
125
+
126
+ return this.documentScrollHeight;
127
+ }
128
+
129
+ private getDocumentScrollWidth() {
130
+ // Store the original scroll width because the scroll width can increase when the drag element is moved beyond the scroll width.
131
+ if (this.documentScrollWidth == null) {
132
+ this.documentScrollWidth = document.documentElement.scrollWidth;
133
+ }
134
+
135
+ return this.documentScrollWidth;
136
+ }
137
+
138
+ private getNewVerticalScrollDirection(
139
+ pageY: number,
140
+ ): VerticalScrollDirection | undefined {
141
+ const scrollTop = jQuery(document).scrollTop() || 0;
142
+ const distanceTop = pageY - scrollTop;
143
+
144
+ if (distanceTop < 20) {
145
+ return "top";
146
+ }
147
+
148
+ const windowHeight = jQuery(window).height() || 0;
149
+
150
+ if (windowHeight - (pageY - scrollTop) < 20 && this.canScrollDown()) {
151
+ return "bottom";
152
+ }
153
+
154
+ return undefined;
155
+ }
156
+
157
+ private scrollHorizontally() {
158
+ if (!this.horizontalScrollDirection) {
159
+ return;
160
+ }
161
+
162
+ const distance = this.horizontalScrollDirection === "left" ? -20 : 20;
163
+ window.scrollBy({ left: distance, top: 0, behavior: "instant" });
164
+
165
+ this.refreshHitAreas();
166
+
167
+ setTimeout(this.scrollHorizontally.bind(this), 40);
168
+ }
169
+
170
+ private scrollVertically() {
171
+ if (!this.verticalScrollDirection) {
172
+ return;
173
+ }
174
+
175
+ const distance = this.verticalScrollDirection === "top" ? -20 : 20;
176
+ window.scrollBy({ left: 0, top: distance, behavior: "instant" });
177
+
178
+ this.refreshHitAreas();
179
+
180
+ setTimeout(this.scrollVertically.bind(this), 40);
181
+ }
182
+ }
@@ -0,0 +1,7 @@
1
+ export interface ScrollParent {
2
+ checkHorizontalScrolling(pageX: number): void;
3
+ checkVerticalScrolling(pageY: number): void;
4
+ getScrollLeft(): number;
5
+ scrollToY(top: number): void;
6
+ stopScrolling(): void;
7
+ }
@@ -1,276 +1,58 @@
1
1
  import { JqTreeWidget } from "./tree.jquery";
2
- import { HitArea, PositionInfo } from "./types";
2
+ import { PositionInfo } from "./types";
3
+ import { ScrollParent } from "./scrollHandler/types";
4
+ import createScrollParent from "./scrollHandler/createScrollParent";
3
5
 
4
6
  export default class ScrollHandler {
5
7
  private treeWidget: JqTreeWidget;
6
- private previousTop: number;
7
- private isInitialized: boolean;
8
- private $scrollParent: JQuery | null;
9
- private scrollParentTop: number;
8
+ private scrollParent?: ScrollParent;
10
9
 
11
10
  constructor(treeWidget: JqTreeWidget) {
12
11
  this.treeWidget = treeWidget;
13
- this.previousTop = -1;
14
- this.isInitialized = false;
12
+ this.scrollParent = undefined;
15
13
  }
16
14
 
17
- public checkScrolling(): void {
18
- this.ensureInit();
19
- this.checkVerticalScrolling();
20
- this.checkHorizontalScrolling();
15
+ public checkScrolling(positionInfo: PositionInfo): void {
16
+ this.checkVerticalScrolling(positionInfo);
17
+ this.checkHorizontalScrolling(positionInfo);
21
18
  }
22
19
 
23
- public scrollToY(top: number): void {
24
- this.ensureInit();
25
-
26
- if (this.$scrollParent && this.$scrollParent[0]) {
27
- this.$scrollParent[0].scrollTop = top;
28
- } else {
29
- const offset = this.treeWidget.$el.offset();
30
- const treeTop = offset ? offset.top : 0;
31
-
32
- jQuery(document).scrollTop(top + treeTop);
33
- }
20
+ public stopScrolling() {
21
+ this.getScrollParent().stopScrolling();
34
22
  }
35
23
 
36
- public isScrolledIntoView($element: JQuery): boolean {
37
- this.ensureInit();
38
-
39
- let elementBottom: number;
40
- let viewBottom: number;
41
- let elementTop: number;
42
- let viewTop: number;
43
-
44
- const elHeight = $element.height() || 0;
45
-
46
- if (this.$scrollParent) {
47
- viewTop = 0;
48
- viewBottom = this.$scrollParent.height() || 0;
49
-
50
- const offset = $element.offset();
51
- const originalTop = offset ? offset.top : 0;
52
-
53
- elementTop = originalTop - this.scrollParentTop;
54
- elementBottom = elementTop + elHeight;
55
- } else {
56
- viewTop = jQuery(window).scrollTop() || 0;
57
-
58
- const windowHeight = jQuery(window).height() || 0;
59
- viewBottom = viewTop + windowHeight;
60
-
61
- const offset = $element.offset();
62
-
63
- elementTop = offset ? offset.top : 0;
64
- elementBottom = elementTop + elHeight;
65
- }
66
-
67
- return elementBottom <= viewBottom && elementTop >= viewTop;
24
+ public scrollToY(top: number): void {
25
+ this.getScrollParent().scrollToY(top);
68
26
  }
69
27
 
70
28
  public getScrollLeft(): number {
71
- if (!this.$scrollParent) {
72
- return 0;
73
- } else {
74
- return this.$scrollParent.scrollLeft() || 0;
75
- }
76
- }
77
-
78
- private initScrollParent(): void {
79
- const getParentWithOverflow = (): JQuery | null => {
80
- const cssAttributes = ["overflow", "overflow-y"];
81
-
82
- const hasOverFlow = ($el: JQuery): boolean => {
83
- for (const attr of cssAttributes) {
84
- const overflowValue = $el.css(attr);
85
- if (
86
- overflowValue === "auto" ||
87
- overflowValue === "scroll"
88
- ) {
89
- return true;
90
- }
91
- }
92
-
93
- return false;
94
- };
95
-
96
- if (hasOverFlow(this.treeWidget.$el)) {
97
- return this.treeWidget.$el;
98
- }
99
-
100
- for (const el of this.treeWidget.$el.parents().get()) {
101
- const $el = jQuery(el);
102
- if (hasOverFlow($el)) {
103
- return $el;
104
- }
105
- }
106
-
107
- return null;
108
- };
109
-
110
- const setDocumentAsScrollParent = (): void => {
111
- this.scrollParentTop = 0;
112
- this.$scrollParent = null;
113
- };
114
-
115
- if (this.treeWidget.$el.css("position") === "fixed") {
116
- setDocumentAsScrollParent();
117
- }
118
-
119
- const $scrollParent = getParentWithOverflow();
120
-
121
- if (
122
- $scrollParent &&
123
- $scrollParent.length &&
124
- $scrollParent[0]?.tagName !== "HTML"
125
- ) {
126
- this.$scrollParent = $scrollParent;
127
-
128
- const offset = this.$scrollParent.offset();
129
- this.scrollParentTop = offset ? offset.top : 0;
130
- } else {
131
- setDocumentAsScrollParent();
132
- }
133
-
134
- this.isInitialized = true;
29
+ return this.getScrollParent().getScrollLeft();
135
30
  }
136
31
 
137
- private ensureInit(): void {
138
- if (!this.isInitialized) {
139
- this.initScrollParent();
140
- }
141
- }
142
-
143
- private handleVerticalScrollingWithScrollParent(area: HitArea): void {
144
- const scrollParent = this.$scrollParent && this.$scrollParent[0];
145
-
146
- if (!scrollParent) {
32
+ private checkVerticalScrolling(positionInfo: PositionInfo): void {
33
+ if (positionInfo.pageY == null) {
147
34
  return;
148
35
  }
149
36
 
150
- const distanceBottom =
151
- this.scrollParentTop + scrollParent.offsetHeight - area.bottom;
152
-
153
- if (distanceBottom < 20) {
154
- scrollParent.scrollTop += 20;
155
- this.treeWidget.refreshHitAreas();
156
- this.previousTop = -1;
157
- } else if (area.top - this.scrollParentTop < 20) {
158
- scrollParent.scrollTop -= 20;
159
- this.treeWidget.refreshHitAreas();
160
- this.previousTop = -1;
161
- }
162
- }
163
-
164
- private handleVerticalScrollingWithDocument(area: HitArea): void {
165
- const scrollTop = jQuery(document).scrollTop() || 0;
166
- const distanceTop = area.top - scrollTop;
167
-
168
- if (distanceTop < 20) {
169
- jQuery(document).scrollTop(scrollTop - 20);
170
- } else {
171
- const windowHeight = jQuery(window).height() || 0;
172
-
173
- if (windowHeight - (area.bottom - scrollTop) < 20) {
174
- jQuery(document).scrollTop(scrollTop + 20);
175
- }
176
- }
177
- }
178
-
179
- private checkVerticalScrolling(): void {
180
- const hoveredArea = this.treeWidget.dndHandler.hoveredArea;
181
-
182
- if (hoveredArea && hoveredArea.top !== this.previousTop) {
183
- this.previousTop = hoveredArea.top;
184
-
185
- if (this.$scrollParent) {
186
- this.handleVerticalScrollingWithScrollParent(hoveredArea);
187
- } else {
188
- this.handleVerticalScrollingWithDocument(hoveredArea);
189
- }
190
- }
37
+ this.getScrollParent().checkVerticalScrolling(positionInfo.pageY);
191
38
  }
192
39
 
193
- private checkHorizontalScrolling(): void {
194
- const positionInfo = this.treeWidget.dndHandler.positionInfo;
195
-
196
- if (!positionInfo) {
40
+ private checkHorizontalScrolling(positionInfo: PositionInfo): void {
41
+ if (positionInfo.pageX == null) {
197
42
  return;
198
43
  }
199
44
 
200
- if (this.$scrollParent) {
201
- this.handleHorizontalScrollingWithParent(positionInfo);
202
- } else {
203
- this.handleHorizontalScrollingWithDocument(positionInfo);
204
- }
45
+ this.getScrollParent().checkHorizontalScrolling(positionInfo.pageX);
205
46
  }
206
47
 
207
- private handleHorizontalScrollingWithParent(
208
- positionInfo: PositionInfo
209
- ): void {
210
- if (
211
- positionInfo.pageX === undefined ||
212
- positionInfo.pageY === undefined
213
- ) {
214
- return;
215
- }
216
-
217
- const $scrollParent = this.$scrollParent;
218
- const scrollParentOffset = $scrollParent && $scrollParent.offset();
219
-
220
- if (!($scrollParent && scrollParentOffset)) {
221
- return;
222
- }
223
-
224
- const scrollParent = $scrollParent[0];
225
-
226
- if (!scrollParent) {
227
- return;
228
- }
229
-
230
- const canScrollRight =
231
- scrollParent.scrollLeft + scrollParent.clientWidth <
232
- scrollParent.scrollWidth;
233
- const canScrollLeft = scrollParent.scrollLeft > 0;
234
-
235
- const rightEdge = scrollParentOffset.left + scrollParent.clientWidth;
236
- const leftEdge = scrollParentOffset.left;
237
- const isNearRightEdge = positionInfo.pageX > rightEdge - 20;
238
- const isNearLeftEdge = positionInfo.pageX < leftEdge + 20;
239
-
240
- if (isNearRightEdge && canScrollRight) {
241
- scrollParent.scrollLeft = Math.min(
242
- scrollParent.scrollLeft + 20,
243
- scrollParent.scrollWidth
48
+ private getScrollParent(): ScrollParent {
49
+ if (!this.scrollParent) {
50
+ this.scrollParent = createScrollParent(
51
+ this.treeWidget.$el,
52
+ this.treeWidget.refreshHitAreas.bind(this.treeWidget),
244
53
  );
245
- } else if (isNearLeftEdge && canScrollLeft) {
246
- scrollParent.scrollLeft = Math.max(scrollParent.scrollLeft - 20, 0);
247
54
  }
248
- }
249
55
 
250
- private handleHorizontalScrollingWithDocument(
251
- positionInfo: PositionInfo
252
- ): void {
253
- if (
254
- positionInfo.pageX === undefined ||
255
- positionInfo.pageY === undefined
256
- ) {
257
- return;
258
- }
259
-
260
- const $document = jQuery(document);
261
-
262
- const scrollLeft = $document.scrollLeft() || 0;
263
- const windowWidth = jQuery(window).width() || 0;
264
-
265
- const canScrollLeft = scrollLeft > 0;
266
-
267
- const isNearRightEdge = positionInfo.pageX > windowWidth - 20;
268
- const isNearLeftEdge = positionInfo.pageX - scrollLeft < 20;
269
-
270
- if (isNearRightEdge) {
271
- $document.scrollLeft(scrollLeft + 20);
272
- } else if (isNearLeftEdge && canScrollLeft) {
273
- $document.scrollLeft(Math.max(scrollLeft - 20, 0));
274
- }
56
+ return this.scrollParent;
275
57
  }
276
58
  }
@@ -136,9 +136,8 @@ context("when a node has load_on_demand in the data", () => {
136
136
 
137
137
  context("when the node is selected and doesn't have the focus", () => {
138
138
  beforeEach(() => {
139
- given.$tree.tree("selectNode", given.node, {
140
- mustSetFocus: false,
141
- });
139
+ given.$tree.tree("selectNode", given.node);
140
+ (document.activeElement as HTMLElement).blur(); // eslint-disable-line testing-library/no-node-access
142
141
  });
143
142
 
144
143
  it("keeps the node selected and not focused", async () => {
@@ -984,7 +984,7 @@ describe("refresh", () => {
984
984
 
985
985
  it("rerenders the tree", () => {
986
986
  const tree = given.$tree.tree("getTree");
987
- (tree.children[0] as INode).name = "node1a";
987
+ (tree.children[0] as INode).name = "node1a"; // eslint-disable-line testing-library/no-node-access
988
988
 
989
989
  expect(given.$tree).toHaveTreeStructure([
990
990
  expect.objectContaining({ name: "node1" }),