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

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 (56) hide show
  1. package/CHANGELOG.json +33 -0
  2. package/CHANGELOG.md +12 -1
  3. package/dist/dts/binding/binding.d.ts +49 -0
  4. package/dist/dts/binding/normalize.d.ts +9 -0
  5. package/dist/dts/binding/one-time.d.ts +11 -0
  6. package/dist/dts/binding/one-way.d.ts +20 -0
  7. package/dist/dts/{templating/binding-signal.d.ts → binding/signal.d.ts} +1 -1
  8. package/dist/dts/{templating/binding-two-way.d.ts → binding/two-way.d.ts} +3 -4
  9. package/dist/dts/components/element-controller.d.ts +20 -5
  10. package/dist/dts/context.d.ts +20 -7
  11. package/dist/dts/index.d.ts +6 -2
  12. package/dist/dts/interfaces.d.ts +4 -4
  13. package/dist/dts/metadata.d.ts +1 -0
  14. package/dist/dts/platform.d.ts +9 -1
  15. package/dist/dts/styles/css-binding-directive.d.ts +60 -0
  16. package/dist/dts/styles/css.d.ts +9 -2
  17. package/dist/dts/styles/host.d.ts +2 -5
  18. package/dist/dts/templating/{binding.d.ts → html-binding-directive.d.ts} +3 -34
  19. package/dist/dts/templating/html-directive.d.ts +3 -35
  20. package/dist/dts/templating/render.d.ts +19 -5
  21. package/dist/dts/templating/repeat.d.ts +3 -2
  22. package/dist/dts/templating/template.d.ts +2 -6
  23. package/dist/dts/templating/view.d.ts +16 -6
  24. package/dist/dts/testing/fakes.d.ts +2 -1
  25. package/dist/esm/binding/binding.js +18 -0
  26. package/dist/esm/binding/normalize.js +17 -0
  27. package/dist/esm/binding/one-time.js +21 -0
  28. package/dist/esm/binding/one-way.js +30 -0
  29. package/dist/esm/{templating/binding-signal.js → binding/signal.js} +5 -8
  30. package/dist/esm/{templating/binding-two-way.js → binding/two-way.js} +11 -15
  31. package/dist/esm/components/element-controller.js +33 -8
  32. package/dist/esm/context.js +22 -1
  33. package/dist/esm/index.js +8 -2
  34. package/dist/esm/interfaces.js +3 -3
  35. package/dist/esm/metadata.js +3 -1
  36. package/dist/esm/observation/observable.js +3 -6
  37. package/dist/esm/platform.js +9 -0
  38. package/dist/esm/styles/css-binding-directive.js +76 -0
  39. package/dist/esm/styles/css.js +14 -2
  40. package/dist/esm/templating/compiler.js +2 -1
  41. package/dist/esm/templating/{binding.js → html-binding-directive.js} +3 -70
  42. package/dist/esm/templating/html-directive.js +2 -25
  43. package/dist/esm/templating/render.js +25 -12
  44. package/dist/esm/templating/repeat.js +3 -3
  45. package/dist/esm/templating/template.js +9 -10
  46. package/dist/esm/templating/view.js +2 -6
  47. package/dist/esm/testing/fakes.js +1 -1
  48. package/dist/fast-element.api.json +1127 -342
  49. package/dist/fast-element.d.ts +125 -41
  50. package/dist/fast-element.debug.js +217 -117
  51. package/dist/fast-element.debug.min.js +1 -1
  52. package/dist/fast-element.js +217 -117
  53. package/dist/fast-element.min.js +1 -1
  54. package/dist/fast-element.untrimmed.d.ts +132 -80
  55. package/docs/api-report.md +52 -51
  56. package/package.json +5 -5
@@ -1,10 +1,11 @@
1
1
  import type { FASTElement } from "../components/fast-element.js";
2
2
  import type { DOMPolicy } from "../dom.js";
3
3
  import { Constructable } from "../interfaces.js";
4
+ import { Binding, BindingDirective } from "../binding/binding.js";
4
5
  import type { Subscriber } from "../observation/notifier.js";
5
6
  import type { ExecutionContext, Expression, ExpressionObserver } from "../observation/observable.js";
