@microsoft/fast-element 2.0.0-beta.22 → 2.0.0-beta.24

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.json CHANGED
@@ -1,6 +1,80 @@
1
1
  {
2
2
  "name": "@microsoft/fast-element",
3
3
  "entries": [
4
+ {
5
+ "date": "Fri, 16 Jun 2023 18:17:12 GMT",
6
+ "tag": "@microsoft/fast-element_v2.0.0-beta.24",
7
+ "version": "2.0.0-beta.24",
8
+ "comments": {
9
+ "prerelease": [
10
+ {
11
+ "author": "chhol@microsoft.com",
12
+ "package": "@microsoft/fast-element",
13
+ "commit": "8250aa8352940584ff443b550ee756d49f01c478",
14
+ "comment": "fix: update compiler to ensure first and last child references are defined"
15
+ },
16
+ {
17
+ "author": "nicholasrice@users.noreply.github.com",
18
+ "package": "@microsoft/fast-element",
19
+ "commit": "e678a782dd06a1c9ca79726da4a5765244858d21",
20
+ "comment": "Adds 'else' template option to the when directive"
21
+ },
22
+ {
23
+ "author": "nicholasrice@users.noreply.github.com",
24
+ "package": "@microsoft/fast-element",
25
+ "commit": "58f7ce2ca73cf59dd957889e0763f45d087c77c9",
26
+ "comment": "fixed a bug where re-binding a ChildrenDirective instance would throw a runtime exception from the mutation handler"
27
+ },
28
+ {
29
+ "author": "nicholasrice@users.noreply.github.com",
30
+ "package": "@microsoft/fast-element",
31
+ "commit": "88a0d7feb71b2452fa521b72ce308b1e499dfd94",
32
+ "comment": "Update adoptedStyleSheets strategy to use push/splice when available to fix Safari 16.4 bug"
33
+ },
34
+ {
35
+ "author": "nicholasrice@users.noreply.github.com",
36
+ "package": "@microsoft/fast-element",
37
+ "commit": "9793634f3d06316a6a8689a909f4d41bdd667e99",
38
+ "comment": "fixes a bug where ChildrenDirective could not be used multiple times for the same element"
39
+ },
40
+ {
41
+ "author": "nicholasrice@users.noreply.github.com",
42
+ "package": "@microsoft/fast-element",
43
+ "commit": "86c1952373b1fa0d7100cf0d8e942a0580cda725",
44
+ "comment": "fixed bug causing behaviors attached to stylesheets not to be removed when the stylesheet was removed"
45
+ }
46
+ ],
47
+ "none": [
48
+ {
49
+ "author": "chhol@microsoft.com",
50
+ "package": "@microsoft/fast-element",
51
+ "commit": "ca0e62ee8d05f72d1d8c1ad66bd6eea8e3f0a4eb",
52
+ "comment": "update prettier and eslint-config-prettier versions"
53
+ }
54
+ ]
55
+ }
56
+ },
57
+ {
58
+ "date": "Tue, 28 Mar 2023 22:14:10 GMT",
59
+ "tag": "@microsoft/fast-element_v2.0.0-beta.23",
60
+ "version": "2.0.0-beta.23",
61
+ "comments": {
62
+ "prerelease": [
63
+ {
64
+ "author": "rob@bluespire.com",
65
+ "package": "@microsoft/fast-element",
66
+ "commit": "1d9c23ecd77a4079126b1156567b906efff66350",
67
+ "comment": "docs: add missing API docs"
68
+ },
69
+ {
70
+ "author": "rob@bluespire.com",
71
+ "package": "@microsoft/fast-element",
72
+ "commit": "032285c2bf0311f9f44cbc875b40696fc8f62857",
73
+ "comment": "fix: correct types for a break in TypeScript 5 legacy decorators"
74
+ }
75
+ ]
76
+ }
77
+ },
4
78
  {
5
79
  "date": "Sat, 11 Mar 2023 00:09:48 GMT",
6
80
  "tag": "@microsoft/fast-element_v2.0.0-beta.22",
package/CHANGELOG.md CHANGED
@@ -1,9 +1,31 @@
1
1
  # Change Log - @microsoft/fast-element
2
2
 
3
- This log was last generated on Sat, 11 Mar 2023 00:09:48 GMT and should not be manually modified.
3
+ This log was last generated on Fri, 16 Jun 2023 18:17:12 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 2.0.0-beta.24
8
+
9
+ Fri, 16 Jun 2023 18:17:12 GMT
10
+
11
+ ### Changes
12
+
13
+ - fix: update compiler to ensure first and last child references are defined (chhol@microsoft.com)
14
+ - Adds 'else' template option to the when directive (nicholasrice@users.noreply.github.com)
15
+ - fixed a bug where re-binding a ChildrenDirective instance would throw a runtime exception from the mutation handler (nicholasrice@users.noreply.github.com)
16
+ - Update adoptedStyleSheets strategy to use push/splice when available to fix Safari 16.4 bug (nicholasrice@users.noreply.github.com)
17
+ - fixes a bug where ChildrenDirective could not be used multiple times for the same element (nicholasrice@users.noreply.github.com)
18
+ - fixed bug causing behaviors attached to stylesheets not to be removed when the stylesheet was removed (nicholasrice@users.noreply.github.com)
19
+
20
+ ## 2.0.0-beta.23
21
+
22
+ Tue, 28 Mar 2023 22:14:10 GMT
23
+
24
+ ### Changes
25
+
26
+ - docs: add missing API docs (rob@bluespire.com)
27
+ - fix: correct types for a break in TypeScript 5 legacy decorators (rob@bluespire.com)
28
+
7
29
  ## 2.0.0-beta.22
8
30
 
9
31
  Sat, 11 Mar 2023 00:09:48 GMT
@@ -2,13 +2,26 @@ import type { Expression } from "../observation/observable.js";
2
2
  import type { Subscriber } from "../observation/notifier.js";
3
3
  import type { DOMPolicy } from "../dom.js";
4
4
  import { Binding } from "./binding.js";
5
+ /**
6
+ * The gateway to signal APIs.
7
+ * @public
8
+ */
5
9
  export declare const Signal: Readonly<{
10
+ /**
11
+ * Subscribes to a signal.
12
+ * @param signal The signal to subscribe to.
13
+ * @param subscriber The subscriber.
14
+ */
6
15
  subscribe(signal: string, subscriber: Subscriber): void;
16
+ /**
17
+ * Unsubscribes from the signal.
18
+ * @param signal The signal to unsubscribe from.
19
+ * @param subscriber The subscriber.
20
+ */
7
21
  unsubscribe(signal: string, subscriber: Subscriber): void;
8
22
  /**
9
- * Sends the specified signal to signaled bindings.
23
+ * Sends the specified signal to subscribers.
10
24
  * @param signal - The signal to send.
11
- * @public
12
25
  */
13
26
  send(signal: string): void;
14
27
  }>;
@@ -21,6 +21,9 @@ export interface TwoWaySettings {
21
21
  */
22
22
  determineChangeEvent(bindingSource: BindingDirective, target: HTMLElement): string;
23
23
  }
24
+ /**
25
+ * Enables configuring two-way binding settings.
26
+ */
24
27
  export declare const TwoWaySettings: Readonly<{
25
28
  /**
26
29
  * Configures two-way binding.
@@ -1,4 +1,4 @@
1
- import { Constructable } from "./interfaces.js";
1
+ import { Constructable, ParameterDecorator } from "./interfaces.js";
2
2
  /**
3
3
  * A Context object defines an optional initial value for a Context, as well as a name identifier for debugging purposes.
4
4
  * @public
package/dist/dts/dom.d.ts CHANGED
@@ -36,7 +36,7 @@ export declare const DOMAspect: Readonly<{
36
36
  * The type of HTML aspect to target.
37
37
  * @public
38
38
  */
39
- export declare type DOMAspect = typeof DOMAspect[Exclude<keyof typeof DOMAspect, "none">];
39
+ export declare type DOMAspect = (typeof DOMAspect)[Exclude<keyof typeof DOMAspect, "none">];
40
40
  /**
41
41
  * A function used to send values to a DOM sink.
42
42
  * @public
@@ -8,6 +8,7 @@ export * from "./observation/update-queue.js";
8
8
  export * from "./binding/binding.js";
9
9
  export * from "./binding/one-way.js";
10
10
  export * from "./binding/one-time.js";
11
+ export * from "./binding/normalize.js";
11
12
  export * from "./styles/element-styles.js";
12
13
  export * from "./styles/css.js";
13
14
  export * from "./styles/css-directive.js";
@@ -51,6 +51,11 @@ export declare type TrustedTypesPolicy = {
51
51
  export declare type Mutable<T> = {
52
52
  -readonly [P in keyof T]: T[P];
53
53
  };
54
+ /**
55
+ * A temporary type as a workaround for the TS compiler's erroneous built-in ParameterDecorator type.
56
+ * @public
57
+ */
58
+ export declare type ParameterDecorator = (target: Object, propertyKey: string | undefined, parameterIndex: number) => void;
54
59
  /**
55
60
  * The FAST global.
56
61
  * @public
@@ -57,7 +57,7 @@ export declare const SpliceStrategySupport: Readonly<{
57
57
  * The available values for SpliceStrategySupport.
58
58
  * @public
59
59
  */
60
- export declare type SpliceStrategySupport = typeof SpliceStrategySupport[keyof typeof SpliceStrategySupport];
60
+ export declare type SpliceStrategySupport = (typeof SpliceStrategySupport)[keyof typeof SpliceStrategySupport];
61
61
  /**
62
62
  * An approach to tracking changes in an array.
63
63
  * @public
@@ -60,7 +60,7 @@ export declare const SourceLifetime: Readonly<{
60
60
  * Describes how the source's lifetime relates to its controller's lifetime.
61
61
  * @public
62
62
  */
63
- export declare type SourceLifetime = typeof SourceLifetime[keyof typeof SourceLifetime];
63
+ export declare type SourceLifetime = (typeof SourceLifetime)[keyof typeof SourceLifetime];
64
64
  /**
65
65
  * Controls the lifecycle of an expression and provides relevant context.
66
66
  * @public
@@ -5,6 +5,8 @@ import type { CaptureType, SyntheticViewTemplate } from "./template.js";
5
5
  * @param condition - The condition to test for rendering.
6
6
  * @param templateOrTemplateBinding - The template or a binding that gets
7
7
  * the template to render when the condition is true.
8
+ * @param elseTemplateOrTemplateBinding - Optional template or binding that that
9
+ * gets the template to render when the conditional is false.
8
10
  * @public
9
11
  */
10
- export declare function when<TSource = any, TReturn = any, TParent = any>(condition: Expression<TSource, TReturn, TParent> | boolean, templateOrTemplateBinding: SyntheticViewTemplate<TSource, TParent> | Expression<TSource, SyntheticViewTemplate<TSource, TParent>, TParent>): CaptureType<TSource, TParent>;
12
+ export declare function when<TSource = any, TReturn = any, TParent = any>(condition: Expression<TSource, TReturn, TParent> | boolean, templateOrTemplateBinding: SyntheticViewTemplate<TSource, TParent> | Expression<TSource, SyntheticViewTemplate<TSource, TParent>, TParent>, elseTemplateOrTemplateBinding?: SyntheticViewTemplate<TSource, TParent> | Expression<TSource, SyntheticViewTemplate<TSource, TParent>, TParent>): CaptureType<TSource, TParent>;
@@ -2,7 +2,16 @@ import { isString } from "../interfaces.js";
2
2
  import { makeSerializationNoop } from "../platform.js";
3
3
  import { Binding } from "./binding.js";
4
4
  const subscribers = Object.create(null);
5
+ /**
6
+ * The gateway to signal APIs.
7
+ * @public
8
+ */
5
9
  export const Signal = Object.freeze({
10
+ /**
11
+ * Subscribes to a signal.
12
+ * @param signal The signal to subscribe to.
13
+ * @param subscriber The subscriber.
14
+ */
6
15
  subscribe(signal, subscriber) {
7
16
  const found = subscribers[signal];
8
17
  if (found) {
@@ -14,6 +23,11 @@ export const Signal = Object.freeze({
14
23
  subscribers[signal] = subscriber;
15
24
  }
16
25
  },
26
+ /**
27
+ * Unsubscribes from the signal.
28
+ * @param signal The signal to unsubscribe from.
29
+ * @param subscriber The subscriber.
30
+ */
17
31
  unsubscribe(signal, subscriber) {
18
32
  const found = subscribers[signal];
19
33
  if (found && found instanceof Set) {
@@ -24,9 +38,8 @@ export const Signal = Object.freeze({
24
38
  }
25
39
  },
26
40
  /**
27
- * Sends the specified signal to signaled bindings.
41
+ * Sends the specified signal to subscribers.
28
42
  * @param signal - The signal to send.
29
- * @public
30
43
  */
31
44
  send(signal) {
32
45
  const found = subscribers[signal];
@@ -10,6 +10,9 @@ let twoWaySettings = {
10
10
  return "change";
11
11
  },
12
12
  };
13
+ /**
14
+ * Enables configuring two-way binding settings.
15
+ */
13
16
  export const TwoWaySettings = Object.freeze({
14
17
  /**
15
18
  * Configures two-way binding.
@@ -71,7 +74,8 @@ class TwoWayObserver {
71
74
  value = target[bindingSource.targetAspect];
72
75
  break;
73
76
  }
74
- last.propertySource[last.propertyName] = this.dataBinding.options.fromView(value);
77
+ last.propertySource[last.propertyName] =
78
+ this.dataBinding.options.fromView(value);
75
79
  }
76
80
  }
77
81
  makeSerializationNoop(TwoWayObserver);
@@ -278,7 +278,7 @@ export class ElementController extends PropertyChangeNotifier {
278
278
  styles.removeStylesFrom(source);
279
279
  if (sourceBehaviors !== null) {
280
280
  for (let i = 0, ii = sourceBehaviors.length; i < ii; ++i) {
281
- this.addBehavior(sourceBehaviors[i]);
281
+ this.removeBehavior(sourceBehaviors[i]);
282
282
  }
283
283
  }
284
284
  }
@@ -466,13 +466,10 @@ export class AdoptedStyleSheetsStrategy {
466
466
  });
467
467
  }
468
468
  addStylesTo(target) {
469
- const t = normalizeStyleTarget(target);
470
- t.adoptedStyleSheets = [...t.adoptedStyleSheets, ...this.sheets];
469
+ addAdoptedStyleSheets(normalizeStyleTarget(target), this.sheets);
471
470
  }
472
471
  removeStylesFrom(target) {
473
- const t = normalizeStyleTarget(target);
474
- const sheets = this.sheets;
475
- t.adoptedStyleSheets = t.adoptedStyleSheets.filter((x) => sheets.indexOf(x) === -1);
472
+ removeAdoptedStyleSheets(normalizeStyleTarget(target), this.sheets);
476
473
  }
477
474
  }
478
475
  AdoptedStyleSheetsStrategy.styleSheetCache = new Map();
@@ -508,6 +505,39 @@ export class StyleElementStrategy {
508
505
  }
509
506
  }
510
507
  }
511
- ElementStyles.setDefaultStrategy(ElementStyles.supportsAdoptedStyleSheets
512
- ? AdoptedStyleSheetsStrategy
513
- : StyleElementStrategy);
508
+ let addAdoptedStyleSheets = (target, sheets) => {
509
+ target.adoptedStyleSheets = [...target.adoptedStyleSheets, ...sheets];
510
+ };
511
+ let removeAdoptedStyleSheets = (target, sheets) => {
512
+ target.adoptedStyleSheets = target.adoptedStyleSheets.filter((x) => sheets.indexOf(x) === -1);
513
+ };
514
+ if (ElementStyles.supportsAdoptedStyleSheets) {
515
+ try {
516
+ // Test if browser implementation uses FrozenArray.
517
+ // If not, use push / splice to alter the stylesheets
518
+ // in place. This circumvents a bug in Safari 16.4 where
519
+ // periodically, assigning the array would previously
520
+ // cause sheets to be removed.
521
+ document.adoptedStyleSheets.push();
522
+ document.adoptedStyleSheets.splice();
523
+ addAdoptedStyleSheets = (target, sheets) => {
524
+ target.adoptedStyleSheets.push(...sheets);
525
+ };
526
+ removeAdoptedStyleSheets = (target, sheets) => {
527
+ for (const sheet of sheets) {
528
+ const index = target.adoptedStyleSheets.indexOf(sheet);
529
+ if (index !== -1) {
530
+ target.adoptedStyleSheets.splice(index, 1);
531
+ }
532
+ }
533
+ };
534
+ }
535
+ catch (e) {
536
+ // Do nothing if an error is thrown, the default
537
+ // case handles FrozenArray.
538
+ }
539
+ ElementStyles.setDefaultStrategy(AdoptedStyleSheetsStrategy);
540
+ }
541
+ else {
542
+ ElementStyles.setDefaultStrategy(StyleElementStrategy);
543
+ }
package/dist/esm/index.js CHANGED
@@ -10,6 +10,7 @@ export * from "./observation/update-queue.js";
10
10
  export * from "./binding/binding.js";
11
11
  export * from "./binding/one-way.js";
12
12
  export * from "./binding/one-time.js";
13
+ export * from "./binding/normalize.js";
13
14
  // Styles
14
15
  export * from "./styles/element-styles.js";
15
16
  export * from "./styles/css.js";
@@ -12,7 +12,7 @@ export class ChildrenDirective extends NodeObservationDirective {
12
12
  */
13
13
  constructor(options) {
14
14
  super(options);
15
- this.observerProperty = `${this.id}-o`;
15
+ this.observerProperty = Symbol();
16
16
  this.handleEvent = (mutations, observer) => {
17
17
  const target = observer.target;
18
18
  this.updateTarget(this.getSource(target), this.computeNodes(target));
@@ -28,9 +28,9 @@ export class ChildrenDirective extends NodeObservationDirective {
28
28
  if (!observer) {
29
29
  observer = new MutationObserver(this.handleEvent);
30
30
  observer.toJSON = noop;
31
- observer.target = target;
32
31
  target[this.observerProperty] = observer;
33
32
  }
33
+ observer.target = target;
34
34
  observer.observe(target, this.options);
35
35
  }
36
36
  /**
@@ -215,6 +215,9 @@ export const Compiler = {
215
215
  else {
216
216
  template = html;
217
217
  }
218
+ if (!template.content.firstChild && !template.content.lastChild) {
219
+ template.content.appendChild(document.createComment(""));
220
+ }
218
221
  // https://bugs.chromium.org/p/chromium/issues/detail?id=1111864
219
222
  const fragment = document.adoptNode(template.content);
220
223
  const context = new CompilationContext(fragment, factories, policy);
@@ -1,15 +1,22 @@
1
1
  import { isFunction } from "../interfaces.js";
2
+ const noTemplate = () => null;
3
+ function normalizeBinding(value) {
4
+ return value === undefined ? noTemplate : isFunction(value) ? value : () => value;
5
+ }
2
6
  /**
3
7
  * A directive that enables basic conditional rendering in a template.
4
8
  * @param condition - The condition to test for rendering.
5
9
  * @param templateOrTemplateBinding - The template or a binding that gets
6
10
  * the template to render when the condition is true.
11
+ * @param elseTemplateOrTemplateBinding - Optional template or binding that that
12
+ * gets the template to render when the conditional is false.
7
13
  * @public
8
14
  */
9
- export function when(condition, templateOrTemplateBinding) {
15
+ export function when(condition, templateOrTemplateBinding, elseTemplateOrTemplateBinding) {
10
16
  const dataBinding = isFunction(condition) ? condition : () => condition;
11
- const templateBinding = isFunction(templateOrTemplateBinding)
12
- ? templateOrTemplateBinding
13
- : () => templateOrTemplateBinding;
14
- return (source, context) => dataBinding(source, context) ? templateBinding(source, context) : null;
17
+ const templateBinding = normalizeBinding(templateOrTemplateBinding);
18
+ const elseBinding = normalizeBinding(elseTemplateOrTemplateBinding);
19
+ return (source, context) => dataBinding(source, context)
20
+ ? templateBinding(source, context)
21
+ : elseBinding(source, context);
15
22
  }