@microsoft/fast-element 2.0.0-beta.1 → 2.0.0-beta.10

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 (96) hide show
  1. package/CHANGELOG.json +333 -0
  2. package/CHANGELOG.md +106 -1
  3. package/dist/dts/components/attributes.d.ts +10 -0
  4. package/dist/dts/components/{controller.d.ts → element-controller.d.ts} +24 -25
  5. package/dist/dts/components/fast-definitions.d.ts +43 -9
  6. package/dist/dts/components/fast-element.d.ts +15 -21
  7. package/dist/dts/context.d.ts +157 -0
  8. package/dist/dts/di/di.d.ts +899 -0
  9. package/dist/dts/index.d.ts +2 -2
  10. package/dist/dts/interfaces.d.ts +44 -12
  11. package/dist/dts/metadata.d.ts +25 -0
  12. package/dist/dts/observation/arrays.d.ts +1 -1
  13. package/dist/dts/observation/observable.d.ts +101 -75
  14. package/dist/dts/pending-task.d.ts +20 -0
  15. package/dist/dts/platform.d.ts +6 -0
  16. package/dist/dts/state/exports.d.ts +3 -0
  17. package/dist/dts/state/reactive.d.ts +8 -0
  18. package/dist/dts/state/state.d.ts +141 -0
  19. package/dist/dts/state/visitor.d.ts +6 -0
  20. package/dist/dts/state/watch.d.ts +10 -0
  21. package/dist/dts/styles/css-directive.d.ts +2 -2
  22. package/dist/dts/styles/element-styles.d.ts +9 -3
  23. package/dist/dts/styles/host.d.ts +68 -0
  24. package/dist/dts/templating/binding-signal.d.ts +21 -0
  25. package/dist/dts/templating/binding-two-way.d.ts +39 -0
  26. package/dist/dts/templating/binding.d.ts +69 -294
  27. package/dist/dts/templating/children.d.ts +1 -1
  28. package/dist/dts/templating/compiler.d.ts +1 -2
  29. package/dist/dts/templating/html-directive.d.ts +93 -35
  30. package/dist/dts/templating/node-observation.d.ts +4 -5
  31. package/dist/dts/templating/ref.d.ts +5 -13
  32. package/dist/dts/templating/render.d.ts +272 -0
  33. package/dist/dts/templating/repeat.d.ts +20 -75
  34. package/dist/dts/templating/slotted.d.ts +1 -1
  35. package/dist/dts/templating/template.d.ts +12 -61
  36. package/dist/dts/templating/view.d.ts +77 -12
  37. package/dist/dts/templating/when.d.ts +3 -3
  38. package/dist/dts/testing/exports.d.ts +3 -0
  39. package/dist/dts/testing/fakes.d.ts +4 -0
  40. package/dist/dts/testing/fixture.d.ts +84 -0
  41. package/dist/dts/testing/timeout.d.ts +7 -0
  42. package/dist/{tsdoc-metadata.json → dts/tsdoc-metadata.json} +0 -0
  43. package/dist/dts/utilities.d.ts +0 -18
  44. package/dist/esm/components/attributes.js +13 -4
  45. package/dist/esm/components/{controller.js → element-controller.js} +95 -105
  46. package/dist/esm/components/fast-definitions.js +38 -28
  47. package/dist/esm/components/fast-element.js +31 -12
  48. package/dist/esm/context.js +163 -0
  49. package/dist/esm/debug.js +36 -4
  50. package/dist/esm/di/di.js +1435 -0
  51. package/dist/esm/index.js +2 -1
  52. package/dist/esm/interfaces.js +4 -0
  53. package/dist/esm/metadata.js +60 -0
  54. package/dist/esm/observation/arrays.js +304 -3
  55. package/dist/esm/observation/observable.js +81 -87
  56. package/dist/esm/pending-task.js +16 -0
  57. package/dist/esm/platform.js +25 -1
  58. package/dist/esm/state/exports.js +3 -0
  59. package/dist/esm/state/reactive.js +34 -0
  60. package/dist/esm/state/state.js +148 -0
  61. package/dist/esm/state/visitor.js +28 -0
  62. package/dist/esm/state/watch.js +36 -0
  63. package/dist/esm/styles/css.js +4 -4
  64. package/dist/esm/styles/element-styles.js +14 -0
  65. package/dist/esm/{observation/behavior.js → styles/host.js} +0 -0
  66. package/dist/esm/templating/binding-signal.js +83 -0
  67. package/dist/esm/templating/binding-two-way.js +103 -0
  68. package/dist/esm/templating/binding.js +134 -414
  69. package/dist/esm/templating/compiler.js +30 -7
  70. package/dist/esm/templating/html-directive.js +100 -28
  71. package/dist/esm/templating/node-observation.js +9 -8
  72. package/dist/esm/templating/ref.js +4 -12
  73. package/dist/esm/templating/render.js +391 -0
  74. package/dist/esm/templating/repeat.js +96 -72
  75. package/dist/esm/templating/template.js +11 -29
  76. package/dist/esm/templating/view.js +107 -29
  77. package/dist/esm/templating/when.js +5 -4
  78. package/dist/esm/testing/exports.js +3 -0
  79. package/dist/esm/testing/fakes.js +76 -0
  80. package/dist/esm/testing/fixture.js +86 -0
  81. package/dist/esm/testing/timeout.js +24 -0
  82. package/dist/esm/utilities.js +0 -95
  83. package/dist/fast-element.api.json +9034 -10524
  84. package/dist/fast-element.d.ts +707 -811
  85. package/dist/fast-element.debug.js +1133 -850
  86. package/dist/fast-element.debug.min.js +1 -1
  87. package/dist/fast-element.js +1097 -846
  88. package/dist/fast-element.min.js +1 -1
  89. package/dist/fast-element.untrimmed.d.ts +724 -818
  90. package/docs/api-report.md +264 -305
  91. package/package.json +39 -10
  92. package/dist/dts/hooks.d.ts +0 -20
  93. package/dist/dts/observation/behavior.d.ts +0 -19
  94. package/dist/dts/observation/splice-strategies.d.ts +0 -13
  95. package/dist/esm/hooks.js +0 -32
  96. package/dist/esm/observation/splice-strategies.js +0 -400
