cx 25.4.1 → 25.5.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 (140) hide show
  1. package/dist/charts.js +2 -2
  2. package/dist/data.js +17 -3
  3. package/dist/manifest.js +732 -732
  4. package/dist/ui.js +94 -61
  5. package/dist/widgets.js +25 -13
  6. package/package.json +1 -1
  7. package/src/charts/Legend.d.ts +45 -45
  8. package/src/charts/LegendEntry.js +128 -128
  9. package/src/charts/LegendEntry.scss +27 -27
  10. package/src/charts/PieChart.d.ts +92 -92
  11. package/src/charts/RangeMarker.js +6 -2
  12. package/src/charts/axis/Axis.d.ts +113 -113
  13. package/src/charts/axis/Axis.js +280 -280
  14. package/src/charts/axis/CategoryAxis.d.ts +30 -30
  15. package/src/charts/axis/CategoryAxis.js +241 -241
  16. package/src/charts/axis/NumericAxis.d.ts +46 -46
  17. package/src/charts/axis/NumericAxis.js +351 -351
  18. package/src/charts/axis/Stack.js +55 -55
  19. package/src/charts/axis/TimeAxis.d.ts +31 -28
  20. package/src/charts/axis/TimeAxis.js +611 -611
  21. package/src/charts/helpers/PointReducer.js +47 -47
  22. package/src/charts/helpers/SnapPointFinder.js +69 -69
  23. package/src/data/AugmentedViewBase.js +77 -75
  24. package/src/data/Binding.spec.js +69 -69
  25. package/src/data/ExposedRecordView.js +75 -70
  26. package/src/data/ExposedValueView.js +73 -72
  27. package/src/data/Expression.js +229 -229
  28. package/src/data/Expression.spec.js +229 -229
  29. package/src/data/Ref.d.ts +24 -24
  30. package/src/data/Ref.spec.js +79 -79
  31. package/src/data/StoreRef.spec.js +24 -24
  32. package/src/data/StringTemplate.js +92 -92
  33. package/src/data/StringTemplate.spec.js +132 -132
  34. package/src/data/StructuredDataAccessor.d.ts +7 -7
  35. package/src/data/StructuredSelector.js +132 -132
  36. package/src/data/SubscribableView.js +54 -54
  37. package/src/data/getAccessor.spec.js +11 -11
  38. package/src/data/getSelector.js +49 -49
  39. package/src/hooks/createLocalStorageRef.d.ts +3 -3
  40. package/src/hooks/createLocalStorageRef.js +20 -20
  41. package/src/index.scss +6 -6
  42. package/src/ui/Container.js +154 -183
  43. package/src/ui/Culture.d.ts +57 -57
  44. package/src/ui/Culture.js +139 -139
  45. package/src/ui/Cx.js +3 -3
  46. package/src/ui/DataProxy.js +45 -44
  47. package/src/ui/DetachedScope.js +98 -94
  48. package/src/ui/FocusManager.js +171 -171
  49. package/src/ui/Format.js +108 -108
  50. package/src/ui/HoverSync.js +147 -147
  51. package/src/ui/Instance.d.ts +1 -1
  52. package/src/ui/Instance.js +25 -16
  53. package/src/ui/IsolatedScope.js +30 -30
  54. package/src/ui/Repeater.d.ts +61 -61
  55. package/src/ui/Repeater.js +109 -102
  56. package/src/ui/Rescope.js +35 -31
  57. package/src/ui/Restate.js +167 -163
  58. package/src/ui/Widget.js +184 -200
  59. package/src/ui/adapter/ArrayAdapter.js +152 -142
  60. package/src/ui/adapter/TreeAdapter.js +101 -100
  61. package/src/ui/createFunctionalComponent.d.ts +1 -1
  62. package/src/ui/createFunctionalComponent.js +31 -36
  63. package/src/ui/layout/ContentPlaceholder.d.ts +19 -19
  64. package/src/ui/layout/ContentPlaceholder.js +105 -105
  65. package/src/ui/layout/ContentPlaceholder.spec.js +579 -579
  66. package/src/ui/layout/LabelsTopLayout.js +134 -134
  67. package/src/ui/layout/exploreChildren.d.ts +12 -15
  68. package/src/ui/layout/exploreChildren.js +27 -40
  69. package/src/util/Format.js +270 -270
  70. package/src/util/date/encodeDate.d.ts +1 -1
  71. package/src/util/date/encodeDate.js +8 -8
  72. package/src/util/date/encodeDateWithTimezoneOffset.d.ts +1 -1
  73. package/src/util/date/index.d.ts +11 -11
  74. package/src/util/date/index.js +11 -11
  75. package/src/util/date/parseDateInvariant.d.ts +3 -3
  76. package/src/util/date/parseDateInvariant.js +20 -20
  77. package/src/util/debounce.js +18 -18
  78. package/src/util/getSearchQueryPredicate.js +59 -59
  79. package/src/util/index.d.ts +51 -51
  80. package/src/util/index.js +54 -54
  81. package/src/util/isValidIdentifierName.d.ts +1 -1
  82. package/src/util/isValidIdentifierName.js +5 -5
  83. package/src/util/isValidIdentifierName.spec.js +33 -33
  84. package/src/util/scss/add-rules.scss +38 -38
  85. package/src/util/validatedDebounce.js +19 -19
  86. package/src/widgets/Button.js +118 -118
  87. package/src/widgets/CxCredit.scss +37 -37
  88. package/src/widgets/HighlightedSearchText.js +36 -36
  89. package/src/widgets/HighlightedSearchText.scss +18 -18
  90. package/src/widgets/List.js +594 -587
  91. package/src/widgets/List.scss +91 -91
  92. package/src/widgets/Sandbox.js +9 -8
  93. package/src/widgets/drag-drop/DropZone.js +214 -214
  94. package/src/widgets/form/Calendar.d.ts +86 -86
  95. package/src/widgets/form/Calendar.js +618 -618
  96. package/src/widgets/form/Calendar.scss +196 -196
  97. package/src/widgets/form/Checkbox.scss +127 -127
  98. package/src/widgets/form/ColorField.js +397 -397
  99. package/src/widgets/form/ColorField.scss +96 -96
  100. package/src/widgets/form/ColorPicker.scss +283 -283
  101. package/src/widgets/form/DateTimeField.js +576 -576
  102. package/src/widgets/form/DateTimePicker.js +392 -392
  103. package/src/widgets/form/LookupField.d.ts +179 -179
  104. package/src/widgets/form/LookupField.scss +219 -219
  105. package/src/widgets/form/MonthField.d.ts +99 -99
  106. package/src/widgets/form/MonthField.js +523 -523
  107. package/src/widgets/form/MonthPicker.d.ts +76 -76
  108. package/src/widgets/form/MonthPicker.js +641 -641
  109. package/src/widgets/form/MonthPicker.scss +118 -118
  110. package/src/widgets/form/NumberField.js +459 -459
  111. package/src/widgets/form/NumberField.scss +61 -61
  112. package/src/widgets/form/Radio.scss +121 -121
  113. package/src/widgets/form/Select.scss +99 -99
  114. package/src/widgets/form/Slider.scss +118 -118
  115. package/src/widgets/form/Switch.scss +140 -140
  116. package/src/widgets/form/TextArea.scss +43 -43
  117. package/src/widgets/form/TextField.js +290 -290
  118. package/src/widgets/form/TextField.scss +55 -55
  119. package/src/widgets/form/UploadButton.d.ts +34 -34
  120. package/src/widgets/form/variables.scss +353 -353
  121. package/src/widgets/grid/Grid.d.ts +442 -442
  122. package/src/widgets/grid/Grid.js +7 -0
  123. package/src/widgets/grid/GridRow.js +228 -228
  124. package/src/widgets/grid/TreeNode.d.ts +23 -23
  125. package/src/widgets/grid/TreeNode.scss +88 -88
  126. package/src/widgets/grid/variables.scss +133 -133
  127. package/src/widgets/nav/LinkButton.js +128 -128
  128. package/src/widgets/nav/Menu.scss +74 -74
  129. package/src/widgets/nav/Route.js +102 -106
  130. package/src/widgets/overlay/Dropdown.js +612 -612
  131. package/src/widgets/overlay/FlyweightTooltipTracker.js +39 -39
  132. package/src/widgets/overlay/Overlay.d.ts +73 -73
  133. package/src/widgets/overlay/Tooltip.js +1 -1
  134. package/src/widgets/overlay/Window.js +202 -202
  135. package/src/widgets/overlay/captureMouse.js +124 -124
  136. package/src/widgets/overlay/createHotPromiseWindowFactory.d.ts +18 -18
  137. package/src/widgets/overlay/createHotPromiseWindowFactory.js +56 -56
  138. package/src/widgets/overlay/index.d.ts +11 -11
  139. package/src/widgets/overlay/index.js +11 -11
  140. package/src/widgets/variables.scss +144 -144
