jqtree 1.6.2 → 1.7.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.
Files changed (276) hide show
  1. package/.eslintrc +3 -12
  2. package/.github/workflows/ci.yml +57 -30
  3. package/.github/workflows/codeql-analysis.yml +9 -5
  4. package/.prettier +3 -0
  5. package/.tool-versions +1 -0
  6. package/README.md +12 -9
  7. package/bower.json +10 -3
  8. package/{.postcssrc → config/.postcssrc} +0 -0
  9. package/{babel.config.json → config/babel.config.json} +0 -0
  10. package/{babel.coverage.config.json → config/babel.coverage.config.json} +0 -0
  11. package/{jest-jsdom.config.js → config/jest.config.js} +8 -3
  12. package/config/playwright.config.js +18 -0
  13. package/config/production +4 -0
  14. package/{rollup.config.js → config/rollup.config.mjs} +3 -8
  15. package/{jqtree.postcss → css/jqtree.postcss} +0 -0
  16. package/devserver/index.html +1 -9
  17. package/docs/Gemfile +2 -0
  18. package/docs/Gemfile.lock +263 -0
  19. package/{_config.yml → docs/_config.yml} +8 -1
  20. package/{_entries → docs/_entries}/01_general.md +0 -0
  21. package/{_entries → docs/_entries}/02_introduction.md +0 -0
  22. package/{_entries → docs/_entries}/03_features.md +1 -1
  23. package/{_entries → docs/_entries}/04_demo.html +1 -7
  24. package/{_entries → docs/_entries}/05_requirements.md +0 -0
  25. package/{_entries → docs/_entries}/06_downloads.md +0 -0
  26. package/{_entries → docs/_entries}/07_tutorial.md +0 -0
  27. package/{_entries → docs/_entries}/08_examples.md +0 -0
  28. package/{_entries → docs/_entries}/09_usecases.md +0 -0
  29. package/{_entries → docs/_entries}/10_changelog.md +13 -0
  30. package/{_entries → docs/_entries}/11_options.md +0 -0
  31. package/{_entries → docs/_entries}/12_animationspeed.md +0 -0
  32. package/{_entries → docs/_entries}/13_autoescape.md +0 -0
  33. package/{_entries → docs/_entries}/14_autoopen.md +0 -0
  34. package/{_entries → docs/_entries}/15_buttonleft.md +0 -0
  35. package/{_entries → docs/_entries}/16_closedicon.md +0 -0
  36. package/{_entries → docs/_entries}/17_data.md +0 -0
  37. package/{_entries → docs/_entries}/18_datafilter.md +0 -0
  38. package/{_entries → docs/_entries}/19_data-url.md +0 -0
  39. package/{_entries → docs/_entries}/20_draganddrop.md +0 -0
  40. package/{_entries → docs/_entries}/21_keyboardsupport.md +0 -0
  41. package/{_entries → docs/_entries}/22_oncanmove.md +0 -0
  42. package/{_entries → docs/_entries}/23_oncanmoveto.md +2 -2
  43. package/{_entries → docs/_entries}/24_oncanselectnode.md +0 -0
  44. package/{_entries → docs/_entries}/25_oncreateli.md +2 -2
  45. package/{_entries → docs/_entries}/26_ondragmove.md +0 -0
  46. package/{_entries → docs/_entries}/27_ondragstop.md +0 -0
  47. package/{_entries → docs/_entries}/28_onismovehandle.md +0 -0
  48. package/{_entries → docs/_entries}/29_onloadfailed.md +0 -0
  49. package/{_entries → docs/_entries}/30_onloading.md +2 -2
  50. package/{_entries → docs/_entries}/31_openedicon.md +0 -0
  51. package/{_entries → docs/_entries}/32_openfolderdelay.md +2 -0
  52. package/{_entries → docs/_entries}/33_rtl.md +0 -0
  53. package/{_entries → docs/_entries}/34_savestate.md +0 -0
  54. package/{_entries → docs/_entries}/35_selectable.md +0 -0
  55. package/{_entries → docs/_entries}/36_showemptyfolder.md +0 -0
  56. package/{_entries → docs/_entries}/37_slide.md +0 -0
  57. package/{_entries → docs/_entries}/38_start_dnd_delay.md +0 -0
  58. package/{_entries → docs/_entries}/39_tabindex.md +0 -0
  59. package/{_entries → docs/_entries}/40_usecontextmenu.md +0 -0
  60. package/{_entries → docs/_entries}/41_functions.md +0 -0
  61. package/{_entries → docs/_entries}/42_addparentnode.md +1 -1
  62. package/{_entries → docs/_entries}/43_addnodeafter.md +1 -1
  63. package/{_entries → docs/_entries}/44_addnodebefore.md +1 -1
  64. package/{_entries → docs/_entries}/45_appendnode.md +5 -5
  65. package/{_entries → docs/_entries}/46_closenode.md +0 -0
  66. package/{_entries → docs/_entries}/47_destroy.md +0 -0
  67. package/{_entries → docs/_entries}/48_getnodebycallback.md +0 -0
  68. package/{_entries → docs/_entries}/49_getnodebyid.md +0 -0
  69. package/{_entries → docs/_entries}/50_getnodebyhtmlelement.md +2 -2
  70. package/{_entries → docs/_entries}/51_getselectednode.md +0 -0
  71. package/{_entries → docs/_entries}/52_getstate.md +0 -0
  72. package/{_entries → docs/_entries}/53_gettree.md +1 -1
  73. package/{_entries → docs/_entries}/54_isdragging.md +1 -1
  74. package/{_entries → docs/_entries}/55_loaddata.md +3 -3
  75. package/{_entries → docs/_entries}/56_loaddatafromurl.md +4 -4
  76. package/{_entries → docs/_entries}/57_movedown.md +0 -0
  77. package/{_entries → docs/_entries}/58_movenode.md +3 -3
  78. package/{_entries → docs/_entries}/59_moveup.md +0 -0
  79. package/{_entries → docs/_entries}/60_opennode.md +3 -3
  80. package/docs/_entries/61_prependnode.md +21 -0
  81. package/{_entries → docs/_entries}/62_refresh.md +0 -0
  82. package/{_entries → docs/_entries}/63_reload.md +2 -2
  83. package/{_entries → docs/_entries}/64_removenode.md +0 -0
  84. package/{_entries → docs/_entries}/65_selectnode.md +0 -0
  85. package/{_entries → docs/_entries}/66_scrolltonode.md +0 -0
  86. package/{_entries → docs/_entries}/67_setoption.md +0 -0
  87. package/{_entries → docs/_entries}/68_setstate.md +0 -0
  88. package/{_entries → docs/_entries}/69_toggle.md +0 -0
  89. package/{_entries → docs/_entries}/70_tojson.md +0 -0
  90. package/{_entries → docs/_entries}/71_updatenode.md +1 -1
  91. package/{_entries → docs/_entries}/72_events.md +0 -0
  92. package/{_entries → docs/_entries}/73_tree-click.md +0 -0
  93. package/{_entries → docs/_entries}/74_tree-close.md +0 -0
  94. package/{_entries → docs/_entries}/75_tree-contextmenu.md +0 -0
  95. package/{_entries → docs/_entries}/76_tree-dblclick.md +0 -0
  96. package/{_entries → docs/_entries}/77_tree-init.md +0 -0
  97. package/{_entries → docs/_entries}/78_tree-load-data.md +0 -0
  98. package/{_entries → docs/_entries}/79_tree-loading-data.md +0 -0
  99. package/{_entries → docs/_entries}/80_tree-move.md +0 -0
  100. package/{_entries → docs/_entries}/81_tree-refresh.md +0 -0
  101. package/{_entries → docs/_entries}/82_tree-open.md +0 -0
  102. package/{_entries → docs/_entries}/83_tree-select.md +0 -0
  103. package/{_entries → docs/_entries}/84_multiple-selection.md +0 -0
  104. package/{_entries → docs/_entries}/85_add-to-selection.md +0 -0
  105. package/{_entries → docs/_entries}/86_get-selected-nodes.md +0 -0
  106. package/{_entries → docs/_entries}/87_is-node-selected.md +1 -1
  107. package/{_entries → docs/_entries}/88_remove-from-selection.md +0 -0
  108. package/{_entries → docs/_entries}/89_node-functions.md +0 -0
  109. package/{_entries → docs/_entries}/90_children.md +0 -0
  110. package/{_entries → docs/_entries}/91_getdata.md +2 -2
  111. package/{_entries → docs/_entries}/92_getlevel.md +0 -0
  112. package/docs/_entries/93_getnextnode.md +15 -0
  113. package/{_entries → docs/_entries}/94_getnextsibling.md +0 -0
  114. package/{_entries/95_getpreviousnode.md → docs/_entries/95_getnextvisiblenode.md} +1 -1
  115. package/docs/_entries/96_getpreviousnode.md +0 -0
  116. package/{_entries/96_getprevioussibling.md → docs/_entries/97_getprevioussibling.md} +0 -0
  117. package/docs/_entries/98_getpreviousvisiblenode.md +14 -0
  118. package/{_entries/97_parent.md → docs/_entries/99_parent.md} +1 -1
  119. package/{_entries → docs/_entries}/insert.py +0 -0
  120. package/{_entries → docs/_entries}/renumber.py +0 -0
  121. package/{_examples → docs/_examples}/01_load_json_data.html +3 -5
  122. package/{_examples → docs/_examples}/02_load_json_data_from_server.html +3 -5
  123. package/{_examples → docs/_examples}/03_drag_and_drop.html +3 -5
  124. package/{_examples → docs/_examples}/04_save_state.html +3 -5
  125. package/{_examples → docs/_examples}/05_load_on_demand.html +3 -5
  126. package/{_examples → docs/_examples}/06_autoescape.html +3 -5
  127. package/{_examples → docs/_examples}/07_autoscroll.html +3 -5
  128. package/{_examples → docs/_examples}/08_multiple_select.html +3 -5
  129. package/{_examples → docs/_examples}/09_custom_html.html +3 -5
  130. package/{_examples → docs/_examples}/10_icon_buttons.html +3 -5
  131. package/{_examples → docs/_examples}/11_right-to-left.html +3 -5
  132. package/{_examples → docs/_examples}/12_button_on_right.html +3 -5
  133. package/docs/_examples/13_drag_outside.html +48 -0
  134. package/{_examples → docs/_examples}/14_filter.html +7 -9
  135. package/docs/_layouts/example.html +7 -0
  136. package/{_layouts/base.html → docs/_layouts/page.html} +4 -11
  137. package/docs/documentation.css +3 -0
  138. package/docs/index.html +65 -0
  139. package/docs/jqtree.css +189 -0
  140. package/docs/package.json +22 -0
  141. package/docs/pnpm-lock.yaml +798 -0
  142. package/docs/postcss.config.js +7 -0
  143. package/{static → docs/static}/bower.json +1 -2
  144. package/{static → docs/static}/bower_components/fontawesome/css/all.min.css +0 -0
  145. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-brands-400.eot +0 -0
  146. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-brands-400.svg +0 -0
  147. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-brands-400.ttf +0 -0
  148. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-brands-400.woff +0 -0
  149. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-brands-400.woff2 +0 -0
  150. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-regular-400.eot +0 -0
  151. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-regular-400.svg +0 -0
  152. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-regular-400.ttf +0 -0
  153. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-regular-400.woff +0 -0
  154. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-regular-400.woff2 +0 -0
  155. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-solid-900.eot +0 -0
  156. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-solid-900.svg +0 -0
  157. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-solid-900.ttf +0 -0
  158. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-solid-900.woff +0 -0
  159. package/{static → docs/static}/bower_components/fontawesome/webfonts/fa-solid-900.woff2 +0 -0
  160. package/{static → docs/static}/bower_components/jquery/dist/jquery.js +209 -97
  161. package/docs/static/bower_components/jquery/dist/jquery.min.js +2 -0
  162. package/{static → docs/static}/bower_components/jquery-mockjax/dist/jquery.mockjax.js +0 -0
  163. package/docs/static/documentation.css +1453 -0
  164. package/docs/static/documentation.js +26 -0
  165. package/{static → docs/static}/example.css +5 -38
  166. package/{static → docs/static}/example.postcss +5 -35
  167. package/{static → docs/static}/example_data.js +0 -0
  168. package/{static → docs/static}/examples/autoescape.js +0 -0
  169. package/{static → docs/static}/examples/autoscroll.js +0 -0
  170. package/{static → docs/static}/examples/button-on-right.js +0 -0
  171. package/{static → docs/static}/examples/custom_html.js +5 -9
  172. package/{static → docs/static}/examples/drag-outside.js +0 -0
  173. package/{static → docs/static}/examples/drag_and_drop.js +0 -0
  174. package/{static → docs/static}/examples/filter.js +2 -2
  175. package/{static → docs/static}/examples/icon_buttons.js +0 -0
  176. package/{static → docs/static}/examples/load_json_data.js +0 -0
  177. package/{static → docs/static}/examples/load_json_data_from_server.js +0 -0
  178. package/{static → docs/static}/examples/load_on_demand.js +0 -0
  179. package/{static → docs/static}/examples/multiple_select.js +0 -0
  180. package/{static → docs/static}/examples/right-to-left.js +0 -0
  181. package/{static → docs/static}/examples/save_state.js +0 -0
  182. package/{static → docs/static}/monokai.css +0 -0
  183. package/{static → docs/static}/spinner.gif +0 -0
  184. package/docs/tailwind.config.js +16 -0
  185. package/docs/tree.jquery.js +21 -0
  186. package/lib/dataLoader.js +5 -31
  187. package/lib/dragAndDropHandler.js +26 -135
  188. package/lib/elementsRenderer.js +29 -59
  189. package/lib/keyHandler.js +8 -32
  190. package/lib/mouse.widget.js +16 -77
  191. package/lib/node.js +60 -125
  192. package/lib/nodeElement.js +8 -75
  193. package/lib/playwright/coverage.js +101 -0
  194. package/lib/playwright/playwright.test.js +212 -182
  195. package/lib/playwright/testUtils.js +201 -0
  196. package/lib/saveStateHandler.js +12 -61
  197. package/lib/scrollHandler.js +17 -74
  198. package/lib/selectNodeHandler.js +5 -24
  199. package/lib/simple.widget.js +18 -53
  200. package/lib/test/jqTree/create.test.js +0 -4
  201. package/lib/test/jqTree/events.test.js +10 -16
  202. package/lib/test/jqTree/keyboard.test.js +0 -6
  203. package/lib/test/jqTree/loadOnDemand.test.js +107 -139
  204. package/lib/test/jqTree/methods.test.js +136 -159
  205. package/lib/test/jqTree/options.test.js +53 -63
  206. package/lib/test/node.test.js +127 -72
  207. package/lib/test/nodeUtil.test.js +0 -1
  208. package/lib/test/support/jqTreeMatchers.js +4 -9
  209. package/lib/test/support/setupTests.js +0 -4
  210. package/lib/test/support/testUtil.js +2 -11
  211. package/lib/test/support/treeStructure.js +0 -6
  212. package/lib/test/util.test.js +0 -1
  213. package/lib/tree.jquery.js +32 -243
  214. package/lib/util.js +0 -6
  215. package/lib/version.js +1 -1
  216. package/package.json +54 -54
  217. package/src/dragAndDropHandler.ts +8 -4
  218. package/src/jqtreeOptions.ts +1 -1
  219. package/src/keyHandler.ts +3 -3
  220. package/src/node.ts +43 -12
  221. package/src/playwright/.eslintrc +2 -2
  222. package/src/playwright/coverage.ts +41 -0
  223. package/src/playwright/playwright.test.ts +50 -52
  224. package/src/playwright/playwright.test.ts-snapshots/with-dragAndDrop-moves-a-node-1-Chromium-darwin.png +0 -0
  225. package/src/playwright/playwright.test.ts-snapshots/with-dragAndDrop-moves-a-node-1-Chromium-linux.png +0 -0
  226. package/src/playwright/playwright.test.ts-snapshots/without-dragAndDrop-displays-a-tree-1-Chromium-darwin.png +0 -0
  227. package/src/playwright/playwright.test.ts-snapshots/without-dragAndDrop-displays-a-tree-1-Chromium-linux.png +0 -0
  228. package/src/playwright/playwright.test.ts-snapshots/without-dragAndDrop-selects-a-node-1-Chromium-darwin.png +0 -0
  229. package/src/playwright/playwright.test.ts-snapshots/without-dragAndDrop-selects-a-node-1-Chromium-linux.png +0 -0
  230. package/src/playwright/testUtils.ts +122 -0
  231. package/src/test/.eslintrc +15 -3
  232. package/src/test/jqTree/events.test.ts +10 -9
  233. package/src/test/jqTree/loadOnDemand.test.ts +10 -10
  234. package/src/test/jqTree/methods.test.ts +37 -45
  235. package/src/test/jqTree/options.test.ts +26 -28
  236. package/src/test/node.test.ts +146 -54
  237. package/src/tree.jquery.d.ts +1 -1
  238. package/src/tree.jquery.ts +6 -5
  239. package/src/version.ts +1 -1
  240. package/tree.jquery.debug.js +217 -867
  241. package/tree.jquery.debug.js.map +1 -1
  242. package/tree.jquery.js +3 -3
  243. package/tree.jquery.js.map +1 -1
  244. package/_entries/61_prependnode.md +0 -21
  245. package/_entries/93_getnextnode.md +0 -12
  246. package/_examples/13_drag_outside.html +0 -26
  247. package/_layouts/frontpage.html +0 -20
  248. package/_layouts/page.html +0 -7
  249. package/index.html +0 -48
  250. package/jest-browser.config.js +0 -15
  251. package/jest-playwright.config.js +0 -21
  252. package/jest.config.js +0 -8
  253. package/lib/playwright/testUtil.js +0 -459
  254. package/lib/playwright/visualRegression.js +0 -193
  255. package/production +0 -5
  256. package/src/playwright/screenshots/displays_a_tree_Desktop.png +0 -0
  257. package/src/playwright/screenshots/displays_a_tree_iPhone 6.png +0 -0
  258. package/src/playwright/screenshots/moves_a_node_Desktop.png +0 -0
  259. package/src/playwright/screenshots/moves_a_node_iPhone 6.png +0 -0
  260. package/src/playwright/screenshots/opens_a_node_Desktop.png +0 -0
  261. package/src/playwright/screenshots/opens_a_node_iPhone 6.png +0 -0
  262. package/src/playwright/screenshots/selects_a_node_Desktop.png +0 -0
  263. package/src/playwright/screenshots/selects_a_node_iPhone 6.png +0 -0
  264. package/src/playwright/testUtil.ts +0 -170
  265. package/src/playwright/visualRegression.ts +0 -88
  266. package/static/bower_components/bootstrap/dist/css/bootstrap-theme.min.css +0 -6
  267. package/static/bower_components/bootstrap/dist/css/bootstrap.min.css +0 -6
  268. package/static/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot +0 -0
  269. package/static/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg +0 -288
  270. package/static/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf +0 -0
  271. package/static/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff +0 -0
  272. package/static/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 +0 -0
  273. package/static/bower_components/bootstrap/dist/js/bootstrap.min.js +0 -6
  274. package/static/bower_components/jquery/dist/jquery.min.js +0 -2
  275. package/static/documentation.css +0 -171
  276. package/static/documentation.js +0 -48
