@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,839 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { Message } from "../interfaces.js";
|
|
13
|
+
import { PropertyChangeNotifier } from "../observation/notifier.js";
|
|
14
|
+
import { ExecutionContext, Observable, SourceLifetime, } from "../observation/observable.js";
|
|
15
|
+
import { FAST, makeSerializationNoop } from "../platform.js";
|
|
16
|
+
import { ElementStyles } from "../styles/element-styles.js";
|
|
17
|
+
import { wrapDetailWithTrust } from "../trust/utils.js";
|
|
18
|
+
import { FASTElementDefinition, getLateAttributeLookup, } from "./fast-definitions.js";
|
|
19
|
+
const defaultEventOptions = {
|
|
20
|
+
bubbles: true,
|
|
21
|
+
composed: true,
|
|
22
|
+
cancelable: true,
|
|
23
|
+
};
|
|
24
|
+
const isConnectedPropertyName = "isConnected";
|
|
25
|
+
const shadowRoots = new WeakMap();
|
|
26
|
+
const lateAttributeObserver = Symbol("fast-late-attribute-observer");
|
|
27
|
+
const behaviorFactories = new Set();
|
|
28
|
+
/**
|
|
29
|
+
* Registers a focused integration hook for optional element behaviors.
|
|
30
|
+
* @param factory - Factory invoked for each new element controller.
|
|
31
|
+
* @returns A callback that removes the factory.
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
export function registerElementControllerBehaviorFactory(factory) {
|
|
35
|
+
behaviorFactories.add(factory);
|
|
36
|
+
return () => behaviorFactories.delete(factory);
|
|
37
|
+
}
|
|
38
|
+
function getShadowRoot(element) {
|
|
39
|
+
var _a, _b;
|
|
40
|
+
return (_b = (_a = element.shadowRoot) !== null && _a !== void 0 ? _a : shadowRoots.get(element)) !== null && _b !== void 0 ? _b : null;
|
|
41
|
+
}
|
|
42
|
+
let elementControllerStrategy;
|
|
43
|
+
/**
|
|
44
|
+
* The various lifecycle stages of an ElementController.
|
|
45
|
+
* @public
|
|
46
|
+
*/
|
|
47
|
+
export var Stages;
|
|
48
|
+
(function (Stages) {
|
|
49
|
+
/** The element is in the process of connecting. */
|
|
50
|
+
Stages[Stages["connecting"] = 0] = "connecting";
|
|
51
|
+
/** The element is connected. */
|
|
52
|
+
Stages[Stages["connected"] = 1] = "connected";
|
|
53
|
+
/** The element is in the process of disconnecting. */
|
|
54
|
+
Stages[Stages["disconnecting"] = 2] = "disconnecting";
|
|
55
|
+
/** The element is disconnected. */
|
|
56
|
+
Stages[Stages["disconnected"] = 3] = "disconnected";
|
|
57
|
+
})(Stages || (Stages = {}));
|
|
58
|
+
/**
|
|
59
|
+
* Controls the lifecycle and rendering of a `FASTElement`.
|
|
60
|
+
* @public
|
|
61
|
+
*/
|
|
62
|
+
export class ElementController {
|
|
63
|
+
/**
|
|
64
|
+
* Indicates whether or not the custom element has been
|
|
65
|
+
* connected to the document.
|
|
66
|
+
*/
|
|
67
|
+
get isConnected() {
|
|
68
|
+
Observable.track(this, isConnectedPropertyName);
|
|
69
|
+
return this.stage === Stages.connected;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The context the expression is evaluated against.
|
|
73
|
+
*/
|
|
74
|
+
get context() {
|
|
75
|
+
var _a, _b;
|
|
76
|
+
return (_b = (_a = this.view) === null || _a === void 0 ? void 0 : _a.context) !== null && _b !== void 0 ? _b : ExecutionContext.default;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Indicates whether the controller is bound.
|
|
80
|
+
*/
|
|
81
|
+
get isBound() {
|
|
82
|
+
var _a, _b;
|
|
83
|
+
return (_b = (_a = this.view) === null || _a === void 0 ? void 0 : _a.isBound) !== null && _b !== void 0 ? _b : false;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Indicates how the source's lifetime relates to the controller's lifetime.
|
|
87
|
+
*/
|
|
88
|
+
get sourceLifetime() {
|
|
89
|
+
var _a;
|
|
90
|
+
return (_a = this.view) === null || _a === void 0 ? void 0 : _a.sourceLifetime;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Gets/sets the template used to render the component.
|
|
94
|
+
* @remarks
|
|
95
|
+
* This value can only be accurately read after connect but can be set at any time.
|
|
96
|
+
*/
|
|
97
|
+
get template() {
|
|
98
|
+
var _a;
|
|
99
|
+
// 1. Template overrides take top precedence.
|
|
100
|
+
if (this._template === null) {
|
|
101
|
+
const definition = this.definition;
|
|
102
|
+
if (this.source.resolveTemplate) {
|
|
103
|
+
// 2. Allow for element instance overrides next.
|
|
104
|
+
this._template = this.source.resolveTemplate();
|
|
105
|
+
}
|
|
106
|
+
else if (definition.template) {
|
|
107
|
+
// 3. Default to the static definition.
|
|
108
|
+
this._template =
|
|
109
|
+
(_a = definition.template) !== null && _a !== void 0 ? _a : null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return this._template;
|
|
113
|
+
}
|
|
114
|
+
set template(value) {
|
|
115
|
+
if (this._template === value) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this._template = value;
|
|
119
|
+
if (!this.needsInitialization) {
|
|
120
|
+
this.renderTemplate(value);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The shadow root options for the component.
|
|
125
|
+
*/
|
|
126
|
+
get shadowOptions() {
|
|
127
|
+
return this._shadowRootOptions;
|
|
128
|
+
}
|
|
129
|
+
set shadowOptions(value) {
|
|
130
|
+
// options on the shadowRoot can only be set once
|
|
131
|
+
if (this._shadowRootOptions === void 0 && value !== void 0) {
|
|
132
|
+
this._shadowRootOptions = value;
|
|
133
|
+
let shadowRoot = this.source.shadowRoot;
|
|
134
|
+
if (shadowRoot) {
|
|
135
|
+
this.hasExistingShadowRoot = true;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
shadowRoot = this.source.attachShadow(value);
|
|
139
|
+
if (value.mode === "closed") {
|
|
140
|
+
shadowRoots.set(this.source, shadowRoot);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* The main set of styles used for the component, independent
|
|
147
|
+
* of any dynamically added styles.
|
|
148
|
+
*/
|
|
149
|
+
get mainStyles() {
|
|
150
|
+
var _a;
|
|
151
|
+
// 1. Styles overrides take top precedence.
|
|
152
|
+
if (this._mainStyles === null) {
|
|
153
|
+
const definition = this.definition;
|
|
154
|
+
if (this.source.resolveStyles) {
|
|
155
|
+
// 2. Allow for element instance overrides next.
|
|
156
|
+
this._mainStyles = this.source.resolveStyles();
|
|
157
|
+
}
|
|
158
|
+
else if (definition.styles) {
|
|
159
|
+
// 3. Default to the static definition.
|
|
160
|
+
this._mainStyles = (_a = definition.styles) !== null && _a !== void 0 ? _a : null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return this._mainStyles;
|
|
164
|
+
}
|
|
165
|
+
set mainStyles(value) {
|
|
166
|
+
if (this._mainStyles === value) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (this._mainStyles !== null) {
|
|
170
|
+
this.removeStyles(this._mainStyles);
|
|
171
|
+
}
|
|
172
|
+
this._mainStyles = value;
|
|
173
|
+
if (!this.needsInitialization) {
|
|
174
|
+
this.addStyles(value);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Creates a Controller to control the specified element.
|
|
179
|
+
* @param element - The element to be controlled by this controller.
|
|
180
|
+
* @param definition - The element definition metadata that instructs this
|
|
181
|
+
* controller in how to handle rendering and other platform integrations.
|
|
182
|
+
* @internal
|
|
183
|
+
*/
|
|
184
|
+
constructor(element, definition) {
|
|
185
|
+
/**
|
|
186
|
+
* A map of observable properties that were set on the element before upgrade.
|
|
187
|
+
*/
|
|
188
|
+
this.boundObservables = null;
|
|
189
|
+
/**
|
|
190
|
+
* Indicates whether the controller needs to perform initial rendering.
|
|
191
|
+
*/
|
|
192
|
+
this.needsInitialization = true;
|
|
193
|
+
/**
|
|
194
|
+
* Indicates whether the element has an existing shadow root (e.g. from declarative shadow DOM).
|
|
195
|
+
*/
|
|
196
|
+
this.hasExistingShadowRoot = false;
|
|
197
|
+
/**
|
|
198
|
+
* Resolves `true` when the element had an existing shadow root
|
|
199
|
+
* (from SSR or declarative shadow DOM) at connect time, `false`
|
|
200
|
+
* otherwise.
|
|
201
|
+
*/
|
|
202
|
+
this.isPrerendered = new Promise(resolve => {
|
|
203
|
+
this._resolvePrerendered = resolve;
|
|
204
|
+
});
|
|
205
|
+
/**
|
|
206
|
+
* Resolves `true` after prerendered content has been successfully
|
|
207
|
+
* hydrated, or `false` when the component is client-side rendered
|
|
208
|
+
* or hydration is not enabled.
|
|
209
|
+
*/
|
|
210
|
+
this.isHydrated = new Promise(resolve => {
|
|
211
|
+
this._resolveHydrated = resolve;
|
|
212
|
+
});
|
|
213
|
+
/**
|
|
214
|
+
* The template used to render the component.
|
|
215
|
+
*/
|
|
216
|
+
this._template = null;
|
|
217
|
+
/**
|
|
218
|
+
* The current lifecycle stage of the controller.
|
|
219
|
+
*/
|
|
220
|
+
this.stage = Stages.disconnected;
|
|
221
|
+
/**
|
|
222
|
+
* A guard against connecting behaviors multiple times
|
|
223
|
+
* during connect in scenarios where a behavior adds
|
|
224
|
+
* another behavior during it's connectedCallback
|
|
225
|
+
*/
|
|
226
|
+
this.guardBehaviorConnection = false;
|
|
227
|
+
/**
|
|
228
|
+
* The behaviors associated with the component.
|
|
229
|
+
*/
|
|
230
|
+
this.behaviors = null;
|
|
231
|
+
/**
|
|
232
|
+
* Tracks whether behaviors are connected so that
|
|
233
|
+
* behaviors cant be connected multiple times
|
|
234
|
+
*/
|
|
235
|
+
this.behaviorsConnected = false;
|
|
236
|
+
/**
|
|
237
|
+
* The main set of styles used for the component, independent of any
|
|
238
|
+
* dynamically added styles.
|
|
239
|
+
*/
|
|
240
|
+
this._mainStyles = null;
|
|
241
|
+
/**
|
|
242
|
+
* This allows Observable.getNotifier(...) to return the Controller
|
|
243
|
+
* when the notifier for the Controller itself is being requested. The
|
|
244
|
+
* result is that the Observable system does not need to create a separate
|
|
245
|
+
* instance of Notifier for observables on the Controller. The component and
|
|
246
|
+
* the controller will now share the same notifier, removing one-object construct
|
|
247
|
+
* per web component instance.
|
|
248
|
+
*/
|
|
249
|
+
this.$fastController = this;
|
|
250
|
+
/**
|
|
251
|
+
* The view associated with the custom element.
|
|
252
|
+
* @remarks
|
|
253
|
+
* If `null` then the element is managing its own rendering.
|
|
254
|
+
*/
|
|
255
|
+
this.view = null;
|
|
256
|
+
this._notifier = new PropertyChangeNotifier(element);
|
|
257
|
+
this.source = element;
|
|
258
|
+
this.definition = definition;
|
|
259
|
+
this.shadowOptions = definition.shadowOptions;
|
|
260
|
+
const prototype = Reflect.getPrototypeOf(element);
|
|
261
|
+
const accessors = prototype === null ? [] : Observable.getAccessors(prototype);
|
|
262
|
+
if (accessors.length > 0) {
|
|
263
|
+
const boundObservables = (this.boundObservables = Object.create(null));
|
|
264
|
+
for (let i = 0, ii = accessors.length; i < ii; ++i) {
|
|
265
|
+
const propertyName = accessors[i].name;
|
|
266
|
+
const value = element[propertyName];
|
|
267
|
+
if (value !== void 0) {
|
|
268
|
+
delete element[propertyName];
|
|
269
|
+
boundObservables[propertyName] = value;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (Object.keys(boundObservables).length === 0) {
|
|
273
|
+
this.boundObservables = null;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
// Capture any observable values that were set after construction but before
|
|
277
|
+
// the first connect (for example, late-defined declarative accessors).
|
|
278
|
+
this.captureBoundObservables();
|
|
279
|
+
for (const factory of behaviorFactories) {
|
|
280
|
+
const behavior = factory(element);
|
|
281
|
+
if (behavior !== void 0) {
|
|
282
|
+
this.addBehavior(behavior);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* The subject that subscribers will receive notifications for.
|
|
288
|
+
*/
|
|
289
|
+
get subject() {
|
|
290
|
+
return this._notifier.subject;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Notifies all subscribers of a property change.
|
|
294
|
+
* @param args - The property name that changed.
|
|
295
|
+
*/
|
|
296
|
+
notify(args) {
|
|
297
|
+
this._notifier.notify(args);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Subscribes to notification of changes in the element's state.
|
|
301
|
+
* @param subscriber - The object that is subscribing for change notification.
|
|
302
|
+
* @param propertyToWatch - The name of the property to watch for changes.
|
|
303
|
+
*/
|
|
304
|
+
subscribe(subscriber, propertyToWatch) {
|
|
305
|
+
this._notifier.subscribe(subscriber, propertyToWatch);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Unsubscribes from notification of changes in the element's state.
|
|
309
|
+
* @param subscriber - The object that is unsubscribing from change notification.
|
|
310
|
+
* @param propertyToUnwatch - The name of the property to unsubscribe from.
|
|
311
|
+
*/
|
|
312
|
+
unsubscribe(subscriber, propertyToUnwatch) {
|
|
313
|
+
this._notifier.unsubscribe(subscriber, propertyToUnwatch);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Registers an unbind handler with the controller.
|
|
317
|
+
* @param behavior - An object to call when the controller unbinds.
|
|
318
|
+
*/
|
|
319
|
+
onUnbind(behavior) {
|
|
320
|
+
var _a;
|
|
321
|
+
(_a = this.view) === null || _a === void 0 ? void 0 : _a.onUnbind(behavior);
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Adds the behavior to the component.
|
|
325
|
+
* @param behavior - The behavior to add.
|
|
326
|
+
*/
|
|
327
|
+
addBehavior(behavior) {
|
|
328
|
+
var _a, _b;
|
|
329
|
+
const targetBehaviors = (_a = this.behaviors) !== null && _a !== void 0 ? _a : (this.behaviors = new Map());
|
|
330
|
+
const count = (_b = targetBehaviors.get(behavior)) !== null && _b !== void 0 ? _b : 0;
|
|
331
|
+
if (count === 0) {
|
|
332
|
+
targetBehaviors.set(behavior, 1);
|
|
333
|
+
behavior.addedCallback && behavior.addedCallback(this);
|
|
334
|
+
if (behavior.connectedCallback &&
|
|
335
|
+
!this.guardBehaviorConnection &&
|
|
336
|
+
(this.stage === Stages.connected || this.stage === Stages.connecting)) {
|
|
337
|
+
behavior.connectedCallback(this);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
targetBehaviors.set(behavior, count + 1);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Removes the behavior from the component.
|
|
346
|
+
* @param behavior - The behavior to remove.
|
|
347
|
+
* @param force - Forces removal even if this behavior was added more than once.
|
|
348
|
+
*/
|
|
349
|
+
removeBehavior(behavior, force = false) {
|
|
350
|
+
const targetBehaviors = this.behaviors;
|
|
351
|
+
if (targetBehaviors === null) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const count = targetBehaviors.get(behavior);
|
|
355
|
+
if (count === void 0) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
if (count === 1 || force) {
|
|
359
|
+
targetBehaviors.delete(behavior);
|
|
360
|
+
if (behavior.disconnectedCallback && this.stage !== Stages.disconnected) {
|
|
361
|
+
behavior.disconnectedCallback(this);
|
|
362
|
+
}
|
|
363
|
+
behavior.removedCallback && behavior.removedCallback(this);
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
targetBehaviors.set(behavior, count - 1);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Adds styles to this element. Providing an HTMLStyleElement will attach the element instance to the shadowRoot.
|
|
371
|
+
* @param styles - The styles to add.
|
|
372
|
+
*/
|
|
373
|
+
addStyles(styles) {
|
|
374
|
+
var _a;
|
|
375
|
+
if (!styles) {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
const source = this.source;
|
|
379
|
+
if (styles instanceof HTMLElement) {
|
|
380
|
+
const target = (_a = getShadowRoot(source)) !== null && _a !== void 0 ? _a : this.source;
|
|
381
|
+
target.append(styles);
|
|
382
|
+
}
|
|
383
|
+
else if (!styles.isAttachedTo(source)) {
|
|
384
|
+
styles.addStylesTo(source);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Removes styles from this element. Providing an HTMLStyleElement will detach the element instance from the shadowRoot.
|
|
389
|
+
* @param styles - the styles to remove.
|
|
390
|
+
*/
|
|
391
|
+
removeStyles(styles) {
|
|
392
|
+
var _a;
|
|
393
|
+
if (!styles) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
const source = this.source;
|
|
397
|
+
if (styles instanceof HTMLElement) {
|
|
398
|
+
const target = (_a = getShadowRoot(source)) !== null && _a !== void 0 ? _a : source;
|
|
399
|
+
target.removeChild(styles);
|
|
400
|
+
}
|
|
401
|
+
else if (styles.isAttachedTo(source)) {
|
|
402
|
+
styles.removeStylesFrom(source);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Runs connected lifecycle behavior on the associated element.
|
|
407
|
+
*/
|
|
408
|
+
connect() {
|
|
409
|
+
if (this.stage !== Stages.disconnected) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
this.stage = Stages.connecting;
|
|
413
|
+
this.captureBoundObservables();
|
|
414
|
+
this.syncLateAttributes();
|
|
415
|
+
this.observeLateAttributes();
|
|
416
|
+
this.bindObservables();
|
|
417
|
+
this.connectBehaviors();
|
|
418
|
+
if (this.needsInitialization) {
|
|
419
|
+
this.renderTemplate(this.template);
|
|
420
|
+
this.addStyles(this.mainStyles);
|
|
421
|
+
this.needsInitialization = false;
|
|
422
|
+
}
|
|
423
|
+
else if (this.view !== null) {
|
|
424
|
+
this.view.bind(this.source);
|
|
425
|
+
}
|
|
426
|
+
this.stage = Stages.connected;
|
|
427
|
+
Observable.notify(this, isConnectedPropertyName);
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Binds any observables that were set before upgrade.
|
|
431
|
+
*/
|
|
432
|
+
bindObservables() {
|
|
433
|
+
if (this.boundObservables !== null) {
|
|
434
|
+
const element = this.source;
|
|
435
|
+
const boundObservables = this.boundObservables;
|
|
436
|
+
const propertyNames = Object.keys(boundObservables);
|
|
437
|
+
for (let i = 0, ii = propertyNames.length; i < ii; ++i) {
|
|
438
|
+
const propertyName = propertyNames[i];
|
|
439
|
+
element[propertyName] = boundObservables[propertyName];
|
|
440
|
+
}
|
|
441
|
+
this.boundObservables = null;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Captures public own-properties that shadow observable accessors on the
|
|
446
|
+
* prototype so they can be rebound through the accessor before rendering.
|
|
447
|
+
*/
|
|
448
|
+
captureBoundObservables() {
|
|
449
|
+
const element = this.source;
|
|
450
|
+
const propertyNames = Object.getOwnPropertyNames(element);
|
|
451
|
+
const hasPrototypeAccessor = (propertyName) => {
|
|
452
|
+
let currentTarget = Reflect.getPrototypeOf(element);
|
|
453
|
+
while (currentTarget !== null) {
|
|
454
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(currentTarget, propertyName);
|
|
455
|
+
if ((descriptor === null || descriptor === void 0 ? void 0 : descriptor.get) || (descriptor === null || descriptor === void 0 ? void 0 : descriptor.set)) {
|
|
456
|
+
return true;
|
|
457
|
+
}
|
|
458
|
+
currentTarget = Reflect.getPrototypeOf(currentTarget);
|
|
459
|
+
}
|
|
460
|
+
return false;
|
|
461
|
+
};
|
|
462
|
+
let boundObservables = this.boundObservables;
|
|
463
|
+
for (let i = 0, ii = propertyNames.length; i < ii; ++i) {
|
|
464
|
+
const ownPropertyName = propertyNames[i];
|
|
465
|
+
const propertyName = ownPropertyName;
|
|
466
|
+
if (!hasPrototypeAccessor(propertyName)) {
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
const value = element[propertyName];
|
|
470
|
+
if (value === void 0) {
|
|
471
|
+
delete element[propertyName];
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
474
|
+
delete element[propertyName];
|
|
475
|
+
(boundObservables !== null && boundObservables !== void 0 ? boundObservables : (boundObservables = this.boundObservables = Object.create(null)))[propertyName] = value;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Synchronizes late-defined attribute-map attributes from the live DOM to the
|
|
480
|
+
* associated property values before the initial render occurs.
|
|
481
|
+
*/
|
|
482
|
+
syncLateAttributes() {
|
|
483
|
+
const lateAttributes = getLateAttributeLookup(this.definition);
|
|
484
|
+
if (lateAttributes === null) {
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
for (const attributeName of Object.keys(lateAttributes)) {
|
|
488
|
+
if (!this.source.hasAttribute(attributeName)) {
|
|
489
|
+
continue;
|
|
490
|
+
}
|
|
491
|
+
this.onAttributeChangedCallback(attributeName, null, this.source.getAttribute(attributeName));
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Observes late-defined attribute-map attributes that the platform does not
|
|
496
|
+
* surface through attributeChangedCallback because they were added after
|
|
497
|
+
* customElements.define() completed.
|
|
498
|
+
*/
|
|
499
|
+
observeLateAttributes() {
|
|
500
|
+
const lateAttributes = getLateAttributeLookup(this.definition);
|
|
501
|
+
if (lateAttributes === null) {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
const element = this.source;
|
|
505
|
+
if (element[lateAttributeObserver] !== void 0) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
element[lateAttributeObserver] = new MutationObserver(records => {
|
|
509
|
+
const controller = element.$fastController;
|
|
510
|
+
const lateAttributes = getLateAttributeLookup(controller.definition);
|
|
511
|
+
if (lateAttributes === null) {
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
for (let i = 0, ii = records.length; i < ii; ++i) {
|
|
515
|
+
const attributeName = records[i].attributeName;
|
|
516
|
+
if (attributeName === null || lateAttributes[attributeName] === void 0) {
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
519
|
+
controller.onAttributeChangedCallback(attributeName, null, element.getAttribute(attributeName));
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
element[lateAttributeObserver].observe(element, {
|
|
523
|
+
attributes: true,
|
|
524
|
+
attributeFilter: Object.keys(lateAttributes),
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Connects any existing behaviors on the associated element.
|
|
529
|
+
*/
|
|
530
|
+
connectBehaviors() {
|
|
531
|
+
if (this.behaviorsConnected === false) {
|
|
532
|
+
const behaviors = this.behaviors;
|
|
533
|
+
if (behaviors !== null) {
|
|
534
|
+
this.guardBehaviorConnection = true;
|
|
535
|
+
for (const key of behaviors.keys()) {
|
|
536
|
+
key.connectedCallback && key.connectedCallback(this);
|
|
537
|
+
}
|
|
538
|
+
this.guardBehaviorConnection = false;
|
|
539
|
+
}
|
|
540
|
+
this.behaviorsConnected = true;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Disconnects any behaviors on the associated element.
|
|
545
|
+
*/
|
|
546
|
+
disconnectBehaviors() {
|
|
547
|
+
if (this.behaviorsConnected === true) {
|
|
548
|
+
const behaviors = this.behaviors;
|
|
549
|
+
if (behaviors !== null) {
|
|
550
|
+
for (const key of behaviors.keys()) {
|
|
551
|
+
key.disconnectedCallback && key.disconnectedCallback(this);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
this.behaviorsConnected = false;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Runs disconnected lifecycle behavior on the associated element.
|
|
559
|
+
*/
|
|
560
|
+
disconnect() {
|
|
561
|
+
if (this.stage !== Stages.connected) {
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
this.stage = Stages.disconnecting;
|
|
565
|
+
Observable.notify(this, isConnectedPropertyName);
|
|
566
|
+
if (this.view !== null) {
|
|
567
|
+
this.view.unbind();
|
|
568
|
+
}
|
|
569
|
+
this.disconnectBehaviors();
|
|
570
|
+
this.stage = Stages.disconnected;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Runs the attribute changed callback for the associated element.
|
|
574
|
+
* @param name - The name of the attribute that changed.
|
|
575
|
+
* @param oldValue - The previous value of the attribute.
|
|
576
|
+
* @param newValue - The new value of the attribute.
|
|
577
|
+
*/
|
|
578
|
+
onAttributeChangedCallback(name, oldValue, newValue) {
|
|
579
|
+
const attrDef = this.definition.attributeLookup[name];
|
|
580
|
+
if (attrDef !== void 0) {
|
|
581
|
+
attrDef.onAttributeChangedCallback(this.source, newValue);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Emits a custom HTML event.
|
|
586
|
+
* @param type - The type name of the event.
|
|
587
|
+
* @param detail - The event detail object to send with the event.
|
|
588
|
+
* @param options - The event options. By default bubbles and composed.
|
|
589
|
+
* @remarks
|
|
590
|
+
* Only emits events if connected.
|
|
591
|
+
*/
|
|
592
|
+
emit(type, detail, options) {
|
|
593
|
+
if (this.stage === Stages.connected) {
|
|
594
|
+
const _a = options !== null && options !== void 0 ? options : {}, { confidence, reasoning, warnings } = _a, eventOptions = __rest(_a, ["confidence", "reasoning", "warnings"]);
|
|
595
|
+
const wrappedDetail = wrapDetailWithTrust(detail, {
|
|
596
|
+
confidence,
|
|
597
|
+
reasoning,
|
|
598
|
+
warnings,
|
|
599
|
+
});
|
|
600
|
+
return this.source.dispatchEvent(new CustomEvent(type, Object.assign(Object.assign(Object.assign({}, defaultEventOptions), eventOptions), { detail: wrappedDetail })));
|
|
601
|
+
}
|
|
602
|
+
return false;
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Renders the provided template to the element.
|
|
606
|
+
*
|
|
607
|
+
* @param template - The template to render.
|
|
608
|
+
* @remarks
|
|
609
|
+
* If `null` is provided, any existing view will be removed.
|
|
610
|
+
*/
|
|
611
|
+
renderTemplate(template) {
|
|
612
|
+
var _a;
|
|
613
|
+
const element = this.source;
|
|
614
|
+
const host = (_a = getShadowRoot(element)) !== null && _a !== void 0 ? _a : element;
|
|
615
|
+
if (this.view !== null) {
|
|
616
|
+
this.view.dispose();
|
|
617
|
+
this.view = null;
|
|
618
|
+
}
|
|
619
|
+
else if (!this.needsInitialization || this.hasExistingShadowRoot) {
|
|
620
|
+
if (!this.hasExistingShadowRoot || !this.needsInitialization) {
|
|
621
|
+
for (let child = host.firstChild; child !== null; child = host.firstChild) {
|
|
622
|
+
host.removeChild(child);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
if (template) {
|
|
627
|
+
const hasPrerenderedContent = this.hasExistingShadowRoot && this.needsInitialization;
|
|
628
|
+
let didHydrate = false;
|
|
629
|
+
if (hasPrerenderedContent && ElementController.hydrationHook) {
|
|
630
|
+
didHydrate = ElementController.hydrationHook(this, template, element, host);
|
|
631
|
+
}
|
|
632
|
+
if (!didHydrate) {
|
|
633
|
+
this.renderClientSide(template, element, host);
|
|
634
|
+
}
|
|
635
|
+
this._resolvePrerendered(hasPrerenderedContent);
|
|
636
|
+
this._resolveHydrated(didHydrate);
|
|
637
|
+
}
|
|
638
|
+
else if (this.needsInitialization) {
|
|
639
|
+
this._resolvePrerendered(false);
|
|
640
|
+
this._resolveHydrated(false);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Standard client-side render: clears any stale content, clones the
|
|
645
|
+
* compiled fragment, binds, and appends to the host.
|
|
646
|
+
*/
|
|
647
|
+
renderClientSide(template, element, host) {
|
|
648
|
+
var _a;
|
|
649
|
+
if (this.hasExistingShadowRoot) {
|
|
650
|
+
for (let child = host.firstChild; child !== null; child = host.firstChild) {
|
|
651
|
+
host.removeChild(child);
|
|
652
|
+
}
|
|
653
|
+
this.hasExistingShadowRoot = false;
|
|
654
|
+
}
|
|
655
|
+
// Hosts given a scoped custom element registry must create their template's
|
|
656
|
+
// children against it; every other host takes the unchanged default path.
|
|
657
|
+
const scope = ((_a = this._shadowRootOptions) === null || _a === void 0 ? void 0 : _a.customElementRegistry) !== void 0
|
|
658
|
+
? host
|
|
659
|
+
: void 0;
|
|
660
|
+
this.view = template.render(element, host, element, scope);
|
|
661
|
+
this.view.sourceLifetime =
|
|
662
|
+
SourceLifetime.coupled;
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Locates or creates a controller for the specified element.
|
|
666
|
+
* @param element - The element to return the controller for.
|
|
667
|
+
* @param override - Reset the controller even if one has been defined.
|
|
668
|
+
* @remarks
|
|
669
|
+
* The specified element must have a {@link FASTElementDefinition}
|
|
670
|
+
* registered either through the use of the {@link customElement}
|
|
671
|
+
* decorator or a call to `FASTElement.define`.
|
|
672
|
+
*/
|
|
673
|
+
static forCustomElement(element, override = false) {
|
|
674
|
+
const controller = element.$fastController;
|
|
675
|
+
if (controller !== void 0 && !override) {
|
|
676
|
+
return controller;
|
|
677
|
+
}
|
|
678
|
+
const definition = FASTElementDefinition.getForInstance(element);
|
|
679
|
+
if (definition === void 0) {
|
|
680
|
+
throw FAST.error(Message.missingElementDefinition);
|
|
681
|
+
}
|
|
682
|
+
Observable.getNotifier(definition).subscribe({
|
|
683
|
+
handleChange: () => {
|
|
684
|
+
ElementController.forCustomElement(element, true);
|
|
685
|
+
element.$fastController.connect();
|
|
686
|
+
},
|
|
687
|
+
}, "template");
|
|
688
|
+
Observable.getNotifier(definition).subscribe({
|
|
689
|
+
handleChange: () => {
|
|
690
|
+
ElementController.forCustomElement(element, true);
|
|
691
|
+
element.$fastController.connect();
|
|
692
|
+
},
|
|
693
|
+
}, "shadowOptions");
|
|
694
|
+
return (element.$fastController = new elementControllerStrategy(element, definition));
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* Sets the strategy that ElementController.forCustomElement uses to construct
|
|
698
|
+
* ElementController instances for an element.
|
|
699
|
+
* @param strategy - The strategy to use.
|
|
700
|
+
*/
|
|
701
|
+
static setStrategy(strategy) {
|
|
702
|
+
elementControllerStrategy = strategy;
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* Installs the hydration hook. Called by enableHydration().
|
|
706
|
+
* @internal
|
|
707
|
+
*/
|
|
708
|
+
static installHydrationHook(hook) {
|
|
709
|
+
ElementController.hydrationHook = hook;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
// --- Static hydration hook ---
|
|
713
|
+
/**
|
|
714
|
+
* A hook that, when set, handles prerendered content hydration.
|
|
715
|
+
* Called by renderTemplate when an existing shadow root is detected.
|
|
716
|
+
* Returns true if hydration was performed, false to fall back to client-side.
|
|
717
|
+
* @internal
|
|
718
|
+
*/
|
|
719
|
+
ElementController.hydrationHook = null;
|
|
720
|
+
makeSerializationNoop(ElementController);
|
|
721
|
+
// Set default strategy for ElementController
|
|
722
|
+
ElementController.setStrategy(ElementController);
|
|
723
|
+
/**
|
|
724
|
+
* Converts a styleTarget into the operative target. When the provided target is an Element
|
|
725
|
+
* that is a FASTElement, the function will return the ShadowRoot for that element. Otherwise,
|
|
726
|
+
* it will return the root node for the element.
|
|
727
|
+
* @param target
|
|
728
|
+
* @returns
|
|
729
|
+
*/
|
|
730
|
+
function normalizeStyleTarget(target) {
|
|
731
|
+
var _a;
|
|
732
|
+
if ("adoptedStyleSheets" in target) {
|
|
733
|
+
return target;
|
|
734
|
+
}
|
|
735
|
+
else {
|
|
736
|
+
return ((_a = getShadowRoot(target)) !== null && _a !== void 0 ? _a : target.getRootNode());
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
// Default StyleStrategy implementations are defined in this module because they
|
|
740
|
+
// require access to element shadowRoots, and we don't want to leak shadowRoot
|
|
741
|
+
// objects out of this module.
|
|
742
|
+
/**
|
|
743
|
+
* https://wicg.github.io/construct-stylesheets/
|
|
744
|
+
* https://developers.google.com/web/updates/2019/02/constructable-stylesheets
|
|
745
|
+
*
|
|
746
|
+
* @internal
|
|
747
|
+
*/
|
|
748
|
+
export class AdoptedStyleSheetsStrategy {
|
|
749
|
+
constructor(styles) {
|
|
750
|
+
const styleSheetCache = AdoptedStyleSheetsStrategy.styleSheetCache;
|
|
751
|
+
this.sheets = styles.map((x) => {
|
|
752
|
+
if (x instanceof CSSStyleSheet) {
|
|
753
|
+
return x;
|
|
754
|
+
}
|
|
755
|
+
let sheet = styleSheetCache.get(x);
|
|
756
|
+
if (sheet === void 0) {
|
|
757
|
+
sheet = new CSSStyleSheet();
|
|
758
|
+
sheet.replaceSync(x);
|
|
759
|
+
styleSheetCache.set(x, sheet);
|
|
760
|
+
}
|
|
761
|
+
return sheet;
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
addStylesTo(target) {
|
|
765
|
+
addAdoptedStyleSheets(normalizeStyleTarget(target), this.sheets);
|
|
766
|
+
}
|
|
767
|
+
removeStylesFrom(target) {
|
|
768
|
+
removeAdoptedStyleSheets(normalizeStyleTarget(target), this.sheets);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
AdoptedStyleSheetsStrategy.styleSheetCache = new Map();
|
|
772
|
+
let id = 0;
|
|
773
|
+
const nextStyleId = () => `fast-${++id}`;
|
|
774
|
+
function usableStyleTarget(target) {
|
|
775
|
+
return target === document ? document.body : target;
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* @internal
|
|
779
|
+
*/
|
|
780
|
+
export class StyleElementStrategy {
|
|
781
|
+
constructor(styles) {
|
|
782
|
+
this.styles = styles;
|
|
783
|
+
this.styleClass = nextStyleId();
|
|
784
|
+
}
|
|
785
|
+
addStylesTo(target) {
|
|
786
|
+
target = usableStyleTarget(normalizeStyleTarget(target));
|
|
787
|
+
const styles = this.styles;
|
|
788
|
+
const styleClass = this.styleClass;
|
|
789
|
+
for (let i = 0; i < styles.length; i++) {
|
|
790
|
+
const element = document.createElement("style");
|
|
791
|
+
element.innerHTML = styles[i];
|
|
792
|
+
element.className = styleClass;
|
|
793
|
+
target.append(element);
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
removeStylesFrom(target) {
|
|
797
|
+
target = usableStyleTarget(normalizeStyleTarget(target));
|
|
798
|
+
const styles = target.querySelectorAll(`.${this.styleClass}`);
|
|
799
|
+
for (let i = 0, ii = styles.length; i < ii; ++i) {
|
|
800
|
+
target.removeChild(styles[i]);
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
let addAdoptedStyleSheets = (target, sheets) => {
|
|
805
|
+
target.adoptedStyleSheets = [...target.adoptedStyleSheets, ...sheets];
|
|
806
|
+
};
|
|
807
|
+
let removeAdoptedStyleSheets = (target, sheets) => {
|
|
808
|
+
target.adoptedStyleSheets = target.adoptedStyleSheets.filter((x) => sheets.indexOf(x) === -1);
|
|
809
|
+
};
|
|
810
|
+
if (ElementStyles.supportsAdoptedStyleSheets) {
|
|
811
|
+
try {
|
|
812
|
+
// Test if browser implementation uses FrozenArray.
|
|
813
|
+
// If not, use push / splice to alter the stylesheets
|
|
814
|
+
// in place. This circumvents a bug in Safari 16.4 where
|
|
815
|
+
// periodically, assigning the array would previously
|
|
816
|
+
// cause sheets to be removed.
|
|
817
|
+
document.adoptedStyleSheets.push();
|
|
818
|
+
document.adoptedStyleSheets.splice();
|
|
819
|
+
addAdoptedStyleSheets = (target, sheets) => {
|
|
820
|
+
target.adoptedStyleSheets.push(...sheets);
|
|
821
|
+
};
|
|
822
|
+
removeAdoptedStyleSheets = (target, sheets) => {
|
|
823
|
+
for (const sheet of sheets) {
|
|
824
|
+
const index = target.adoptedStyleSheets.indexOf(sheet);
|
|
825
|
+
if (index !== -1) {
|
|
826
|
+
target.adoptedStyleSheets.splice(index, 1);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
catch (_e) {
|
|
832
|
+
// Do nothing if an error is thrown, the default
|
|
833
|
+
// case handles FrozenArray.
|
|
834
|
+
}
|
|
835
|
+
ElementStyles.setDefaultStrategy(AdoptedStyleSheetsStrategy);
|
|
836
|
+
}
|
|
837
|
+
else {
|
|
838
|
+
ElementStyles.setDefaultStrategy(StyleElementStrategy);
|
|
839
|
+
}
|