cx 26.0.14 → 26.1.1

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 (263) hide show
  1. package/build/ui/VDOM.d.ts +1 -20
  2. package/build/ui/VDOM.js +1 -3
  3. package/build/ui/Widget.d.ts +1 -1
  4. package/build/ui/Widget.js +0 -5
  5. package/build/ui/app/startAppLoop.js +2 -10
  6. package/build/util/Component.js +5 -0
  7. package/build/util/test/createTestRenderer.d.ts +3 -1
  8. package/build/util/test/createTestRenderer.js +8 -2
  9. package/build/widgets/form/Checkbox.d.ts +0 -1
  10. package/build/widgets/form/Checkbox.js +1 -0
  11. package/build/widgets/form/ColorField.d.ts +0 -1
  12. package/build/widgets/form/ColorField.js +2 -2
  13. package/build/widgets/form/DateTimeField.d.ts +0 -2
  14. package/build/widgets/form/DateTimeField.js +1 -0
  15. package/build/widgets/form/DateTimePicker.d.ts +0 -2
  16. package/build/widgets/form/DateTimePicker.js +1 -0
  17. package/build/widgets/form/Radio.d.ts +0 -1
  18. package/build/widgets/form/Slider.js +9 -1
  19. package/build/widgets/form/Switch.d.ts +0 -1
  20. package/build/widgets/form/Switch.js +1 -1
  21. package/build/widgets/form/Wheel.d.ts +0 -1
  22. package/build/widgets/grid/Grid.d.ts +0 -2
  23. package/build/widgets/grid/GridCellEditor.js +3 -1
  24. package/build/widgets/icons/calendar.js +4 -3
  25. package/build/widgets/icons/check.js +2 -2
  26. package/build/widgets/icons/clear.js +2 -2
  27. package/build/widgets/icons/close.js +2 -2
  28. package/build/widgets/icons/cx.js +2 -2
  29. package/build/widgets/icons/drop-down.js +2 -2
  30. package/build/widgets/icons/file.js +2 -2
  31. package/build/widgets/icons/folder-open.js +2 -2
  32. package/build/widgets/icons/folder.js +2 -2
  33. package/build/widgets/icons/forward.js +2 -2
  34. package/build/widgets/icons/loading.js +2 -2
  35. package/build/widgets/icons/menu.js +2 -2
  36. package/build/widgets/icons/pixel-picker.js +2 -2
  37. package/build/widgets/icons/search.js +2 -2
  38. package/build/widgets/icons/sort-asc.js +2 -2
  39. package/build/widgets/icons/square.js +2 -2
  40. package/build/widgets/overlay/Overlay.d.ts +3 -0
  41. package/build/widgets/overlay/Overlay.js +3 -2
  42. package/dist/manifest.js +867 -867
  43. package/dist/ui.js +4 -18
  44. package/dist/util.js +4 -0
  45. package/dist/widgets.js +395 -319
  46. package/package.json +11 -8
  47. package/src/charts/Chart.ts +108 -108
  48. package/src/core.d.ts +182 -182
  49. package/src/data/Expression.spec.ts +229 -229
  50. package/src/data/Expression.ts +233 -233
  51. package/src/data/Grouper.ts +158 -158
  52. package/src/data/Selector.ts +10 -10
  53. package/src/data/StringTemplate.spec.ts +132 -132
  54. package/src/data/StructuredSelector.ts +146 -146
  55. package/src/data/ZoomIntoPropertyView.spec.ts +64 -64
  56. package/src/data/comparer.ts +78 -78
  57. package/src/data/computable.spec.ts +87 -87
  58. package/src/data/createStructuredSelector.ts +62 -62
  59. package/src/data/getAccessor.spec.ts +11 -11
  60. package/src/data/getAccessor.ts +74 -74
  61. package/src/data/getSelector.spec.ts +43 -43
  62. package/src/data/getSelector.ts +66 -66
  63. package/src/data/ops/filter.spec.ts +35 -35
  64. package/src/data/ops/filter.ts +9 -9
  65. package/src/data/ops/merge.ts +13 -13
  66. package/src/data/ops/removeTreeNodes.spec.ts +37 -37
  67. package/src/data/ops/updateArray.spec.ts +69 -69
  68. package/src/data/ops/updateArray.ts +31 -31
  69. package/src/data/test-types.ts +7 -7
  70. package/src/hooks/invokeCallback.spec.tsx +4 -4
  71. package/src/hooks/resolveCallback.spec.tsx +4 -4
  72. package/src/hooks/store.spec.tsx +15 -15
  73. package/src/hooks/useTrigger.spec.tsx +16 -10
  74. package/src/hooks/useTrigger.ts +26 -26
  75. package/src/index.scss +6 -6
  76. package/src/jsx-runtime.ts +79 -79
  77. package/src/svg/BoundedObject.ts +101 -101
  78. package/src/svg/util/Rect.ts +105 -105
  79. package/src/ui/CSS.ts +87 -87
  80. package/src/ui/CSSHelper.ts +17 -17
  81. package/src/ui/ContentResolver.spec.tsx +31 -29
  82. package/src/ui/Controller.spec.tsx +47 -39
  83. package/src/ui/Culture.ts +159 -159
  84. package/src/ui/Cx.spec.tsx +10 -8
  85. package/src/ui/DataProxy.spec.tsx +18 -18
  86. package/src/ui/Instance.ts +866 -866
  87. package/src/ui/IsolatedScope.spec.tsx +16 -9
  88. package/src/ui/Prop.ts +140 -140
  89. package/src/ui/PureContainer.spec.tsx +20 -18
  90. package/src/ui/RenderingContext.ts +99 -99
  91. package/src/ui/Repeater.spec.tsx +8 -6
  92. package/src/ui/Rescope.spec.tsx +13 -13
  93. package/src/ui/Restate.spec.tsx +31 -27
  94. package/src/ui/StructuredInstanceDataAccessor.ts +32 -32
  95. package/src/ui/VDOM.ts +1 -34
  96. package/src/ui/Widget.tsx +0 -7
  97. package/src/ui/adapter/TreeAdapter.spec.ts +76 -76
  98. package/src/ui/adapter/TreeAdapter.ts +185 -185
  99. package/src/ui/app/History.ts +133 -133
  100. package/src/ui/app/Url.spec.ts +50 -50
  101. package/src/ui/app/startAppLoop.tsx +5 -9
  102. package/src/ui/app/startHotAppLoop.ts +41 -41
  103. package/src/ui/createFunctionalComponent.spec.tsx +20 -18
  104. package/src/ui/layout/ContentPlaceholder.spec.tsx +46 -34
  105. package/src/ui/layout/FirstVisibleChildLayout.spec.tsx +31 -19
  106. package/src/ui/layout/FirstVisibleChildLayout.ts +60 -60
  107. package/src/ui/selection/PropertySelection.ts +87 -87
  108. package/src/util/Component.spec.ts +30 -0
  109. package/src/util/Component.ts +301 -296
  110. package/src/util/Console.ts +13 -13
  111. package/src/util/DOM.ts +88 -88
  112. package/src/util/hasKey.ts +18 -18
  113. package/src/util/index.ts +55 -55
  114. package/src/util/isArray.ts +3 -3
  115. package/src/util/isDefined.ts +3 -3
  116. package/src/util/isString.ts +3 -3
  117. package/src/util/test/createTestRenderer.tsx +9 -2
  118. package/src/widgets/AccessorBindings.spec.tsx +4 -4
  119. package/src/widgets/DocumentTitle.ts +95 -95
  120. package/src/widgets/HtmlElement.spec.tsx +6 -6
  121. package/src/widgets/ReactElementWrapper.spec.tsx +37 -37
  122. package/src/widgets/autoFocus.ts +9 -9
  123. package/src/widgets/cx.ts +63 -63
  124. package/src/widgets/form/Checkbox.tsx +0 -1
  125. package/src/widgets/form/ColorField.tsx +15 -12
  126. package/src/widgets/form/DateTimeField.tsx +0 -2
  127. package/src/widgets/form/DateTimePicker.tsx +0 -2
  128. package/src/widgets/form/Radio.tsx +0 -1
  129. package/src/widgets/form/Slider.tsx +12 -4
  130. package/src/widgets/form/Switch.tsx +2 -3
  131. package/src/widgets/form/ValidationGroup.spec.tsx +12 -12
  132. package/src/widgets/form/Wheel.tsx +0 -1
  133. package/src/widgets/grid/Grid.tsx +0 -1
  134. package/src/widgets/grid/GridCellEditor.tsx +7 -1
  135. package/src/widgets/icons/calendar.tsx +20 -15
  136. package/src/widgets/icons/check.tsx +2 -1
  137. package/src/widgets/icons/clear.tsx +2 -1
  138. package/src/widgets/icons/close.tsx +2 -2
  139. package/src/widgets/icons/cx.tsx +2 -1
  140. package/src/widgets/icons/drop-down.tsx +2 -1
  141. package/src/widgets/icons/file.tsx +2 -1
  142. package/src/widgets/icons/folder-open.tsx +2 -1
  143. package/src/widgets/icons/folder.tsx +2 -1
  144. package/src/widgets/icons/forward.tsx +2 -1
  145. package/src/widgets/icons/loading.tsx +2 -1
  146. package/src/widgets/icons/menu.tsx +2 -1
  147. package/src/widgets/icons/pixel-picker.tsx +2 -2
  148. package/src/widgets/icons/search.tsx +2 -1
  149. package/src/widgets/icons/sort-asc.tsx +2 -1
  150. package/src/widgets/icons/square.tsx +2 -1
  151. package/src/widgets/nav/Route.spec.tsx +2 -2
  152. package/src/widgets/overlay/Overlay.tsx +5 -1
  153. package/src/widgets/overlay/captureMouse.ts +195 -195
  154. package/src/widgets/overlay/createHotPromiseWindowFactory.ts +71 -71
  155. package/src/widgets/overlay/index.d.ts +11 -11
  156. package/src/widgets/overlay/tooltip-ops.ts +173 -173
  157. package/build/data/ArrayElementView.spec.d.ts +0 -1
  158. package/build/data/ArrayElementView.spec.js +0 -81
  159. package/build/data/Binding.spec.d.ts +0 -1
  160. package/build/data/Binding.spec.js +0 -61
  161. package/build/data/Expression.spec.d.ts +0 -1
  162. package/build/data/Expression.spec.js +0 -196
  163. package/build/data/Grouper.spec.d.ts +0 -1
  164. package/build/data/Grouper.spec.js +0 -48
  165. package/build/data/Ref.spec.d.ts +0 -1
  166. package/build/data/Ref.spec.js +0 -72
  167. package/build/data/Store.spec.d.ts +0 -1
  168. package/build/data/Store.spec.js +0 -19
  169. package/build/data/StoreRef.spec.d.ts +0 -1
  170. package/build/data/StoreRef.spec.js +0 -22
  171. package/build/data/StringTemplate.spec.d.ts +0 -1
  172. package/build/data/StringTemplate.spec.js +0 -112
  173. package/build/data/StructuredSelector.spec.d.ts +0 -1
  174. package/build/data/StructuredSelector.spec.js +0 -102
  175. package/build/data/View.spec.d.ts +0 -1
  176. package/build/data/View.spec.js +0 -44
  177. package/build/data/ZoomIntoPropertyView.spec.d.ts +0 -1
  178. package/build/data/ZoomIntoPropertyView.spec.js +0 -54
  179. package/build/data/comparer.spec.d.ts +0 -1
  180. package/build/data/comparer.spec.js +0 -50
  181. package/build/data/computable.spec.d.ts +0 -1
  182. package/build/data/computable.spec.js +0 -56
  183. package/build/data/createAccessorModelProxy.spec.d.ts +0 -1
  184. package/build/data/createAccessorModelProxy.spec.js +0 -30
  185. package/build/data/createStructuredSelector.spec.d.ts +0 -1
  186. package/build/data/createStructuredSelector.spec.js +0 -42
  187. package/build/data/diff/diffs.spec.d.ts +0 -1
  188. package/build/data/diff/diffs.spec.js +0 -45
  189. package/build/data/getAccessor.spec.d.ts +0 -1
  190. package/build/data/getAccessor.spec.js +0 -10
  191. package/build/data/getSelector.spec.d.ts +0 -1
  192. package/build/data/getSelector.spec.js +0 -36
  193. package/build/data/ops/append.spec.d.ts +0 -1
  194. package/build/data/ops/append.spec.js +0 -24
  195. package/build/data/ops/filter.spec.d.ts +0 -1
  196. package/build/data/ops/filter.spec.js +0 -25
  197. package/build/data/ops/findTreeNode.spec.d.ts +0 -1
  198. package/build/data/ops/findTreeNode.spec.js +0 -20
  199. package/build/data/ops/merge.spec.d.ts +0 -1
  200. package/build/data/ops/merge.spec.js +0 -23
  201. package/build/data/ops/removeTreeNodes.spec.d.ts +0 -1
  202. package/build/data/ops/removeTreeNodes.spec.js +0 -35
  203. package/build/data/ops/updateArray.spec.d.ts +0 -1
  204. package/build/data/ops/updateArray.spec.js +0 -33
  205. package/build/data/ops/updateTree.spec.d.ts +0 -1
  206. package/build/data/ops/updateTree.spec.js +0 -44
  207. package/build/hooks/invokeCallback.spec.d.ts +0 -1
  208. package/build/hooks/invokeCallback.spec.js +0 -44
  209. package/build/hooks/resolveCallback.spec.d.ts +0 -1
  210. package/build/hooks/resolveCallback.spec.js +0 -35
  211. package/build/hooks/store.spec.d.ts +0 -1
  212. package/build/hooks/store.spec.js +0 -48
  213. package/build/hooks/useTrigger.spec.d.ts +0 -1
  214. package/build/hooks/useTrigger.spec.js +0 -59
  215. package/build/ui/Controller.spec.d.ts +0 -1
  216. package/build/ui/Controller.spec.js +0 -247
  217. package/build/ui/Cx.spec.d.ts +0 -1
  218. package/build/ui/Cx.spec.js +0 -153
  219. package/build/ui/DataProxy.spec.d.ts +0 -1
  220. package/build/ui/DataProxy.spec.js +0 -208
  221. package/build/ui/IsolatedScope.spec.d.ts +0 -1
  222. package/build/ui/IsolatedScope.spec.js +0 -42
  223. package/build/ui/PureContainer.spec.d.ts +0 -1
  224. package/build/ui/PureContainer.spec.js +0 -149
  225. package/build/ui/Repeater.spec.d.ts +0 -1
  226. package/build/ui/Repeater.spec.js +0 -109
  227. package/build/ui/Rescope.spec.d.ts +0 -1
  228. package/build/ui/Rescope.spec.js +0 -134
  229. package/build/ui/Restate.spec.d.ts +0 -1
  230. package/build/ui/Restate.spec.js +0 -257
  231. package/build/ui/adapter/ArrayAdapter.spec.d.ts +0 -1
  232. package/build/ui/adapter/ArrayAdapter.spec.js +0 -44
  233. package/build/ui/adapter/TreeAdapter.spec.d.ts +0 -1
  234. package/build/ui/adapter/TreeAdapter.spec.js +0 -71
  235. package/build/ui/app/Url.spec.d.ts +0 -1
  236. package/build/ui/app/Url.spec.js +0 -43
  237. package/build/ui/createFunctionalComponent.spec.d.ts +0 -1
  238. package/build/ui/createFunctionalComponent.spec.js +0 -272
  239. package/build/ui/layout/ContentPlaceholder.spec.d.ts +0 -1
  240. package/build/ui/layout/ContentPlaceholder.spec.js +0 -333
  241. package/build/ui/layout/FirstVisibleChildLayout.spec.d.ts +0 -1
  242. package/build/ui/layout/FirstVisibleChildLayout.spec.js +0 -101
  243. package/build/util/Format.spec.d.ts +0 -1
  244. package/build/util/Format.spec.js +0 -58
  245. package/build/util/TraversalStack.spec.d.ts +0 -1
  246. package/build/util/TraversalStack.spec.js +0 -43
  247. package/build/util/date/upperBoundCheck.spec.d.ts +0 -1
  248. package/build/util/date/upperBoundCheck.spec.js +0 -22
  249. package/build/util/getSearchQueryPredicate.spec.d.ts +0 -1
  250. package/build/util/getSearchQueryPredicate.spec.js +0 -33
  251. package/build/util/isValidIdentifierName.spec.d.ts +0 -1
  252. package/build/util/isValidIdentifierName.spec.js +0 -28
  253. package/build/util/routeAppend.spec.d.ts +0 -1
  254. package/build/util/routeAppend.spec.js +0 -14
  255. package/build/widgets/AccessorBindings.spec.d.ts +0 -1
  256. package/build/widgets/AccessorBindings.spec.js +0 -40
  257. package/build/widgets/HtmlElement.spec.d.ts +0 -1
  258. package/build/widgets/HtmlElement.spec.js +0 -38
  259. package/build/widgets/form/ValidationGroup.spec.d.ts +0 -1
  260. package/build/widgets/form/ValidationGroup.spec.js +0 -62
  261. package/build/widgets/nav/Route.spec.d.ts +0 -1
  262. package/build/widgets/nav/Route.spec.js +0 -15
  263. package/dist/manifest.d.ts +0 -1443