@@ -7,16 +7,24 @@ import { titleSpan } from "../support/testUtil";
7
7
 
8
8
  const context = describe;
9
9
 
10
+ const server = setupServer();
11
+
12
+ beforeAll(() => server.listen());
13
+
10
14
  beforeEach(() => {
11
15
  $("body").append('<div id="tree1"></div>');
12
16
  });
13
17
 
14
18
  afterEach(() => {
19
+ server.resetHandlers();
20
+
15
21
  const $tree = $("#tree1");
16
22
  $tree.tree("destroy");
17
23
  $tree.remove();
18
24
  });
19
25
 
26
+ afterAll(() => server.close());
27
+
20
28
  describe("tree.click", () => {
21
29
  interface Vars {
22
30
  node1: INode;
@@ -131,19 +139,12 @@ describe("tree.init", () => {
131
139
  });
132
140
 
133
141
  context("with data loaded from an url", () => {
134
- let server: ReturnType<typeof setupServer> | null = null;
135
-
136
- beforeAll(() => {
137
- server = setupServer(
142
+ beforeEach(() => {
143
+ server.use(
138
144
  rest.get("/tree/", (_request, response, ctx) =>
139
145
  response(ctx.status(200), ctx.json(exampleData))
140
146
  )
141
147
  );
142
- server.listen();
143
- });
144
-
145
- afterAll(() => {
146
- server?.close();
147
148
  });
148
149
 
149
150
  it("is called", () =>
@@ -7,17 +7,25 @@ import { togglerLink } from "../support/testUtil";
7
7
 
8
8
  const context = describe;
9
9
 
10
+ const server = setupServer();
11
+
12
+ beforeAll(() => server.listen());
13
+
10
14
  beforeEach(() => {
11
15
  $("body").append('<div id="tree1"></div>');
12
16
  });
13
17
 
14
18
  afterEach(() => {
19
+ server.resetHandlers();
20
+
15
21
  const $tree = $("#tree1");
16
22
  $tree.tree("destroy");
17
23
  $tree.remove();
18
24
  localStorage.clear();
19
25
  });
20
26
 
27
+ afterAll(() => server.close());
28
+
21
29
  context("when a node has load_on_demand in the data", () => {
22
30
  interface Vars {
23
31
  autoOpen: boolean;
@@ -37,10 +45,8 @@ context("when a node has load_on_demand in the data", () => {
37
45
  },
38
46
  ];
39
47
 
40
- let server: ReturnType<typeof setupServer> | null = null;
41
-
42
- beforeAll(() => {
43
- server = setupServer(
48
+ beforeEach(() => {
49
+ server.use(
44
50
  rest.get("/tree/", (request, response, ctx) => {
45
51
  const parentId = request.url.searchParams.get("node");
46
52
 
@@ -54,12 +60,6 @@ context("when a node has load_on_demand in the data", () => {
54
60
  }
55
61
  })
56
62
  );
57
-
58
- server.listen();
59
- });
60
-
61
- afterAll(() => {
62
- server?.close();
63
63
  });
64
64
 
65
65
  beforeEach(() => {
@@ -1,5 +1,5 @@
1
1
  import getGiven from "givens";
2
- import { screen } from "@testing-library/dom";
2
+ import { screen, waitFor } from "@testing-library/dom";
3
3
  import { rest } from "msw";
4
4
  import { setupServer } from "msw/node";
5
5
  import "../../tree.jquery";
@@ -9,17 +9,25 @@ import __version__ from "../../version";
9
9
 
10
10
  const context = describe;
11
11
 
12
+ const server = setupServer();
13
+
14
+ beforeAll(() => server.listen());
15
+
12
16
  beforeEach(() => {
13
17
  $("body").append('<div id="tree1"></div>');
14
18
  });
15
19
 
16
20
  afterEach(() => {
21
+ server.resetHandlers();
22
+
17
23
  const $tree = $("#tree1");
18
24
  $tree.tree("destroy");
19
25
  $tree.remove();
20
26
  localStorage.clear();
21
27
  });
22
28
 
29
+ afterAll(() => server.close());
30
+
23
31
  describe("addNodeAfter", () => {
24
32
  interface Vars {
25
33
  node: INode;
@@ -739,22 +747,13 @@ describe("loadDataFromUrl", () => {
739
747
  given("serverData", () => exampleData);
740
748
  given("$tree", () => $("#tree1"));
741
749
 
742
- let server: ReturnType<typeof setupServer> | null = null;
743
-
744
- beforeAll(() => {
745
- server = setupServer(
746
- rest.get("/tree/", (_request, response, ctx) => {
747
- return response(ctx.status(200), ctx.json(given.serverData));
748
- })
750
+ beforeEach(() => {
751
+ server.use(
752
+ rest.get("/tree/", (_request, response, ctx) =>
753
+ response(ctx.status(200), ctx.json(given.serverData))
754
+ )
749
755
  );
750
- server.listen();
751
- });
752
-
753
- afterAll(() => {
754
- server?.close();
755
- });
756
756
 
757
- beforeEach(() => {
758
757
  given.$tree.tree({ data: given.initialData });
759
758
  });
760
759
 
@@ -909,12 +908,15 @@ describe("openNode", () => {
909
908
  });
910
909
 
911
910
  context("with onFinished parameter", () => {
912
- it("calls the function", () =>
913
- new Promise((resolve) =>
914
- given.$tree.tree("openNode", given.node1, (node) =>
915
- resolve(expect(node).toBe(given.node1))
916
- )
917
- ));
911
+ it("calls the function", async () => {
912
+ const onFinished = jest.fn();
913
+
914
+ given.$tree.tree("openNode", given.node1, onFinished);
915
+
916
+ await waitFor(() => {
917
+ expect(onFinished).toHaveBeenCalledWith(given.node1);
918
+ });
919
+ });
918
920
  });
919
921
  });
920
922
 
@@ -1008,23 +1010,14 @@ describe("reload", () => {
1008
1010
  given("node1", () => given.$tree.tree("getNodeByNameMustExist", "node1"));
1009
1011
  given("$tree", () => $("#tree1"));
1010
1012
 
1011
- let server: ReturnType<typeof setupServer> | null = null;
1012
-
1013
- beforeAll(() => {
1014
- server = setupServer(
1015
- rest.get("/tree/", (_request, response, ctx) =>
1013
+ beforeEach(async () => {
1014
+ server.use(
1015
+ rest.get("/tree2/", (_request, response, ctx) =>
1016
1016
  response(ctx.status(200), ctx.json(exampleData))
1017
1017
  )
1018
1018
  );
1019
- server.listen();
1020
- });
1021
-
1022
- afterAll(() => {
1023
- server?.close();
1024
- });
1025
1019
 
1026
- beforeEach(async () => {
1027
- given.$tree.tree({ dataUrl: "/tree/" });
1020
+ given.$tree.tree({ dataUrl: "/tree2/" });
1028
1021
  await screen.findByText("node1");
1029
1022
 
1030
1023
  given.$tree.tree("removeNode", given.node1);
@@ -1045,19 +1038,18 @@ describe("reload", () => {
1045
1038
  });
1046
1039
 
1047
1040
  context("with a onFinished parameter", () => {
1048
- it("calls onFinished", () =>
1049
- new Promise<void>((resolve) => {
1050
- const handleFinished = () => {
1051
- expect(given.$tree).toHaveTreeStructure([
1052
- expect.objectContaining({ name: "node1" }),
1053
- expect.objectContaining({ name: "node2" }),
1054
- ]);
1041
+ it("calls onFinished", async () => {
1042
+ const handleFinished = jest.fn();
1043
+
1044
+ given.$tree.tree("reload", handleFinished);
1055
1045
 
1056
- resolve();
1057
- };
1046
+ await waitFor(() => expect(handleFinished).toHaveBeenCalledWith());
1058
1047
 
1059
- given.$tree.tree("reload", handleFinished);
1060
- }));
1048
+ expect(given.$tree).toHaveTreeStructure([
1049
+ expect.objectContaining({ name: "node1" }),
1050
+ expect.objectContaining({ name: "node2" }),
1051
+ ]);
1052
+ });
1061
1053
  });
1062
1054
  });
1063
1055
 
@@ -1,5 +1,5 @@
1
1
  import getGiven from "givens";
2
- import { screen } from "@testing-library/dom";
2
+ import { screen, waitFor } from "@testing-library/dom";
3
3
  import { rest } from "msw";
4
4
  import { setupServer } from "msw/node";
5
5
  import "../../tree.jquery";
@@ -8,17 +8,25 @@ import { titleSpan, togglerLink } from "../support/testUtil";
8
8
 
9
9
  const context = describe;
10
10
 
11
+ const server = setupServer();
12
+
13
+ beforeAll(() => server.listen());
14
+
11
15
  beforeEach(() => {
12
16
  $("body").append('<div id="tree1"></div>');
13
17
  });
14
18
 
15
19
  afterEach(() => {
20
+ server.resetHandlers();
21
+
16
22
  const $tree = $("#tree1");
17
23
  $tree.tree("destroy");
18
24
  $tree.remove();
19
25
  localStorage.clear();
20
26
  });
21
27
 
28
+ afterAll(() => server.close());
29
+
22
30
  describe("autoEscape", () => {
23
31
  interface Vars {
24
32
  autoEscape: boolean;
@@ -186,10 +194,8 @@ describe("dataUrl", () => {
186
194
  },
187
195
  ];
188
196
 
189
- let server: ReturnType<typeof setupServer> | null = null;
190
-
191
- beforeAll(() => {
192
- server = setupServer(
197
+ beforeEach(() => {
198
+ server.use(
193
199
  rest.get("/tree/", (request, response, ctx) => {
194
200
  const nodeName = request.headers.get("node");
195
201
  const data = nodeName ? [nodeName] : exampleData;
@@ -197,11 +203,6 @@ describe("dataUrl", () => {
197
203
  return response(ctx.status(200), ctx.json(data));
198
204
  })
199
205
  );
200
- server.listen();
201
- });
202
-
203
- afterAll(() => {
204
- server?.close();
205
206
  });
206
207
 
207
208
  interface Vars {
@@ -347,31 +348,28 @@ describe("onLoadFailed", () => {
347
348
  given("$tree", () => $("#tree1"));
348
349
 
349
350
  context("when the loading fails", () => {
350
- let server: ReturnType<typeof setupServer> | null = null;
351
-
352
- beforeAll(() => {
353
- server = setupServer(
351
+ beforeEach(() => {
352
+ server.use(
354
353
  rest.get("/tree/", (_request, response, ctx) =>
355
354
  response(ctx.status(500), ctx.body("Internal server error"))
356
355
  )
357
356
  );
358
- server.listen();
359
357
  });
360
358
 
361
- afterAll(() => {
362
- server?.close();
363
- });
359
+ it("calls onLoadFailed", async () => {
360
+ const onLoadFailed = jest.fn();
361
+
362
+ given.$tree.tree({
363
+ dataUrl: "/tree/",
364
+ onLoadFailed,
365
+ });
364
366
 
365
- it("calls onLoadFailed", () =>
366
- new Promise<void>((done) => {
367
- given.$tree.tree({
368
- dataUrl: "/tree/",
369
- onLoadFailed: (jqXHR) => {
370
- expect(jqXHR.status).toBe(500);
371
- done();
372
- },
373
- });
374
- }));
367
+ await waitFor(() => {
368
+ expect(onLoadFailed).toHaveBeenCalledWith(
369
+ expect.objectContaining({ status: 500 })
370
+ );
371
+ });
372
+ });
375
373
  });
376
374
  });
377
375
 
@@ -568,52 +568,47 @@ describe("getLastChild", () => {
568
568
 
569
569
  describe("getNextNode", () => {
570
570
  interface Vars {
571
- includeChildren: boolean;
572
571
  fromNode: Node;
573
- nextNode: Node | null;
574
572
  tree: Node;
575
573
  }
576
574
  const given = getGiven<Vars>();
577
575
  given("tree", () => new Node().loadFromData(exampleData));
578
- given("nextNode", () => given.fromNode.getNextNode(given.includeChildren));
579
576
 
580
- context("with includeChildren is true", () => {
581
- given("includeChildren", () => true);
577
+ context("with a parent node", () => {
578
+ given("fromNode", () => given.tree.getNodeByNameMustExist("node1"));
582
579
 
583
- context("with a parent node", () => {
584
- given("fromNode", () => given.tree.getNodeByNameMustExist("node1"));
585
-
586
- context("when the parent node is closed", () => {
587
- it("returns the next sibling", () => {
588
- expect(given.nextNode).toMatchObject({ name: "node2" });
580
+ context("when the parent node is closed", () => {
581
+ it("returns the first child", () => {
582
+ expect(given.fromNode.getNextNode()).toMatchObject({
583
+ name: "child1",
589
584
  });
590
585
  });
586
+ });
591
587
 
592
- context("when the parent node is open", () => {
593
- beforeEach(() => {
594
- given.fromNode.is_open = true;
595
- });
588
+ context("when the parent node is open", () => {
589
+ beforeEach(() => {
590
+ given.fromNode.is_open = true;
591
+ });
596
592
 
597
- it("returns the first child", () => {
598
- expect(given.nextNode).toMatchObject({ name: "child1" });
593
+ it("returns the first child", () => {
594
+ expect(given.fromNode.getNextNode()).toMatchObject({
595
+ name: "child1",
599
596
  });
600
597
  });
601
598
  });
599
+ });
602
600
 
603
- context("with the node is the last child", () => {
604
- given("fromNode", () =>
605
- given.tree.getNodeByNameMustExist("child2")
606
- );
601
+ context("with the node is the last child", () => {
602
+ given("fromNode", () => given.tree.getNodeByNameMustExist("child2"));
607
603
 
608
- it("returns the next sibling of the parent", () => {
609
- expect(given.nextNode).toMatchObject({ name: "node2" });
604
+ it("returns the next sibling of the parent", () => {
605
+ expect(given.fromNode.getNextNode()).toMatchObject({
606
+ name: "node2",
610
607
  });
611
608
  });
612
609
  });
613
610
 
614
611
  context("with includeChildren is false", () => {
615
- given("includeChildren", () => false);
616
-
617
612
  context("with an open parent node", () => {
618
613
  given("fromNode", () => given.tree.getNodeByNameMustExist("node1"));
619
614
 
@@ -622,10 +617,63 @@ describe("getNextNode", () => {
622
617
  });
623
618
 
624
619
  it("returns the next sibling", () => {
625
- expect(given.nextNode).toMatchObject({ name: "node2" });
620
+ expect(given.fromNode.getNextNode(false)).toMatchObject({
621
+ name: "node2",
622
+ });
623
+ });
624
+ });
625
+ });
626
+ });
627
+
628
+ describe("getNextVisibleNode", () => {
629
+ interface Vars {
630
+ fromNode: Node;
631
+ tree: Node;
632
+ }
633
+ const given = getGiven<Vars>();
634
+ given("tree", () => new Node().loadFromData(exampleData));
635
+
636
+ context("with a parent node", () => {
637
+ given("fromNode", () => given.tree.getNodeByNameMustExist("node1"));
638
+
639
+ context("when the parent node is closed", () => {
640
+ it("returns the next sibling", () => {
641
+ expect(given.fromNode.getNextVisibleNode()).toMatchObject({
642
+ name: "node2",
643
+ });
644
+ });
645
+ });
646
+
647
+ context("when the parent node is open", () => {
648
+ beforeEach(() => {
649
+ given.fromNode.is_open = true;
650
+ });
651
+
652
+ it("returns the first child", () => {
653
+ expect(given.fromNode.getNextVisibleNode()).toMatchObject({
654
+ name: "child1",
655
+ });
626
656
  });
627
657
  });
628
658
  });
659
+
660
+ context("with the node is the last child", () => {
661
+ given("fromNode", () => given.tree.getNodeByNameMustExist("child2"));
662
+
663
+ it("returns the next sibling of the parent", () => {
664
+ expect(given.fromNode.getNextVisibleNode()).toMatchObject({
665
+ name: "node2",
666
+ });
667
+ });
668
+ });
669
+
670
+ context("with the tree node", () => {
671
+ given("fromNode", () => given.tree);
672
+
673
+ it("returns null", () => {
674
+ expect(given.fromNode.getNextVisibleNode()).toBeNull();
675
+ });
676
+ });
629
677
  });
630
678
 
631
679
  describe("getNextSibling", () => {
@@ -766,48 +814,92 @@ describe("getParent", () => {
766
814
 
767
815
  describe("getPreviousNode", () => {
768
816
  interface Vars {
769
- node2: Node;
770
- node3: Node;
771
817
  tree: Node;
772
818
  }
773
819
  const given = getGiven<Vars>();
774
- given("node2", () => given.tree.getNodeByNameMustExist("node2"));
775
- given("node3", () => given.tree.getNodeByNameMustExist("node3"));
776
820
  given("tree", () => new Node().loadFromData(exampleData));
777
821
 
778
- context("with a tree", () => {
779
- it("returns null", () => {
780
- expect(given.tree.getPreviousNode()).toBeNull();
822
+ it("returns null with a tree node", () => {
823
+ expect(given.tree.getPreviousNode()).toBeNull();
824
+ });
825
+
826
+ it("returns the last child of the previous sibling when the previous node is closed and has children", () => {
827
+ given.tree.getNodeByNameMustExist("node2").is_open = false;
828
+ const node2 = given.tree.getNodeByNameMustExist("node2");
829
+
830
+ expect(node2.getPreviousNode()).toMatchObject({
831
+ name: "child2",
781
832
  });
782
833
  });
783
834
 
784
- context("when the previous sibling has children", () => {
785
- context("when the previous node is closed", () => {
786
- it("returns the previous sibling", () => {
787
- expect(given.node2.getPreviousNode()).toMatchObject({
788
- name: "node1",
789
- });
790
- });
835
+ it("returns the last child of the previous sibling when the previous node is open and has children", () => {
836
+ given.tree.getNodeByNameMustExist("node2").is_open = true;
837
+ const node2 = given.tree.getNodeByNameMustExist("node2");
838
+
839
+ expect(node2.getPreviousNode()).toMatchObject({
840
+ name: "child2",
791
841
  });
842
+ });
792
843
 
793
- context("when the previous node is open", () => {
794
- beforeEach(() => {
795
- given.tree.getNodeByNameMustExist("node1").is_open = true;
796
- });
844
+ it("returns the first child if a node is the second child", () => {
845
+ const child2 = given.tree.getNodeByNameMustExist("child2");
797
846
 
798
- it("returns the last child of the previous sibling", () => {
799
- expect(given.node2.getPreviousNode()).toMatchObject({
800
- name: "child2",
801
- });
802
- });
847
+ expect(child2.getPreviousNode()).toMatchObject({
848
+ name: "child1",
803
849
  });
804
850
  });
805
851
 
806
- context("with a node that is the first child", () => {
807
- it("returns the parent", () => {
808
- expect(given.node3.getPreviousNode()).toMatchObject({
809
- name: "node2",
810
- });
852
+ it("returns the parent with a node that is the first child", () => {
853
+ const node3 = given.tree.getNodeByNameMustExist("node3");
854
+
855
+ expect(node3.getPreviousNode()).toMatchObject({
856
+ name: "node2",
857
+ });
858
+ });
859
+ });
860
+
861
+ describe("getPreviousVisibleNode", () => {
862
+ interface Vars {
863
+ tree: Node;
864
+ }
865
+ const given = getGiven<Vars>();
866
+ given("tree", () => new Node().loadFromData(exampleData));
867
+
868
+ it("returns null with a tree node", () => {
869
+ expect(given.tree.getPreviousVisibleNode()).toBeNull();
870
+ });
871
+
872
+ it("returns the previous sibling when the previous sibling is closed and has children", () => {
873
+ given.tree.getNodeByNameMustExist("node2").is_open = false;
874
+ const node2 = given.tree.getNodeByNameMustExist("node2");
875
+
876
+ expect(node2.getPreviousVisibleNode()).toMatchObject({
877
+ name: "node1",
878
+ });
879
+ });
880
+
881
+ it("returns the last child of the previous sibling when the previous sibling is open and has children", () => {
882
+ given.tree.getNodeByNameMustExist("node1").is_open = true;
883
+ const node2 = given.tree.getNodeByNameMustExist("node2");
884
+
885
+ expect(node2.getPreviousVisibleNode()).toMatchObject({
886
+ name: "child2",
887
+ });
888
+ });
889
+
890
+ it("returns the first child if a node is the second child", () => {
891
+ const child2 = given.tree.getNodeByNameMustExist("child2");
892
+
893
+ expect(child2.getPreviousVisibleNode()).toMatchObject({
894
+ name: "child1",
895
+ });
896
+ });
897
+
898
+ it("returns the parent when a node is the first child", () => {
899
+ const node3 = given.tree.getNodeByNameMustExist("node3");
900
+
901
+ expect(node3.getPreviousVisibleNode()).toMatchObject({
902
+ name: "node2",
811
903
  });
812
904
  });
813
905
  });
@@ -62,7 +62,7 @@ interface IJQTreeOptions {
62
62
  onGetStateFromStorage?: () => string;
63
63
  onSetStateFromStorage?: (data: string) => void;
64
64
  openedIcon?: string | Element;
65
- openFolderDelay?: number;
65
+ openFolderDelay?: number | false;
66
66
  rtl?: boolean;
67
67
  selectable?: boolean;
68
68
  saveState?: boolean | string;
@@ -1118,11 +1118,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
1118
1118
  }
1119
1119
 
1120
1120
  private doLoadData(data: NodeData[] | null, parentNode: Node | null): void {
1121
- if (!data) {
1122
- return;
1123
- } else {
1124
- this._triggerEvent("tree.load_data", { tree_data: data });
1125
-
1121
+ if (data) {
1126
1122
  if (parentNode) {
1127
1123
  this.deselectNodes(parentNode);
1128
1124
  this.loadSubtree(data, parentNode);
@@ -1134,6 +1130,11 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
1134
1130
  this.dndHandler.refresh();
1135
1131
  }
1136
1132
  }
1133
+
1134
+ this._triggerEvent("tree.load_data", {
1135
+ tree_data: data,
1136
+ parent_node: parentNode,
1137
+ });
1137
1138
  }
1138
1139
 
1139
1140
  private deselectNodes(parentNode: Node): void {
package/src/version.ts CHANGED
@@ -1,3 +1,3 @@
1
- const version = "1.6.2";
1
+ const version = "1.7.0";
2
2
 
3
3
  export default version;