6
- import { ContentTemplate, ContentView } from "./binding.js";
7
- import { AddViewBehaviorFactory, Binding, HTMLDirective, ViewBehavior, ViewBehaviorFactory, ViewController } from "./html-directive.js";
7
+ import type { ContentTemplate, ContentView } from "./html-binding-directive.js";
8
+ import { AddViewBehaviorFactory, HTMLDirective, ViewBehavior, ViewBehaviorFactory, ViewController } from "./html-directive.js";
8
9
  import { CaptureType, SyntheticViewTemplate, TemplateValue, ViewTemplate } from "./template.js";
9
10
  /**
10
11
  * A Behavior that enables advanced rendering.
@@ -42,13 +43,13 @@ export declare class RenderBehavior<TSource = any> implements ViewBehavior, Subs
42
43
  * A Directive that enables use of the RenderBehavior.
43
44
  * @public
44
45
  */
45
- export declare class RenderDirective<TSource = any> implements HTMLDirective, ViewBehaviorFactory {
46
+ export declare class RenderDirective<TSource = any> implements HTMLDirective, ViewBehaviorFactory, BindingDirective {
46
47
  readonly dataBinding: Binding<TSource>;
47
48
  readonly templateBinding: Binding<TSource, ContentTemplate>;
48
49
  readonly templateBindingDependsOnData: boolean;
49
50
  /**
50
51
  * The structural id of the DOM node to which the created behavior will apply.
51
- */
52
+ */ BindingDirective: any;
52
53
  targetNodeId: string;
53
54
  /**
54
55
  * Creates an instance of RenderDirective.
@@ -143,6 +144,19 @@ export declare type BaseElementRenderOptions<TSource = any, TParent = any> = Com
143
144
  */
144
145
  policy?: DOMPolicy;
145
146
  };
147
+ /**
148
+ * Render options for directly creating an element with {@link RenderInstruction.createElementTemplate}
149
+ * @public
150
+ */
151
+ export declare type ElementCreateOptions<TSource = any, TParent = any> = Omit<BaseElementRenderOptions, "type" | "name"> & {
152
+ /**
153
+ * Directives to use when creating the element template. These directives are applied directly to the specified tag.
154
+ *
155
+ * @remarks
156
+ * Directives supported by this API are: `ref`, `children`, `slotted`, or any custom `HTMLDirective` that can be used on a HTML tag.
157
+ */
158
+ directives?: TemplateValue<TSource, TParent>[];
159
+ };
146
160
  /**
147
161
  * Render options used to specify an element.
148
162
  * @public
@@ -163,7 +177,7 @@ export declare type TagNameRenderOptions<TSource = any, TParent = any> = BaseEle
163
177
  */
164
178
  tagName: string;
165
179
  };
166
- declare function createElementTemplate<TSource = any, TParent = any>(tagName: string, attributes?: Record<string, string | TemplateValue<TSource, TParent>>, content?: string | ContentTemplate, policy?: DOMPolicy): ViewTemplate<TSource, TParent>;
180
+ declare function createElementTemplate<TSource = any, TParent = any>(tagName: string, options?: ElementCreateOptions): ViewTemplate<TSource, TParent>;
167
181
  declare function create(options: TagNameRenderOptions): RenderInstruction;
168
182
  declare function create(options: ElementConstructorRenderOptions): RenderInstruction;
169
183
  declare function create(options: TemplateRenderOptions): RenderInstruction;
@@ -1,7 +1,8 @@
1
1
  import type { Subscriber } from "../observation/notifier.js";
2
2
  import { Expression, ExpressionObserver } from "../observation/observable.js";
3
3
  import { Splice } from "../observation/arrays.js";
4
- import { AddViewBehaviorFactory, Binding, HTMLDirective, ViewBehavior, ViewBehaviorFactory, ViewController } from "./html-directive.js";
4
+ import type { Binding, BindingDirective } from "../binding/binding.js";
5
+ import { AddViewBehaviorFactory, HTMLDirective, ViewBehavior, ViewBehaviorFactory, ViewController } from "./html-directive.js";
5
6
  import type { CaptureType, SyntheticViewTemplate, ViewTemplate } from "./template.js";
6
7
  import { SyntheticView } from "./view.js";
