@microsoft/fast-element 2.0.0-beta.1 → 2.0.0-beta.4
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 +147 -0
- package/CHANGELOG.md +42 -1
- package/dist/dts/components/fast-definitions.d.ts +11 -8
- package/dist/dts/components/fast-element.d.ts +13 -3
- package/dist/dts/context.d.ts +157 -0
- package/dist/dts/di/di.d.ts +854 -0
- package/dist/dts/hooks.d.ts +2 -2
- package/dist/dts/interfaces.d.ts +39 -7
- package/dist/dts/metadata.d.ts +25 -0
- package/dist/dts/observation/arrays.d.ts +1 -1
- package/dist/dts/observation/behavior.d.ts +4 -4
- package/dist/dts/observation/observable.d.ts +59 -72
- package/dist/dts/styles/element-styles.d.ts +6 -0
- package/dist/dts/templating/binding-signal.d.ts +21 -0
- package/dist/dts/templating/binding-two-way.d.ts +31 -0
- package/dist/dts/templating/binding.d.ts +74 -201
- package/dist/dts/templating/compiler.d.ts +1 -2
- package/dist/dts/templating/html-directive.d.ts +31 -3
- package/dist/dts/templating/render.d.ts +277 -0
- package/dist/dts/templating/repeat.d.ts +13 -63
- package/dist/dts/templating/template.d.ts +11 -60
- package/dist/dts/templating/view.d.ts +9 -9
- package/dist/dts/templating/when.d.ts +3 -3
- package/dist/dts/testing/exports.d.ts +2 -0
- package/dist/dts/testing/fixture.d.ts +90 -0
- package/dist/dts/testing/timeout.d.ts +7 -0
- package/dist/{tsdoc-metadata.json → dts/tsdoc-metadata.json} +0 -0
- package/dist/esm/components/fast-definitions.js +27 -27
- package/dist/esm/components/fast-element.js +20 -4
- package/dist/esm/context.js +163 -0
- package/dist/esm/debug.js +35 -4
- package/dist/esm/di/di.js +1349 -0
- package/dist/esm/metadata.js +60 -0
- package/dist/esm/observation/arrays.js +1 -1
- package/dist/esm/observation/observable.js +73 -21
- package/dist/esm/platform.js +1 -1
- package/dist/esm/styles/element-styles.js +14 -0
- package/dist/esm/templating/binding-signal.js +79 -0
- package/dist/esm/templating/binding-two-way.js +98 -0
- package/dist/esm/templating/binding.js +137 -313
- package/dist/esm/templating/compiler.js +30 -7
- package/dist/esm/templating/html-directive.js +16 -2
- package/dist/esm/templating/render.js +392 -0
- package/dist/esm/templating/repeat.js +60 -38
- package/dist/esm/templating/template.js +9 -26
- package/dist/esm/templating/when.js +5 -4
- package/dist/esm/testing/exports.js +2 -0
- package/dist/esm/testing/fixture.js +88 -0
- package/dist/esm/testing/timeout.js +24 -0
- package/dist/fast-element.api.json +8509 -10358
- package/dist/fast-element.d.ts +315 -522
- package/dist/fast-element.debug.js +417 -438
- package/dist/fast-element.debug.min.js +1 -1
- package/dist/fast-element.js +382 -434
- package/dist/fast-element.min.js +1 -1
- package/dist/fast-element.untrimmed.d.ts +324 -529
- package/docs/api-report.md +124 -232
- package/package.json +32 -4
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { emptyArray } from "./platform.js";
|
|
2
|
+
// Tiny polyfill for TypeScript's Reflect metadata API.
|
|
3
|
+
const metadataByTarget = new Map();
|
|
4
|
+
if (!("metadata" in Reflect)) {
|
|
5
|
+
Reflect.metadata = function (key, value) {
|
|
6
|
+
return function (target) {
|
|
7
|
+
Reflect.defineMetadata(key, value, target);
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
Reflect.defineMetadata = function (key, value, target) {
|
|
11
|
+
let metadata = metadataByTarget.get(target);
|
|
12
|
+
if (metadata === void 0) {
|
|
13
|
+
metadataByTarget.set(target, (metadata = new Map()));
|
|
14
|
+
}
|
|
15
|
+
metadata.set(key, value);
|
|
16
|
+
};
|
|
17
|
+
Reflect.getOwnMetadata = function (key, target) {
|
|
18
|
+
const metadata = metadataByTarget.get(target);
|
|
19
|
+
if (metadata !== void 0) {
|
|
20
|
+
return metadata.get(key);
|
|
21
|
+
}
|
|
22
|
+
return void 0;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Provides basic metadata capabilities used by Context and Dependency Injection.
|
|
27
|
+
*/
|
|
28
|
+
export const Metadata = Object.freeze({
|
|
29
|
+
/**
|
|
30
|
+
* Gets the "design:paramtypes" metadata for the specified type.
|
|
31
|
+
* @param Type - The type to get the metadata for.
|
|
32
|
+
* @returns The metadata array or a frozen empty array if no metadata is found.
|
|
33
|
+
*/
|
|
34
|
+
getDesignParamTypes: Type => {
|
|
35
|
+
var _a;
|
|
36
|
+
return (_a = Reflect.getOwnMetadata("design:paramtypes", Type)) !== null && _a !== void 0 ? _a : emptyArray;
|
|
37
|
+
},
|
|
38
|
+
/**
|
|
39
|
+
* Gets the "annotation:paramtypes" metadata for the specified type.
|
|
40
|
+
* @param Type - The type to get the metadata for.
|
|
41
|
+
* @returns The metadata array or a frozen empty array if no metadata is found.
|
|
42
|
+
*/
|
|
43
|
+
getAnnotationParamTypes: Type => {
|
|
44
|
+
var _a;
|
|
45
|
+
return (_a = Reflect.getOwnMetadata("annotation:paramtypes", Type)) !== null && _a !== void 0 ? _a : emptyArray;
|
|
46
|
+
},
|
|
47
|
+
/**
|
|
48
|
+
*
|
|
49
|
+
* @param Type - Gets the "annotation:paramtypes" metadata for the specified type. If none is found,
|
|
50
|
+
* an empty, mutable metadata array is created and added.
|
|
51
|
+
* @returns The metadata array.
|
|
52
|
+
*/
|
|
53
|
+
getOrCreateAnnotationParamTypes(Type) {
|
|
54
|
+
let types = this.getAnnotationParamTypes(Type);
|
|
55
|
+
if (types === emptyArray) {
|
|
56
|
+
Reflect.defineMetadata("annotation:paramtypes", (types = []), Type);
|
|
57
|
+
}
|
|
58
|
+
return types;
|
|
59
|
+
},
|
|
60
|
+
});
|
|
@@ -63,7 +63,7 @@ export const Observable = FAST.getById(2 /* KernelServiceId.observable */, () =>
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
class
|
|
66
|
+
class ExpressionNotifierImplementation extends SubscriberSet {
|
|
67
67
|
constructor(binding, initialSubscriber, isVolatileBinding = false) {
|
|
68
68
|
super(binding, initialSubscriber);
|
|
69
69
|
this.binding = binding;
|
|
@@ -218,14 +218,14 @@ export const Observable = FAST.getById(2 /* KernelServiceId.observable */, () =>
|
|
|
218
218
|
*/
|
|
219
219
|
getAccessors,
|
|
220
220
|
/**
|
|
221
|
-
* Creates a {@link
|
|
222
|
-
* provided {@link
|
|
221
|
+
* Creates a {@link ExpressionNotifier} that can watch the
|
|
222
|
+
* provided {@link Expression} for changes.
|
|
223
223
|
* @param binding - The binding to observe.
|
|
224
224
|
* @param initialSubscriber - An initial subscriber to changes in the binding value.
|
|
225
225
|
* @param isVolatileBinding - Indicates whether the binding's dependency list must be re-evaluated on every value evaluation.
|
|
226
226
|
*/
|
|
227
227
|
binding(binding, initialSubscriber, isVolatileBinding = this.isVolatileBinding(binding)) {
|
|
228
|
-
return new
|
|
228
|
+
return new ExpressionNotifierImplementation(binding, initialSubscriber, isVolatileBinding);
|
|
229
229
|
},
|
|
230
230
|
/**
|
|
231
231
|
* Determines whether a binding expression is volatile and needs to have its dependency list re-evaluated
|
|
@@ -272,72 +272,124 @@ const contextEvent = FAST.getById(3 /* KernelServiceId.contextEvent */, () => {
|
|
|
272
272
|
},
|
|
273
273
|
};
|
|
274
274
|
});
|
|
275
|
-
|
|
275
|
+
/**
|
|
276
|
+
* Provides additional contextual information available to behaviors and expressions.
|
|
277
|
+
* @public
|
|
278
|
+
*/
|
|
279
|
+
export class ExecutionContext {
|
|
276
280
|
constructor(parentSource = null, parentContext = null) {
|
|
281
|
+
/**
|
|
282
|
+
* The index of the current item within a repeat context.
|
|
283
|
+
*/
|
|
277
284
|
this.index = 0;
|
|
285
|
+
/**
|
|
286
|
+
* The length of the current collection within a repeat context.
|
|
287
|
+
*/
|
|
278
288
|
this.length = 0;
|
|
279
289
|
this.parent = parentSource;
|
|
280
290
|
this.parentContext = parentContext;
|
|
281
291
|
}
|
|
292
|
+
/**
|
|
293
|
+
* The current event within an event handler.
|
|
294
|
+
*/
|
|
282
295
|
get event() {
|
|
283
296
|
return contextEvent.get();
|
|
284
297
|
}
|
|
298
|
+
/**
|
|
299
|
+
* Indicates whether the current item within a repeat context
|
|
300
|
+
* has an even index.
|
|
301
|
+
*/
|
|
285
302
|
get isEven() {
|
|
286
303
|
return this.index % 2 === 0;
|
|
287
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* Indicates whether the current item within a repeat context
|
|
307
|
+
* has an odd index.
|
|
308
|
+
*/
|
|
288
309
|
get isOdd() {
|
|
289
310
|
return this.index % 2 !== 0;
|
|
290
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* Indicates whether the current item within a repeat context
|
|
314
|
+
* is the first item in the collection.
|
|
315
|
+
*/
|
|
291
316
|
get isFirst() {
|
|
292
317
|
return this.index === 0;
|
|
293
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* Indicates whether the current item within a repeat context
|
|
321
|
+
* is somewhere in the middle of the collection.
|
|
322
|
+
*/
|
|
294
323
|
get isInMiddle() {
|
|
295
324
|
return !this.isFirst && !this.isLast;
|
|
296
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* Indicates whether the current item within a repeat context
|
|
328
|
+
* is the last item in the collection.
|
|
329
|
+
*/
|
|
297
330
|
get isLast() {
|
|
298
331
|
return this.index === this.length - 1;
|
|
299
332
|
}
|
|
333
|
+
/**
|
|
334
|
+
* Returns the typed event detail of a custom event.
|
|
335
|
+
*/
|
|
300
336
|
eventDetail() {
|
|
301
337
|
return this.event.detail;
|
|
302
338
|
}
|
|
339
|
+
/**
|
|
340
|
+
* Returns the typed event target of the event.
|
|
341
|
+
*/
|
|
303
342
|
eventTarget() {
|
|
304
343
|
return this.event.target;
|
|
305
344
|
}
|
|
345
|
+
/**
|
|
346
|
+
* Updates the position/size on a context associated with a list item.
|
|
347
|
+
* @param index - The new index of the item.
|
|
348
|
+
* @param length - The new length of the list.
|
|
349
|
+
*/
|
|
306
350
|
updatePosition(index, length) {
|
|
307
351
|
this.index = index;
|
|
308
352
|
this.length = length;
|
|
309
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* Creates a new execution context descendent from the current context.
|
|
356
|
+
* @param source - The source for the context if different than the parent.
|
|
357
|
+
* @returns A child execution context.
|
|
358
|
+
*/
|
|
310
359
|
createChildContext(parentSource) {
|
|
311
|
-
return new
|
|
360
|
+
return new ExecutionContext(parentSource, this);
|
|
312
361
|
}
|
|
362
|
+
/**
|
|
363
|
+
* Creates a new execution context descent suitable for use in list rendering.
|
|
364
|
+
* @param item - The list item to serve as the source.
|
|
365
|
+
* @param index - The index of the item in the list.
|
|
366
|
+
* @param length - The length of the list.
|
|
367
|
+
*/
|
|
313
368
|
createItemContext(index, length) {
|
|
314
369
|
const childContext = Object.create(this);
|
|
315
370
|
childContext.index = index;
|
|
316
371
|
childContext.length = length;
|
|
317
372
|
return childContext;
|
|
318
373
|
}
|
|
319
|
-
}
|
|
320
|
-
Observable.defineProperty(DefaultExecutionContext.prototype, "index");
|
|
321
|
-
Observable.defineProperty(DefaultExecutionContext.prototype, "length");
|
|
322
|
-
/**
|
|
323
|
-
* The common execution context APIs.
|
|
324
|
-
* @public
|
|
325
|
-
*/
|
|
326
|
-
export const ExecutionContext = Object.freeze({
|
|
327
|
-
default: new DefaultExecutionContext(),
|
|
328
374
|
/**
|
|
329
375
|
* Sets the event for the current execution context.
|
|
330
376
|
* @param event - The event to set.
|
|
331
377
|
* @internal
|
|
332
378
|
*/
|
|
333
|
-
setEvent(event) {
|
|
379
|
+
static setEvent(event) {
|
|
334
380
|
contextEvent.set(event);
|
|
335
|
-
}
|
|
381
|
+
}
|
|
336
382
|
/**
|
|
337
383
|
* Creates a new root execution context.
|
|
338
384
|
* @returns A new execution context.
|
|
339
385
|
*/
|
|
340
|
-
create() {
|
|
341
|
-
return new
|
|
342
|
-
}
|
|
343
|
-
}
|
|
386
|
+
static create() {
|
|
387
|
+
return new ExecutionContext();
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* The default execution context.
|
|
392
|
+
*/
|
|
393
|
+
ExecutionContext.default = new ExecutionContext();
|
|
394
|
+
Observable.defineProperty(ExecutionContext.prototype, "index");
|
|
395
|
+
Observable.defineProperty(ExecutionContext.prototype, "length");
|
package/dist/esm/platform.js
CHANGED
|
@@ -71,6 +71,20 @@ export class ElementStyles {
|
|
|
71
71
|
static setDefaultStrategy(Strategy) {
|
|
72
72
|
DefaultStyleStrategy = Strategy;
|
|
73
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Normalizes a set of composable style options.
|
|
76
|
+
* @param styles - The style options to normalize.
|
|
77
|
+
* @returns A singular ElementStyles instance or undefined.
|
|
78
|
+
*/
|
|
79
|
+
static normalize(styles) {
|
|
80
|
+
return styles === void 0
|
|
81
|
+
? void 0
|
|
82
|
+
: Array.isArray(styles)
|
|
83
|
+
? new ElementStyles(styles)
|
|
84
|
+
: styles instanceof ElementStyles
|
|
85
|
+
? styles
|
|
86
|
+
: new ElementStyles([styles]);
|
|
87
|
+
}
|
|
74
88
|
}
|
|
75
89
|
/**
|
|
76
90
|
* Indicates whether the DOM supports the adoptedStyleSheets feature.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { isString } from "../interfaces.js";
|
|
2
|
+
import { Binding } from "./html-directive.js";
|
|
3
|
+
const subscribers = Object.create(null);
|
|
4
|
+
export const Signal = Object.freeze({
|
|
5
|
+
subscribe(signal, subscriber) {
|
|
6
|
+
const found = subscribers[signal];
|
|
7
|
+
if (found) {
|
|
8
|
+
found instanceof Set
|
|
9
|
+
? found.add(subscriber)
|
|
10
|
+
: (subscribers[signal] = new Set([found, subscriber]));
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
subscribers[signal] = subscriber;
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
unsubscribe(signal, subscriber) {
|
|
17
|
+
const found = subscribers[signal];
|
|
18
|
+
if (found && found instanceof Set) {
|
|
19
|
+
found.delete(subscriber);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
subscribers[signal] = void 0;
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
/**
|
|
26
|
+
* Sends the specified signal to signaled bindings.
|
|
27
|
+
* @param signal - The signal to send.
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
send(signal) {
|
|
31
|
+
const found = subscribers[signal];
|
|
32
|
+
if (found) {
|
|
33
|
+
found instanceof Set
|
|
34
|
+
? found.forEach(x => x.handleChange(this, signal))
|
|
35
|
+
: found.handleChange(this, signal);
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
class SignalObserver {
|
|
40
|
+
constructor(dataBinding, subscriber) {
|
|
41
|
+
this.dataBinding = dataBinding;
|
|
42
|
+
this.subscriber = subscriber;
|
|
43
|
+
}
|
|
44
|
+
observe(source, context) {
|
|
45
|
+
const signal = (this.signal = this.getSignal(source, context));
|
|
46
|
+
Signal.subscribe(signal, this);
|
|
47
|
+
return this.dataBinding.evaluate(source, context);
|
|
48
|
+
}
|
|
49
|
+
dispose() {
|
|
50
|
+
Signal.unsubscribe(this.signal, this);
|
|
51
|
+
}
|
|
52
|
+
handleChange() {
|
|
53
|
+
this.subscriber.handleChange(this.dataBinding.evaluate, this);
|
|
54
|
+
}
|
|
55
|
+
getSignal(source, context) {
|
|
56
|
+
const options = this.dataBinding.options;
|
|
57
|
+
return isString(options) ? options : options(source, context);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
class SignalBinding extends Binding {
|
|
61
|
+
constructor(evaluate, options) {
|
|
62
|
+
super();
|
|
63
|
+
this.evaluate = evaluate;
|
|
64
|
+
this.options = options;
|
|
65
|
+
}
|
|
66
|
+
createObserver(directive, subscriber) {
|
|
67
|
+
return new SignalObserver(this, subscriber);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Creates a signal binding configuration with the supplied options.
|
|
72
|
+
* @param binding - The binding to refresh when signaled.
|
|
73
|
+
* @param options - The signal name or a binding to use to retrieve the signal name.
|
|
74
|
+
* @returns A binding configuration.
|
|
75
|
+
* @public
|
|
76
|
+
*/
|
|
77
|
+
export function signal(binding, options) {
|
|
78
|
+
return new SignalBinding(binding, options);
|
|
79
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { isString } from "../interfaces.js";
|
|
2
|
+
import { Observable, } from "../observation/observable.js";
|
|
3
|
+
import { FAST } from "../platform.js";
|
|
4
|
+
import { Binding } from "./html-directive.js";
|
|
5
|
+
const defaultOptions = {
|
|
6
|
+
fromView: v => v,
|
|
7
|
+
};
|
|
8
|
+
let twoWaySettings = {
|
|
9
|
+
determineChangeEvent() {
|
|
10
|
+
return "change";
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
class TwoWayObserver {
|
|
14
|
+
constructor(directive, subscriber, dataBinding) {
|
|
15
|
+
this.directive = directive;
|
|
16
|
+
this.subscriber = subscriber;
|
|
17
|
+
this.dataBinding = dataBinding;
|
|
18
|
+
this.notifier = Observable.binding(dataBinding.evaluate, this, dataBinding.isVolatile);
|
|
19
|
+
}
|
|
20
|
+
observe(source, context) {
|
|
21
|
+
var _a;
|
|
22
|
+
if (!this.changeEvent) {
|
|
23
|
+
this.changeEvent =
|
|
24
|
+
(_a = this.dataBinding.options.changeEvent) !== null && _a !== void 0 ? _a : twoWaySettings.determineChangeEvent(this.directive, this.target);
|
|
25
|
+
}
|
|
26
|
+
this.target.addEventListener(this.changeEvent, this);
|
|
27
|
+
return this.notifier.observe(source, context);
|
|
28
|
+
}
|
|
29
|
+
dispose() {
|
|
30
|
+
this.notifier.dispose();
|
|
31
|
+
this.target.removeEventListener(this.changeEvent, this);
|
|
32
|
+
}
|
|
33
|
+
/** @internal */
|
|
34
|
+
handleChange(subject, args) {
|
|
35
|
+
this.subscriber.handleChange(this.dataBinding.evaluate, this);
|
|
36
|
+
}
|
|
37
|
+
/** @internal */
|
|
38
|
+
handleEvent(event) {
|
|
39
|
+
const directive = this.directive;
|
|
40
|
+
const target = event.currentTarget;
|
|
41
|
+
const notifier = this.notifier;
|
|
42
|
+
const last = notifier.last; // using internal API!!!
|
|
43
|
+
if (!last) {
|
|
44
|
+
FAST.warn(1203 /* Message.twoWayBindingRequiresObservables */);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
let value;
|
|
48
|
+
switch (directive.aspectType) {
|
|
49
|
+
case 1:
|
|
50
|
+
value = target.getAttribute(directive.targetAspect);
|
|
51
|
+
break;
|
|
52
|
+
case 2:
|
|
53
|
+
value = target.hasAttribute(directive.targetAspect);
|
|
54
|
+
break;
|
|
55
|
+
case 4:
|
|
56
|
+
value = target.innerText;
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
value = target[directive.targetAspect];
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
last.propertySource[last.propertyName] = this.dataBinding.options.fromView(value);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
class TwoWayBinding extends Binding {
|
|
66
|
+
constructor(evaluate, isVolatile, options = defaultOptions) {
|
|
67
|
+
super();
|
|
68
|
+
this.evaluate = evaluate;
|
|
69
|
+
this.isVolatile = isVolatile;
|
|
70
|
+
this.options = options;
|
|
71
|
+
if (!options.fromView) {
|
|
72
|
+
options.fromView = defaultOptions.fromView;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
createObserver(directive, subscriber) {
|
|
76
|
+
return new TwoWayObserver(directive, subscriber, this);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Configures two-way binding.
|
|
80
|
+
* @param settings - The settings to use for the two-way binding system.
|
|
81
|
+
*/
|
|
82
|
+
static configure(settings) {
|
|
83
|
+
twoWaySettings = settings;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Creates a default binding.
|
|
88
|
+
* @param binding - The binding to refresh when changed.
|
|
89
|
+
* @param isBindingVolatile - Indicates whether the binding is volatile or not.
|
|
90
|
+
* @returns A binding configuration.
|
|
91
|
+
* @public
|
|
92
|
+
*/
|
|
93
|
+
export function twoWay(binding, optionsOrChangeEvent, isBindingVolatile = Observable.isVolatileBinding(binding)) {
|
|
94
|
+
if (isString(optionsOrChangeEvent)) {
|
|
95
|
+
optionsOrChangeEvent = { changeEvent: optionsOrChangeEvent };
|
|
96
|
+
}
|
|
97
|
+
return new TwoWayBinding(binding, isBindingVolatile, optionsOrChangeEvent);
|
|
98
|
+
}
|