@lushly-dev/fast-element 3.0.1-preview.0 → 3.0.1-preview.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.
- package/CHANGELOG.md +6 -0
- package/dist/command/command.api.json +7857 -0
- package/dist/context/context.api.json +1084 -0
- package/dist/declarative/declarative.api.json +8130 -0
- package/dist/definition-schema/definition-schema.api.json +2689 -0
- package/dist/di/di.api.json +4945 -0
- package/dist/dts/arrays.d.ts +2 -0
- package/dist/dts/binding/binding.d.ts +59 -0
- package/dist/dts/binding/exports.d.ts +9 -0
- package/dist/dts/binding/normalize.d.ts +9 -0
- package/dist/dts/binding/one-time.d.ts +11 -0
- package/dist/dts/binding/one-way.d.ts +20 -0
- package/dist/dts/binding/signal.d.ts +36 -0
- package/dist/dts/binding/two-way.d.ts +44 -0
- package/dist/dts/command/behavior.d.ts +94 -0
- package/dist/dts/command/behaviors/confirm-behavior.d.ts +139 -0
- package/dist/dts/command/behaviors/undo-behavior.d.ts +178 -0
- package/dist/dts/command/command.d.ts +79 -0
- package/dist/dts/command/component-registry.d.ts +50 -0
- package/dist/dts/command/components/confirm-dialog.d.ts +117 -0
- package/dist/dts/command/index.d.ts +21 -0
- package/dist/dts/command/registry.d.ts +201 -0
- package/dist/dts/command/schema-validation.d.ts +45 -0
- package/dist/dts/command/types.d.ts +332 -0
- package/dist/dts/command/validation.d.ts +116 -0
- package/dist/dts/command/weak-ref.d.ts +11 -0
- package/dist/dts/components/attributes.d.ts +153 -0
- package/dist/dts/components/definition-schema-transforms.d.ts +9 -0
- package/dist/dts/components/element-controller.d.ts +349 -0
- package/dist/dts/components/element-hydration.d.ts +2 -0
- package/dist/dts/components/enable-hydration.d.ts +66 -0
- package/dist/dts/components/fast-definitions.d.ts +211 -0
- package/dist/dts/components/fast-element-registry.d.ts +23 -0
- package/dist/dts/components/fast-element.d.ts +91 -0
- package/dist/dts/components/hydration-tracker.d.ts +110 -0
- package/dist/dts/components/hydration.d.ts +52 -0
- package/dist/dts/components/schema.d.ts +205 -0
- package/dist/dts/context.d.ts +171 -0
- package/dist/dts/debug.d.ts +5 -0
- package/dist/dts/declarative/attribute-map.d.ts +58 -0
- package/dist/dts/declarative/debug.d.ts +4 -0
- package/dist/dts/declarative/index.d.ts +14 -0
- package/dist/dts/declarative/interfaces.d.ts +8 -0
- package/dist/dts/declarative/observer-map-utilities.d.ts +58 -0
- package/dist/dts/declarative/observer-map.d.ts +89 -0
- package/dist/dts/declarative/runtime.d.ts +5 -0
- package/dist/dts/declarative/syntax.d.ts +21 -0
- package/dist/dts/declarative/template-bridge.d.ts +33 -0
- package/dist/dts/declarative/template-parser.d.ts +98 -0
- package/dist/dts/declarative/template.d.ts +9 -0
- package/dist/dts/declarative/utilities.d.ts +358 -0
- package/dist/dts/definition-schema/api.d.ts +42 -0
- package/dist/dts/definition-schema/cem.d.ts +78 -0
- package/dist/dts/definition-schema/extension.d.ts +18 -0
- package/dist/dts/definition-schema/extract.d.ts +38 -0
- package/dist/dts/definition-schema/index.d.ts +9 -0
- package/dist/dts/definition-schema/storage.d.ts +35 -0
- package/dist/dts/definition-schema/types.d.ts +176 -0
- package/dist/dts/dev-mode.d.ts +13 -0
- package/dist/dts/di/di.d.ts +894 -0
- package/dist/dts/dom-policy.d.ts +101 -0
- package/dist/dts/dom.d.ts +88 -0
- package/dist/dts/hydration/diagnostics.d.ts +93 -0
- package/dist/dts/hydration/exports.d.ts +18 -0
- package/dist/dts/hydration/hydration-debugger.d.ts +35 -0
- package/dist/dts/hydration/messages.d.ts +62 -0
- package/dist/dts/hydration/runtime.d.ts +7 -0
- package/dist/dts/hydration/target-builder.d.ts +107 -0
- package/dist/dts/index.d.ts +51 -0
- package/dist/dts/index.debug.d.ts +1 -0
- package/dist/dts/index.rollup.d.ts +1 -0
- package/dist/dts/index.rollup.debug.d.ts +1 -0
- package/dist/dts/interfaces.d.ts +106 -0
- package/dist/dts/metadata.d.ts +26 -0
- package/dist/dts/observation/arrays.d.ts +248 -0
- package/dist/dts/observation/notifier.d.ts +127 -0
- package/dist/dts/observation/observable.d.ts +276 -0
- package/dist/dts/observation/update-queue.d.ts +40 -0
- package/dist/dts/observation/volatile.d.ts +9 -0
- package/dist/dts/platform.d.ts +87 -0
- package/dist/dts/registry.d.ts +2 -0
- package/dist/dts/render.d.ts +7 -0
- package/dist/dts/schema.d.ts +1 -0
- package/dist/dts/scoped/detection.d.ts +55 -0
- package/dist/dts/scoped/index.d.ts +68 -0
- package/dist/dts/scoped/mixin.d.ts +118 -0
- package/dist/dts/scoped/registry.d.ts +76 -0
- package/dist/dts/scoped/types.d.ts +48 -0
- package/dist/dts/state/exports.d.ts +3 -0
- package/dist/dts/state/reactive.d.ts +8 -0
- package/dist/dts/state/state.d.ts +141 -0
- package/dist/dts/state/visitor.d.ts +6 -0
- package/dist/dts/state/watch.d.ts +10 -0
- package/dist/dts/styles/css-directive.d.ts +50 -0
- package/dist/dts/styles/css.d.ts +34 -0
- package/dist/dts/styles/element-styles.d.ts +61 -0
- package/dist/dts/styles/host.d.ts +65 -0
- package/dist/dts/styles/style-strategy.d.ts +42 -0
- package/dist/dts/templating/children.d.ts +62 -0
- package/dist/dts/templating/compiler.d.ts +54 -0
- package/dist/dts/templating/html-binding-directive.d.ts +155 -0
- package/dist/dts/templating/html-directive.d.ts +218 -0
- package/dist/dts/templating/html.d.ts +1 -0
- package/dist/dts/templating/hydration-view.d.ts +130 -0
- package/dist/dts/templating/markup.d.ts +48 -0
- package/dist/dts/templating/node-observation.d.ts +99 -0
- package/dist/dts/templating/ref.d.ts +23 -0
- package/dist/dts/templating/render.d.ts +318 -0
- package/dist/dts/templating/repeat.d.ts +131 -0
- package/dist/dts/templating/slotted.d.ts +38 -0
- package/dist/dts/templating/template.d.ts +221 -0
- package/dist/dts/templating/view.d.ts +268 -0
- package/dist/dts/templating/when.d.ts +12 -0
- package/dist/dts/testing/exports.d.ts +3 -0
- package/dist/dts/testing/fakes.d.ts +15 -0
- package/dist/dts/testing/fixture.d.ts +84 -0
- package/dist/dts/testing/models.d.ts +20 -0
- package/dist/dts/testing/timeout.d.ts +7 -0
- package/dist/dts/trust/index.d.ts +8 -0
- package/dist/dts/trust/types.d.ts +48 -0
- package/dist/dts/trust/utils.d.ts +26 -0
- package/dist/dts/tsdoc-metadata.json +11 -0
- package/dist/dts/utilities.d.ts +76 -0
- package/dist/esm/arrays.js +1 -0
- package/dist/esm/binding/binding.js +18 -0
- package/dist/esm/binding/exports.js +6 -0
- package/dist/esm/binding/normalize.js +17 -0
- package/dist/esm/binding/one-time.js +21 -0
- package/dist/esm/binding/one-way.js +30 -0
- package/dist/esm/binding/signal.js +99 -0
- package/dist/esm/binding/two-way.js +110 -0
- package/dist/esm/command/behavior.js +155 -0
- package/dist/esm/command/behaviors/confirm-behavior.js +225 -0
- package/dist/esm/command/behaviors/undo-behavior.js +312 -0
- package/dist/esm/command/command.js +104 -0
- package/dist/esm/command/component-registry.js +107 -0
- package/dist/esm/command/components/confirm-dialog.js +370 -0
- package/dist/esm/command/index.js +22 -0
- package/dist/esm/command/registry.js +752 -0
- package/dist/esm/command/schema-validation.js +194 -0
- package/dist/esm/command/types.js +86 -0
- package/dist/esm/command/validation.js +511 -0
- package/dist/esm/command/weak-ref.js +5 -0
- package/dist/esm/components/attributes.js +219 -0
- package/dist/esm/components/definition-schema-transforms.js +23 -0
- package/dist/esm/components/element-controller.js +839 -0
- package/dist/esm/components/element-hydration.js +2 -0
- package/dist/esm/components/enable-hydration.js +123 -0
- package/dist/esm/components/fast-definitions.js +294 -0
- package/dist/esm/components/fast-element-registry.js +67 -0
- package/dist/esm/components/fast-element.js +82 -0
- package/dist/esm/components/hydration-tracker.js +210 -0
- package/dist/esm/components/hydration.js +187 -0
- package/dist/esm/components/schema.js +253 -0
- package/dist/esm/context.js +185 -0
- package/dist/esm/debug.js +71 -0
- package/dist/esm/declarative/attribute-map.js +121 -0
- package/dist/esm/declarative/debug.js +4 -0
- package/dist/esm/declarative/index.js +10 -0
- package/dist/esm/declarative/interfaces.js +9 -0
- package/dist/esm/declarative/observer-map-utilities.js +565 -0
- package/dist/esm/declarative/observer-map.js +216 -0
- package/dist/esm/declarative/runtime.js +14 -0
- package/dist/esm/declarative/syntax.js +36 -0
- package/dist/esm/declarative/template-bridge.js +160 -0
- package/dist/esm/declarative/template-parser.js +306 -0
- package/dist/esm/declarative/template.js +116 -0
- package/dist/esm/declarative/utilities.js +1069 -0
- package/dist/esm/definition-schema/api.js +129 -0
- package/dist/esm/definition-schema/cem.js +89 -0
- package/dist/esm/definition-schema/extension.js +53 -0
- package/dist/esm/definition-schema/extract.js +167 -0
- package/dist/esm/definition-schema/index.js +8 -0
- package/dist/esm/definition-schema/storage.js +58 -0
- package/dist/esm/definition-schema/types.js +8 -0
- package/dist/esm/dev-mode.js +22 -0
- package/dist/esm/di/di.js +1440 -0
- package/dist/esm/dom-policy.js +374 -0
- package/dist/esm/dom.js +101 -0
- package/dist/esm/hydration/diagnostics.js +50 -0
- package/dist/esm/hydration/exports.js +6 -0
- package/dist/esm/hydration/hydration-debugger.js +112 -0
- package/dist/esm/hydration/messages.js +84 -0
- package/dist/esm/hydration/runtime.js +33 -0
- package/dist/esm/hydration/target-builder.js +264 -0
- package/dist/esm/index.debug.js +3 -0
- package/dist/esm/index.js +49 -0
- package/dist/esm/index.rollup.debug.js +6 -0
- package/dist/esm/index.rollup.js +4 -0
- package/dist/esm/interfaces.js +55 -0
- package/dist/esm/metadata.js +63 -0
- package/dist/esm/observation/arrays.js +661 -0
- package/dist/esm/observation/notifier.js +164 -0
- package/dist/esm/observation/observable.js +324 -0
- package/dist/esm/observation/update-queue.js +56 -0
- package/dist/esm/observation/volatile.js +16 -0
- package/dist/esm/platform.js +98 -0
- package/dist/esm/registry.js +2 -0
- package/dist/esm/render.js +1 -0
- package/dist/esm/schema.js +1 -0
- package/dist/esm/scoped/detection.js +102 -0
- package/dist/esm/scoped/index.js +69 -0
- package/dist/esm/scoped/mixin.js +127 -0
- package/dist/esm/scoped/registry.js +125 -0
- package/dist/esm/scoped/types.js +4 -0
- package/dist/esm/state/exports.js +3 -0
- package/dist/esm/state/reactive.js +34 -0
- package/dist/esm/state/state.js +148 -0
- package/dist/esm/state/visitor.js +28 -0
- package/dist/esm/state/watch.js +36 -0
- package/dist/esm/styles/css-directive.js +36 -0
- package/dist/esm/styles/css.js +56 -0
- package/dist/esm/styles/element-styles.js +144 -0
- package/dist/esm/styles/host.js +1 -0
- package/dist/esm/styles/style-strategy.js +1 -0
- package/dist/esm/templating/children.js +67 -0
- package/dist/esm/templating/compiler.js +359 -0
- package/dist/esm/templating/html-binding-directive.js +288 -0
- package/dist/esm/templating/html-directive.js +113 -0
- package/dist/esm/templating/html.js +1 -0
- package/dist/esm/templating/hydration-view.js +228 -0
- package/dist/esm/templating/markup.js +83 -0
- package/dist/esm/templating/node-observation.js +84 -0
- package/dist/esm/templating/ref.js +21 -0
- package/dist/esm/templating/render.js +468 -0
- package/dist/esm/templating/repeat.js +434 -0
- package/dist/esm/templating/slotted.js +49 -0
- package/dist/esm/templating/template.js +206 -0
- package/dist/esm/templating/view.js +298 -0
- package/dist/esm/templating/when.js +22 -0
- package/dist/esm/testing/exports.js +3 -0
- package/dist/esm/testing/fakes.js +107 -0
- package/dist/esm/testing/fixture.js +86 -0
- package/dist/esm/testing/models.js +58 -0
- package/dist/esm/testing/timeout.js +24 -0
- package/dist/esm/trust/index.js +7 -0
- package/dist/esm/trust/types.js +6 -0
- package/dist/esm/trust/utils.js +126 -0
- package/dist/esm/utilities.js +140 -0
- package/dist/fast-element.api.json +26798 -0
- package/dist/fast-element.d.ts +3985 -0
- package/dist/fast-element.debug.js +7618 -0
- package/dist/fast-element.debug.min.js +3 -0
- package/dist/fast-element.js +7617 -0
- package/dist/fast-element.min.js +3 -0
- package/dist/fast-element.untrimmed.d.ts +4103 -0
- package/dist/observation/arrays/arrays.api.json +2621 -0
- package/dist/scoped/scoped.api.json +891 -0
- package/dist/trust/trust.api.json +629 -0
- package/package.json +12 -12
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { ExecutionContext, Observable, SourceLifetime, } from "../observation/observable.js";
|
|
2
|
+
import { makeSerializationNoop } from "../platform.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a child view from a template on behalf of a directive, carrying over the
|
|
5
|
+
* scoped custom element registry scope of the parent view (if it has one).
|
|
6
|
+
* For views without a scope this is exactly `template.create()`.
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export function createChildView(template, controller) {
|
|
10
|
+
const scope = controller._scope;
|
|
11
|
+
return scope === void 0
|
|
12
|
+
? template.create()
|
|
13
|
+
: template.create(void 0, scope);
|
|
14
|
+
}
|
|
15
|
+
export function removeNodeSequence(firstNode, lastNode) {
|
|
16
|
+
const parent = firstNode.parentNode;
|
|
17
|
+
let current = firstNode;
|
|
18
|
+
let next;
|
|
19
|
+
while (current !== lastNode) {
|
|
20
|
+
next = current.nextSibling;
|
|
21
|
+
if (!next) {
|
|
22
|
+
throw new Error(`Unmatched first/last child inside "${lastNode.getRootNode().host.nodeName}".`);
|
|
23
|
+
}
|
|
24
|
+
parent.removeChild(current);
|
|
25
|
+
current = next;
|
|
26
|
+
}
|
|
27
|
+
parent.removeChild(lastNode);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The default execution context for template views.
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
export class DefaultExecutionContext {
|
|
34
|
+
constructor() {
|
|
35
|
+
/**
|
|
36
|
+
* The index of the current item within a repeat context.
|
|
37
|
+
*/
|
|
38
|
+
this.index = 0;
|
|
39
|
+
/**
|
|
40
|
+
* The length of the current collection within a repeat context.
|
|
41
|
+
*/
|
|
42
|
+
this.length = 0;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The current event within an event handler.
|
|
46
|
+
*/
|
|
47
|
+
get event() {
|
|
48
|
+
return ExecutionContext.getEvent();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Indicates whether the current item within a repeat context
|
|
52
|
+
* has an even index.
|
|
53
|
+
*/
|
|
54
|
+
get isEven() {
|
|
55
|
+
return this.index % 2 === 0;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Indicates whether the current item within a repeat context
|
|
59
|
+
* has an odd index.
|
|
60
|
+
*/
|
|
61
|
+
get isOdd() {
|
|
62
|
+
return this.index % 2 !== 0;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Indicates whether the current item within a repeat context
|
|
66
|
+
* is the first item in the collection.
|
|
67
|
+
*/
|
|
68
|
+
get isFirst() {
|
|
69
|
+
return this.index === 0;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Indicates whether the current item within a repeat context
|
|
73
|
+
* is somewhere in the middle of the collection.
|
|
74
|
+
*/
|
|
75
|
+
get isInMiddle() {
|
|
76
|
+
return !this.isFirst && !this.isLast;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Indicates whether the current item within a repeat context
|
|
80
|
+
* is the last item in the collection.
|
|
81
|
+
*/
|
|
82
|
+
get isLast() {
|
|
83
|
+
return this.index === this.length - 1;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Returns the typed event detail of a custom event.
|
|
87
|
+
*/
|
|
88
|
+
eventDetail() {
|
|
89
|
+
return this.event.detail;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Returns the typed event target of the event.
|
|
93
|
+
*/
|
|
94
|
+
eventTarget() {
|
|
95
|
+
return this.event.target;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The standard View implementation, which also implements ElementView and SyntheticView.
|
|
100
|
+
* @public
|
|
101
|
+
*/
|
|
102
|
+
export class HTMLView extends DefaultExecutionContext {
|
|
103
|
+
/**
|
|
104
|
+
* Constructs an instance of HTMLView.
|
|
105
|
+
* @param fragment - The html fragment that contains the nodes for this view.
|
|
106
|
+
* @param behaviors - The behaviors to be applied to this view.
|
|
107
|
+
*/
|
|
108
|
+
constructor(fragment, factories, targets,
|
|
109
|
+
/**
|
|
110
|
+
* The shadow root whose scoped custom element registry this view's
|
|
111
|
+
* elements were created against, if any. Child views inherit it.
|
|
112
|
+
* @internal
|
|
113
|
+
*/
|
|
114
|
+
_scope) {
|
|
115
|
+
super();
|
|
116
|
+
this.fragment = fragment;
|
|
117
|
+
this.factories = factories;
|
|
118
|
+
this.targets = targets;
|
|
119
|
+
this._scope = _scope;
|
|
120
|
+
this.behaviors = null;
|
|
121
|
+
this.unbindables = [];
|
|
122
|
+
/**
|
|
123
|
+
* The data that the view is bound to.
|
|
124
|
+
*/
|
|
125
|
+
this.source = null;
|
|
126
|
+
/**
|
|
127
|
+
* Indicates whether the controller is bound.
|
|
128
|
+
*/
|
|
129
|
+
this.isBound = false;
|
|
130
|
+
/**
|
|
131
|
+
* Indicates how the source's lifetime relates to the controller's lifetime.
|
|
132
|
+
*/
|
|
133
|
+
this.sourceLifetime = SourceLifetime.unknown;
|
|
134
|
+
/**
|
|
135
|
+
* When true, directives skip attribute/booleanAttribute DOM
|
|
136
|
+
* updates during bind(). Set only during the prerendered bind
|
|
137
|
+
* window and cleared immediately after.
|
|
138
|
+
* @internal
|
|
139
|
+
*/
|
|
140
|
+
this._skipAttrUpdates = false;
|
|
141
|
+
/**
|
|
142
|
+
* A promise that resolves with `true` after prerendered content
|
|
143
|
+
* has been hydrated, or `false` when the view is client-side
|
|
144
|
+
* rendered. Resolves once the first bind completes.
|
|
145
|
+
*/
|
|
146
|
+
this.isPrerendered = Promise.resolve(false);
|
|
147
|
+
/**
|
|
148
|
+
* Resolves `true` after prerendered content has been hydrated,
|
|
149
|
+
* `false` when client-side rendered or hydration not enabled.
|
|
150
|
+
*/
|
|
151
|
+
this.isHydrated = Promise.resolve(false);
|
|
152
|
+
/**
|
|
153
|
+
* The execution context the view is running within.
|
|
154
|
+
*/
|
|
155
|
+
this.context = this;
|
|
156
|
+
this.firstChild = fragment.firstChild;
|
|
157
|
+
this.lastChild = fragment.lastChild;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Appends the view's DOM nodes to the referenced node.
|
|
161
|
+
* @param node - The parent node to append the view's DOM nodes to.
|
|
162
|
+
*/
|
|
163
|
+
appendTo(node) {
|
|
164
|
+
node.appendChild(this.fragment);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Inserts the view's DOM nodes before the referenced node.
|
|
168
|
+
* @param node - The node to insert the view's DOM before.
|
|
169
|
+
*/
|
|
170
|
+
insertBefore(node) {
|
|
171
|
+
if (this.fragment.hasChildNodes()) {
|
|
172
|
+
node.parentNode.insertBefore(this.fragment, node);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
const end = this.lastChild;
|
|
176
|
+
if (node.previousSibling === end)
|
|
177
|
+
return;
|
|
178
|
+
const parentNode = node.parentNode;
|
|
179
|
+
let current = this.firstChild;
|
|
180
|
+
let next;
|
|
181
|
+
while (current !== end) {
|
|
182
|
+
next = current.nextSibling;
|
|
183
|
+
parentNode.insertBefore(current, node);
|
|
184
|
+
current = next;
|
|
185
|
+
}
|
|
186
|
+
parentNode.insertBefore(end, node);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Removes the view's DOM nodes.
|
|
191
|
+
* The nodes are not disposed and the view can later be re-inserted.
|
|
192
|
+
*/
|
|
193
|
+
remove() {
|
|
194
|
+
const fragment = this.fragment;
|
|
195
|
+
const end = this.lastChild;
|
|
196
|
+
let current = this.firstChild;
|
|
197
|
+
let next;
|
|
198
|
+
while (current !== end) {
|
|
199
|
+
next = current.nextSibling;
|
|
200
|
+
fragment.appendChild(current);
|
|
201
|
+
current = next;
|
|
202
|
+
}
|
|
203
|
+
fragment.appendChild(end);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Removes the view and unbinds its behaviors, disposing of DOM nodes afterward.
|
|
207
|
+
* Once a view has been disposed, it cannot be inserted or bound again.
|
|
208
|
+
*/
|
|
209
|
+
dispose() {
|
|
210
|
+
removeNodeSequence(this.firstChild, this.lastChild);
|
|
211
|
+
this.unbind();
|
|
212
|
+
}
|
|
213
|
+
onUnbind(behavior) {
|
|
214
|
+
this.unbindables.push(behavior);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Binds a view's behaviors to its binding source.
|
|
218
|
+
*
|
|
219
|
+
* On the first call, this iterates through all compiled factories, calling
|
|
220
|
+
* createBehavior() on each to produce a ViewBehavior instance (e.g., an
|
|
221
|
+
* HTMLBindingDirective), and then immediately binds it. This is where event
|
|
222
|
+
* listeners are registered, expression observers are created, and initial
|
|
223
|
+
* DOM values are set.
|
|
224
|
+
*
|
|
225
|
+
* On subsequent calls with a new source, existing behaviors are re-bound
|
|
226
|
+
* to the new data source, which re-evaluates all binding expressions and
|
|
227
|
+
* updates the DOM accordingly.
|
|
228
|
+
*
|
|
229
|
+
* @param source - The binding source for the view's binding behaviors.
|
|
230
|
+
* @param context - The execution context to run the behaviors within.
|
|
231
|
+
*/
|
|
232
|
+
bind(source, context = this) {
|
|
233
|
+
if (this.source === source && this.context === context) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
let behaviors = this.behaviors;
|
|
237
|
+
if (behaviors === null) {
|
|
238
|
+
// First bind: create behaviors from factories and bind each one.
|
|
239
|
+
// The view (this) acts as the ViewController, providing targets and source.
|
|
240
|
+
this.source = source;
|
|
241
|
+
this.context = context;
|
|
242
|
+
this.behaviors = behaviors = new Array(this.factories.length);
|
|
243
|
+
const factories = this.factories;
|
|
244
|
+
for (let i = 0, ii = factories.length; i < ii; ++i) {
|
|
245
|
+
const behavior = factories[i].createBehavior();
|
|
246
|
+
behavior.bind(this);
|
|
247
|
+
behaviors[i] = behavior;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
if (this.source !== null) {
|
|
252
|
+
this.evaluateUnbindables();
|
|
253
|
+
}
|
|
254
|
+
this.isBound = false;
|
|
255
|
+
this.source = source;
|
|
256
|
+
this.context = context;
|
|
257
|
+
for (let i = 0, ii = behaviors.length; i < ii; ++i) {
|
|
258
|
+
behaviors[i].bind(this);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
this.isBound = true;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Unbinds a view's behaviors from its binding source.
|
|
265
|
+
*/
|
|
266
|
+
unbind() {
|
|
267
|
+
if (!this.isBound || this.source === null) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
this.evaluateUnbindables();
|
|
271
|
+
this.source = null;
|
|
272
|
+
this.context = this;
|
|
273
|
+
this.isBound = false;
|
|
274
|
+
}
|
|
275
|
+
evaluateUnbindables() {
|
|
276
|
+
const unbindables = this.unbindables;
|
|
277
|
+
for (let i = 0, ii = unbindables.length; i < ii; ++i) {
|
|
278
|
+
unbindables[i].unbind(this);
|
|
279
|
+
}
|
|
280
|
+
unbindables.length = 0;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Efficiently disposes of a contiguous range of synthetic view instances.
|
|
284
|
+
* @param views - A contiguous range of views to be disposed.
|
|
285
|
+
*/
|
|
286
|
+
static disposeContiguousBatch(views) {
|
|
287
|
+
if (views.length === 0) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
removeNodeSequence(views[0].firstChild, views[views.length - 1].lastChild);
|
|
291
|
+
for (let i = 0, ii = views.length; i < ii; ++i) {
|
|
292
|
+
views[i].unbind();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
makeSerializationNoop(HTMLView);
|
|
297
|
+
Observable.defineProperty(HTMLView.prototype, "index");
|
|
298
|
+
Observable.defineProperty(HTMLView.prototype, "length");
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { isFunction } from "../interfaces.js";
|
|
2
|
+
const noTemplate = () => null;
|
|
3
|
+
function normalizeBinding(value) {
|
|
4
|
+
return value === undefined ? noTemplate : isFunction(value) ? value : () => value;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* A directive that enables basic conditional rendering in a template.
|
|
8
|
+
* @param condition - The condition to test for rendering.
|
|
9
|
+
* @param templateOrTemplateBinding - The template or a binding that gets
|
|
10
|
+
* the template to render when the condition is true.
|
|
11
|
+
* @param elseTemplateOrTemplateBinding - Optional template or binding that that
|
|
12
|
+
* gets the template to render when the conditional is false.
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export function when(condition, templateOrTemplateBinding, elseTemplateOrTemplateBinding) {
|
|
16
|
+
const dataBinding = isFunction(condition) ? condition : () => condition;
|
|
17
|
+
const templateBinding = normalizeBinding(templateOrTemplateBinding);
|
|
18
|
+
const elseBinding = normalizeBinding(elseTemplateOrTemplateBinding);
|
|
19
|
+
return (source, context) => dataBinding(source, context)
|
|
20
|
+
? templateBinding(source, context)
|
|
21
|
+
: elseBinding(source, context);
|
|
22
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { noop } from "../interfaces.js";
|
|
2
|
+
import { ExecutionContext } from "../observation/observable.js";
|
|
3
|
+
export const Fake = Object.freeze({
|
|
4
|
+
executionContext(parent, parentContext) {
|
|
5
|
+
return {
|
|
6
|
+
/**
|
|
7
|
+
* The index of the current item within a repeat context.
|
|
8
|
+
*/
|
|
9
|
+
index: 0,
|
|
10
|
+
/**
|
|
11
|
+
* The length of the current collection within a repeat context.
|
|
12
|
+
*/
|
|
13
|
+
length: 0,
|
|
14
|
+
/**
|
|
15
|
+
* The parent data source within a nested context.
|
|
16
|
+
*/
|
|
17
|
+
parent: parent,
|
|
18
|
+
/**
|
|
19
|
+
* The parent execution context when in nested context scenarios.
|
|
20
|
+
*/
|
|
21
|
+
parentContext: parentContext,
|
|
22
|
+
/**
|
|
23
|
+
* The current event within an event handler.
|
|
24
|
+
*/
|
|
25
|
+
get event() {
|
|
26
|
+
return ExecutionContext.getEvent();
|
|
27
|
+
},
|
|
28
|
+
/**
|
|
29
|
+
* Indicates whether the current item within a repeat context
|
|
30
|
+
* has an even index.
|
|
31
|
+
*/
|
|
32
|
+
get isEven() {
|
|
33
|
+
return this.index % 2 === 0;
|
|
34
|
+
},
|
|
35
|
+
/**
|
|
36
|
+
* Indicates whether the current item within a repeat context
|
|
37
|
+
* has an odd index.
|
|
38
|
+
*/
|
|
39
|
+
get isOdd() {
|
|
40
|
+
return this.index % 2 !== 0;
|
|
41
|
+
},
|
|
42
|
+
/**
|
|
43
|
+
* Indicates whether the current item within a repeat context
|
|
44
|
+
* is the first item in the collection.
|
|
45
|
+
*/
|
|
46
|
+
get isFirst() {
|
|
47
|
+
return this.index === 0;
|
|
48
|
+
},
|
|
49
|
+
/**
|
|
50
|
+
* Indicates whether the current item within a repeat context
|
|
51
|
+
* is somewhere in the middle of the collection.
|
|
52
|
+
*/
|
|
53
|
+
get isInMiddle() {
|
|
54
|
+
return !this.isFirst && !this.isLast;
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* Indicates whether the current item within a repeat context
|
|
58
|
+
* is the last item in the collection.
|
|
59
|
+
*/
|
|
60
|
+
get isLast() {
|
|
61
|
+
return this.index === this.length - 1;
|
|
62
|
+
},
|
|
63
|
+
/**
|
|
64
|
+
* Returns the typed event detail of a custom event.
|
|
65
|
+
*/
|
|
66
|
+
eventDetail() {
|
|
67
|
+
return this.event.detail;
|
|
68
|
+
},
|
|
69
|
+
/**
|
|
70
|
+
* Returns the typed event target of the event.
|
|
71
|
+
*/
|
|
72
|
+
eventTarget() {
|
|
73
|
+
return this.event.target;
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
viewController(targets = {}, ...behaviors) {
|
|
78
|
+
const unbindables = new Set();
|
|
79
|
+
return {
|
|
80
|
+
isBound: false,
|
|
81
|
+
context: null,
|
|
82
|
+
onUnbind(object) {
|
|
83
|
+
unbindables.add(object);
|
|
84
|
+
},
|
|
85
|
+
source: null,
|
|
86
|
+
targets,
|
|
87
|
+
toJSON: noop,
|
|
88
|
+
bind(source, context = Fake.executionContext()) {
|
|
89
|
+
if (this.isBound) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
this.source = source;
|
|
93
|
+
this.context = context;
|
|
94
|
+
behaviors.forEach(x => x.bind(this));
|
|
95
|
+
this.isBound = true;
|
|
96
|
+
},
|
|
97
|
+
unbind() {
|
|
98
|
+
if (this.isBound) {
|
|
99
|
+
unbindables.forEach(x => x.unbind(this));
|
|
100
|
+
this.source = null;
|
|
101
|
+
this.context = null;
|
|
102
|
+
this.isBound = false;
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { FASTElementDefinition } from "../components/fast-definitions.js";
|
|
11
|
+
import { ViewTemplate } from "../templating/template.js";
|
|
12
|
+
function findElement(view) {
|
|
13
|
+
let current = view.firstChild;
|
|
14
|
+
while (current !== null && current.nodeType !== 1) {
|
|
15
|
+
current = current.nextSibling;
|
|
16
|
+
}
|
|
17
|
+
return current;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Creates a random, unique name suitable for use as a Custom Element name.
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
export function uniqueElementName(prefix = "fast-unique") {
|
|
24
|
+
return `${prefix}-${Math.random().toString(36).substring(7)}`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Creates a test fixture suitable for testing custom elements, templates, and bindings.
|
|
28
|
+
* @param templateNameOrType An HTML template or single element name to create the fixture for.
|
|
29
|
+
* @param options Enables customizing fixture creation behavior.
|
|
30
|
+
* @remarks
|
|
31
|
+
* Yields control to the caller one Microtask later, in order to
|
|
32
|
+
* ensure that the DOM has settled.
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
export function fixture(templateNameOrType_1) {
|
|
36
|
+
return __awaiter(this, arguments, void 0, function* (templateNameOrType, options = {}) {
|
|
37
|
+
const document = options.document || globalThis.document;
|
|
38
|
+
const parent = options.parent || document.createElement("div");
|
|
39
|
+
const source = options.source || {};
|
|
40
|
+
if (typeof templateNameOrType === "function") {
|
|
41
|
+
const def = FASTElementDefinition.getByType(templateNameOrType);
|
|
42
|
+
if (!def) {
|
|
43
|
+
throw new Error("Missing FASTElement definition.");
|
|
44
|
+
}
|
|
45
|
+
templateNameOrType = def.name;
|
|
46
|
+
}
|
|
47
|
+
if (typeof templateNameOrType === "string") {
|
|
48
|
+
const html = `<${templateNameOrType}></${templateNameOrType}>`;
|
|
49
|
+
templateNameOrType = new ViewTemplate(html);
|
|
50
|
+
}
|
|
51
|
+
const view = templateNameOrType.create();
|
|
52
|
+
const element = findElement(view);
|
|
53
|
+
let isConnected = false;
|
|
54
|
+
view.bind(source);
|
|
55
|
+
view.appendTo(parent);
|
|
56
|
+
customElements.upgrade(parent);
|
|
57
|
+
// Hook into the Microtask Queue to ensure the DOM is settled
|
|
58
|
+
// before yielding control to the caller.
|
|
59
|
+
yield Promise.resolve();
|
|
60
|
+
const connect = () => __awaiter(this, void 0, void 0, function* () {
|
|
61
|
+
if (isConnected) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
isConnected = true;
|
|
65
|
+
document.body.appendChild(parent);
|
|
66
|
+
yield Promise.resolve();
|
|
67
|
+
});
|
|
68
|
+
const disconnect = () => __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
if (!isConnected) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
isConnected = false;
|
|
73
|
+
document.body.removeChild(parent);
|
|
74
|
+
yield Promise.resolve();
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
document,
|
|
78
|
+
template: templateNameOrType,
|
|
79
|
+
view,
|
|
80
|
+
parent,
|
|
81
|
+
element,
|
|
82
|
+
connect,
|
|
83
|
+
disconnect,
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Observable, observable } from "../observation/observable.js";
|
|
2
|
+
class ChildModel {
|
|
3
|
+
}
|
|
4
|
+
observable(ChildModel.prototype, "value");
|
|
5
|
+
ChildModel.prototype.value = "value";
|
|
6
|
+
class Model {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.childChangedCalled = false;
|
|
9
|
+
}
|
|
10
|
+
childChanged() {
|
|
11
|
+
this.childChangedCalled = true;
|
|
12
|
+
}
|
|
13
|
+
incrementTrigger() {
|
|
14
|
+
this.trigger++;
|
|
15
|
+
}
|
|
16
|
+
decrementTrigger() {
|
|
17
|
+
this.trigger--;
|
|
18
|
+
}
|
|
19
|
+
get ifConditional() {
|
|
20
|
+
Observable.trackVolatile();
|
|
21
|
+
if (this.trigger < 1) {
|
|
22
|
+
return 42;
|
|
23
|
+
}
|
|
24
|
+
return this.value;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
observable(Model.prototype, "child");
|
|
28
|
+
Model.prototype.child = new ChildModel();
|
|
29
|
+
observable(Model.prototype, "child2");
|
|
30
|
+
Model.prototype.child2 = new ChildModel();
|
|
31
|
+
observable(Model.prototype, "trigger");
|
|
32
|
+
Model.prototype.trigger = 0;
|
|
33
|
+
observable(Model.prototype, "value");
|
|
34
|
+
Model.prototype.value = 10;
|
|
35
|
+
Object.defineProperty(Model.prototype, "ternaryConditional", {
|
|
36
|
+
get() {
|
|
37
|
+
Observable.trackVolatile();
|
|
38
|
+
return this.trigger < 1 ? 42 : this.value;
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
Object.defineProperty(Model.prototype, "andCondition", {
|
|
42
|
+
get() {
|
|
43
|
+
Observable.trackVolatile();
|
|
44
|
+
return this.trigger && this.value;
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
class DerivedModel extends Model {
|
|
48
|
+
constructor() {
|
|
49
|
+
super(...arguments);
|
|
50
|
+
this.child2ChangedCalled = false;
|
|
51
|
+
}
|
|
52
|
+
child2Changed() {
|
|
53
|
+
this.child2ChangedCalled = true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
observable(DerivedModel.prototype, "derivedChild");
|
|
57
|
+
DerivedModel.prototype.derivedChild = new ChildModel();
|
|
58
|
+
export { ChildModel, DerivedModel, Model };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* A timeout helper for use in tests.
|
|
12
|
+
* @param timeout The length of the timeout.
|
|
13
|
+
* @returns A promise that resolves once the configured time has elapsed.
|
|
14
|
+
* @public
|
|
15
|
+
*/
|
|
16
|
+
export function timeout() {
|
|
17
|
+
return __awaiter(this, arguments, void 0, function* (timeout = 0) {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
window.setTimeout(() => {
|
|
20
|
+
resolve(void 0);
|
|
21
|
+
}, timeout);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|