7
8
  /**
@@ -68,7 +69,7 @@ export declare class RepeatBehavior<TSource = any> implements ViewBehavior, Subs
68
69
  * A directive that configures list rendering.
69
70
  * @public
70
71
  */
71
- export declare class RepeatDirective<TSource = any> implements HTMLDirective, ViewBehaviorFactory {
72
+ export declare class RepeatDirective<TSource = any> implements HTMLDirective, ViewBehaviorFactory, BindingDirective {
72
73
  readonly dataBinding: Binding<TSource>;
73
74
  readonly templateBinding: Binding<TSource, SyntheticViewTemplate>;
74
75
  readonly options: RepeatOptions;
@@ -1,6 +1,7 @@
1
1
  import type { DOMPolicy } from "../dom.js";
2
+ import { Binding } from "../binding/binding.js";
2
3
  import type { Expression } from "../observation/observable.js";
3
- import { AddViewBehaviorFactory, Binding, HTMLDirective, ViewBehaviorFactory } from "./html-directive.js";
4
+ import { AddViewBehaviorFactory, HTMLDirective, ViewBehaviorFactory } from "./html-directive.js";
4
5
  import type { ElementView, HTMLView, SyntheticView } from "./view.js";
5
6
  /**
6
7
  * A template capable of creating views specifically for rendering custom elements.
@@ -129,11 +130,6 @@ export declare class ViewTemplate<TSource = any, TParent = any> implements Eleme
129
130
  * host that the template is being attached to.
130
131
  */
131
132
  render(source: TSource, host: Node, hostBindingTarget?: Element): HTMLView<TSource, TParent>;
132
- /**
133
- * Opts out of JSON stringification.
134
- * @internal
135
- */
136
- toJSON: () => undefined;
137
133
  /**
138
134
  * Creates a template based on a set of static strings and dynamic values.
139
135
  * @param strings - The static strings to create the template with.
@@ -1,4 +1,4 @@
1
- import { Disposable } from "../interfaces.js";
1
+ import type { Disposable } from "../interfaces.js";
2
2
  import { ExecutionContext, SourceLifetime } from "../observation/observable.js";
3
3
  import type { CompiledViewBehaviorFactory, ViewBehaviorTargets, ViewController } from "./html-directive.js";
4
4
  /**
@@ -14,6 +14,10 @@ export interface View<TSource = any, TParent = any> extends Disposable {
14
14
  * The data that the view is bound to.
15
15
  */
16
16
  readonly source: TSource | null;
17
+ /**
18
+ * Indicates whether the controller is bound.
19
+ */
20
+ readonly isBound: boolean;
17
21
  /**
18
22
  * Binds a view's behaviors to its binding source.
19
23
  * @param source - The binding source for the view's binding behaviors.
@@ -29,6 +33,17 @@ export interface View<TSource = any, TParent = any> extends Disposable {
29
33
  * @public
30
34
  */
31
35
  export interface ElementView<TSource = any, TParent = any> extends View<TSource, TParent> {
36
+ /**
37
+ * Indicates how the source's lifetime relates to the controller's lifetime.
38
+ */
39
+ readonly sourceLifetime?: SourceLifetime;
40
+ /**
41
+ * Registers an unbind handler with the controller.
42
+ * @param behavior - An object to call when the controller unbinds.
43
+ */
44
+ onUnbind(behavior: {
45
+ unbind(controller: ViewController<TSource, TParent>): any;
46
+ }): void;
32
47
  /**
33
48
  * Appends the view's DOM nodes to the referenced node.
34
49
  * @param node - The parent node to append the view's DOM nodes to.
@@ -185,11 +200,6 @@ export declare class HTMLView<TSource = any, TParent = any> implements ElementVi
185
200
  * Unbinds a view's behaviors from its binding source.
186
201
  */
187
202
  unbind(): void;
188
- /**
189
- * Opts out of JSON stringification.
190
- * @internal
191
- */
192
- toJSON: () => undefined;
193
203
  private evaluateUnbindables;
194
204
  /**
195
205
  * Efficiently disposes of a contiguous range of synthetic view instances.
@@ -1,4 +1,5 @@
1
- import { ExecutionContext, ViewBehavior, ViewBehaviorTargets } from "../index.js";
1
+ import { ExecutionContext } from "../observation/observable.js";
2
+ import type { ViewBehavior, ViewBehaviorTargets } from "../templating/html-directive.js";
2
3
  export declare const Fake: Readonly<{
3
4
  executionContext<TParent = any>(parent?: TParent | undefined, parentContext?: ExecutionContext<TParent> | undefined): ExecutionContext<TParent>;
4
5
  viewController<TSource = any, TParent_1 = any>(targets?: ViewBehaviorTargets, ...behaviors: ViewBehavior<TSource, TParent_1>[]): {
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Captures a binding expression along with related information and capabilities.
3
+ *
4
+ * @public
5
+ */
6
+ export class Binding {
7
+ /**
8
+ * Creates a binding.
9
+ * @param evaluate - Evaluates the binding.
10
+ * @param policy - The security policy to associate with this binding.
11
+ * @param isVolatile - Indicates whether the binding is volatile.
12
+ */
13
+ constructor(evaluate, policy, isVolatile = false) {
14
+ this.evaluate = evaluate;
15
+ this.policy = policy;
16
+ this.isVolatile = isVolatile;
17
+ }
18
+ }
@@ -0,0 +1,17 @@
1
+ import { isFunction } from "../interfaces.js";
2
+ import { Binding } from "./binding.js";
3
+ import { oneWay } from "./one-way.js";
4
+ import { oneTime } from "./one-time.js";
5
+ /**
6
+ * Normalizes the input value into a binding.
7
+ * @param value - The value to create the default binding for.
8
+ * @returns A binding configuration for the provided value.
9
+ * @public
10
+ */
11
+ export function normalizeBinding(value) {
12
+ return isFunction(value)
13
+ ? oneWay(value)
14
+ : value instanceof Binding
15
+ ? value
16
+ : oneTime(() => value);
17
+ }
@@ -0,0 +1,21 @@
1
+ import { makeSerializationNoop } from "../platform.js";
2
+ import { Binding } from "./binding.js";
3
+ class OneTimeBinding extends Binding {
4
+ createObserver() {
5
+ return this;
6
+ }
7
+ bind(controller) {
8
+ return this.evaluate(controller.source, controller.context);
9
+ }
10
+ }
11
+ makeSerializationNoop(OneTimeBinding);
12
+ /**
13
+ * Creates a one time binding
14
+ * @param expression - The binding to refresh when signaled.
15
+ * @param policy - The security policy to associate with th binding.
16
+ * @returns A binding configuration.
17
+ * @public
18
+ */
19
+ export function oneTime(expression, policy) {
20
+ return new OneTimeBinding(expression, policy);
21
+ }
@@ -0,0 +1,30 @@
1
+ import { Observable } from "../observation/observable.js";
2
+ import { Binding } from "./binding.js";
3
+ class OneWayBinding extends Binding {
4
+ createObserver(subscriber) {
5
+ return Observable.binding(this.evaluate, subscriber, this.isVolatile);
6
+ }
7
+ }
8
+ /**
9
+ * Creates an standard binding.
10
+ * @param expression - The binding to refresh when changed.
11
+ * @param policy - The security policy to associate with th binding.
12
+ * @param isVolatile - Indicates whether the binding is volatile or not.
13
+ * @returns A binding configuration.
14
+ * @public
15
+ */
16
+ export function oneWay(expression, policy, isVolatile = Observable.isVolatileBinding(expression)) {
17
+ return new OneWayBinding(expression, policy, isVolatile);
18
+ }
19
+ /**
20
+ * Creates an event listener binding.
21
+ * @param expression - The binding to invoke when the event is raised.
22
+ * @param options - Event listener options.
23
+ * @returns A binding configuration.
24
+ * @public
25
+ */
26
+ export function listener(expression, options) {
27
+ const config = new OneWayBinding(expression);
28
+ config.options = options;
29
+ return config;
30
+ }
@@ -1,5 +1,6 @@
1
- import { isString, noop } from "../interfaces.js";
2
- import { Binding } from "./html-directive.js";
1
+ import { isString } from "../interfaces.js";
2
+ import { makeSerializationNoop } from "../platform.js";
3
+ import { Binding } from "./binding.js";
3
4
  const subscribers = Object.create(null);
4
5
  export const Signal = Object.freeze({
5
6
  subscribe(signal, subscriber) {
@@ -41,11 +42,6 @@ class SignalObserver {
41
42
  this.dataBinding = dataBinding;
42
43
  this.subscriber = subscriber;
43
44
  this.isNotBound = true;
44
- /**
45
- * Opts out of JSON stringification.
46
- * @internal
47
- */
48
- this.toJSON = noop;
49
45
  }
50
46
  bind(controller) {
51
47
  if (this.isNotBound) {
@@ -69,8 +65,9 @@ class SignalObserver {
69
65
  : options(controller.source, controller.context);
70
66
  }
71
67
  }
68
+ makeSerializationNoop(SignalObserver);
72
69
  class SignalBinding extends Binding {
73
- createObserver(directive, subscriber) {
70
+ createObserver(subscriber) {
74
71
  return new SignalObserver(this, subscriber);
75
72
  }
76
73
  }
@@ -1,7 +1,7 @@
1
- import { isString, noop } from "../interfaces.js";
1
+ import { isString } from "../interfaces.js";
2
2
  import { Observable, } from "../observation/observable.js";
3
- import { FAST } from "../platform.js";
4
- import { Binding } from "./html-directive.js";
3
+ import { FAST, makeSerializationNoop } from "../platform.js";
4
+ import { Binding } from "./binding.js";
5
5
  const defaultOptions = {
6
6
  fromView: v => v,
7
7
  };
@@ -25,11 +25,6 @@ class TwoWayObserver {
25
25
  this.subscriber = subscriber;
26
26
  this.dataBinding = dataBinding;
27
27
  this.isNotBound = true;
28
- /**
29
- * Opts out of JSON stringification.
30
- * @internal
31
- */
32
- this.toJSON = noop;
33
28
  this.notifier = Observable.binding(dataBinding.evaluate, this, dataBinding.isVolatile);
34
29
  }
35
30
  bind(controller) {
@@ -53,7 +48,7 @@ class TwoWayObserver {
53
48
  this.subscriber.handleChange(this.dataBinding.evaluate, this);
54
49
  }
55
50
  handleEvent(event) {
56
- const directive = this.directive;
51
+ const bindingSource = this.directive;
57
52
  const target = event.currentTarget;
58
53
  const notifier = this.notifier;
59
54
  const last = notifier.last; // using internal API!!!
@@ -62,26 +57,27 @@ class TwoWayObserver {
62
57
  return;
63
58
  }
64
59
  let value;
65
- switch (directive.aspectType) {
60
+ switch (bindingSource.aspectType) {
66
61
  case 1:
67
- value = target.getAttribute(directive.targetAspect);
62
+ value = target.getAttribute(bindingSource.targetAspect);
68
63
  break;
69
64
  case 2:
70
- value = target.hasAttribute(directive.targetAspect);
65
+ value = target.hasAttribute(bindingSource.targetAspect);
71
66
  break;
72
67
  case 4:
73
68
  value = target.innerText;
74
69
  break;
75
70
  default:
76
- value = target[directive.targetAspect];
71
+ value = target[bindingSource.targetAspect];
77
72
  break;
78
73
  }
79
74
  last.propertySource[last.propertyName] = this.dataBinding.options.fromView(value);
80
75
  }
81
76
  }
77
+ makeSerializationNoop(TwoWayObserver);
82
78
  class TwoWayBinding extends Binding {
83
- createObserver(directive, subscriber) {
84
- return new TwoWayObserver(directive, subscriber, this);
79
+ createObserver(subscriber, bindingSource) {
80
+ return new TwoWayObserver(bindingSource, subscriber, this);
85
81
  }
86
82
  }
87
83
  /**
@@ -1,7 +1,7 @@
1
- import { noop } from "../interfaces.js";
1
+ import "../interfaces.js";
2
2
  import { PropertyChangeNotifier } from "../observation/notifier.js";
3
- import { Observable, SourceLifetime } from "../observation/observable.js";
4
- import { FAST } from "../platform.js";
3
+ import { ExecutionContext, Observable, SourceLifetime, } from "../observation/observable.js";
4
+ import { FAST, makeSerializationNoop } from "../platform.js";
5
5
  import { ElementStyles } from "../styles/element-styles.js";
6
6
  import { FASTElementDefinition } from "./fast-definitions.js";
7
7
  const defaultEventOptions = {
@@ -58,11 +58,6 @@ export class ElementController extends PropertyChangeNotifier {
58
58
  * If `null` then the element is managing its own rendering.
59
59
  */
60
60
  this.view = null;
61
- /**
62
- * Opts out of JSON stringification.
63
- * @internal
64
- */
65
- this.toJSON = noop;
66
61
  this.source = element;
67
62
  this.definition = definition;
68
63
  const shadowOptions = definition.shadowOptions;
@@ -103,6 +98,27 @@ export class ElementController extends PropertyChangeNotifier {
103
98
  Observable.track(this, isConnectedPropertyName);
104
99
  return this.stage === 1 /* Stages.connected */;
105
100
  }
101
+ /**
102
+ * The context the expression is evaluated against.
103
+ */
104
+ get context() {
105
+ var _a, _b;
106
+ return (_b = (_a = this.view) === null || _a === void 0 ? void 0 : _a.context) !== null && _b !== void 0 ? _b : ExecutionContext.default;
107
+ }
108
+ /**
109
+ * Indicates whether the controller is bound.
110
+ */
111
+ get isBound() {
112
+ var _a, _b;
113
+ return (_b = (_a = this.view) === null || _a === void 0 ? void 0 : _a.isBound) !== null && _b !== void 0 ? _b : false;
114
+ }
115
+ /**
116
+ * Indicates how the source's lifetime relates to the controller's lifetime.
117
+ */
118
+ get sourceLifetime() {
119
+ var _a;
120
+ return (_a = this.view) === null || _a === void 0 ? void 0 : _a.sourceLifetime;
121
+ }
106
122
  /**
107
123
  * Gets/sets the template used to render the component.
108
124
  * @remarks
@@ -165,6 +181,14 @@ export class ElementController extends PropertyChangeNotifier {
165
181
  this.addStyles(value);
166
182
  }
167
183
  }
184
+ /**
185
+ * Registers an unbind handler with the controller.
186
+ * @param behavior - An object to call when the controller unbinds.
187
+ */
188
+ onUnbind(behavior) {
189
+ var _a;
190
+ (_a = this.view) === null || _a === void 0 ? void 0 : _a.onUnbind(behavior);
191
+ }
168
192
  /**
169
193
  * Adds the behavior to the component.
170
194
  * @param behavior - The behavior to add.
@@ -397,6 +421,7 @@ export class ElementController extends PropertyChangeNotifier {
397
421
  elementControllerStrategy = strategy;
398
422
  }
399
423
  }
424
+ makeSerializationNoop(ElementController);
400
425
  // Set default strategy for ElementController
401
426
  ElementController.setStrategy(ElementController);
402
427
  /**
@@ -1,6 +1,7 @@
1
1
  import "./interfaces.js";
2
2
  import { Metadata } from "./metadata.js";
3
3
  import { FAST } from "./platform.js";
4
+ const contextsByName = new Map();
4
5
  const contextEventType = "context-request";
5
6
  let requestStrategy;
6
7
  /**
@@ -12,6 +13,20 @@ export const Context = Object.freeze({
12
13
  * The event type used for W3C Context Protocol requests.
13
14
  */
14
15
  eventType: contextEventType,
16
+ /**
17
+ * Returns a FASTContext object from the global context registry matching the given name if found.
18
+ * Otherwise, returns a new FASTContext with this name.
19
+ * @param name - The name of the FASTContext to get or create.
20
+ * @returns A FASTContext object.
21
+ */
22
+ for(name) {
23
+ let c = contextsByName.get(name);
24
+ if (c === void 0) {
25
+ c = Context.create(name);
26
+ contextsByName.set(name, c);
27
+ }
28
+ return c;
29
+ },
15
30
  /**
16
31
  * Creates a W3C Community Protocol-based Context object to use in requesting/providing
17
32
  * context through the DOM.
@@ -94,8 +109,14 @@ export const Context = Object.freeze({
94
109
  dispatch(target, context, callback, multiple = false) {
95
110
  target.dispatchEvent(new ContextEvent(context, callback, multiple));
96
111
  },
112
+ /**
113
+ * Enables an event target to provide a context value.
114
+ * @param target The target to provide the context value for.
115
+ * @param context The context to provide the value for.
116
+ * @param value The value to provide for the context.
117
+ */
97
118
  provide(target, context, value) {
98
- this.handle(target, (event) => {
119
+ Context.handle(target, (event) => {
99
120
  event.stopImmediatePropagation();
100
121
  event.callback(value);
101
122
  }, context);
package/dist/esm/index.js CHANGED
@@ -1,21 +1,27 @@
1
- export * from "./platform.js";
1
+ export { FAST, emptyArray } from "./platform.js";
2
+ // DOM
2
3
  export * from "./dom.js";
3
4
  // Observation
4
5
  export * from "./observation/observable.js";
5
6
  export * from "./observation/notifier.js";
6
7
  export * from "./observation/arrays.js";
7
8
  export * from "./observation/update-queue.js";
9
+ // Binding
10
+ export * from "./binding/binding.js";
11
+ export * from "./binding/one-way.js";
12
+ export * from "./binding/one-time.js";
8
13
  // Styles
9
14
  export * from "./styles/element-styles.js";
10
15
  export * from "./styles/css.js";
11
16
  export * from "./styles/css-directive.js";
12
17
  export * from "./styles/host.js";
13
18
  export * from "./styles/style-strategy.js";
19
+ export * from "./styles/css-binding-directive.js";
14
20
  // Templating
15
21
  export * from "./templating/template.js";
16
22
  export * from "./templating/compiler.js";
17
23
  export { Markup, Parser } from "./templating/markup.js";
18
- export * from "./templating/binding.js";
24
+ export * from "./templating/html-binding-directive.js";
19
25
  export * from "./templating/html-directive.js";
20
26
  export * from "./templating/ref.js";
21
27
  export * from "./templating/when.js";
@@ -45,16 +45,16 @@ switch (kernelMode) {
45
45
  export { KernelServiceId };
46
46
  /**
47
47
  * Determines whether or not an object is a function.
48
- * @internal
48
+ * @public
49
49
  */
50
50
  export const isFunction = (object) => typeof object === "function";
51
51
  /**
52
52
  * Determines whether or not an object is a string.
53
- * @internal
53
+ * @public
54
54
  */
55
55
  export const isString = (object) => typeof object === "string";
56
56
  /**
57
57
  * A function which does nothing.
58
- * @internal
58
+ * @public
59
59
  */
60
60
  export const noop = () => void 0;
@@ -23,8 +23,10 @@ if (!("metadata" in Reflect)) {
23
23
  };
24
24
  }
25
25
  const annotationParamTypesKey = "annotation:paramtypes";
26
+ const designParamTypesKey = "design:paramtypes";
26
27
  /**
27
28
  * Provides basic metadata capabilities used by Context and Dependency Injection.
29
+ * @public
28
30
  */
29
31
  export const Metadata = Object.freeze({
30
32
  /**
@@ -34,7 +36,7 @@ export const Metadata = Object.freeze({
34
36
  */
35
37
  getDesignParamTypes: (Type) => {
36
38
  var _a;
37
- return ((_a = Reflect.getOwnMetadata("design:paramtypes", Type)) !== null && _a !== void 0 ? _a : emptyArray);
39
+ return ((_a = Reflect.getOwnMetadata(designParamTypesKey, Type)) !== null && _a !== void 0 ? _a : emptyArray);
38
40
  },
39
41
  /**
40
42
  * Gets the "annotation:paramtypes" metadata for the specified type.
@@ -1,5 +1,5 @@
1
- import { isFunction, isString, KernelServiceId, noop, } from "../interfaces.js";
2
- import { createMetadataLocator, FAST } from "../platform.js";
1
+ import { isFunction, isString, KernelServiceId, } from "../interfaces.js";
2
+ import { createMetadataLocator, FAST, makeSerializationNoop } from "../platform.js";
3
3
  import { Updates } from "./update-queue.js";
4
4
  import { PropertyChangeNotifier, SubscriberSet } from "./notifier.js";
5
5
  /**
@@ -79,10 +79,6 @@ export const Observable = FAST.getById(KernelServiceId.observable, () => {
79
79
  this.propertyName = void 0;
80
80
  this.notifier = void 0;
81
81
  this.next = void 0;
82
- /**
83
- * Opts out of JSON stringification.
84
- */
85
- this.toJSON = noop;
86
82
  }
87
83
  setMode(isAsync) {
88
84
  this.isAsync = this.needsQueue = isAsync;
@@ -184,6 +180,7 @@ export const Observable = FAST.getById(KernelServiceId.observable, () => {
184
180
  }
185
181
  }
186
182
  }
183
+ makeSerializationNoop(ExpressionNotifierImplementation);
187
184
  return Object.freeze({
188
185
  /**
189
186
  * @internal
@@ -1,3 +1,4 @@
1
+ import { noop } from "./interfaces.js";
1
2
  import "./polyfills.js";
2
3
  // ensure FAST global - duplicated debug.ts
3
4
  const propConfig = {
@@ -86,3 +87,11 @@ export function createMetadataLocator() {
86
87
  return metadata;
87
88
  };
88
89
  }
90
+ /**
91
+ * Makes a type noop for JSON serialization.
92
+ * @param type - The type to make noop for JSON serialization.
93
+ * @internal
94
+ */
95
+ export function makeSerializationNoop(type) {
96
+ type.prototype.toJSON = noop;
97
+ }
@@ -0,0 +1,76 @@
1
+ import { CSSDirective } from "./css-directive.js";
2
+ function handleChange(directive, controller, observer) {
3
+ controller.source.style.setProperty(directive.targetAspect, observer.bind(controller));
4
+ }
5
+ /**
6
+ * Enables bindings in CSS.
7
+ *
8
+ * @public
9
+ */
10
+ export class CSSBindingDirective {
11
+ /**
12
+ * Creates an instance of CSSBindingDirective.
13
+ * @param dataBinding - The binding to use in CSS.
14
+ * @param targetAspect - The CSS property to target.
15
+ */
16
+ constructor(dataBinding, targetAspect) {
17
+ this.dataBinding = dataBinding;
18
+ this.targetAspect = targetAspect;
19
+ }
20
+ /**
21
+ * Creates a CSS fragment to interpolate into the CSS document.
22
+ * @returns - the string to interpolate into CSS
23
+ */
24
+ createCSS(add) {
25
+ add(this);
26
+ return `var(${this.targetAspect})`;
27
+ }
28
+ /**
29
+ * Executed when this behavior is attached to a controller.
30
+ * @param controller - Controls the behavior lifecycle.
31
+ */
32
+ addedCallback(controller) {
33
+ var _a;
34
+ const element = controller.source;
35
+ if (!element.$cssBindings) {
36
+ element.$cssBindings = new Map();
37
+ const setAttribute = element.setAttribute;
38
+ element.setAttribute = (attr, value) => {
39
+ setAttribute.call(element, attr, value);
40
+ if (attr === "style") {
41
+ element.$cssBindings.forEach((v, k) => handleChange(k, v.controller, v.observer));
42
+ }
43
+ };
44
+ }
45
+ const observer = (_a = controller[this.targetAspect]) !== null && _a !== void 0 ? _a : (controller[this.targetAspect] = this.dataBinding.createObserver(this, this));
46
+ observer.controller = controller;
47
+ controller.source.$cssBindings.set(this, { controller, observer });
48
+ }
49
+ /**
50
+ * Executed when this behavior's host is connected.
51
+ * @param controller - Controls the behavior lifecycle.
52
+ */
53
+ connectedCallback(controller) {
54
+ handleChange(this, controller, controller[this.targetAspect]);
55
+ }
56
+ /**
57
+ * Executed when this behavior is detached from a controller.
58
+ * @param controller - Controls the behavior lifecycle.
59
+ */
60
+ removedCallback(controller) {
61
+ if (controller.source.$cssBindings) {
62
+ controller.source.$cssBindings.delete(this);
63
+ }
64
+ }
65
+ /**
66
+ * Called when a subject this instance has subscribed to changes.
67
+ * @param subject - The subject of the change.
68
+ * @param args - The event args detailing the change that occurred.
69
+ *
70
+ * @internal
71
+ */
72
+ handleChange(_, observer) {
73
+ handleChange(this, observer.controller, observer);
74
+ }
75
+ }
76
+ CSSDirective.define(CSSBindingDirective);