@@ -1,133 +1,133 @@
1
- import { Url } from "./Url";
2
- import { batchUpdatesAndNotify } from "../batchUpdates";
3
- import { SubscriberList } from "../../util/SubscriberList";
4
- import { View } from "../../data/View";
5
-
6
- interface Transition {
7
- url: string;
8
- state: any;
9
- title: string | null;
10
- replace: boolean;
11
- completed?: boolean;
12
- }
13
-
14
- type NavigateConfirmationCallback = (state: any) => boolean | Promise<boolean>;
15
-
16
- let last = 0;
17
- let next = 1;
18
- let transitions: Record<number, Transition> = {};
19
- let subscribers: SubscriberList | null = null;
20
- let reload = false;
21
- let navigateConfirmationCallback: NavigateConfirmationCallback | null = null;
22
- let permanentNavigateConfirmation = false;
23
-
24
- export class History {
25
- static store: View;
26
- static urlBinding: string;
27
- static hashBinding?: string;
28
-
29
- static connect(store: View, urlBinding: string, hashBinding?: string): void {
30
- this.store = store;
31
- this.urlBinding = urlBinding;
32
- this.hashBinding = hashBinding;
33
- this.updateStore();
34
- window.onpopstate = () => {
35
- this.updateStore();
36
- };
37
- }
38
-
39
- static pushState(state: any, title: string | null, url: string): boolean {
40
- return this.confirmAndNavigate(state, title, url);
41
- }
42
-
43
- static replaceState(state: any, title: string | null, url: string): boolean {
44
- return this.navigate(state, title, url, true);
45
- }
46
-
47
- static reloadOnNextChange(): void {
48
- reload = true;
49
- }
50
-
51
- static addNavigateConfirmation(callback: NavigateConfirmationCallback, permanent = false): void {
52
- navigateConfirmationCallback = callback;
53
- permanentNavigateConfirmation = permanent;
54
- }
55
-
56
- static confirm(continueCallback: () => boolean, state: any): boolean {
57
- if (!navigateConfirmationCallback) return continueCallback();
58
-
59
- let result = navigateConfirmationCallback(state);
60
- Promise.resolve(result).then((value) => {
61
- if (value) {
62
- if (!permanentNavigateConfirmation) navigateConfirmationCallback = null;
63
- continueCallback();
64
- }
65
- });
66
-
67
- return false;
68
- }
69
-
70
- static confirmAndNavigate(state: any, title: string | null, url: string, replace?: boolean): boolean {
71
- return this.confirm(() => this.navigate(state, title, url, replace), url);
72
- }
73
-
74
- static navigate(state: any, title: string | null, url: string, replace = false): boolean {
75
- url = Url.resolve(url);
76
-
77
- if (!window.history.pushState || reload) {
78
- window.location[replace ? "replace" : "assign"](url);
79
- return true;
80
- }
81
-
82
- let transition: Transition | undefined;
83
- let changed = false;
84
- batchUpdatesAndNotify(
85
- () => {
86
- changed = this.updateStore(url);
87
- if (changed)
88
- transitions[++last] = transition = {
89
- url,
90
- state,
91
- title,
92
- replace,
93
- };
94
- },
95
- () => {
96
- if (transition) transition.completed = true;
97
-
98
- //update history once the page is rendered and the title is set
99
- while (transitions[next] && transitions[next].completed) {
100
- let tr = transitions[next];
101
- delete transitions[next];
102
- next++;
103
- if (tr.replace) {
104
- window.history.replaceState(tr.state, tr.title ?? "", tr.url);
105
- if (subscribers) subscribers.notify(tr.url, "replaceState");
106
- } else {
107
- window.history.pushState(tr.state, tr.title ?? "", tr.url);
108
- if (subscribers) subscribers.notify(tr.url, "pushState");
109
- }
110
- }
111
- },
112
- );
113
-
114
- return changed;
115
- }
116
-
117
- static updateStore(href?: string): boolean {
118
- let url = Url.unresolve(href || document.location.href);
119
- let hash: string | null = null;
120
- let hashIndex = url.indexOf("#");
121
- if (hashIndex !== -1) {
122
- hash = url.substring(hashIndex);
123
- url = url.substring(0, hashIndex);
124
- }
125
- if (this.hashBinding) this.store.set(this.hashBinding, hash);
126
- return this.store.set(this.urlBinding, url);
127
- }
128
-
129
- static subscribe(callback: (url: string, op: string) => void): () => void {
130
- if (!subscribers) subscribers = new SubscriberList();
131
- return subscribers.subscribe(callback);
132
- }
133
- }
1
+ import { Url } from "./Url";
2
+ import { batchUpdatesAndNotify } from "../batchUpdates";
3
+ import { SubscriberList } from "../../util/SubscriberList";
4
+ import { View } from "../../data/View";
5
+
6
+ interface Transition {
7
+ url: string;
8
+ state: any;
9
+ title: string | null;
10
+ replace: boolean;
11
+ completed?: boolean;
12
+ }
13
+
14
+ type NavigateConfirmationCallback = (state: any) => boolean | Promise<boolean>;
15
+
16
+ let last = 0;
17
+ let next = 1;
18
+ let transitions: Record<number, Transition> = {};
19
+ let subscribers: SubscriberList | null = null;
20
+ let reload = false;
21
+ let navigateConfirmationCallback: NavigateConfirmationCallback | null = null;
22
+ let permanentNavigateConfirmation = false;
23
+
24
+ export class History {
25
+ static store: View;
26
+ static urlBinding: string;
27
+ static hashBinding?: string;
28
+
29
+ static connect(store: View, urlBinding: string, hashBinding?: string): void {
30
+ this.store = store;
31
+ this.urlBinding = urlBinding;
32
+ this.hashBinding = hashBinding;
33
+ this.updateStore();
34
+ window.onpopstate = () => {
35
+ this.updateStore();
36
+ };
37
+ }
38
+
39
+ static pushState(state: any, title: string | null, url: string): boolean {
40
+ return this.confirmAndNavigate(state, title, url);
41
+ }
42
+
43
+ static replaceState(state: any, title: string | null, url: string): boolean {
44
+ return this.navigate(state, title, url, true);
45
+ }
46
+
47
+ static reloadOnNextChange(): void {
48
+ reload = true;
49
+ }
50
+
51
+ static addNavigateConfirmation(callback: NavigateConfirmationCallback, permanent = false): void {
52
+ navigateConfirmationCallback = callback;
53
+ permanentNavigateConfirmation = permanent;
54
+ }
55
+
56
+ static confirm(continueCallback: () => boolean, state: any): boolean {
57
+ if (!navigateConfirmationCallback) return continueCallback();
58
+
59
+ let result = navigateConfirmationCallback(state);
60
+ Promise.resolve(result).then((value) => {
61
+ if (value) {
62
+ if (!permanentNavigateConfirmation) navigateConfirmationCallback = null;
63
+ continueCallback();
64
+ }
65
+ });
66
+
67
+ return false;
68
+ }
69
+
70
+ static confirmAndNavigate(state: any, title: string | null, url: string, replace?: boolean): boolean {
71
+ return this.confirm(() => this.navigate(state, title, url, replace), url);
72
+ }
73
+
74
+ static navigate(state: any, title: string | null, url: string, replace = false): boolean {
75
+ url = Url.resolve(url);
76
+
77
+ if (!window.history.pushState || reload) {
78
+ window.location[replace ? "replace" : "assign"](url);
79
+ return true;
80
+ }
81
+
82
+ let transition: Transition | undefined;
83
+ let changed = false;
84
+ batchUpdatesAndNotify(
85
+ () => {
86
+ changed = this.updateStore(url);
87
+ if (changed)
88
+ transitions[++last] = transition = {
89
+ url,
90
+ state,
91
+ title,
92
+ replace,
93
+ };
94
+ },
95
+ () => {
96
+ if (transition) transition.completed = true;
97
+
98
+ //update history once the page is rendered and the title is set
99
+ while (transitions[next] && transitions[next].completed) {
100
+ let tr = transitions[next];
101
+ delete transitions[next];
102
+ next++;
103
+ if (tr.replace) {
104
+ window.history.replaceState(tr.state, tr.title ?? "", tr.url);
105
+ if (subscribers) subscribers.notify(tr.url, "replaceState");
106
+ } else {
107
+ window.history.pushState(tr.state, tr.title ?? "", tr.url);
108
+ if (subscribers) subscribers.notify(tr.url, "pushState");
109
+ }
110
+ }
111
+ },
112
+ );
113
+
114
+ return changed;
115
+ }
116
+
117
+ static updateStore(href?: string): boolean {
118
+ let url = Url.unresolve(href || document.location.href);
119
+ let hash: string | null = null;
120
+ let hashIndex = url.indexOf("#");
121
+ if (hashIndex !== -1) {
122
+ hash = url.substring(hashIndex);
123
+ url = url.substring(0, hashIndex);
124
+ }
125
+ if (this.hashBinding) this.store.set(this.hashBinding, hash);
126
+ return this.store.set(this.urlBinding, url);
127
+ }
128
+
129
+ static subscribe(callback: (url: string, op: string) => void): () => void {
130
+ if (!subscribers) subscribers = new SubscriberList();
131
+ return subscribers.subscribe(callback);
132
+ }
133
+ }
@@ -1,50 +1,50 @@
1
- import { Url } from "./Url";
2
- import Route from "route-parser";
3
- import assert from "assert";
4
- describe("Url", function () {
5
- describe(".unresolve", function () {
6
- it("preserves query parameters", function () {
7
- Url.absoluteBase = "https://cxjs.io/docs/";
8
- assert.equal("~/?state=1", Url.unresolve("https://cxjs.io/docs/?state=1"));
9
- });
10
-
11
- it("doesn't touch unresolved urls", function () {
12
- assert.equal("~/test", Url.unresolve("~/test"));
13
- });
14
- });
15
-
16
- describe(".getBaseFromScriptSrc", () => {
17
- it("ignores query strings", function () {
18
- assert.equal(Url.getBaseFromScriptSrc("/vendor.js?qs=1", "~/vendor.js"), "/");
19
- });
20
-
21
- it("allows wildcards", function () {
22
- assert.equal(Url.getBaseFromScriptSrc("/vendor.123.js?qs=1", "~/vendor.*.js"), "/");
23
- });
24
-
25
- it("works for an application folder", function () {
26
- assert.equal(Url.getBaseFromScriptSrc("/datasync/vendor.124c82.js", "~/vendor.*.js"), "/datasync/");
27
- });
28
- });
29
- });
30
-
31
- describe("Route", function () {
32
- it("matches query param", function () {
33
- let route = new Route("~/?state=:state");
34
- let result = route.match("~/?state=1");
35
- assert(result !== false);
36
- assert.equal(result.state, "1");
37
- });
38
-
39
- it("matches routes with extra query params", function () {
40
- let route = new Route("~/?state=:state");
41
- let result = route.match("~/?state=1&more=2");
42
- assert(result);
43
- });
44
-
45
- it.skip("matches query params in any order", function () {
46
- let route = new Route("~/?a=:a&b=:b");
47
- let result = route.match("~/?b=1&a=2");
48
- assert(result);
49
- });
50
- });
1
+ import { Url } from "./Url";
2
+ import Route from "route-parser";
3
+ import assert from "assert";
4
+ describe("Url", function () {
5
+ describe(".unresolve", function () {
6
+ it("preserves query parameters", function () {
7
+ Url.absoluteBase = "https://cxjs.io/docs/";
8
+ assert.equal("~/?state=1", Url.unresolve("https://cxjs.io/docs/?state=1"));
9
+ });
10
+
11
+ it("doesn't touch unresolved urls", function () {
12
+ assert.equal("~/test", Url.unresolve("~/test"));
13
+ });
14
+ });
15
+
16
+ describe(".getBaseFromScriptSrc", () => {
17
+ it("ignores query strings", function () {
18
+ assert.equal(Url.getBaseFromScriptSrc("/vendor.js?qs=1", "~/vendor.js"), "/");
19
+ });
20
+
21
+ it("allows wildcards", function () {
22
+ assert.equal(Url.getBaseFromScriptSrc("/vendor.123.js?qs=1", "~/vendor.*.js"), "/");
23
+ });
24
+
25
+ it("works for an application folder", function () {
26
+ assert.equal(Url.getBaseFromScriptSrc("/datasync/vendor.124c82.js", "~/vendor.*.js"), "/datasync/");
27
+ });
28
+ });
29
+ });
30
+
31
+ describe("Route", function () {
32
+ it("matches query param", function () {
33
+ let route = new Route("~/?state=:state");
34
+ let result = route.match("~/?state=1");
35
+ assert(result !== false);
36
+ assert.equal(result.state, "1");
37
+ });
38
+
39
+ it("matches routes with extra query params", function () {
40
+ let route = new Route("~/?state=:state");
41
+ let result = route.match("~/?state=1&more=2");
42
+ assert(result);
43
+ });
44
+
45
+ it.skip("matches query params in any order", function () {
46
+ let route = new Route("~/?a=:a&b=:b");
47
+ let result = route.match("~/?b=1&a=2");
48
+ assert(result);
49
+ });
50
+ });
@@ -1,6 +1,7 @@
1
1
  /** @jsxImportSource react */
