@microsoft/fast-element 1.10.2 → 2.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/.eslintrc.json +1 -12
  2. package/CHANGELOG.json +387 -1
  3. package/CHANGELOG.md +74 -2
  4. package/README.md +2 -2
  5. package/dist/dts/components/attributes.d.ts +4 -1
  6. package/dist/dts/components/controller.d.ts +12 -11
  7. package/dist/dts/components/fast-definitions.d.ts +10 -2
  8. package/dist/dts/components/fast-element.d.ts +12 -5
  9. package/dist/dts/context.d.ts +157 -0
  10. package/dist/dts/debug.d.ts +1 -0
  11. package/dist/dts/hooks.d.ts +20 -0
  12. package/dist/dts/index.d.ts +16 -15
  13. package/dist/dts/index.debug.d.ts +2 -0
  14. package/dist/dts/index.rollup.d.ts +2 -0
  15. package/dist/dts/index.rollup.debug.d.ts +3 -0
  16. package/dist/dts/interfaces.d.ts +145 -0
  17. package/dist/dts/metadata.d.ts +25 -0
  18. package/dist/dts/observation/arrays.d.ts +207 -0
  19. package/dist/dts/observation/behavior.d.ts +4 -4
  20. package/dist/dts/observation/notifier.d.ts +18 -18
  21. package/dist/dts/observation/observable.d.ts +56 -18
  22. package/dist/dts/observation/splice-strategies.d.ts +13 -0
  23. package/dist/dts/observation/update-queue.d.ts +40 -0
  24. package/dist/dts/platform.d.ts +18 -67
  25. package/dist/dts/polyfills.d.ts +8 -0
  26. package/dist/dts/styles/css-directive.d.ts +43 -5
  27. package/dist/dts/styles/css.d.ts +19 -3
  28. package/dist/dts/styles/element-styles.d.ts +42 -62
  29. package/dist/dts/templating/binding-signal.d.ts +38 -0
  30. package/dist/dts/templating/binding-two-way.d.ts +56 -0
  31. package/dist/dts/templating/binding.d.ts +233 -65
  32. package/dist/dts/templating/children.d.ts +18 -15
  33. package/dist/dts/templating/compiler.d.ts +46 -28
  34. package/dist/dts/templating/dom.d.ts +41 -0
  35. package/dist/dts/templating/html-directive.d.ts +181 -43
  36. package/dist/dts/templating/markup.d.ts +48 -0
  37. package/dist/dts/templating/node-observation.d.ts +45 -29
  38. package/dist/dts/templating/ref.d.ts +6 -12
  39. package/dist/dts/templating/repeat.d.ts +26 -14
  40. package/dist/dts/templating/slotted.d.ts +13 -14
  41. package/dist/dts/templating/template.d.ts +27 -21
  42. package/dist/dts/templating/view.d.ts +15 -22
  43. package/dist/{tsdoc-metadata.json → dts/tsdoc-metadata.json} +1 -1
  44. package/dist/dts/utilities.d.ts +40 -0
  45. package/dist/esm/components/attributes.js +25 -24
  46. package/dist/esm/components/controller.js +77 -57
  47. package/dist/esm/components/fast-definitions.js +16 -22
  48. package/dist/esm/components/fast-element.js +10 -2
  49. package/dist/esm/context.js +159 -0
  50. package/dist/esm/debug.js +30 -0
  51. package/dist/esm/hooks.js +32 -0
  52. package/dist/esm/index.debug.js +2 -0
  53. package/dist/esm/index.js +19 -14
  54. package/dist/esm/index.rollup.debug.js +3 -0
  55. package/dist/esm/index.rollup.js +2 -0
  56. package/dist/esm/interfaces.js +8 -1
  57. package/dist/esm/metadata.js +60 -0
  58. package/dist/esm/observation/arrays.js +269 -0
  59. package/dist/esm/observation/notifier.js +27 -35
  60. package/dist/esm/observation/observable.js +93 -68
  61. package/dist/esm/observation/{array-change-records.js → splice-strategies.js} +136 -62
  62. package/dist/esm/observation/update-queue.js +67 -0
  63. package/dist/esm/platform.js +36 -42
  64. package/dist/esm/polyfills.js +85 -0
  65. package/dist/esm/styles/css-directive.js +29 -13
  66. package/dist/esm/styles/css.js +27 -40
  67. package/dist/esm/styles/element-styles.js +65 -104
  68. package/dist/esm/templating/binding-signal.js +84 -0
  69. package/dist/esm/templating/binding-two-way.js +82 -0
  70. package/dist/esm/templating/binding.js +306 -153
  71. package/dist/esm/templating/children.js +33 -23
  72. package/dist/esm/templating/compiler.js +236 -152
  73. package/dist/esm/templating/dom.js +49 -0
  74. package/dist/esm/templating/html-directive.js +128 -40
  75. package/dist/esm/templating/markup.js +75 -0
  76. package/dist/esm/templating/node-observation.js +50 -45
  77. package/dist/esm/templating/ref.js +7 -16
  78. package/dist/esm/templating/repeat.js +39 -36
  79. package/dist/esm/templating/slotted.js +23 -20
  80. package/dist/esm/templating/template.js +51 -95
  81. package/dist/esm/templating/view.js +44 -43
  82. package/dist/esm/templating/when.js +2 -1
  83. package/dist/esm/utilities.js +139 -0
  84. package/dist/fast-element.api.json +11789 -5377
  85. package/dist/fast-element.d.ts +1178 -530
  86. package/dist/fast-element.debug.js +3722 -0
  87. package/dist/fast-element.debug.min.js +1 -0
  88. package/dist/fast-element.js +3484 -4033
  89. package/dist/fast-element.min.js +1 -1
  90. package/dist/fast-element.untrimmed.d.ts +2699 -0
  91. package/docs/api-report.md +472 -219
  92. package/docs/fast-element-2-changes.md +15 -0
  93. package/docs/guide/declaring-templates.md +4 -4
  94. package/docs/guide/defining-elements.md +2 -2
  95. package/docs/guide/next-steps.md +2 -2
  96. package/docs/guide/observables-and-state.md +1 -1
  97. package/docs/guide/using-directives.md +1 -1
  98. package/karma.conf.cjs +6 -17
  99. package/package.json +63 -15
  100. package/dist/dts/dom.d.ts +0 -112
  101. package/dist/dts/observation/array-change-records.d.ts +0 -48
  102. package/dist/dts/observation/array-observer.d.ts +0 -9
  103. package/dist/esm/dom.js +0 -207
  104. package/dist/esm/observation/array-observer.js +0 -177