@@ -1,9 +1,9 @@
1
- import { isString } from "../interfaces.js";
1
+ import { isFunction } from "../interfaces.js";
2
2
  import { ExecutionContext, Observable, } from "../observation/observable.js";
3
3
  import { FAST } from "../platform.js";
4
4
  import { DOM } from "./dom.js";
5
- import { Aspect, HTMLDirective, } from "./html-directive.js";
6
- import { Markup } from "./markup.js";
5
+ import { Aspect, Binding, HTMLDirective, } from "./html-directive.js";
6
+ import { Markup, nextId } from "./markup.js";
7
7
  const createInnerHTMLBinding = globalThis.TrustedHTML
8
8
  ? (binding) => (s, c) => {
9
9
  const value = binding(s, c);
@@ -13,107 +13,26 @@ const createInnerHTMLBinding = globalThis.TrustedHTML
13
13
  throw FAST.error(1202 /* Message.bindingInnerHTMLRequiresTrustedTypes */);
14
14
  }
15
15
  : (binding) => binding;
16
- /**
17
- * Describes how aspects of an HTML element will be affected by bindings.
18
- * @public
19
- */
20
- export const BindingMode = Object.freeze({
21
- /**
22
- * Creates a binding mode based on the supplied behavior types.
23
- * @param UpdateType - The base behavior type used to update aspects.
24
- * @param EventType - The base behavior type used to respond to events.
25
- * @returns A new binding mode.
26
- */
27
- define(UpdateType, EventType = EventBinding) {
28
- return Object.freeze({
29
- [1]: d => new UpdateType(d, DOM.setAttribute),
30
- [2]: d => new UpdateType(d, DOM.setBooleanAttribute),
31
- [3]: d => new UpdateType(d, (t, a, v) => (t[a] = v)),
32
- [4]: d => new (createContentBinding(UpdateType))(d, updateContentTarget),
33
- [5]: d => new UpdateType(d, updateTokenListTarget),
34
- [6]: d => new EventType(d),
35
- });
36
- },
37
- });
38
- /**
39
- * Describes the configuration for a binding expression.
40
- * @public
41
- */
42
- export const BindingConfig = Object.freeze({
43
- /**
44
- * Creates a binding configuration based on the provided mode and options.
45
- * @param mode - The mode to use for the configuration.
46
- * @param defaultOptions - The default options to use for the configuration.
47
- * @returns A new binding configuration.
48
- */
49
- define(mode, defaultOptions) {
50
- const config = (options) => {
51
- return {
52
- mode: config.mode,
53
- options: Object.assign({}, defaultOptions, options),
54
- };
55
- };
56
- config.options = defaultOptions;
57
- config.mode = mode;
58
- return config;
59
- },
60
- });
61
- /**
62
- * A base binding behavior for DOM updates.
63
- * @public
64
- */
65
- export class UpdateBinding {
66
- /**
67
- * Creates an instance of UpdateBinding.
68
- * @param directive - The directive that has the configuration for this behavior.
69
- * @param updateTarget - The function used to update the target with the latest value.
70
- */
71
- constructor(directive, updateTarget) {
72
- this.directive = directive;
73
- this.updateTarget = updateTarget;
16
+ class OnChangeBinding extends Binding {
17
+ createObserver(_, subscriber) {
18
+ return Observable.binding(this.evaluate, subscriber, this.isVolatile);
74
19
  }
75
- /**
76
- * Bind this behavior to the source.
77
- * @param source - The source to bind to.
78
- * @param context - The execution context that the binding is operating within.
79
- * @param targets - The targets that behaviors in a view can attach to.
80
- */
81
- bind(source, context, targets) { }
82
- /**
83
- * Unbinds this behavior from the source.
84
- * @param source - The source to unbind from.
85
- * @param context - The execution context that the binding is operating within.
86
- * @param targets - The targets that behaviors in a view can attach to.
87
- */
88
- unbind(source, context, targets) { }
89
- /**
90
- * Creates a behavior.
91
- * @param targets - The targets available for behaviors to be attached to.
92
- */
93
- createBehavior(targets) {
20
+ }
21
+ class OneTimeBinding extends Binding {
22
+ createObserver() {
94
23
  return this;
95
24
  }
25
+ bind(controller) {
26
+ return this.evaluate(controller.source, controller.context);
27
+ }
96
28
  }
97
- function createContentBinding(Type) {
98
- return class extends Type {
99
- unbind(source, context, targets) {
100
- super.unbind(source, context, targets);
101
- const target = targets[this.directive.nodeId];
102
- const view = target.$fastView;
103
- if (view !== void 0 && view.isComposed) {
104
- view.unbind();
105
- view.needsBindOnly = true;
106
- }
107
- }
108
- };
109
- }
110
- function updateContentTarget(target, aspect, value, source, context) {
29
+ function updateContent(target, aspect, value, controller) {
111
30
  // If there's no actual value, then this equates to the
112
31
  // empty string for the purposes of content bindings.
113
32
  if (value === null || value === undefined) {
114
33
  value = "";
115
34
  }
116
- // If the value has a "create" method, then it's a template-like.
35
+ // If the value has a "create" method, then it's a ContentTemplate.
117
36
  if (value.create) {
118
37
  target.textContent = "";
119
38
  let view = target.$fastView;
@@ -139,14 +58,14 @@ function updateContentTarget(target, aspect, value, source, context) {
139
58
  // and that there's actually no need to compose it.
140
59
  if (!view.isComposed) {
141
60
  view.isComposed = true;
142
- view.bind(source, context);
61
+ view.bind(controller.source, controller.context);
143
62
  view.insertBefore(target);
144
63
  target.$fastView = view;
145
64
  target.$fastTemplate = value;
146
65
  }
147
66
  else if (view.needsBindOnly) {
148
67
  view.needsBindOnly = false;
149
- view.bind(source, context);
68
+ view.bind(controller.source, controller.context);
150
69
  }
151
70
  }
152
71
  else {
@@ -166,10 +85,9 @@ function updateContentTarget(target, aspect, value, source, context) {
166
85
  target.textContent = value;
167
86
  }
168
87
  }
169
- function updateTokenListTarget(target, aspect, value) {
88
+ function updateTokenList(target, aspect, value) {
170
89
  var _a;
171
- const directive = this.directive;
172
- const lookup = `${directive.id}-t`;
90
+ const lookup = `${this.id}-t`;
173
91
  const state = (_a = target[lookup]) !== null && _a !== void 0 ? _a : (target[lookup] = { c: 0, v: Object.create(null) });
174
92
  const versions = state.v;
175
93
  let currentVersion = state.c;
@@ -199,364 +117,166 @@ function updateTokenListTarget(target, aspect, value) {
199
117
  }
200
118
  }
201
119
  }
120
+ const setProperty = (t, a, v) => (t[a] = v);
121
+ const eventTarget = () => void 0;
202
122
  /**
203
- * A binding behavior for one-time bindings.
123
+ * A directive that applies bindings.
204
124
  * @public
205
125
  */
206
- export class OneTimeBinding extends UpdateBinding {
126
+ export class HTMLBindingDirective {
207
127
  /**
208
- * Bind this behavior to the source.
209
- * @param source - The source to bind to.
210
- * @param context - The execution context that the binding is operating within.
211
- * @param targets - The targets that behaviors in a view can attach to.
128
+ * Creates an instance of HTMLBindingDirective.
129
+ * @param dataBinding - The binding configuration to apply.
212
130
  */
213
- bind(source, context, targets) {
214
- const directive = this.directive;
215
- this.updateTarget(targets[directive.nodeId], directive.targetAspect, directive.binding(source, context), source, context);
216
- }
217
- }
218
- const signals = Object.create(null);
219
- /**
220
- * A binding behavior for signal bindings.
221
- * @public
222
- */
223
- export class SignalBinding extends UpdateBinding {
224
- constructor() {
225
- super(...arguments);
226
- this.handlerProperty = `${this.directive.id}-h`;
131
+ constructor(dataBinding) {
132
+ this.dataBinding = dataBinding;
133
+ this.updateTarget = null;
134
+ /**
135
+ * The unique id of the factory.
136
+ */
137
+ this.id = nextId();
138
+ /**
139
+ * The type of aspect to target.
140
+ */
141
+ this.aspectType = Aspect.content;
142
+ /** @internal */
143
+ this.bind = this.bindDefault;
144
+ this.data = `${this.id}-d`;
227
145
  }
228
146
  /**
229
- * Bind this behavior to the source.
230
- * @param source - The source to bind to.
231
- * @param context - The execution context that the binding is operating within.
232
- * @param targets - The targets that behaviors in a view can attach to.
147
+ * Creates HTML to be used within a template.
148
+ * @param add - Can be used to add behavior factories to a template.
233
149
  */
234
- bind(source, context, targets) {
235
- const directive = this.directive;
236
- const target = targets[directive.nodeId];
237
- const signal = this.getSignal(source, context);
238
- const handler = (target[this.handlerProperty] = () => {
239
- this.updateTarget(target, directive.targetAspect, directive.binding(source, context), source, context);
240
- });
241
- handler();
242
- const found = signals[signal];
243
- if (found) {
244
- Array.isArray(found)
245
- ? found.push(handler)
246
- : (signals[signal] = [found, handler]);
247
- }
248
- else {
249
- signals[signal] = handler;
250
- }
150
+ createHTML(add) {
151
+ return Markup.interpolation(add(this));
251
152
  }
252
153
  /**
253
- * Unbinds this behavior from the source.
254
- * @param source - The source to unbind from.
255
- * @param context - The execution context that the binding is operating within.
256
- * @param targets - The targets that behaviors in a view can attach to.
154
+ * Creates a behavior.
257
155
  */
258
- unbind(source, context, targets) {
259
- const signal = this.getSignal(source, context);
260
- const found = signals[signal];
261
- if (found && Array.isArray(found)) {
262
- const directive = this.directive;
263
- const target = targets[directive.nodeId];
264
- const handler = target[this.handlerProperty];
265
- const index = found.indexOf(handler);
266
- if (index !== -1) {
267
- found.splice(index, 1);
156
+ createBehavior() {
157
+ if (this.updateTarget === null) {
158
+ if (this.targetAspect === "innerHTML") {
159
+ this.dataBinding.evaluate = createInnerHTMLBinding(this.dataBinding.evaluate);
160
+ }
161
+ switch (this.aspectType) {
162
+ case 1:
163
+ this.updateTarget = DOM.setAttribute;
164
+ break;
165
+ case 2:
166
+ this.updateTarget = DOM.setBooleanAttribute;
167
+ break;
168
+ case 3:
169
+ this.updateTarget = setProperty;
170
+ break;
171
+ case 4:
172
+ this.bind = this.bindContent;
173
+ this.updateTarget = updateContent;
174
+ break;
175
+ case 5:
176
+ this.updateTarget = updateTokenList;
177
+ break;
178
+ case 6:
179
+ this.bind = this.bindEvent;
180
+ this.updateTarget = eventTarget;
181
+ break;
182
+ default:
183
+ throw FAST.error(1205 /* Message.unsupportedBindingBehavior */);
268
184
  }
269
185
  }
270
- else {
271
- signals[signal] = void 0;
272
- }
273
- }
274
- getSignal(source, context) {
275
- const options = this.directive.options;
276
- return isString(options) ? options : options(source, context);
277
- }
278
- /**
279
- * Sends the specified signal to signaled bindings.
280
- * @param signal - The signal to send.
281
- * @public
282
- */
283
- static send(signal) {
284
- const found = signals[signal];
285
- if (found) {
286
- Array.isArray(found) ? found.forEach(x => x()) : found();
287
- }
288
- }
289
- }
290
- /**
291
- * A binding behavior for bindings that change.
292
- * @public
293
- */
294
- export class ChangeBinding extends UpdateBinding {
295
- /**
296
- * Creates an instance of ChangeBinding.
297
- * @param directive - The directive that has the configuration for this behavior.
298
- * @param updateTarget - The function used to update the target with the latest value.
299
- */
300
- constructor(directive, updateTarget) {
301
- super(directive, updateTarget);
302
- this.isBindingVolatile = Observable.isVolatileBinding(directive.binding);
303
- this.observerProperty = `${directive.id}-o`;
186
+ return this;
304
187
  }
305
- /**
306
- * Returns the binding observer used to update the node.
307
- * @param target - The target node.
308
- * @returns A BindingObserver.
309
- */
310
- getObserver(target) {
188
+ /** @internal */
189
+ bindDefault(controller) {
311
190
  var _a;
312
- return ((_a = target[this.observerProperty]) !== null && _a !== void 0 ? _a : (target[this.observerProperty] = Observable.binding(this.directive.binding, this, this.isBindingVolatile)));
313
- }
314
- /**
315
- * Bind this behavior to the source.
316
- * @param source - The source to bind to.
317
- * @param context - The execution context that the binding is operating within.
318
- * @param targets - The targets that behaviors in a view can attach to.
319
- */
320
- bind(source, context, targets) {
321
- const directive = this.directive;
322
- const target = targets[directive.nodeId];
323
- const observer = this.getObserver(target);
191
+ const target = controller.targets[this.nodeId];
192
+ const observer = (_a = target[this.data]) !== null && _a !== void 0 ? _a : (target[this.data] = this.dataBinding.createObserver(this, this));
324
193
  observer.target = target;
325
- observer.source = source;
326
- observer.context = context;
327
- this.updateTarget(target, directive.targetAspect, observer.observe(source, context), source, context);
328
- }
329
- /**
330
- * Unbinds this behavior from the source.
331
- * @param source - The source to unbind from.
332
- * @param context - The execution context that the binding is operating within.
333
- * @param targets - The targets that behaviors in a view can attach to.
334
- */
335
- unbind(source, context, targets) {
336
- const target = targets[this.directive.nodeId];
337
- const observer = this.getObserver(target);
338
- observer.dispose();
339
- observer.target = null;
340
- observer.source = null;
341
- observer.context = null;
194
+ observer.controller = controller;
195
+ this.updateTarget(target, this.targetAspect, observer.bind(controller), controller);
196
+ if (this.updateTarget === updateContent) {
197
+ controller.onUnbind(this);
198
+ }
342
199
  }
343
200
  /** @internal */
344
- handleChange(binding, observer) {
345
- const target = observer.target;
346
- const source = observer.source;
347
- const context = observer.context;
348
- this.updateTarget(target, this.directive.targetAspect, observer.observe(source, context), source, context);
349
- }
350
- }
351
- /**
352
- * A binding behavior for handling events.
353
- * @public
354
- */
355
- export class EventBinding {
356
- /**
357
- * Creates an instance of EventBinding.
358
- * @param directive - The directive that has the configuration for this behavior.
359
- */
360
- constructor(directive) {
361
- this.directive = directive;
362
- this.sourceProperty = `${directive.id}-s`;
363
- this.contextProperty = `${directive.id}-c`;
201
+ bindContent(controller) {
202
+ this.bindDefault(controller);
203
+ controller.onUnbind(this);
364
204
  }
365
- /**
366
- * Bind this behavior to the source.
367
- * @param source - The source to bind to.
368
- * @param context - The execution context that the binding is operating within.
369
- * @param targets - The targets that behaviors in a view can attach to.
370
- */
371
- bind(source, context, targets) {
372
- const directive = this.directive;
373
- const target = targets[directive.nodeId];
374
- target[this.sourceProperty] = source;
375
- target[this.contextProperty] = context;
376
- target.addEventListener(directive.targetAspect, this, directive.options);
377
- }
378
- /**
379
- * Unbinds this behavior from the source.
380
- * @param source - The source to unbind from.
381
- * @param context - The execution context that the binding is operating within.
382
- * @param targets - The targets that behaviors in a view can attach to.
383
- */
384
- unbind(source, context, targets) {
385
- const directive = this.directive;
386
- const target = targets[directive.nodeId];
387
- target[this.sourceProperty] = target[this.contextProperty] = null;
388
- target.removeEventListener(directive.targetAspect, this, directive.options);
205
+ /** @internal */
206
+ bindEvent(controller) {
207
+ const target = controller.targets[this.nodeId];
208
+ target[this.data] = controller;
209
+ target.addEventListener(this.targetAspect, this, this.dataBinding.options);
389
210
  }
390
- /**
391
- * Creates a behavior.
392
- * @param targets - The targets available for behaviors to be attached to.
393
- */
394
- createBehavior(targets) {
395
- return this;
211
+ /** @internal */
212
+ unbind(controller) {
213
+ const target = controller.targets[this.nodeId];
214
+ const view = target.$fastView;
215
+ if (view !== void 0 && view.isComposed) {
216
+ view.unbind();
217
+ view.needsBindOnly = true;
218
+ }
396
219
  }
397
- /**
398
- * @internal
399
- */
220
+ /** @internal */
400
221
  handleEvent(event) {
401
222
  const target = event.currentTarget;
402
223
  ExecutionContext.setEvent(event);
403
- const result = this.directive.binding(target[this.sourceProperty], target[this.contextProperty]);
224
+ const controller = target[this.data];
225
+ const result = this.dataBinding.evaluate(controller.source, controller.context);
404
226
  ExecutionContext.setEvent(null);
405
227
  if (result !== true) {
406
228
  event.preventDefault();
407
229
  }
408
230
  }
409
- }
410
- let twoWaySettings = {
411
- determineChangeEvent() {
412
- return "change";
413
- },
414
- };
415
- /**
416
- * A binding behavior for bindings that update in two directions.
417
- * @public
418
- */
419
- export class TwoWayBinding extends ChangeBinding {
420
- /**
421
- * Bind this behavior to the source.
422
- * @param source - The source to bind to.
423
- * @param context - The execution context that the binding is operating within.
424
- * @param targets - The targets that behaviors in a view can attach to.
425
- */
426
- bind(source, context, targets) {
427
- var _a;
428
- super.bind(source, context, targets);
429
- const directive = this.directive;
430
- const target = targets[directive.nodeId];
431
- if (!this.changeEvent) {
432
- this.changeEvent =
433
- (_a = directive.options.changeEvent) !== null && _a !== void 0 ? _a : twoWaySettings.determineChangeEvent(directive, target);
434
- }
435
- target.addEventListener(this.changeEvent, this);
436
- }
437
- /**
438
- * Unbinds this behavior from the source.
439
- * @param source - The source to unbind from.
440
- * @param context - The execution context that the binding is operating within.
441
- * @param targets - The targets that behaviors in a view can attach to.
442
- */
443
- unbind(source, context, targets) {
444
- super.unbind(source, context, targets);
445
- targets[this.directive.nodeId].removeEventListener(this.changeEvent, this);
446
- }
447
231
  /** @internal */
448
- handleEvent(event) {
449
- const directive = this.directive;
450
- const target = event.currentTarget;
451
- let value;
452
- switch (directive.aspectType) {
453
- case 1:
454
- value = target.getAttribute(directive.targetAspect);
455
- break;
456
- case 2:
457
- value = target.hasAttribute(directive.targetAspect);
458
- break;
459
- case 4:
460
- value = target.innerText;
461
- break;
462
- default:
463
- value = target[directive.targetAspect];
464
- break;
465
- }
466
- const observer = this.getObserver(target);
467
- const last = observer.last; // using internal API!!!
468
- last.propertySource[last.propertyName] = directive.options.fromView(value);
469
- }
470
- /**
471
- * Configures two-way binding.
472
- * @param settings - The settings to use for the two-way binding system.
473
- */
474
- static configure(settings) {
475
- twoWaySettings = settings;
232
+ handleChange(binding, observer) {
233
+ const target = observer.target;
234
+ const controller = observer.controller;
235
+ this.updateTarget(target, this.targetAspect, observer.bind(controller), controller);
476
236
  }
477
237
  }
238
+ HTMLDirective.define(HTMLBindingDirective, { aspected: true });
478
239
  /**
479
- * The default onChange binding configuration.
480
- * @public
481
- */
482
- export const onChange = BindingConfig.define(BindingMode.define(ChangeBinding), {});
483
- /**
484
- * The default twoWay binding configuration.
485
- * @public
486
- */
487
- export const twoWay = BindingConfig.define(BindingMode.define(TwoWayBinding), {
488
- fromView: v => v,
489
- });
490
- /**
491
- * The default onTime binding configuration.
240
+ * Creates an standard binding.
241
+ * @param binding - The binding to refresh when changed.
242
+ * @param isVolatile - Indicates whether the binding is volatile or not.
243
+ * @returns A binding configuration.
492
244
  * @public
493
245
  */
494
- export const oneTime = BindingConfig.define(BindingMode.define(OneTimeBinding), {
495
- once: true,
496
- });
497
- const signalMode = BindingMode.define(SignalBinding);
246
+ export function bind(binding, isVolatile = Observable.isVolatileBinding(binding)) {
247
+ return new OnChangeBinding(binding, isVolatile);
248
+ }
498
249
  /**
499
- * Creates a signal binding configuration with the supplied options.
500
- * @param options - The signal name or a binding to use to retrieve the signal name.
250
+ * Creates a one time binding
251
+ * @param binding - The binding to refresh when signaled.
501
252
  * @returns A binding configuration.
502
253
  * @public
503
254
  */
504
- export const signal = (options) => {
505
- return { mode: signalMode, options };
506
- };
255
+ export function oneTime(binding) {
256
+ return new OneTimeBinding(binding);
257
+ }
507
258
  /**
508
- * A directive that applies bindings.
259
+ * Creates an event listener binding.
260
+ * @param binding - The binding to invoke when the event is raised.
261
+ * @param options - Event listener options.
262
+ * @returns A binding configuration.
509
263
  * @public
510
264
  */
511
- export class HTMLBindingDirective {
512
- /**
513
- * Creates an instance of HTMLBindingDirective.
514
- * @param binding - The binding to apply.
515
- * @param mode - The binding mode to use when applying the binding.
516
- * @param options - The options to configure the binding with.
517
- */
518
- constructor(binding, mode, options) {
519
- this.binding = binding;
520
- this.mode = mode;
521
- this.options = options;
522
- this.factory = null;
523
- /**
524
- * The type of aspect to target.
525
- */
526
- this.aspectType = Aspect.content;
527
- }
528
- /**
529
- * Creates HTML to be used within a template.
530
- * @param add - Can be used to add behavior factories to a template.
531
- */
532
- createHTML(add) {
533
- return Markup.interpolation(add(this));
534
- }
535
- /**
536
- * Creates a behavior.
537
- * @param targets - The targets available for behaviors to be attached to.
538
- */
539
- createBehavior(targets) {
540
- if (this.factory == null) {
541
- if (this.targetAspect === "innerHTML") {
542
- this.binding = createInnerHTMLBinding(this.binding);
543
- }
544
- this.factory = this.mode[this.aspectType](this);
545
- }
546
- return this.factory.createBehavior(targets);
547
- }
265
+ export function listener(binding, options) {
266
+ const config = new OnChangeBinding(binding, false);
267
+ config.options = options;
268
+ return config;
548
269
  }
549
- HTMLDirective.define(HTMLBindingDirective, { aspected: true });
550
270
  /**
551
- * Creates a binding directive with the specified configuration.
552
- * @param binding - The binding expression.
553
- * @param config - The binding configuration.
554
- * @returns A binding directive.
271
+ * Normalizes the input value into a binding.
272
+ * @param value - The value to create the default binding for.
273
+ * @returns A binding configuration for the provided value.
555
274
  * @public
556
275
  */
557
- export function bind(binding, config = onChange) {
558
- if (!("mode" in config)) {
559
- config = onChange(config);
560
- }
561
- return new HTMLBindingDirective(binding, config.mode, config.options);
276
+ export function normalizeBinding(value) {
277
+ return isFunction(value)
278
+ ? bind(value)
279
+ : value instanceof Binding
280
+ ? value
281
+ : oneTime(() => value);
562
282
  }