2
2
 
3
- import { Widget, VDOM, WidgetConfig } from "../Widget";
3
+ import type { Root } from "cx-react";
4
+ import { Widget, VDOM } from "../Widget";
4
5
  import { Store } from "../../data/Store";
5
6
  import { Cx } from "../Cx";
6
7
  import { Instance } from "../Instance";
@@ -44,11 +45,8 @@ export function startAppLoop(
44
45
  />
45
46
  ) as any;
46
47
 
47
- let root: any = null;
48
- if (VDOM.DOM.createRoot) {
49
- root = VDOM.DOM.createRoot(parentDOMElement);
50
- root.render(content);
51
- } else VDOM.DOM.render(content, parentDOMElement);
48
+ let root = VDOM.DOM.createRoot(parentDOMElement);
49
+ root.render(content);
52
50
 
53
51
  let stopped = false;
54
52
 
@@ -66,10 +64,8 @@ export function startAppLoop(
66
64
  };
67
65
  }
68
66
 
69
- function destroy(parentDOMElement: HTMLElement, options: StartAppLoopOptions, root: any): void {
67
+ function destroy(parentDOMElement: HTMLElement, options: StartAppLoopOptions, root: Root): void {
70
68
  if (root) root.unmount();
71
- else VDOM.DOM.unmountComponentAtNode(parentDOMElement);
72
-
73
69
  if (options.removeParentDOMElement && parentDOMElement.parentNode)
74
70
  parentDOMElement.parentNode.removeChild(parentDOMElement);
75
71
  }
@@ -1,41 +1,41 @@
1
- import { startAppLoop, StartAppLoopOptions } from "./startAppLoop";
2
- import { Widget, WidgetConfig } from "../Widget";
3
- import { Store } from "../../data/Store";
4
- import { Create } from "../../util/Component";
5
-
6
- export interface HotModule {
7
- hot?: {
8
- accept: () => void;
9
- dispose: (callback: (data: any) => void) => void;
10
- data?: any;
11
- };
12
- }
13
-
14
- export function startHotAppLoop(
15
- appModule: HotModule,
16
- element: HTMLElement,
17
- store: Store,
18
- widgets: Create<typeof Widget> | Create<typeof Widget>[],
19
- options: StartAppLoopOptions = {},
20
- ): () => void {
21
- let stop: (() => void) | undefined;
22
- //webpack (HMR)
23
- if (appModule.hot) {
24
- // accept itself
25
- appModule.hot.accept();
26
-
27
- // remember data on dispose
28
- appModule.hot.dispose(function (data: any) {
29
- data.state = store.getData();
30
- if (stop) stop();
31
- });
32
-
33
- //apply data on hot replace
34
- if (appModule.hot.data?.state) store.load(appModule.hot.data.state);
35
- }
36
-
37
- Widget.resetCounter();
38
-
39
- //app loop
40
- return (stop = startAppLoop(element, store, widgets, options));
41
- }
1
+ import { startAppLoop, StartAppLoopOptions } from "./startAppLoop";
2
+ import { Widget, WidgetConfig } from "../Widget";
3
+ import { Store } from "../../data/Store";
4
+ import { Create } from "../../util/Component";
5
+
6
+ export interface HotModule {
7
+ hot?: {
8
+ accept: () => void;
9
+ dispose: (callback: (data: any) => void) => void;
10
+ data?: any;
11
+ };
12
+ }
13
+
14
+ export function startHotAppLoop(
15
+ appModule: HotModule,
16
+ element: HTMLElement,
17
+ store: Store,
18
+ widgets: Create<typeof Widget> | Create<typeof Widget>[],
19
+ options: StartAppLoopOptions = {},
20
+ ): () => void {
21
+ let stop: (() => void) | undefined;
22
+ //webpack (HMR)
23
+ if (appModule.hot) {
24
+ // accept itself
25
+ appModule.hot.accept();
26
+
27
+ // remember data on dispose
28
+ appModule.hot.dispose(function (data: any) {
29
+ data.state = store.getData();
30
+ if (stop) stop();
31
+ });
32
+
33
+ //apply data on hot replace
34
+ if (appModule.hot.data?.state) store.load(appModule.hot.data.state);
35
+ }
36
+
37
+ Widget.resetCounter();
38
+
39
+ //app loop
40
+ return (stop = startAppLoop(element, store, widgets, options));
41
+ }
@@ -2,7 +2,7 @@ import { Store } from "../data/Store";
2
2
  import { createFunctionalComponent } from "./createFunctionalComponent";
3
3
  import { bind } from "./bind";
4
4
  import { expr } from "./expr";
5
- import { createTestRenderer } from "../util/test/createTestRenderer";
5
+ import { createTestRenderer, act } from "../util/test/createTestRenderer";
6
6
 
7
7
  import assert from "assert";
8
8
  import { Rescope } from "./Rescope";
@@ -66,7 +66,7 @@ describe("createFunctionalComponent type safety", () => {
66
66
  });
67
67
 
68
68
  describe("createFunctionalComponent", () => {
69
- it("allows spread", () => {
69
+ it("allows spread", async () => {
70
70
  const SuperDiv = createFunctionalComponent(({ ...props }) => {
71
71
  return (
72
72
  <cx>
@@ -88,7 +88,7 @@ describe("createFunctionalComponent", () => {
88
88
 
89
89
  let store = new Store();
90
90
 
91
- const component = createTestRenderer(store, widget);
91
+ const component = await createTestRenderer(store, widget);
92
92
 
93
93
  let tree = component.toJSON();
94
94
  assert.deepEqual(tree, {
@@ -103,7 +103,7 @@ describe("createFunctionalComponent", () => {
103
103
  });
104
104
  });
105
105
 
106
- it("visible and Rescope behave as expected", () => {
106
+ it("visible and Rescope behave as expected", async () => {
107
107
  const RootRescope = createFunctionalComponent(({}) => {
108
108
  return (
109
109
  <cx>
@@ -128,7 +128,7 @@ describe("createFunctionalComponent", () => {
128
128
  },
129
129
  });
130
130
 
131
- const component = createTestRenderer(store, widget);
131
+ const component = await createTestRenderer(store, widget);
132
132
 
133
133
  let tree = component.toJSON();
134
134
  assert.deepEqual(tree, {
@@ -138,7 +138,7 @@ describe("createFunctionalComponent", () => {
138
138
  });
139
139
  });
140
140
 
141
- it("visible and multiple items behave as expected", () => {
141
+ it("visible and multiple items behave as expected", async () => {
142
142
  const FComponent = createFunctionalComponent(({}) => {
143
143
  return (
144
144
  <cx>
@@ -157,7 +157,7 @@ describe("createFunctionalComponent", () => {
157
157
 
158
158
  let store = new Store();
159
159
 
160
- const component = createTestRenderer(store, widget);
160
+ const component = await createTestRenderer(store, widget);
161
161
 
162
162
  let tree = component.toJSON();
163
163
  assert.deepEqual(tree, [
@@ -174,7 +174,7 @@ describe("createFunctionalComponent", () => {
174
174
  ]);
175
175
  });
176
176
 
177
- it("respects inner layouts", () => {
177
+ it("respects inner layouts", async () => {
178
178
  const FComponent = createFunctionalComponent(({}) => {
179
179
  return (
180
180
  <cx>
@@ -194,7 +194,7 @@ describe("createFunctionalComponent", () => {
194
194
 
195
195
  let store = new Store();
196
196
 
197
- const component = createTestRenderer(store, widget);
197
+ const component = await createTestRenderer(store, widget);
198
198
 
199
199
  let tree = component.toJSON();
200
200
 
@@ -279,7 +279,7 @@ describe("createFunctionalComponent", () => {
279
279
  });
280
280
  });
281
281
 
282
- it("can use refs for data bindings", () => {
282
+ it("can use refs for data bindings", async () => {
283
283
  const X = createFunctionalComponent(({}) => {
284
284
  let { ref } = useStoreMethods();
285
285
  let x = ref("x", "OK");
@@ -298,7 +298,7 @@ describe("createFunctionalComponent", () => {
298
298
 
299
299
  let store = new Store();
300
300
 
301
- const component = createTestRenderer(store, widget);
301
+ const component = await createTestRenderer(store, widget);
302
302
 
303
303
  let tree = component.toJSON();
304
304
  assert.deepEqual(tree, {
@@ -308,7 +308,7 @@ describe("createFunctionalComponent", () => {
308
308
  });
309
309
  });
310
310
 
311
- it("adds children at the right place", () => {
311
+ it("adds children at the right place", async () => {
312
312
  const X = createFunctionalComponent(({ children }: { children: any }) => (
313
313
  <cx>
314
314
  <header />
@@ -327,7 +327,7 @@ describe("createFunctionalComponent", () => {
327
327
 
328
328
  let store = new Store();
329
329
 
330
- const component = createTestRenderer(store, widget);
330
+ const component = await createTestRenderer(store, widget);
331
331
 
332
332
  let tree = component.toJSON();
333
333
 
@@ -356,7 +356,7 @@ describe("createFunctionalComponent", () => {
356
356
  ]);
357
357
  });
358
358
 
359
- it("works well with repeaters", () => {
359
+ it("works well with repeaters", async () => {
360
360
  const X = createFunctionalComponent(({}) => {
361
361
  let { ref } = useStoreMethods();
362
362
  let text = ref("$record.text");
@@ -377,7 +377,7 @@ describe("createFunctionalComponent", () => {
377
377
 
378
378
  let store = new Store({ data: { array: [{ text: "0" }, { text: "1" }, { text: "2" }] } });
379
379
 
380
- const component = createTestRenderer(store, widget);
380
+ const component = await createTestRenderer(store, widget);
381
381
 
382
382
  let tree = component.toJSON();
383
383
 
@@ -399,7 +399,9 @@ describe("createFunctionalComponent", () => {
399
399
  },
400
400
  ]);
401
401
 
402
- store.update("array", (array) => [array[0], { text: "10" }, array[2]]);
402
+ await act(async () => {
403
+ store.update("array", (array) => [array[0], { text: "10" }, array[2]]);
404
+ });
403
405
 
404
406
  tree = component.toJSON();
405
407
 
@@ -422,7 +424,7 @@ describe("createFunctionalComponent", () => {
422
424
  ]);
423
425
  });
424
426
 
425
- it("can have its own layout", () => {
427
+ it("can have its own layout", async () => {
426
428
  const X = createFunctionalComponent(() => (
427
429
  <cx>
428
430
  <div>1</div>
@@ -439,7 +441,7 @@ describe("createFunctionalComponent", () => {
439
441
 
440
442
  let store = new Store();
441
443
 
442
- const component = createTestRenderer(store, widget);
444
+ const component = await createTestRenderer(store, widget);
443
445
 
444
446
  let tree = component.toJSON();
445
447