@@ -0,0 +1,67 @@
1
+ import "../interfaces.js";
2
+ import { FAST } from "../platform.js";
3
+ /**
4
+ * The default UpdateQueue.
5
+ * @public
6
+ */
7
+ export const Updates = FAST.getById(1 /* KernelServiceId.updateQueue */, () => {
8
+ const tasks = [];
9
+ const pendingErrors = [];
10
+ const rAF = globalThis.requestAnimationFrame;
11
+ let updateAsync = true;
12
+ function throwFirstError() {
13
+ if (pendingErrors.length) {
14
+ throw pendingErrors.shift();
15
+ }
16
+ }
17
+ function tryRunTask(task) {
18
+ try {
19
+ task.call();
20
+ }
21
+ catch (error) {
22
+ if (updateAsync) {
23
+ pendingErrors.push(error);
24
+ setTimeout(throwFirstError, 0);
25
+ }
26
+ else {
27
+ tasks.length = 0;
28
+ throw error;
29
+ }
30
+ }
31
+ }
32
+ function process() {
33
+ const capacity = 1024;
34
+ let index = 0;
35
+ while (index < tasks.length) {
36
+ tryRunTask(tasks[index]);
37
+ index++;
38
+ // Prevent leaking memory for long chains of recursive calls to `enqueue`.
39
+ // If we call `enqueue` within a task scheduled by `enqueue`, the queue will
40
+ // grow, but to avoid an O(n) walk for every task we execute, we don't
41
+ // shift tasks off the queue after they have been executed.
42
+ // Instead, we periodically shift 1024 tasks off the queue.
43
+ if (index > capacity) {
44
+ // Manually shift all values starting at the index back to the
45
+ // beginning of the queue.
46
+ for (let scan = 0, newLength = tasks.length - index; scan < newLength; scan++) {
47
+ tasks[scan] = tasks[scan + index];
48
+ }
49
+ tasks.length -= index;
50
+ index = 0;
51
+ }
52
+ }
53
+ tasks.length = 0;
54
+ }
55
+ function enqueue(callable) {
56
+ tasks.push(callable);
57
+ if (tasks.length < 2) {
58
+ updateAsync ? rAF(process) : process();
59
+ }
60
+ }
61
+ return Object.freeze({
62
+ enqueue,
63
+ next: () => new Promise(enqueue),
64
+ process,
65
+ setMode: (isAsync) => (updateAsync = isAsync),
66
+ });
67
+ });
@@ -1,54 +1,17 @@
1
- /**
2
- * A reference to globalThis, with support
3
- * for browsers that don't yet support the spec.
4
- * @public
5
- */
6
- export const $global = (function () {
7
- if (typeof globalThis !== "undefined") {
8
- // We're running in a modern environment.
9
- return globalThis;
10
- }
11
- if (typeof global !== "undefined") {
12
- // We're running in NodeJS
13
- return global;
14
- }
15
- if (typeof self !== "undefined") {
16
- // We're running in a worker.
17
- return self;
18
- }
19
- if (typeof window !== "undefined") {
20
- // We're running in the browser's main thread.
21
- return window;
22
- }
23
- try {
24
- // Hopefully we never get here...
25
- // Not all environments allow eval and Function. Use only as a last resort:
26
- // eslint-disable-next-line no-new-func
27
- return new Function("return this")();
28
- }
29
- catch (_a) {
30
- // If all fails, give up and create an object.
31
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
32
- return {};
33
- }
34
- })();
35
- // API-only Polyfill for trustedTypes
36
- if ($global.trustedTypes === void 0) {
37
- $global.trustedTypes = { createPolicy: (n, r) => r };
38
- }
1
+ // ensure FAST global - duplicated in polyfills.ts and debug.ts
39
2
  const propConfig = {
40
3
  configurable: false,
41
4
  enumerable: false,
42
5
  writable: false,
43
6
  };
