@microsoft/fast-element 3.0.0-rc.1 → 3.0.0-rc.2
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 +51 -1
- package/README.md +50 -14
- package/dist/context/context.api.json +13 -13
- package/dist/declarative/declarative.api.json +654 -15
- package/dist/di/di.api.json +15 -15
- package/dist/dts/__test__/helpers.d.ts +6 -0
- package/dist/dts/__test__/setup-node.d.ts +0 -0
- package/dist/dts/binding/binding.d.ts +15 -5
- package/dist/dts/binding/one-time.d.ts +1 -1
- package/dist/dts/binding/one-way.d.ts +1 -1
- package/dist/dts/binding/signal.d.ts +1 -1
- package/dist/dts/binding/two-way.d.ts +1 -1
- package/dist/dts/components/attributes.d.ts +1 -1
- package/dist/dts/components/enable-hydration.d.ts +22 -2
- package/dist/dts/components/fast-definitions.d.ts +7 -4
- package/dist/dts/components/fast-element.d.ts +42 -12
- package/dist/dts/components/hydration-tracker.d.ts +47 -4
- package/dist/dts/components/hydration.d.ts +5 -0
- package/dist/dts/context.d.ts +7 -7
- package/dist/dts/declarative/debug.d.ts +2 -3
- package/dist/dts/declarative/index.d.ts +3 -2
- package/dist/dts/declarative/interfaces.d.ts +1 -2
- package/dist/dts/declarative/template.d.ts +2 -1
- package/dist/dts/declarative/utilities.d.ts +50 -4
- package/dist/dts/di/di.d.ts +6 -6
- package/dist/dts/dom-policy.d.ts +22 -4
- package/dist/dts/dom.d.ts +4 -16
- package/dist/dts/hydration/diagnostics.d.ts +93 -0
- package/dist/dts/hydration/hydration-debugger.d.ts +35 -0
- package/dist/dts/hydration/messages.d.ts +62 -0
- package/dist/dts/hydration/target-builder.d.ts +26 -1
- package/dist/dts/hydration.d.ts +7 -3
- package/dist/dts/index.d.ts +7 -3
- package/dist/dts/interfaces.d.ts +1 -0
- package/dist/dts/observation/observable.d.ts +3 -3
- package/dist/dts/platform.d.ts +20 -4
- package/dist/dts/registry.d.ts +1 -0
- package/dist/dts/templating/children.d.ts +1 -1
- package/dist/dts/templating/compiler.d.ts +1 -1
- package/dist/dts/templating/html-binding-directive.d.ts +6 -2
- package/dist/dts/templating/html-directive.d.ts +2 -1
- package/dist/dts/templating/hydration-view.d.ts +24 -3
- package/dist/dts/templating/ref.d.ts +1 -1
- package/dist/dts/templating/render.d.ts +2 -2
- package/dist/dts/templating/repeat.d.ts +1 -1
- package/dist/dts/templating/slotted.d.ts +1 -1
- package/dist/dts/templating/template.d.ts +5 -5
- package/dist/dts/templating/when.d.ts +1 -1
- package/dist/dts/testing/fakes.d.ts +4 -4
- package/dist/esm/__test__/helpers.js +22 -0
- package/dist/esm/__test__/setup-node.js +18 -0
- package/dist/esm/binding/two-way.js +1 -2
- package/dist/esm/components/attributes.js +12 -8
- package/dist/esm/components/element-controller.js +11 -6
- package/dist/esm/components/enable-hydration.js +27 -3
- package/dist/esm/components/fast-definitions.js +19 -18
- package/dist/esm/components/hydration-tracker.js +34 -5
- package/dist/esm/components/hydration.js +85 -6
- package/dist/esm/debug.js +1 -0
- package/dist/esm/declarative/attribute-map.js +2 -1
- package/dist/esm/declarative/debug.js +0 -1
- package/dist/esm/declarative/index.js +1 -0
- package/dist/esm/declarative/interfaces.js +0 -1
- package/dist/esm/declarative/observer-map-utilities.js +58 -55
- package/dist/esm/declarative/template-bridge.js +4 -14
- package/dist/esm/declarative/template.js +4 -3
- package/dist/esm/declarative/utilities.js +236 -1
- package/dist/esm/di/di.js +2 -1
- package/dist/esm/dom-policy.js +33 -4
- package/dist/esm/hydration/diagnostics.js +50 -0
- package/dist/esm/hydration/hydration-debugger.js +112 -0
- package/dist/esm/hydration/messages.js +84 -0
- package/dist/esm/hydration/target-builder.js +65 -19
- package/dist/esm/hydration.js +3 -1
- package/dist/esm/index.js +6 -2
- package/dist/esm/interfaces.js +1 -0
- package/dist/esm/metadata.js +2 -8
- package/dist/esm/observation/notifier.js +2 -4
- package/dist/esm/registry.js +1 -0
- package/dist/esm/templating/html-binding-directive.js +1 -1
- package/dist/esm/templating/hydration-view.js +20 -27
- package/dist/esm/templating/render.js +39 -18
- package/dist/esm/templating/repeat.js +51 -17
- package/dist/esm/templating/view.js +1 -1
- package/dist/esm/testing/fixture.js +2 -2
- package/dist/esm/testing/timeout.js +2 -2
- package/dist/fast-element.api.json +1329 -99
- package/dist/fast-element.d.ts +147 -66
- package/dist/fast-element.debug.js +392 -99
- package/dist/fast-element.debug.min.js +2 -2
- package/dist/fast-element.js +392 -99
- package/dist/fast-element.min.js +2 -2
- package/dist/fast-element.untrimmed.d.ts +133 -70
- package/dist/hydration/hydration.api.json +1280 -57
- package/dist/styles/styles.api.json +1 -1
- package/package.json +21 -9
- package/ARCHITECTURE_FASTELEMENT.md +0 -63
- package/ARCHITECTURE_HTML_TAGGED_TEMPLATE_LITERAL.md +0 -36
- package/ARCHITECTURE_INTRO.md +0 -10
- package/ARCHITECTURE_OVERVIEW.md +0 -52
- package/ARCHITECTURE_UPDATES.md +0 -11
- package/CHANGELOG.json +0 -2275
- package/DECLARATIVE_DESIGN.md +0 -806
- package/DECLARATIVE_HTML.md +0 -470
- package/DECLARATIVE_MIGRATION.md +0 -215
- package/DECLARATIVE_RENDERING.md +0 -530
- package/DECLARATIVE_RENDERING_LIFECYCLE.md +0 -288
- package/DECLARATIVE_SCHEMA_OBSERVER_MAP.md +0 -489
- package/DESIGN.md +0 -615
- package/MIGRATION.md +0 -387
- package/SIZES.md +0 -25
- package/api-extractor.arrays.json +0 -15
- package/api-extractor.context.json +0 -15
- package/api-extractor.declarative.json +0 -15
- package/api-extractor.di.json +0 -15
- package/api-extractor.hydration.json +0 -15
- package/api-extractor.styles.json +0 -15
- package/biome.json +0 -4
- package/docs/ACKNOWLEDGEMENTS.md +0 -12
- package/docs/api-report.api.md +0 -1299
- package/docs/arrays/api-report.api.md +0 -114
- package/docs/context/api-report.api.md +0 -69
- package/docs/declarative/api-report.api.md +0 -397
- package/docs/di/api-report.api.md +0 -315
- package/docs/fast-element-2-changes.md +0 -15
- package/docs/hydration/api-report.api.md +0 -285
- package/docs/styles/api-report.api.md +0 -135
- package/playwright.config.ts +0 -26
- package/playwright.declarative.config.ts +0 -26
- package/playwright.declarative.webui.config.ts +0 -20
- package/scripts/declarative/build-fixtures-with-webui.js +0 -135
- package/scripts/declarative/build-fixtures.js +0 -49
- package/scripts/declarative/build-fixtures.utilities.js +0 -101
- package/scripts/measure-sizes.js +0 -219
- package/scripts/run-api-extractor.js +0 -70
- package/test/declarative/fixtures/README.md +0 -72
- package/test/declarative/fixtures/WRITING_FIXTURES.md +0 -330
- package/test/declarative/fixtures/bindings/README.md +0 -12
- package/test/declarative/fixtures/bindings/attribute/entry.html +0 -13
- package/test/declarative/fixtures/bindings/attribute/fast-build.config.json +0 -6
- package/test/declarative/fixtures/bindings/attribute/index.html +0 -25
- package/test/declarative/fixtures/bindings/attribute/main.ts +0 -41
- package/test/declarative/fixtures/bindings/attribute/state.json +0 -8
- package/test/declarative/fixtures/bindings/attribute/templates.html +0 -11
- package/test/declarative/fixtures/bindings/content/entry.html +0 -12
- package/test/declarative/fixtures/bindings/content/fast-build.config.json +0 -6
- package/test/declarative/fixtures/bindings/content/index.html +0 -19
- package/test/declarative/fixtures/bindings/content/main.ts +0 -27
- package/test/declarative/fixtures/bindings/content/state.json +0 -4
- package/test/declarative/fixtures/bindings/content/templates.html +0 -6
- package/test/declarative/fixtures/bindings/dot-syntax/entry.html +0 -11
- package/test/declarative/fixtures/bindings/dot-syntax/fast-build.config.json +0 -6
- package/test/declarative/fixtures/bindings/dot-syntax/index.html +0 -47
- package/test/declarative/fixtures/bindings/dot-syntax/main.ts +0 -59
- package/test/declarative/fixtures/bindings/dot-syntax/state.json +0 -16
- package/test/declarative/fixtures/bindings/dot-syntax/templates.html +0 -17
- package/test/declarative/fixtures/bindings/event/entry.html +0 -11
- package/test/declarative/fixtures/bindings/event/fast-build.config.json +0 -6
- package/test/declarative/fixtures/bindings/event/index.html +0 -43
- package/test/declarative/fixtures/bindings/event/main.ts +0 -43
- package/test/declarative/fixtures/bindings/event/state.json +0 -3
- package/test/declarative/fixtures/bindings/event/templates.html +0 -18
- package/test/declarative/fixtures/bindings/host/entry.html +0 -40
- package/test/declarative/fixtures/bindings/host/fast-build.config.json +0 -6
- package/test/declarative/fixtures/bindings/host/index.html +0 -96
- package/test/declarative/fixtures/bindings/host/main.ts +0 -222
- package/test/declarative/fixtures/bindings/host/state.json +0 -9
- package/test/declarative/fixtures/bindings/host/templates.html +0 -55
- package/test/declarative/fixtures/directives/README.md +0 -12
- package/test/declarative/fixtures/directives/children/entry.html +0 -11
- package/test/declarative/fixtures/directives/children/fast-build.config.json +0 -6
- package/test/declarative/fixtures/directives/children/index.html +0 -15
- package/test/declarative/fixtures/directives/children/main.ts +0 -22
- package/test/declarative/fixtures/directives/children/state.json +0 -3
- package/test/declarative/fixtures/directives/children/templates.html +0 -3
- package/test/declarative/fixtures/directives/ref/entry.html +0 -11
- package/test/declarative/fixtures/directives/ref/fast-build.config.json +0 -6
- package/test/declarative/fixtures/directives/ref/index.html +0 -15
- package/test/declarative/fixtures/directives/ref/main.ts +0 -17
- package/test/declarative/fixtures/directives/ref/state.json +0 -1
- package/test/declarative/fixtures/directives/ref/templates.html +0 -3
- package/test/declarative/fixtures/directives/repeat/entry.html +0 -21
- package/test/declarative/fixtures/directives/repeat/fast-build.config.json +0 -6
- package/test/declarative/fixtures/directives/repeat/index.html +0 -133
- package/test/declarative/fixtures/directives/repeat/main.ts +0 -110
- package/test/declarative/fixtures/directives/repeat/sprites.svg +0 -8
- package/test/declarative/fixtures/directives/repeat/state.json +0 -10
- package/test/declarative/fixtures/directives/repeat/templates.html +0 -75
- package/test/declarative/fixtures/directives/slotted/entry.html +0 -17
- package/test/declarative/fixtures/directives/slotted/fast-build.config.json +0 -6
- package/test/declarative/fixtures/directives/slotted/index.html +0 -27
- package/test/declarative/fixtures/directives/slotted/main.ts +0 -29
- package/test/declarative/fixtures/directives/slotted/state.json +0 -1
- package/test/declarative/fixtures/directives/slotted/templates.html +0 -7
- package/test/declarative/fixtures/directives/when/entry.html +0 -51
- package/test/declarative/fixtures/directives/when/fast-build.config.json +0 -6
- package/test/declarative/fixtures/directives/when/index.html +0 -136
- package/test/declarative/fixtures/directives/when/main.ts +0 -172
- package/test/declarative/fixtures/directives/when/state.json +0 -12
- package/test/declarative/fixtures/directives/when/templates.html +0 -75
- package/test/declarative/fixtures/ecosystem/README.md +0 -11
- package/test/declarative/fixtures/ecosystem/declarative-no-hydration/entry.html +0 -12
- package/test/declarative/fixtures/ecosystem/declarative-no-hydration/fast-build.config.json +0 -6
- package/test/declarative/fixtures/ecosystem/declarative-no-hydration/index.html +0 -20
- package/test/declarative/fixtures/ecosystem/declarative-no-hydration/main.ts +0 -68
- package/test/declarative/fixtures/ecosystem/declarative-no-hydration/state.json +0 -4
- package/test/declarative/fixtures/ecosystem/declarative-no-hydration/templates.html +0 -7
- package/test/declarative/fixtures/ecosystem/errors/entry.html +0 -12
- package/test/declarative/fixtures/ecosystem/errors/fast-build.config.json +0 -6
- package/test/declarative/fixtures/ecosystem/errors/index.html +0 -20
- package/test/declarative/fixtures/ecosystem/errors/main.ts +0 -17
- package/test/declarative/fixtures/ecosystem/errors/state.json +0 -1
- package/test/declarative/fixtures/ecosystem/errors/templates.html +0 -7
- package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/entry.html +0 -17
- package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/fast-build.config.json +0 -6
- package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/index.html +0 -56
- package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/main.ts +0 -134
- package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/state.json +0 -12
- package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/templates.html +0 -34
- package/test/declarative/fixtures/ecosystem/performance-metrics/entry.html +0 -25
- package/test/declarative/fixtures/ecosystem/performance-metrics/fast-build.config.json +0 -6
- package/test/declarative/fixtures/ecosystem/performance-metrics/fast-card.css +0 -10
- package/test/declarative/fixtures/ecosystem/performance-metrics/index.html +0 -181
- package/test/declarative/fixtures/ecosystem/performance-metrics/main.ts +0 -58
- package/test/declarative/fixtures/ecosystem/performance-metrics/state.json +0 -6
- package/test/declarative/fixtures/ecosystem/performance-metrics/templates.html +0 -15
- package/test/declarative/fixtures/extensions/README.md +0 -15
- package/test/declarative/fixtures/extensions/attribute-map/entry.html +0 -14
- package/test/declarative/fixtures/extensions/attribute-map/fast-build.config.json +0 -6
- package/test/declarative/fixtures/extensions/attribute-map/index.html +0 -31
- package/test/declarative/fixtures/extensions/attribute-map/main.ts +0 -40
- package/test/declarative/fixtures/extensions/attribute-map/state.json +0 -4
- package/test/declarative/fixtures/extensions/attribute-map/templates.html +0 -14
- package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/entry.html +0 -12
- package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/fast-build.config.json +0 -7
- package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/index.html +0 -25
- package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/main.ts +0 -31
- package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/state.json +0 -5
- package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/templates.html +0 -11
- package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/entry.html +0 -13
- package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/fast-build.config.json +0 -7
- package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/index.html +0 -23
- package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/main.ts +0 -37
- package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/state.json +0 -1
- package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/templates.html +0 -9
- package/test/declarative/fixtures/extensions/observer-map/entry.html +0 -15
- package/test/declarative/fixtures/extensions/observer-map/fast-build.config.json +0 -6
- package/test/declarative/fixtures/extensions/observer-map/index.html +0 -442
- package/test/declarative/fixtures/extensions/observer-map/main.ts +0 -482
- package/test/declarative/fixtures/extensions/observer-map/state.json +0 -158
- package/test/declarative/fixtures/extensions/observer-map/templates.html +0 -172
- package/test/declarative/fixtures/extensions/observer-map-config-object/entry.html +0 -16
- package/test/declarative/fixtures/extensions/observer-map-config-object/fast-build.config.json +0 -6
- package/test/declarative/fixtures/extensions/observer-map-config-object/index.html +0 -27
- package/test/declarative/fixtures/extensions/observer-map-config-object/main.ts +0 -53
- package/test/declarative/fixtures/extensions/observer-map-config-object/state.json +0 -9
- package/test/declarative/fixtures/extensions/observer-map-config-object/templates.html +0 -12
- package/test/declarative/fixtures/extensions/observer-map-deep-merge/README.md +0 -98
- package/test/declarative/fixtures/extensions/observer-map-deep-merge/entry.html +0 -156
- package/test/declarative/fixtures/extensions/observer-map-deep-merge/fast-build.config.json +0 -6
- package/test/declarative/fixtures/extensions/observer-map-deep-merge/index.html +0 -376
- package/test/declarative/fixtures/extensions/observer-map-deep-merge/main.ts +0 -366
- package/test/declarative/fixtures/extensions/observer-map-deep-merge/state.json +0 -69
- package/test/declarative/fixtures/extensions/observer-map-deep-merge/templates.html +0 -91
- package/test/declarative/fixtures/extensions/observer-map-properties/entry.html +0 -14
- package/test/declarative/fixtures/extensions/observer-map-properties/fast-build.config.json +0 -6
- package/test/declarative/fixtures/extensions/observer-map-properties/index.html +0 -110
- package/test/declarative/fixtures/extensions/observer-map-properties/main.ts +0 -175
- package/test/declarative/fixtures/extensions/observer-map-properties/state.json +0 -29
- package/test/declarative/fixtures/extensions/observer-map-properties/templates.html +0 -55
- package/test/declarative/fixtures/scenarios/README.md +0 -7
- package/test/declarative/fixtures/scenarios/nested-elements/entry.html +0 -16
- package/test/declarative/fixtures/scenarios/nested-elements/fast-build.config.json +0 -6
- package/test/declarative/fixtures/scenarios/nested-elements/index.html +0 -126
- package/test/declarative/fixtures/scenarios/nested-elements/main.ts +0 -214
- package/test/declarative/fixtures/scenarios/nested-elements/state.json +0 -10
- package/test/declarative/fixtures/scenarios/nested-elements/templates.html +0 -54
- package/test/declarative/index.html +0 -12
- package/test/declarative/vite.config.ts +0 -55
- package/test/declarative-main.ts +0 -6
- package/test/extension-subpaths-main.ts +0 -9
- package/test/index.html +0 -11
- package/test/main.ts +0 -109
- package/test/pure-declarative-main.ts +0 -1
- package/test/vite.config.ts +0 -19
- package/tsconfig.api-extractor.json +0 -6
|
@@ -6,5 +6,4 @@ export var Message;
|
|
|
6
6
|
(function (Message) {
|
|
7
7
|
Message[Message["noTemplateProvided"] = 2000] = "noTemplateProvided";
|
|
8
8
|
Message[Message["moreThanOneTemplateProvided"] = 2001] = "moreThanOneTemplateProvided";
|
|
9
|
-
Message[Message["moreThanOneMatchingTemplateProvided"] = 2002] = "moreThanOneMatchingTemplateProvided";
|
|
10
9
|
})(Message || (Message = {}));
|
|
@@ -7,7 +7,7 @@ const objectTargetsMap = new WeakMap();
|
|
|
7
7
|
/**
|
|
8
8
|
* A map of arrays being observed.
|
|
9
9
|
*/
|
|
10
|
-
const observedArraysMap = new
|
|
10
|
+
const observedArraysMap = new WeakSet();
|
|
11
11
|
/**
|
|
12
12
|
* Determines the data type of the provided data
|
|
13
13
|
* @param data - The data to analyze
|
|
@@ -76,6 +76,37 @@ function hasObservedSchemaDescendant(schema) {
|
|
|
76
76
|
function isSchemaExcluded(schema) {
|
|
77
77
|
return (schema === null || schema === void 0 ? void 0 : schema.$observe) === false && !hasObservedSchemaDescendant(schema);
|
|
78
78
|
}
|
|
79
|
+
function defineObservableProperty(targetObject, key, schema, rootSchema, target, rootProperty) {
|
|
80
|
+
if (!Observable.getAccessors(targetObject).some(accessor => accessor.name === key)) {
|
|
81
|
+
const field = `_${key}`;
|
|
82
|
+
const callback = `${key}Changed`;
|
|
83
|
+
const accessor = {
|
|
84
|
+
name: key,
|
|
85
|
+
getValue(source) {
|
|
86
|
+
Observable.track(source, key);
|
|
87
|
+
return source[field];
|
|
88
|
+
},
|
|
89
|
+
setValue(source, value) {
|
|
90
|
+
const oldValue = source[field];
|
|
91
|
+
const newValue = assignObservables(schema, rootSchema, value, target, rootProperty);
|
|
92
|
+
if (oldValue !== newValue) {
|
|
93
|
+
source[field] = newValue;
|
|
94
|
+
const changeCallback = source[callback];
|
|
95
|
+
if (typeof changeCallback === "function") {
|
|
96
|
+
changeCallback.call(source, oldValue, newValue);
|
|
97
|
+
}
|
|
98
|
+
Observable.notify(source, key);
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
Observable.defineProperty(targetObject, accessor);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function findArrayItemDef(schema) {
|
|
106
|
+
var _a;
|
|
107
|
+
const items = schema.items;
|
|
108
|
+
return (_a = findDef(schema)) !== null && _a !== void 0 ? _a : (items === undefined ? null : findDef(items));
|
|
109
|
+
}
|
|
79
110
|
/**
|
|
80
111
|
* Assigns Observable properties to items in an array and sets up change notifications
|
|
81
112
|
* @param proxiedData - The array data to make observable
|
|
@@ -92,28 +123,31 @@ function assignObservablesToArray(proxiedData, schema, rootSchema, target, rootP
|
|
|
92
123
|
const data = schemaProperties
|
|
93
124
|
? proxiedData.map((item) => {
|
|
94
125
|
const originalItem = Object.assign({}, item);
|
|
95
|
-
assignProxyToItemsInArray(item, originalItem, schema, rootSchema);
|
|
126
|
+
assignProxyToItemsInArray(item, originalItem, schema, rootSchema, target, rootProperty);
|
|
96
127
|
return Object.assign(item, originalItem);
|
|
97
128
|
})
|
|
98
129
|
: proxiedData;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
130
|
+
if (!observedArraysMap.has(data)) {
|
|
131
|
+
observedArraysMap.add(data);
|
|
132
|
+
Observable.getNotifier(data).subscribe({
|
|
133
|
+
handleChange(subject, args) {
|
|
134
|
+
args.forEach((arg) => {
|
|
135
|
+
if (arg.addedCount > 0) {
|
|
136
|
+
if (schemaProperties) {
|
|
137
|
+
for (let i = arg.addedCount - 1; i >= 0; i--) {
|
|
138
|
+
const item = subject[arg.index + i];
|
|
139
|
+
const originalItem = Object.assign({}, item);
|
|
140
|
+
assignProxyToItemsInArray(item, originalItem, schema, rootSchema, target, rootProperty);
|
|
141
|
+
Object.assign(item, originalItem);
|
|
142
|
+
}
|
|
109
143
|
}
|
|
144
|
+
// Notify observers of the target object's root property
|
|
145
|
+
Observable.notify(target, rootProperty);
|
|
110
146
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
},
|
|
116
|
-
});
|
|
147
|
+
});
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
}
|
|
117
151
|
if (schemaProperties !== null) {
|
|
118
152
|
return data;
|
|
119
153
|
}
|
|
@@ -175,20 +209,6 @@ export function findDef(schema) {
|
|
|
175
209
|
}
|
|
176
210
|
return null;
|
|
177
211
|
}
|
|
178
|
-
/**
|
|
179
|
-
* Subscribe to a notifier on data that is an observed array
|
|
180
|
-
* @param data - The array being observed
|
|
181
|
-
* @param updateArrayObservables - The function to call to update the array item
|
|
182
|
-
*/
|
|
183
|
-
function assignSubscribeToObservableArray(data, updateArrayObservables) {
|
|
184
|
-
Observable.getNotifier(data).subscribe({
|
|
185
|
-
handleChange(subject, args) {
|
|
186
|
-
args.forEach((arg) => {
|
|
187
|
-
updateArrayObservables();
|
|
188
|
-
});
|
|
189
|
-
},
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
212
|
/**
|
|
193
213
|
* Assign observables to data
|
|
194
214
|
* @param schema - The schema
|
|
@@ -205,15 +225,9 @@ export function assignObservables(schema, rootSchema, data, target, rootProperty
|
|
|
205
225
|
let proxiedData = data;
|
|
206
226
|
switch (dataType) {
|
|
207
227
|
case "array": {
|
|
208
|
-
const context =
|
|
228
|
+
const context = findArrayItemDef(schema);
|
|
209
229
|
if (context) {
|
|
210
230
|
proxiedData = assignObservablesToArray(proxiedData, (_a = rootSchema[defsPropertyName]) === null || _a === void 0 ? void 0 : _a[context], rootSchema, target, rootProperty);
|
|
211
|
-
if (!observedArraysMap.has(proxiedData)) {
|
|
212
|
-
observedArraysMap.set(proxiedData, assignSubscribeToObservableArray(proxiedData, () => {
|
|
213
|
-
var _a;
|
|
214
|
-
return assignObservablesToArray(proxiedData, (_a = rootSchema[defsPropertyName]) === null || _a === void 0 ? void 0 : _a[context], rootSchema, target, rootProperty);
|
|
215
|
-
}));
|
|
216
|
-
}
|
|
217
231
|
}
|
|
218
232
|
else {
|
|
219
233
|
// Primitive array (items have no schema $ref): wrap in a proxy so that
|
|
@@ -237,7 +251,7 @@ export function assignObservables(schema, rootSchema, data, target, rootProperty
|
|
|
237
251
|
* @param schema - The schema mapping to the items in the array
|
|
238
252
|
* @param rootSchema - The root schema assigned to the root property
|
|
239
253
|
*/
|
|
240
|
-
function assignProxyToItemsInArray(proxiableItem, originalItem, schema, rootSchema) {
|
|
254
|
+
function assignProxyToItemsInArray(proxiableItem, originalItem, schema, rootSchema, target, rootProperty) {
|
|
241
255
|
const schemaProperties = getSchemaProperties(schema);
|
|
242
256
|
getObjectProperties(proxiableItem, schemaProperties).forEach(key => {
|
|
243
257
|
const childSchema = schemaProperties[key];
|
|
@@ -252,7 +266,7 @@ function assignProxyToItemsInArray(proxiableItem, originalItem, schema, rootSche
|
|
|
252
266
|
// Assign the proxy first
|
|
253
267
|
originalItem[key] = assignProxyToItemsInObject(proxiableItem, key, originalItem[key], schemaProperties[key], rootSchema);
|
|
254
268
|
// Then make the property observable
|
|
255
|
-
|
|
269
|
+
defineObservableProperty(proxiableItem, key, childSchema, rootSchema, target, rootProperty);
|
|
256
270
|
});
|
|
257
271
|
}
|
|
258
272
|
/**
|
|
@@ -303,14 +317,11 @@ function assignProxyToItemsInObject(target, rootProperty, data, schema, rootSche
|
|
|
303
317
|
}
|
|
304
318
|
}
|
|
305
319
|
else if (type === "array") {
|
|
306
|
-
const context =
|
|
320
|
+
const context = findArrayItemDef(schema);
|
|
307
321
|
if (context) {
|
|
308
322
|
const definition = (_a = rootSchema[defsPropertyName]) === null || _a === void 0 ? void 0 : _a[context];
|
|
309
323
|
if ((definition === null || definition === void 0 ? void 0 : definition.type) === "object") {
|
|
310
324
|
proxiedData = assignObservablesToArray(proxiedData, definition, rootSchema, target, rootProperty);
|
|
311
|
-
if (!observedArraysMap.has(proxiedData)) {
|
|
312
|
-
observedArraysMap.set(proxiedData, assignSubscribeToObservableArray(proxiedData, () => assignObservablesToArray(proxiedData, definition, rootSchema, target, rootProperty)));
|
|
313
|
-
}
|
|
314
325
|
}
|
|
315
326
|
}
|
|
316
327
|
}
|
|
@@ -374,7 +385,7 @@ export function assignProxy(schema, rootSchema, target, rootProperty, object) {
|
|
|
374
385
|
obj[prop] = value;
|
|
375
386
|
return true;
|
|
376
387
|
}
|
|
377
|
-
obj[prop] = assignObservables(schema, rootSchema, value, target, rootProperty);
|
|
388
|
+
obj[prop] = assignObservables(childSchema !== null && childSchema !== void 0 ? childSchema : schema, rootSchema, value, target, rootProperty);
|
|
378
389
|
notifyObservables(proxy);
|
|
379
390
|
return true;
|
|
380
391
|
},
|
|
@@ -531,16 +542,8 @@ export function deepMerge(target, source) {
|
|
|
531
542
|
}
|
|
532
543
|
hasChanges = true;
|
|
533
544
|
if (Array.isArray(sourceValue)) {
|
|
534
|
-
const isTargetArray = Array.isArray(targetValue);
|
|
535
545
|
const clonedItems = sourceValue.map((item) => isPlainObject(item) ? Object.assign({}, item) : item);
|
|
536
|
-
|
|
537
|
-
// Use splice to maintain observable array tracking
|
|
538
|
-
targetValue.splice(0, targetValue.length, ...clonedItems);
|
|
539
|
-
}
|
|
540
|
-
else {
|
|
541
|
-
// Target isn't an array, replace it
|
|
542
|
-
target[key] = clonedItems;
|
|
543
|
-
}
|
|
546
|
+
target[key] = clonedItems;
|
|
544
547
|
continue;
|
|
545
548
|
}
|
|
546
549
|
if (isPlainObject(sourceValue)) {
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { FAST } from "../platform.js";
|
|
2
|
-
import { Message } from "./interfaces.js";
|
|
3
1
|
/**
|
|
4
2
|
* Coordinates declarative template publishers and FAST element definitions.
|
|
5
3
|
* Requests are keyed by registry + element name so scoped registries can
|
|
@@ -75,20 +73,12 @@ export class DeclarativeTemplateBridge {
|
|
|
75
73
|
if (!bucket) {
|
|
76
74
|
return;
|
|
77
75
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
});
|
|
83
|
-
for (const request of [...bucket.requests]) {
|
|
84
|
-
this.rejectRequest(registry, name, bucket, request, error);
|
|
85
|
-
}
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
if (publishers.length === 0) {
|
|
76
|
+
// Set iteration preserves insertion order, so duplicate publishers leave
|
|
77
|
+
// the first connected publisher responsible for pending requests.
|
|
78
|
+
const publisher = bucket.publishers.values().next().value;
|
|
79
|
+
if (publisher === undefined) {
|
|
89
80
|
return;
|
|
90
81
|
}
|
|
91
|
-
const [publisher] = publishers;
|
|
92
82
|
for (const request of bucket.requests) {
|
|
93
83
|
if (request.settled) {
|
|
94
84
|
continue;
|
|
@@ -14,7 +14,7 @@ import { Message } from "./interfaces.js";
|
|
|
14
14
|
import { ensureDeclarativeRuntime } from "./runtime.js";
|
|
15
15
|
import { declarativeTemplateBridge } from "./template-bridge.js";
|
|
16
16
|
import { TemplateParser } from "./template-parser.js";
|
|
17
|
-
import { transformInnerHTML } from "./utilities.js";
|
|
17
|
+
import { escapeBracesInCodeElements, transformInnerHTML } from "./utilities.js";
|
|
18
18
|
const templateElementName = "f-template";
|
|
19
19
|
const ensuredTemplateElements = new WeakMap();
|
|
20
20
|
function isTemplateElementConstructor(value) {
|
|
@@ -114,7 +114,8 @@ class FTemplateElement extends HTMLElement {
|
|
|
114
114
|
declarativeTemplateBridge.movePublisher(this.registry, previousName !== null && previousName !== void 0 ? previousName : undefined, nextName !== null && nextName !== void 0 ? nextName : undefined, this);
|
|
115
115
|
}
|
|
116
116
|
publishTemplate(definition) {
|
|
117
|
-
var _a, _b, _c, _d
|
|
117
|
+
var _a, _b, _c, _d;
|
|
118
|
+
var _e;
|
|
118
119
|
ensureDeclarativeRuntime();
|
|
119
120
|
const name = definition.name;
|
|
120
121
|
const templates = Array.from(this.children).filter((child) => child.tagName === "TEMPLATE");
|
|
@@ -130,7 +131,7 @@ class FTemplateElement extends HTMLElement {
|
|
|
130
131
|
(_d = (_c = definition.lifecycleCallbacks) === null || _c === void 0 ? void 0 : _c.templateWillUpdate) === null || _d === void 0 ? void 0 : _d.call(_c, name);
|
|
131
132
|
const schema = (_e = definition.schema) !== null && _e !== void 0 ? _e : new Schema(name);
|
|
132
133
|
definition.schema = schema;
|
|
133
|
-
const innerHTML = transformInnerHTML(this.innerHTML);
|
|
134
|
+
const innerHTML = transformInnerHTML(escapeBracesInCodeElements(this.innerHTML));
|
|
134
135
|
const parser = new TemplateParser();
|
|
135
136
|
const { strings, values } = parser.parse(innerHTML, schema);
|
|
136
137
|
for (const transform of getDefinitionSchemaTransforms(definition)) {
|
|
@@ -6,7 +6,7 @@ export { assignObservables, assignProxy, deepEqual, deepMerge, findDef, isPlainO
|
|
|
6
6
|
* @public
|
|
7
7
|
*/
|
|
8
8
|
export const contextPrefixDot = `${executionContextAccessor}.`;
|
|
9
|
-
export { eventArgAccessor, executionContextAccessor };
|
|
9
|
+
export { attributeDirectivePrefix, clientSideCloseExpression, clientSideOpenExpression, closeExpression, eventArgAccessor, executionContextAccessor, openExpression, };
|
|
10
10
|
/**
|
|
11
11
|
* Parses the arguments string of an event handler binding into an array of
|
|
12
12
|
* typed argument descriptors. Unrecognised tokens are returned as `"binding"`
|
|
@@ -754,6 +754,241 @@ export function transformInnerHTML(innerHTML, index = 0) {
|
|
|
754
754
|
}
|
|
755
755
|
return transformedInnerHTML;
|
|
756
756
|
}
|
|
757
|
+
/**
|
|
758
|
+
* Tag name of the HTML element whose contents are auto-escaped to render
|
|
759
|
+
* code samples literally. Inside this element FAST binding delimiters
|
|
760
|
+
* (`{{...}}`, `{{{...}}}`, `{...}`) are neutralised by replacing each
|
|
761
|
+
* `{` / `}` with the HTML numeric character reference `{` /
|
|
762
|
+
* `}` so the literal text is rendered instead of a binding.
|
|
763
|
+
*
|
|
764
|
+
* The escape behaviour is split between the server-side renderer
|
|
765
|
+
* (`escape_code_sample_elements` in `microsoft-fast-build`) and the
|
|
766
|
+
* client-side `<f-template>` parser (`escapeBracesInCodeElements`
|
|
767
|
+
* below):
|
|
768
|
+
*
|
|
769
|
+
* - Curly-brace escape runs in **both** server and client because
|
|
770
|
+
* `{` / `}` are decoded to literal `{` / `}` in the DOM
|
|
771
|
+
* and the `.innerHTML` serializer does not re-encode them — so the
|
|
772
|
+
* server-side escape would otherwise be undone on the client.
|
|
773
|
+
* - Angle brackets of FAST directive tags (`<f-when>`, `</f-when>`,
|
|
774
|
+
* `<f-repeat>`, `</f-repeat>`, case-insensitive) inside this element
|
|
775
|
+
* are escaped on the **server only**. The DOM serializer
|
|
776
|
+
* re-encodes `<` / `>` in text content automatically, so the client
|
|
777
|
+
* never sees raw directive tags inside `<code>` regardless of what
|
|
778
|
+
* the page source contained.
|
|
779
|
+
* - Real HTML elements (`<button>`) and custom elements (`<my-widget>`)
|
|
780
|
+
* inside this element keep their angle brackets and continue to
|
|
781
|
+
* render as live DOM elements; only the brace-binding syntax inside
|
|
782
|
+
* their text and attribute values is neutralised.
|
|
783
|
+
* @public
|
|
784
|
+
*/
|
|
785
|
+
export const codeElementName = "code";
|
|
786
|
+
const CODE_ESCAPE_VOID_ELEMENTS = new Set([
|
|
787
|
+
"area",
|
|
788
|
+
"base",
|
|
789
|
+
"br",
|
|
790
|
+
"col",
|
|
791
|
+
"embed",
|
|
792
|
+
"hr",
|
|
793
|
+
"img",
|
|
794
|
+
"input",
|
|
795
|
+
"link",
|
|
796
|
+
"meta",
|
|
797
|
+
"param",
|
|
798
|
+
"source",
|
|
799
|
+
"track",
|
|
800
|
+
"wbr",
|
|
801
|
+
]);
|
|
802
|
+
/**
|
|
803
|
+
* Parse an opening tag at `pos` (which points at `<`). Returns the parsed tag
|
|
804
|
+
* descriptor if `<` introduces an element opening tag, otherwise `null`
|
|
805
|
+
* (e.g. for `</tag>`, `<!--`, `<!doctype`, `<?...`, or end-of-input).
|
|
806
|
+
*
|
|
807
|
+
* The parser is tolerant of attribute values containing `>` only when they
|
|
808
|
+
* are quoted; quoted attribute values are correctly handled so that a `>`
|
|
809
|
+
* inside quotes does not terminate the tag.
|
|
810
|
+
*/
|
|
811
|
+
function parseOpeningTagForCodeEscape(html, pos) {
|
|
812
|
+
if (html.charAt(pos) !== "<")
|
|
813
|
+
return null;
|
|
814
|
+
const next = html.charAt(pos + 1);
|
|
815
|
+
if (next === "/" || next === "!" || next === "?" || next === "")
|
|
816
|
+
return null;
|
|
817
|
+
if (!/[A-Za-z]/.test(next))
|
|
818
|
+
return null;
|
|
819
|
+
let nameEnd = pos + 1;
|
|
820
|
+
while (nameEnd < html.length && /[A-Za-z0-9-]/.test(html.charAt(nameEnd))) {
|
|
821
|
+
nameEnd++;
|
|
822
|
+
}
|
|
823
|
+
const tagName = html.slice(pos + 1, nameEnd).toLowerCase();
|
|
824
|
+
if (tagName === "")
|
|
825
|
+
return null;
|
|
826
|
+
let cursor = nameEnd;
|
|
827
|
+
while (cursor < html.length) {
|
|
828
|
+
while (cursor < html.length && /\s/.test(html.charAt(cursor)))
|
|
829
|
+
cursor++;
|
|
830
|
+
const ch = html.charAt(cursor);
|
|
831
|
+
if (ch === ">" || ch === "" || (ch === "/" && html.charAt(cursor + 1) === ">")) {
|
|
832
|
+
break;
|
|
833
|
+
}
|
|
834
|
+
while (cursor < html.length &&
|
|
835
|
+
!/[\s=>/]/.test(html.charAt(cursor)) &&
|
|
836
|
+
html.charAt(cursor) !== "") {
|
|
837
|
+
cursor++;
|
|
838
|
+
}
|
|
839
|
+
let attrTerminator = cursor;
|
|
840
|
+
while (attrTerminator < html.length && /\s/.test(html.charAt(attrTerminator))) {
|
|
841
|
+
attrTerminator++;
|
|
842
|
+
}
|
|
843
|
+
if (html.charAt(attrTerminator) === "=") {
|
|
844
|
+
cursor = attrTerminator + 1;
|
|
845
|
+
while (cursor < html.length && /\s/.test(html.charAt(cursor)))
|
|
846
|
+
cursor++;
|
|
847
|
+
const quote = html.charAt(cursor);
|
|
848
|
+
if (quote === '"' || quote === "'") {
|
|
849
|
+
const end = html.indexOf(quote, cursor + 1);
|
|
850
|
+
cursor = end === -1 ? html.length : end + 1;
|
|
851
|
+
}
|
|
852
|
+
else {
|
|
853
|
+
while (cursor < html.length && !/[\s>]/.test(html.charAt(cursor))) {
|
|
854
|
+
cursor++;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
let isSelfClosing = false;
|
|
860
|
+
if (html.charAt(cursor) === "/" && html.charAt(cursor + 1) === ">") {
|
|
861
|
+
isSelfClosing = true;
|
|
862
|
+
cursor += 2;
|
|
863
|
+
}
|
|
864
|
+
else if (html.charAt(cursor) === ">") {
|
|
865
|
+
cursor += 1;
|
|
866
|
+
}
|
|
867
|
+
else {
|
|
868
|
+
return null;
|
|
869
|
+
}
|
|
870
|
+
return {
|
|
871
|
+
tagName,
|
|
872
|
+
tagStart: pos,
|
|
873
|
+
tagEnd: cursor,
|
|
874
|
+
contentStart: cursor,
|
|
875
|
+
isSelfClosing: isSelfClosing || CODE_ESCAPE_VOID_ELEMENTS.has(tagName),
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Find the position of the matching close tag for an element opened at
|
|
880
|
+
* `contentStart` with name `tagName`. Returns the index of the `<` of the
|
|
881
|
+
* matching `</tagName>` close tag, or `html.length` if no matching tag is
|
|
882
|
+
* found. Nested same-name elements are tracked via a depth counter.
|
|
883
|
+
*/
|
|
884
|
+
function findMatchingCloseTagForCodeEscape(html, contentStart, tagName) {
|
|
885
|
+
let depth = 1;
|
|
886
|
+
let pos = contentStart;
|
|
887
|
+
const closeNeedle = `</${tagName}`;
|
|
888
|
+
while (pos < html.length) {
|
|
889
|
+
const lt = html.indexOf("<", pos);
|
|
890
|
+
if (lt === -1)
|
|
891
|
+
return html.length;
|
|
892
|
+
const lowerSlice = html.slice(lt, lt + closeNeedle.length).toLowerCase();
|
|
893
|
+
if (lowerSlice === closeNeedle) {
|
|
894
|
+
const charAfter = html.charAt(lt + closeNeedle.length);
|
|
895
|
+
if (charAfter === ">" || /\s/.test(charAfter)) {
|
|
896
|
+
depth--;
|
|
897
|
+
if (depth === 0)
|
|
898
|
+
return lt;
|
|
899
|
+
const gt = html.indexOf(">", lt);
|
|
900
|
+
pos = gt === -1 ? html.length : gt + 1;
|
|
901
|
+
continue;
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
if (html.startsWith("<!--", lt)) {
|
|
905
|
+
const end = html.indexOf("-->", lt + 4);
|
|
906
|
+
pos = end === -1 ? html.length : end + 3;
|
|
907
|
+
continue;
|
|
908
|
+
}
|
|
909
|
+
if (html.charAt(lt + 1) === "!" || html.charAt(lt + 1) === "?") {
|
|
910
|
+
const end = html.indexOf(">", lt);
|
|
911
|
+
pos = end === -1 ? html.length : end + 1;
|
|
912
|
+
continue;
|
|
913
|
+
}
|
|
914
|
+
if (html.charAt(lt + 1) === "/") {
|
|
915
|
+
const end = html.indexOf(">", lt);
|
|
916
|
+
pos = end === -1 ? html.length : end + 1;
|
|
917
|
+
continue;
|
|
918
|
+
}
|
|
919
|
+
const opening = parseOpeningTagForCodeEscape(html, lt);
|
|
920
|
+
if (opening === null) {
|
|
921
|
+
pos = lt + 1;
|
|
922
|
+
continue;
|
|
923
|
+
}
|
|
924
|
+
if (opening.tagName === tagName && !opening.isSelfClosing) {
|
|
925
|
+
depth++;
|
|
926
|
+
}
|
|
927
|
+
pos = opening.tagEnd;
|
|
928
|
+
}
|
|
929
|
+
return html.length;
|
|
930
|
+
}
|
|
931
|
+
function escapeBracesInCodeContent(content) {
|
|
932
|
+
return content.replace(/[{}]/g, c => (c === "{" ? "{" : "}"));
|
|
933
|
+
}
|
|
934
|
+
/**
|
|
935
|
+
* Preprocess an HTML string by escaping FAST brace characters inside every
|
|
936
|
+
* `<code>` element. Mirrors part of the brace/angle-bracket escaping
|
|
937
|
+
* behaviour of Microsoft WebUI's `webui-press` markdown renderer so that
|
|
938
|
+
* example template snippets inside `<code>` render literally instead of
|
|
939
|
+
* being interpreted as bindings.
|
|
940
|
+
*
|
|
941
|
+
* Nested `<code>` elements are handled via depth tracking. The pass is
|
|
942
|
+
* idempotent because `{` / `}` inside an already-processed `<code>` have
|
|
943
|
+
* been replaced with entities, so a second pass finds nothing to escape.
|
|
944
|
+
*
|
|
945
|
+
* This is the client-side half of a two-stage escape — see the JSDoc on
|
|
946
|
+
* {@link codeElementName} for why only braces are handled here and
|
|
947
|
+
* `<` / `>` are exclusively handled on the server.
|
|
948
|
+
* @public
|
|
949
|
+
*/
|
|
950
|
+
export function escapeBracesInCodeElements(innerHTML) {
|
|
951
|
+
if (innerHTML.indexOf("<code") === -1) {
|
|
952
|
+
return innerHTML;
|
|
953
|
+
}
|
|
954
|
+
let pos = 0;
|
|
955
|
+
let result = "";
|
|
956
|
+
while (pos < innerHTML.length) {
|
|
957
|
+
const lt = innerHTML.indexOf("<", pos);
|
|
958
|
+
if (lt === -1) {
|
|
959
|
+
result += innerHTML.slice(pos);
|
|
960
|
+
break;
|
|
961
|
+
}
|
|
962
|
+
if (innerHTML.startsWith("<!--", lt)) {
|
|
963
|
+
const end = innerHTML.indexOf("-->", lt + 4);
|
|
964
|
+
const tail = end === -1 ? innerHTML.length : end + 3;
|
|
965
|
+
result += innerHTML.slice(pos, tail);
|
|
966
|
+
pos = tail;
|
|
967
|
+
continue;
|
|
968
|
+
}
|
|
969
|
+
const opening = parseOpeningTagForCodeEscape(innerHTML, lt);
|
|
970
|
+
if (opening === null) {
|
|
971
|
+
result += innerHTML.slice(pos, lt + 1);
|
|
972
|
+
pos = lt + 1;
|
|
973
|
+
continue;
|
|
974
|
+
}
|
|
975
|
+
if (opening.tagName !== codeElementName) {
|
|
976
|
+
result += innerHTML.slice(pos, opening.tagEnd);
|
|
977
|
+
pos = opening.tagEnd;
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
980
|
+
result += innerHTML.slice(pos, opening.tagEnd);
|
|
981
|
+
if (opening.isSelfClosing) {
|
|
982
|
+
pos = opening.tagEnd;
|
|
983
|
+
continue;
|
|
984
|
+
}
|
|
985
|
+
const closeStart = findMatchingCloseTagForCodeEscape(innerHTML, opening.contentStart, codeElementName);
|
|
986
|
+
const innerContent = innerHTML.slice(opening.contentStart, closeStart);
|
|
987
|
+
result += escapeBracesInCodeContent(innerContent);
|
|
988
|
+
pos = closeStart;
|
|
989
|
+
}
|
|
990
|
+
return result;
|
|
991
|
+
}
|
|
757
992
|
/**
|
|
758
993
|
* Resolves boolean logic
|
|
759
994
|
* used for f-when and boolean attributes
|
package/dist/esm/di/di.js
CHANGED
package/dist/esm/dom-policy.js
CHANGED
|
@@ -1,10 +1,40 @@
|
|
|
1
1
|
import { DOMAspect } from "./dom.js";
|
|
2
2
|
import { isString, Message } from "./interfaces.js";
|
|
3
3
|
import { FAST } from "./platform.js";
|
|
4
|
+
const surroundingWhitespaceAndControlChars = /^[\u0000-\u0020\u007F]+|[\u0000-\u0020\u007F]+$/g;
|
|
5
|
+
const whitespaceAndControlChars = /[\u0000-\u0020\u007F]+/g;
|
|
6
|
+
const unsafeURLProtocol = /^(?:javascript|vbscript|data):/;
|
|
7
|
+
function trimURL(value) {
|
|
8
|
+
return value.replace(surroundingWhitespaceAndControlChars, "");
|
|
9
|
+
}
|
|
10
|
+
function decodeURL(value) {
|
|
11
|
+
try {
|
|
12
|
+
return decodeURIComponent(value);
|
|
13
|
+
}
|
|
14
|
+
catch (_a) {
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function hasUnsafeURLProtocol(value) {
|
|
19
|
+
let normalized = trimURL(value);
|
|
20
|
+
for (let i = 0; i < 3; ++i) {
|
|
21
|
+
const decoded = decodeURL(normalized);
|
|
22
|
+
if (decoded === normalized) {
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
normalized = trimURL(decoded);
|
|
26
|
+
}
|
|
27
|
+
normalized = normalized.replace(whitespaceAndControlChars, "").toLowerCase();
|
|
28
|
+
return unsafeURLProtocol.test(normalized);
|
|
29
|
+
}
|
|
30
|
+
function sanitizeURL(value) {
|
|
31
|
+
const trimmed = trimURL(value);
|
|
32
|
+
return hasUnsafeURLProtocol(trimmed) ? "" : trimmed;
|
|
33
|
+
}
|
|
4
34
|
function safeURL(tagName, aspect, aspectName, sink) {
|
|
5
35
|
return (target, name, value, ...rest) => {
|
|
6
36
|
if (isString(value)) {
|
|
7
|
-
value = value
|
|
37
|
+
value = sanitizeURL(value);
|
|
8
38
|
}
|
|
9
39
|
sink(target, name, value, ...rest);
|
|
10
40
|
};
|
|
@@ -266,7 +296,7 @@ function createElementGuards(config, defaults) {
|
|
|
266
296
|
break;
|
|
267
297
|
case undefined:
|
|
268
298
|
// keep the default
|
|
269
|
-
result[tag] = createDOMAspectGuards(
|
|
299
|
+
result[tag] = createDOMAspectGuards(defaultValue, {});
|
|
270
300
|
break;
|
|
271
301
|
default:
|
|
272
302
|
// override the default aspects
|
|
@@ -311,7 +341,7 @@ function tryGuard(aspectGuards, tagName, aspect, aspectName, sink) {
|
|
|
311
341
|
* A helper for creating DOM policies.
|
|
312
342
|
* @public
|
|
313
343
|
*/
|
|
314
|
-
const DOMPolicy = Object.freeze({
|
|
344
|
+
export const DOMPolicy = Object.freeze({
|
|
315
345
|
/**
|
|
316
346
|
* Creates a new DOM Policy object.
|
|
317
347
|
* @param options - The options to use in creating the policy.
|
|
@@ -342,4 +372,3 @@ const DOMPolicy = Object.freeze({
|
|
|
342
372
|
});
|
|
343
373
|
},
|
|
344
374
|
});
|
|
345
|
-
export { DOMPolicy };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { formatDefaultMismatchMessage, unknownHostName } from "./messages.js";
|
|
2
|
+
function formatMinimalMessage(hostName, detail) {
|
|
3
|
+
const host = (hostName !== null && hostName !== void 0 ? hostName : unknownHostName).toLowerCase();
|
|
4
|
+
return formatDefaultMismatchMessage(host, detail);
|
|
5
|
+
}
|
|
6
|
+
const defaultDiagnostic = {
|
|
7
|
+
formatBindingMismatch(_factory, _firstChild, _lastChild, hostName) {
|
|
8
|
+
return {
|
|
9
|
+
message: formatMinimalMessage(hostName, undefined),
|
|
10
|
+
};
|
|
11
|
+
},
|
|
12
|
+
formatStructuralError(_node, hostName, expectedDescription) {
|
|
13
|
+
return {
|
|
14
|
+
message: formatMinimalMessage(hostName, expectedDescription),
|
|
15
|
+
};
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
let activeDiagnostic = defaultDiagnostic;
|
|
19
|
+
/**
|
|
20
|
+
* Installs a {@link HydrationDiagnostic} as the active formatter for
|
|
21
|
+
* hydration mismatch errors. Called by `enableHydration()` when an opt-in
|
|
22
|
+
* debugger configuration is supplied; not exposed as `@public` because
|
|
23
|
+
* library consumers should always go through `enableHydration` to install
|
|
24
|
+
* a debugger.
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
export function installHydrationDiagnostic(diagnostic) {
|
|
28
|
+
activeDiagnostic = diagnostic;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Returns the currently active {@link HydrationDiagnostic} — either the
|
|
32
|
+
* minimal default or one installed by an opt-in debugger.
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export function getHydrationDiagnostic() {
|
|
36
|
+
return activeDiagnostic;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Reads the host element's tag name from any node inside a hydration view.
|
|
40
|
+
* Returns `undefined` when the node is not inside a shadow root.
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
export function getHostName(node) {
|
|
44
|
+
var _a;
|
|
45
|
+
if (!node) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
const root = node.getRootNode();
|
|
49
|
+
return (_a = root.host) === null || _a === void 0 ? void 0 : _a.nodeName;
|
|
50
|
+
}
|