@@ -1,128 +1,128 @@
1
- import { Widget, VDOM } from "../../ui/Widget";
2
- import { Button } from "../Button";
3
- import { History } from "../../ui/app/History";
4
- import { Url } from "../../ui/app/Url";
5
- import { routeAppend } from "../../util/routeAppend";
6
- import { parseStyle } from "../../util/parseStyle";
7
-
8
- export class LinkButton extends Button {
9
- init() {
10
- this.activeStyle = parseStyle(this.activeStyle);
11
- this.inactiveStyle = parseStyle(this.inactiveStyle);
12
- super.init();
13
- }
14
-
15
- declareData() {
16
- super.declareData(
17
- {
18
- href: undefined,
19
- url: undefined,
20
- target: undefined,
21
- active: undefined,
22
- activeClass: undefined,
23
- activeStyle: undefined,
24
- inactiveClass: undefined,
25
- inactiveStyle: undefined,
26
- },
27
- ...arguments,
28
- );
29
- }
30
-
31
- prepareData(context, instance) {
32
- let { data } = instance;
33
-
34
- data.unresolvedHref = data.href;
35
-
36
- if (typeof data.href === "string") {
37
- if (data.unresolvedHref[0] === "+")
38
- data.unresolvedHref = routeAppend(context.lastRoute.reverse(), data.href.substring(1));
39
-
40
- data.href = Url.resolve(data.unresolvedHref);
41
- }
42
-
43
- let active = this.isActive(data);
44
-
45
- data.stateMods = {
46
- disabled: data.disabled,
47
- active,
48
- };
49
-
50
- super.prepareData(context, instance);
51
-
52
- if (active) {
53
- if (data.activeClass) data.classNames += " " + data.activeClass;
54
- if (data.activeStyle)
55
- data.style = {
56
- ...data.style,
57
- ...parseStyle(data.activeStyle),
58
- };
59
- } else {
60
- if (data.inactiveClass) data.classNames += " " + data.inactiveClass;
61
- if (data.inactiveStyle)
62
- data.style = {
63
- ...data.style,
64
- ...parseStyle(data.inactiveStyle),
65
- };
66
- }
67
- }
68
-
69
- isActive(data) {
70
- if (data.active != null) return data.active;
71
-
72
- switch (this.match) {
73
- default:
74
- case "equal":
75
- return data.url === data.unresolvedHref;
76
-
77
- case "prefix":
78
- return data.url && data.unresolvedHref && data.url.indexOf(data.unresolvedHref) === 0;
79
-
80
- case "subroute":
81
- return (
82
- data.url &&
83
- data.unresolvedHref &&
84
- data.url.indexOf(data.unresolvedHref) === 0 &&
85
- (data.url === data.unresolvedHref || data.url[data.unresolvedHref.length] === "/")
86
- );
87
- }
88
- }
89
-
90
- attachProps(context, instance, props) {
91
- props.onClick = (ev) => {
92
- this.handleClick(ev, instance);
93
- };
94
- super.attachProps(context, instance, props);
95
- props.href = instance.data.href;
96
- delete props.active;
97
- delete props.activeClass;
98
- delete props.activeStyle;
99
- delete props.inactiveClass;
100
- delete props.inactiveStyle;
101
- }
102
-
103
- isValidHtmlAttribute(attr) {
104
- if (attr === "url" || attr === "match") return false;
105
- return super.isValidHtmlAttribute(attr);
106
- }
107
-
108
- handleClick(e, instance) {
109
- let { data } = instance;
110
-
111
- if (data.disabled) {
112
- e.preventDefault();
113
- return;
114
- }
115
-
116
- if (this.onClick && instance.invoke("onClick", e, instance) === false) return;
117
-
118
- if (data.href && Url.isLocal(data.href) && !e.ctrlKey && !e.shiftKey && !e.metaKey) {
119
- e.preventDefault();
120
- History.pushState({}, null, data.href);
121
- }
122
- }
123
- }
124
-
125
- LinkButton.prototype.match = "equal";
126
- LinkButton.prototype.tag = "a";
127
-
128
- Widget.alias("link-button", LinkButton);
1
+ import { Widget, VDOM } from "../../ui/Widget";
2
+ import { Button } from "../Button";
3
+ import { History } from "../../ui/app/History";
4
+ import { Url } from "../../ui/app/Url";
5
+ import { routeAppend } from "../../util/routeAppend";
6
+ import { parseStyle } from "../../util/parseStyle";
7
+
8
+ export class LinkButton extends Button {
9
+ init() {
10
+ this.activeStyle = parseStyle(this.activeStyle);
11
+ this.inactiveStyle = parseStyle(this.inactiveStyle);
12
+ super.init();
13
+ }
14
+
15
+ declareData() {
16
+ super.declareData(
17
+ {
18
+ href: undefined,
19
+ url: undefined,
20
+ target: undefined,
21
+ active: undefined,
22
+ activeClass: undefined,
23
+ activeStyle: undefined,
24
+ inactiveClass: undefined,
25
+ inactiveStyle: undefined,
26
+ },
27
+ ...arguments,
28
+ );
29
+ }
30
+
31
+ prepareData(context, instance) {
32
+ let { data } = instance;
33
+
34
+ data.unresolvedHref = data.href;
35
+
36
+ if (typeof data.href === "string") {
37
+ if (data.unresolvedHref[0] === "+")
38
+ data.unresolvedHref = routeAppend(context.lastRoute.reverse(), data.href.substring(1));
39
+
40
+ data.href = Url.resolve(data.unresolvedHref);
41
+ }
42
+
43
+ let active = this.isActive(data);
44
+
45
+ data.stateMods = {
46
+ disabled: data.disabled,
47
+ active,
48
+ };
49
+
50
+ super.prepareData(context, instance);
51
+
52
+ if (active) {
53
+ if (data.activeClass) data.classNames += " " + data.activeClass;
54
+ if (data.activeStyle)
55
+ data.style = {
56
+ ...data.style,
57
+ ...parseStyle(data.activeStyle),
58
+ };
59
+ } else {
60
+ if (data.inactiveClass) data.classNames += " " + data.inactiveClass;
61
+ if (data.inactiveStyle)
62
+ data.style = {
63
+ ...data.style,
64
+ ...parseStyle(data.inactiveStyle),
65
+ };
66
+ }
67
+ }
68
+
69
+ isActive(data) {
70
+ if (data.active != null) return data.active;
71
+
72
+ switch (this.match) {
73
+ default:
74
+ case "equal":
75
+ return data.url === data.unresolvedHref;
76
+
77
+ case "prefix":
78
+ return data.url && data.unresolvedHref && data.url.indexOf(data.unresolvedHref) === 0;
79
+
80
+ case "subroute":
81
+ return (
82
+ data.url &&
83
+ data.unresolvedHref &&
84
+ data.url.indexOf(data.unresolvedHref) === 0 &&
85
+ (data.url === data.unresolvedHref || data.url[data.unresolvedHref.length] === "/")
86
+ );
87
+ }
88
+ }
89
+
90
+ attachProps(context, instance, props) {
91
+ props.onClick = (ev) => {
92
+ this.handleClick(ev, instance);
93
+ };
94
+ super.attachProps(context, instance, props);
95
+ props.href = instance.data.href;
96
+ delete props.active;
97
+ delete props.activeClass;
98
+ delete props.activeStyle;
99
+ delete props.inactiveClass;
100
+ delete props.inactiveStyle;
101
+ }
102
+
103
+ isValidHtmlAttribute(attr) {
104
+ if (attr === "url" || attr === "match") return false;
105
+ return super.isValidHtmlAttribute(attr);
106
+ }
107
+
108
+ handleClick(e, instance) {
109
+ let { data } = instance;
110
+
111
+ if (data.disabled) {
112
+ e.preventDefault();
113
+ return;
114
+ }
115
+
116
+ if (this.onClick && instance.invoke("onClick", e, instance) === false) return;
117
+
118
+ if (data.href && Url.isLocal(data.href) && !e.ctrlKey && !e.shiftKey && !e.metaKey) {
119
+ e.preventDefault();
120
+ History.pushState({}, null, data.href);
121
+ }
122
+ }
123
+ }
124
+
125
+ LinkButton.prototype.match = "equal";
126
+ LinkButton.prototype.tag = "a";
127
+
128
+ Widget.alias("link-button", LinkButton);
@@ -1,74 +1,74 @@
1
- @mixin cx-menu($name: "menu", $state-style-map: $cx-menu-state-style-map, $besm: $cx-besm) {
2
- $block: map-get($besm, block);
3
- $element: map-get($besm, element);
4
- $state: map-get($besm, state);
5
- $mod: map-get($besm, mod);
6
-
7
- .#{$block}#{$name} {
8
- box-sizing: border-box;
9
- margin: 0;
10
- padding: 0;
11
- list-style: none;
12
-
13
- @include cx-add-state-rules($state-style-map, default);
14
-
15
- &.#{$state}horizontal {
16
- white-space: nowrap;
17
-
18
- & > .#{$element}#{$name}-item {
19
- display: inline-block;
20
- user-select: none;
21
-
22
- @each $size, $value in $cx-menu-padding-options {
23
- &.#{$state}size-#{$size} > .#{$mod}#{$name} {
24
- margin: 0 cx-right($value) 0 cx-left($value);
25
- }
26
- }
27
- }
28
- }
29
-
30
- @each $size, $value in $cx-menu-padding-options {
31
- &.#{$state}vertical.#{$state}#{$size}-item-padding .#{$mod}#{$name} {
32
- margin: $value;
33
- display: block;
34
- }
35
- }
36
-
37
- .#{$element}#{$name}-item {
38
- & > hr {
39
- border: none;
40
- border-top: 1px solid $cx-default-menu-separator-color;
41
- margin: map-get($cx-menu-padding-options, medium);
42
- }
43
-
44
- &.#{$state}hidden {
45
- visibility: hidden;
46
- position: absolute;
47
- }
48
- }
49
-
50
- &.#{$state}overflow {
51
- overflow: hidden;
52
- display: flex;
53
-
54
- & > .#{$element}#{$name}-item:last-child {
55
- visibility: hidden;
56
- position: absolute;
57
- max-height: 100%;
58
- }
59
-
60
- &.#{$state}pack > .#{$element}#{$name}-item:last-child {
61
- visibility: visible;
62
- position: relative;
63
- }
64
- }
65
- }
66
-
67
- .#{$element}#{$name}-spacer {
68
- flex: 1 1 0%;
69
- }
70
- }
71
-
72
- @if (cx-should-include("cx/widgets/Menu")) {
73
- @include cx-menu();
74
- }
1
+ @mixin cx-menu($name: "menu", $state-style-map: $cx-menu-state-style-map, $besm: $cx-besm) {
2
+ $block: map-get($besm, block);
3
+ $element: map-get($besm, element);
4
+ $state: map-get($besm, state);
5
+ $mod: map-get($besm, mod);
6
+
7
+ .#{$block}#{$name} {
8
+ box-sizing: border-box;
9
+ margin: 0;
10
+ padding: 0;
11
+ list-style: none;
12
+
13
+ @include cx-add-state-rules($state-style-map, default);
14
+
15
+ &.#{$state}horizontal {
16
+ white-space: nowrap;
17
+
18
+ & > .#{$element}#{$name}-item {
19
+ display: inline-block;
20
+ user-select: none;
21
+
22
+ @each $size, $value in $cx-menu-padding-options {
23
+ &.#{$state}size-#{$size} > .#{$mod}#{$name} {
24
+ margin: 0 cx-right($value) 0 cx-left($value);
25
+ }
26
+ }
27
+ }
28
+ }
29
+
30
+ @each $size, $value in $cx-menu-padding-options {
31
+ &.#{$state}vertical.#{$state}#{$size}-item-padding .#{$mod}#{$name} {
32
+ margin: $value;
33
+ display: block;
34
+ }
35
+ }
36
+
37
+ .#{$element}#{$name}-item {
38
+ & > hr {
39
+ border: none;
40
+ border-top: 1px solid $cx-default-menu-separator-color;
41
+ margin: map-get($cx-menu-padding-options, medium);
42
+ }
43
+
44
+ &.#{$state}hidden {
45
+ visibility: hidden;
46
+ position: absolute;
47
+ }
48
+ }
49
+
50
+ &.#{$state}overflow {
51
+ overflow: hidden;
52
+ display: flex;
53
+
54
+ & > .#{$element}#{$name}-item:last-child {
55
+ visibility: hidden;
56
+ position: absolute;
57
+ max-height: 100%;
58
+ }
59
+
60
+ &.#{$state}pack > .#{$element}#{$name}-item:last-child {
61
+ visibility: visible;
62
+ position: relative;
63
+ }
64
+ }
65
+ }
66
+
67
+ .#{$element}#{$name}-spacer {
68
+ flex: 1 1 0%;
69
+ }
70
+ }
71
+
72
+ @if (cx-should-include("cx/widgets/Menu")) {
73
+ @include cx-menu();
74
+ }
@@ -1,106 +1,102 @@
1
- import {Widget} from '../../ui/Widget';
2
- import {PureContainer} from '../../ui/PureContainer';
3
- import RouteMatcher from 'route-parser';
4
- import {ReadOnlyDataView} from '../../data/ReadOnlyDataView';
5
- import {routeAppend} from "../../util/routeAppend";
6
-
7
- export class Route extends PureContainer {
8
- init() {
9
- if (this.path)
10
- this.route = this.path;
11
-
12
- super.init();
13
-
14
- if (this.route && this.route[0] !== '+')
15
- this.matcher = new RouteMatcher(this.route + (this.prefix ? '(*remainder)' : ''));
16
- }
17
-
18
- initInstance(context, instance) {
19
- super.initInstance(context, instance);
20
- instance.store = new ReadOnlyDataView({
21
- store: instance.store
22
- });
23
- instance.setStore = store => {
24
- instance.store.setStore(store);
25
- };
26
- }
27
-
28
- declareData() {
29
- super.declareData(...arguments, {
30
- url: undefined
31
- });
32
- }
33
-
34
- checkVisible(context, instance, data) {
35
-
36
- if (!data.visible)
37
- return false;
38
-
39
- if (data.url !== instance.cached.url) {
40
- instance.cached.url = data.url;
41
- let matcher = this.matcher;
42
- let route = this.route;
43
- if (this.route[0] === '+') {
44
- route = routeAppend(context.lastRoute.route, this.route.substring(1));
45
- if (!instance.cached.matcher || instance.cached.route !== route)
46
- instance.cached.matcher = new RouteMatcher(route + (this.prefix ? '(*remainder)' : ''));
47
- matcher = instance.cached.matcher;
48
- }
49
- instance.cached.result = matcher.match(data.url);
50
- instance.cached.matcher = matcher;
51
- instance.cached.route = data.route = route;
52
- }
53
- if (!instance.cached.result)
54
- return false;
55
-
56
- return super.checkVisible(context, instance, data);
57
- }
58
-
59
- prepareData(context, {data, store, cached}) {
60
- super.prepareData(...arguments);
61
-
62
- store.setData({
63
- [this.recordName]: cached.result
64
- });
65
-
66
- //TODO: Replace comparison with deepEquals
67
- if (this.params && this.params.bind) {
68
- var params = store.get(this.params.bind);
69
- if (JSON.stringify(params) != JSON.stringify(cached.result)) {
70
- store.set(this.params.bind, cached.result);
71
- }
72
- }
73
-
74
- if (this.map) {
75
- for (var key in result) {
76
- var binding = this.map[key];
77
- if (binding)
78
- store.set(binding, result[key]);
79
- }
80
- }
81
- }
82
-
83
- explore(context, instance) {
84
- context.push('lastRoute', {
85
- route: instance.cached.route,
86
- result: instance.cached.result,
87
- reverse: function (data) {
88
- return instance.cached.matcher.reverse({
89
- ...instance.cached.result,
90
- remainder: '',
91
- ...data
92
- })
93
- }
94
- });
95
- super.explore(context, instance);
96
- }
97
-
98
- exploreCleanup(context, instance) {
99
- context.pop('lastRoute');
100
- }
101
- }
102
-
103
- Route.prototype.recordName = '$route';
104
- Route.prototype.prefix = false;
105
-
106
- Widget.alias('route', Route);
1
+ import { Widget } from "../../ui/Widget";
2
+ import { PureContainer } from "../../ui/PureContainer";
3
+ import RouteMatcher from "route-parser";
4
+ import { ReadOnlyDataView } from "../../data/ReadOnlyDataView";
5
+ import { routeAppend } from "../../util/routeAppend";
6
+
7
+ export class Route extends PureContainer {
8
+ init() {
9
+ if (this.path) this.route = this.path;
10
+
11
+ super.init();
12
+
13
+ if (this.route && this.route[0] !== "+")
14
+ this.matcher = new RouteMatcher(this.route + (this.prefix ? "(*remainder)" : ""));
15
+ }
16
+
17
+ initInstance(context, instance) {
18
+ instance.store = new ReadOnlyDataView({
19
+ store: instance.parentStore,
20
+ });
21
+ super.initInstance(context, instance);
22
+ }
23
+
24
+ applyParentStore(instance) {
25
+ instance.store.setStore(instance.parentStore);
26
+ }
27
+
28
+ declareData() {
29
+ super.declareData(...arguments, {
30
+ url: undefined,
31
+ });
32
+ }
33
+
34
+ checkVisible(context, instance, data) {
35
+ if (!data.visible) return false;
36
+
37
+ if (data.url !== instance.cached.url) {
38
+ instance.cached.url = data.url;
39
+ let matcher = this.matcher;
40
+ let route = this.route;
41
+ if (this.route[0] === "+") {
42
+ route = routeAppend(context.lastRoute.route, this.route.substring(1));
43
+ if (!instance.cached.matcher || instance.cached.route !== route)
44
+ instance.cached.matcher = new RouteMatcher(route + (this.prefix ? "(*remainder)" : ""));
45
+ matcher = instance.cached.matcher;
46
+ }
47
+ instance.cached.result = matcher.match(data.url);
48
+ instance.cached.matcher = matcher;
49
+ instance.cached.route = data.route = route;
50
+ }
51
+ if (!instance.cached.result) return false;
52
+
53
+ return super.checkVisible(context, instance, data);
54
+ }
55
+
56
+ prepareData(context, { data, store, cached }) {
57
+ super.prepareData(...arguments);
58
+
59
+ store.setData({
60
+ [this.recordName]: cached.result,
61
+ });
62
+
63
+ //TODO: Replace comparison with deepEquals
64
+ if (this.params && this.params.bind) {
65
+ var params = store.get(this.params.bind);
66
+ if (JSON.stringify(params) != JSON.stringify(cached.result)) {
67
+ store.set(this.params.bind, cached.result);
68
+ }
69
+ }
70
+
71
+ if (this.map) {
72
+ for (var key in result) {
73
+ var binding = this.map[key];
74
+ if (binding) store.set(binding, result[key]);
75
+ }
76
+ }
77
+ }
78
+
79
+ explore(context, instance) {
80
+ context.push("lastRoute", {
81
+ route: instance.cached.route,
82
+ result: instance.cached.result,
83
+ reverse: function (data) {
84
+ return instance.cached.matcher.reverse({
85
+ ...instance.cached.result,
86
+ remainder: "",
87
+ ...data,
88
+ });
89
+ },
90
+ });
91
+ super.explore(context, instance);
92
+ }
93
+
94
+ exploreCleanup(context, instance) {
95
+ context.pop("lastRoute");
96
+ }
97
+ }
98
+
99
+ Route.prototype.recordName = "$route";
100
+ Route.prototype.prefix = false;
101
+
102
+ Widget.alias("route", Route);