44
- if ($global.FAST === void 0) {
45
- Reflect.defineProperty($global, "FAST", Object.assign({ value: Object.create(null) }, propConfig));
7
+ if (globalThis.FAST === void 0) {
8
+ Reflect.defineProperty(globalThis, "FAST", Object.assign({ value: Object.create(null) }, propConfig));
46
9
  }
47
10
  /**
48
11
  * The FAST global.
49
12
  * @internal
50
13
  */
51
- export const FAST = $global.FAST;
14
+ export const FAST = globalThis.FAST;
52
15
  if (FAST.getById === void 0) {
53
16
  const storage = Object.create(null);
54
17
  Reflect.defineProperty(FAST, "getById", Object.assign({ value(id, initialize) {
@@ -59,11 +22,42 @@ if (FAST.getById === void 0) {
59
22
  return found;
60
23
  } }, propConfig));
61
24
  }
25
+ if (FAST.error === void 0) {
26
+ Object.assign(FAST, {
27
+ warn() { },
28
+ error(code) {
29
+ return new Error(`Code ${code}`);
30
+ },
31
+ addMessages() { },
32
+ });
33
+ }
62
34
  /**
63
35
  * A readonly, empty array.
64
36
  * @remarks
65
37
  * Typically returned by APIs that return arrays when there are
66
38
  * no actual items to return.
67
- * @internal
39
+ * @public
68
40
  */
69
41
  export const emptyArray = Object.freeze([]);
42
+ /**
43
+ * Do not change. Part of shared kernel contract.
44
+ * @internal
45
+ */
46
+ export function createTypeRegistry() {
47
+ const typeToDefinition = new Map();
48
+ return Object.freeze({
49
+ register(definition) {
50
+ if (typeToDefinition.has(definition.type)) {
51
+ return false;
52
+ }
53
+ typeToDefinition.set(definition.type, definition);
54
+ return true;
55
+ },
56
+ getByType(key) {
57
+ return typeToDefinition.get(key);
58
+ },
59
+ getForInstance(object) {
60
+ return typeToDefinition.get(object.constructor);
61
+ },
62
+ });
63
+ }
@@ -0,0 +1,85 @@
1
+ (function ensureGlobalThis() {
2
+ if (typeof globalThis !== "undefined") {
3
+ // We're running in a modern environment.
4
+ return;
5
+ }
6
+ if (typeof global !== "undefined") {
7
+ // We're running in NodeJS
8
+ global.globalThis = global;
9
+ }
10
+ else if (typeof self !== "undefined") {
11
+ self.globalThis = self;
12
+ }
13
+ else if (typeof window !== "undefined") {
14
+ // We're running in the browser's main thread.
15
+ window.globalThis = window;
16
+ }
17
+ else {
18
+ // Hopefully we never get here...
19
+ // Not all environments allow eval and Function. Use only as a last resort:
20
+ // eslint-disable-next-line no-new-func
21
+ const result = new Function("return this")();
22
+ result.globalThis = result;
23
+ }
24
+ })();
25
+ // API-only Polyfill for trustedTypes
26
+ if (!globalThis.trustedTypes) {
27
+ globalThis.trustedTypes = {
28
+ createPolicy: (n, r) => r,
29
+ };
30
+ }
31
+ // ensure FAST global - duplicated in platform.ts
32
+ const propConfig = {
33
+ configurable: false,
34
+ enumerable: false,
35
+ writable: false,
36
+ };
37
+ if (globalThis.FAST === void 0) {
38
+ Reflect.defineProperty(globalThis, "FAST", Object.assign({ value: Object.create(null) }, propConfig));
39
+ }
40
+ const FAST = globalThis.FAST;
41
+ if (FAST.getById === void 0) {
42
+ const storage = Object.create(null);
43
+ Reflect.defineProperty(FAST, "getById", Object.assign({ value(id, initialize) {
44
+ let found = storage[id];
45
+ if (found === void 0) {
46
+ found = initialize ? (storage[id] = initialize()) : null;
47
+ }
48
+ return found;
49
+ } }, propConfig));
50
+ }
51
+ // duplicated from DOM
52
+ const supportsAdoptedStyleSheets = Array.isArray(document.adoptedStyleSheets) &&
53
+ "replace" in CSSStyleSheet.prototype;
54
+ function usableStyleTarget(target) {
55
+ return target === document ? document.body : target;
56
+ }
57
+ let id = 0;
58
+ const nextStyleId = () => `fast-${++id}`;
59
+ export class StyleElementStrategy {
60
+ constructor(styles) {
61
+ this.styles = styles;
62
+ this.styleClass = nextStyleId();
63
+ }
64
+ addStylesTo(target) {
65
+ target = usableStyleTarget(target);
66
+ const styles = this.styles;
67
+ const styleClass = this.styleClass;
68
+ for (let i = 0; i < styles.length; i++) {
69
+ const element = document.createElement("style");
70
+ element.innerHTML = styles[i];
71
+ element.className = styleClass;
72
+ target.append(element);
73
+ }
74
+ }
75
+ removeStylesFrom(target) {
76
+ const styles = target.querySelectorAll(`.${this.styleClass}`);
77
+ target = usableStyleTarget(target);
78
+ for (let i = 0, ii = styles.length; i < ii; ++i) {
79
+ target.removeChild(styles[i]);
80
+ }
81
+ }
82
+ }
83
+ if (!supportsAdoptedStyleSheets) {
84
+ FAST.getById(/* KernelServiceId.styleSheetStrategy */ 5, () => StyleElementStrategy);
85
+ }
@@ -1,21 +1,37 @@
1
+ import { createTypeRegistry } from "../platform.js";
2
+ const registry = createTypeRegistry();
1
3
  /**
2
- * Directive for use in {@link css}.
3
- *
4
+ * Instructs the css engine to provide dynamic styles or
5
+ * associate behaviors with styles.
4
6
  * @public
5
7
  */
6
- export class CSSDirective {
8
+ export const CSSDirective = Object.freeze({
7
9
  /**
8
- * Creates a CSS fragment to interpolate into the CSS document.
9
- * @returns - the string to interpolate into CSS
10
+ * Gets the directive definition associated with the instance.
11
+ * @param instance - The directive instance to retrieve the definition for.
10
12
  */
11
- createCSS() {
12
- return "";
13
- }
13
+ getForInstance: registry.getForInstance,
14
14
  /**
15
- * Creates a behavior to bind to the host element.
16
- * @returns - the behavior to bind to the host element, or undefined.
15
+ * Gets the directive definition associated with the specified type.
16
+ * @param type - The directive type to retrieve the definition for.
17
17
  */
18
- createBehavior() {
19
- return undefined;
20
- }
18
+ getByType: registry.getByType,
19
+ /**
20
+ * Defines a CSSDirective.
21
+ * @param type - The type to define as a directive.
22
+ */
23
+ define(type) {
24
+ registry.register({ type });
25
+ return type;
26
+ },
27
+ });
28
+ /**
29
+ * Decorator: Defines a CSSDirective.
30
+ * @public
31
+ */
32
+ export function cssDirective() {
33
+ /* eslint-disable-next-line @typescript-eslint/explicit-function-return-type */
34
+ return function (type) {
35
+ CSSDirective.define(type);
36
+ };
21
37
  }
@@ -1,18 +1,18 @@
1
+ import { isString } from "../interfaces.js";
1
2
  import { CSSDirective } from "./css-directive.js";
2
3
  import { ElementStyles } from "./element-styles.js";
3
4
  function collectStyles(strings, values) {
4
5
  const styles = [];
5
6
  let cssString = "";
6
7
  const behaviors = [];
8
+ const add = (behavior) => {
9
+ behaviors.push(behavior);
10
+ };
7
11
  for (let i = 0, ii = strings.length - 1; i < ii; ++i) {
8
12
  cssString += strings[i];
9
13
  let value = values[i];
10
- if (value instanceof CSSDirective) {
11
- const behavior = value.createBehavior();
12
- value = value.createCSS();
13
- if (behavior) {
14
- behaviors.push(behavior);
15
- }
14
+ if (CSSDirective.getForInstance(value) !== void 0) {
15
+ value = value.createCSS(add);
16
16
  }
17
17
  if (value instanceof ElementStyles || value instanceof CSSStyleSheet) {
18
18
  if (cssString.trim() !== "") {
@@ -42,21 +42,17 @@ function collectStyles(strings, values) {
42
42
  * The css helper supports interpolation of strings and ElementStyle instances.
43
43
  * @public
44
44
  */
45
- export function css(strings, ...values) {
45
+ export const css = ((strings, ...values) => {
46
46
  const { styles, behaviors } = collectStyles(strings, values);
47
- const elementStyles = ElementStyles.create(styles);
48
- if (behaviors.length) {
49
- elementStyles.withBehaviors(...behaviors);
50
- }
51
- return elementStyles;
52
- }
53
- class CSSPartial extends CSSDirective {
47
+ const elementStyles = new ElementStyles(styles);
48
+ return behaviors.length ? elementStyles.withBehaviors(...behaviors) : elementStyles;
49
+ });
50
+ class CSSPartial {
54
51
  constructor(styles, behaviors) {
55
- super();
56
52
  this.behaviors = behaviors;
57
53
  this.css = "";
58
54
  const stylesheets = styles.reduce((accumulated, current) => {
59
- if (typeof current === "string") {
55
+ if (isString(current)) {
60
56
  this.css += current;
61
57
  }
62
58
  else {
@@ -65,39 +61,30 @@ class CSSPartial extends CSSDirective {
65
61
  return accumulated;
66
62
  }, []);
67
63
  if (stylesheets.length) {
68
- this.styles = ElementStyles.create(stylesheets);
64
+ this.styles = new ElementStyles(stylesheets);
69
65
  }
70
66
  }
71
- createBehavior() {
72
- return this;
73
- }
74
- createCSS() {
67
+ createCSS(add) {
68
+ this.behaviors.forEach(add);
69
+ if (this.styles) {
70
+ add(this);
71
+ }
75
72
  return this.css;
76
73
  }
77
74
  bind(el) {
78
- if (this.styles) {
79
- el.$fastController.addStyles(this.styles);
80
- }
81
- if (this.behaviors.length) {
82
- el.$fastController.addBehaviors(this.behaviors);
83
- }
75
+ el.$fastController.addStyles(this.styles);
84
76
  }
85
77
  unbind(el) {
86
- if (this.styles) {
87
- el.$fastController.removeStyles(this.styles);
88
- }
89
- if (this.behaviors.length) {
90
- el.$fastController.removeBehaviors(this.behaviors);
91
- }
78
+ el.$fastController.removeStyles(this.styles);
92
79
  }
93
80
  }
81
+ CSSDirective.define(CSSPartial);
82
+ css.partial = (strings, ...values) => {
83
+ const { styles, behaviors } = collectStyles(strings, values);
84
+ return new CSSPartial(styles, behaviors);
85
+ };
94
86
  /**
95
- * Transforms a template literal string into partial CSS.
96
- * @param strings - The string fragments that are interpolated with the values.
97
- * @param values - The values that are interpolated with the string fragments.
87
+ * @deprecated Use css.partial instead.
98
88
  * @public
99
89
  */
100
- export function cssPartial(strings, ...values) {
101
- const { styles, behaviors } = collectStyles(strings, values);
102
- return new CSSPartial(styles, behaviors);
103
- }
90
+ export const cssPartial = css.partial;
@@ -1,18 +1,46 @@
1
- import { DOM } from "../dom.js";
1
+ import { FAST } from "../platform.js";
2
+ import "../interfaces.js";
3
+ const styleSheetCache = new Map();
4
+ let DefaultStyleStrategy;
5
+ function reduceStyles(styles) {
6
+ return styles
7
+ .map((x) => x instanceof ElementStyles ? reduceStyles(x.styles) : [x])
8
+ .reduce((prev, curr) => prev.concat(curr), []);
9
+ }
2
10
  /**
3
11
  * Represents styles that can be applied to a custom element.
4
12
  * @public
5
13
  */
6
14
  export class ElementStyles {
7
- constructor() {
15
+ /**
16
+ * Creates an instance of ElementStyles.
17
+ * @param styles - The styles that will be associated with elements.
18
+ */
19
+ constructor(styles) {
20
+ this.styles = styles;
8
21
  this.targets = new WeakSet();
22
+ this._strategy = null;
23
+ this.behaviors = styles
24
+ .map((x) => x instanceof ElementStyles ? x.behaviors : null)
25
+ .reduce((prev, curr) => (curr === null ? prev : prev === null ? curr : prev.concat(curr)), null);
26
+ }
27
+ /**
28
+ * Gets the StyleStrategy associated with these element styles.
29
+ */
30
+ get strategy() {
31
+ if (this._strategy === null) {
32
+ this.withStrategy(DefaultStyleStrategy);
33
+ }
34
+ return this._strategy;
9
35
  }
10
36
  /** @internal */
11
37
  addStylesTo(target) {
38
+ this.strategy.addStylesTo(target);
12
39
  this.targets.add(target);
13
40
  }
14
41
  /** @internal */
15
42
  removeStylesFrom(target) {
43
+ this.strategy.removeStylesFrom(target);
16
44
  this.targets.delete(target);
17
45
  }
18
46
  /** @internal */
@@ -28,121 +56,54 @@ export class ElementStyles {
28
56
  this.behaviors === null ? behaviors : this.behaviors.concat(behaviors);
29
57
  return this;
30
58
  }
59
+ /**
60
+ * Sets the strategy that handles adding/removing these styles for an element.
61
+ * @param strategy - The strategy to use.
62
+ */
63
+ withStrategy(Strategy) {
64
+ this._strategy = new Strategy(reduceStyles(this.styles));
65
+ return this;
66
+ }
67
+ /**
68
+ * Sets the default strategy type to use when creating style strategies.
69
+ * @param Strategy - The strategy type to construct.
70
+ */
71
+ static setDefaultStrategy(Strategy) {
72
+ DefaultStyleStrategy = Strategy;
73
+ }
31
74
  }
32
75
  /**
33
- * Create ElementStyles from ComposableStyles.
76
+ * Indicates whether the DOM supports the adoptedStyleSheets feature.
34
77
  */
35
- ElementStyles.create = (() => {
36
- if (DOM.supportsAdoptedStyleSheets) {
37
- const styleSheetCache = new Map();
38
- return (styles) =>
39
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
40
- new AdoptedStyleSheetsStyles(styles, styleSheetCache);
41
- }
42
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
43
- return (styles) => new StyleElementStyles(styles);
44
- })();
45
- function reduceStyles(styles) {
46
- return styles
47
- .map((x) => x instanceof ElementStyles ? reduceStyles(x.styles) : [x])
48
- .reduce((prev, curr) => prev.concat(curr), []);
49
- }
50
- function reduceBehaviors(styles) {
51
- return styles
52
- .map((x) => (x instanceof ElementStyles ? x.behaviors : null))
53
- .reduce((prev, curr) => {
54
- if (curr === null) {
55
- return prev;
56
- }
57
- if (prev === null) {
58
- prev = [];
59
- }
60
- return prev.concat(curr);
61
- }, null);
62
- }
78
+ ElementStyles.supportsAdoptedStyleSheets = Array.isArray(document.adoptedStyleSheets) &&
79
+ "replace" in CSSStyleSheet.prototype;
63
80
  /**
64
81
  * https://wicg.github.io/construct-stylesheets/
65
82
  * https://developers.google.com/web/updates/2019/02/constructable-stylesheets
66
83
  *
67
84
  * @internal
68
85
  */
69
- export class AdoptedStyleSheetsStyles extends ElementStyles {
70
- constructor(styles, styleSheetCache) {
71
- super();
72
- this.styles = styles;
73
- this.styleSheetCache = styleSheetCache;
74
- this._styleSheets = void 0;
75
- this.behaviors = reduceBehaviors(styles);
76
- }
77
- get styleSheets() {
78
- if (this._styleSheets === void 0) {
79
- const styles = this.styles;
80
- const styleSheetCache = this.styleSheetCache;
81
- this._styleSheets = reduceStyles(styles).map((x) => {
82
- if (x instanceof CSSStyleSheet) {
83
- return x;
84
- }
85
- let sheet = styleSheetCache.get(x);
86
- if (sheet === void 0) {
87
- sheet = new CSSStyleSheet();
88
- sheet.replaceSync(x);
89
- styleSheetCache.set(x, sheet);
90
- }
91
- return sheet;
92
- });
93
- }
94
- return this._styleSheets;
95
- }
96
- addStylesTo(target) {
97
- target.adoptedStyleSheets = [...target.adoptedStyleSheets, ...this.styleSheets];
98
- super.addStylesTo(target);
99
- }
100
- removeStylesFrom(target) {
101
- const sourceSheets = this.styleSheets;
102
- target.adoptedStyleSheets = target.adoptedStyleSheets.filter((x) => sourceSheets.indexOf(x) === -1);
103
- super.removeStylesFrom(target);
104
- }
105
- }
106
- let styleClassId = 0;
107
- function getNextStyleClass() {
108
- return `fast-style-class-${++styleClassId}`;
109
- }
110
- /**
111
- * @internal
112
- */
113
- export class StyleElementStyles extends ElementStyles {
86
+ export class AdoptedStyleSheetsStrategy {
114
87
  constructor(styles) {
115
- super();
116
- this.styles = styles;
117
- this.behaviors = null;
118
- this.behaviors = reduceBehaviors(styles);
119
- this.styleSheets = reduceStyles(styles);
120
- this.styleClass = getNextStyleClass();
88
+ this.sheets = styles.map((x) => {
89
+ if (x instanceof CSSStyleSheet) {
90
+ return x;
91
+ }
92
+ let sheet = styleSheetCache.get(x);
93
+ if (sheet === void 0) {
94
+ sheet = new CSSStyleSheet();
95
+ sheet.replaceSync(x);
96
+ styleSheetCache.set(x, sheet);
97
+ }
98
+ return sheet;
99
+ });
121
100
  }
122
101
  addStylesTo(target) {
123
- const styleSheets = this.styleSheets;
124
- const styleClass = this.styleClass;
125
- target = this.normalizeTarget(target);
126
- for (let i = 0; i < styleSheets.length; i++) {
127
- const element = document.createElement("style");
128
- element.innerHTML = styleSheets[i];
129
- element.className = styleClass;
130
- target.append(element);
131
- }
132
- super.addStylesTo(target);
102
+ target.adoptedStyleSheets = [...target.adoptedStyleSheets, ...this.sheets];
133
103
  }
134
104
  removeStylesFrom(target) {
135
- target = this.normalizeTarget(target);
136
- const styles = target.querySelectorAll(`.${this.styleClass}`);
137
- for (let i = 0, ii = styles.length; i < ii; ++i) {
138
- target.removeChild(styles[i]);
139
- }
140
- super.removeStylesFrom(target);
141
- }
142
- isAttachedTo(target) {
143
- return super.isAttachedTo(this.normalizeTarget(target));
144
- }
145
- normalizeTarget(target) {
146
- return target === document ? document.body : target;
105
+ const sheets = this.sheets;
106
+ target.adoptedStyleSheets = target.adoptedStyleSheets.filter((x) => sheets.indexOf(x) === -1);
147
107
  }
148
108
  }
109
+ ElementStyles.setDefaultStrategy(FAST.getById(5 /* KernelServiceId.styleSheetStrategy */, () => AdoptedStyleSheetsStrategy));