@microsoft/fast-element 1.10.5 → 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.
- package/.eslintrc.json +1 -12
- package/CHANGELOG.json +629 -6
- package/CHANGELOG.md +152 -5
- package/dist/dts/components/attributes.d.ts +14 -1
- package/dist/dts/components/{controller.d.ts → element-controller.d.ts} +32 -32
- package/dist/dts/components/fast-definitions.d.ts +51 -11
- package/dist/dts/components/fast-element.d.ts +18 -23
- package/dist/dts/context.d.ts +157 -0
- package/dist/{esm/observation/behavior.js → dts/debug.d.ts} +0 -0
- package/dist/dts/di/di.d.ts +899 -0
- package/dist/dts/index.d.ts +17 -16
- package/dist/dts/index.debug.d.ts +2 -0
- package/dist/dts/index.rollup.d.ts +2 -0
- package/dist/dts/index.rollup.debug.d.ts +3 -0
- package/dist/dts/interfaces.d.ts +176 -0
- package/dist/dts/metadata.d.ts +25 -0
- package/dist/dts/observation/arrays.d.ts +207 -0
- package/dist/dts/observation/notifier.d.ts +18 -18
- package/dist/dts/observation/observable.d.ts +117 -34
- package/dist/dts/observation/update-queue.d.ts +40 -0
- package/dist/dts/pending-task.d.ts +20 -0
- package/dist/dts/platform.d.ts +23 -66
- package/dist/dts/polyfills.d.ts +8 -0
- package/dist/dts/state/exports.d.ts +3 -0
- package/dist/dts/state/reactive.d.ts +8 -0
- package/dist/dts/state/state.d.ts +141 -0
- package/dist/dts/state/visitor.d.ts +6 -0
- package/dist/dts/state/watch.d.ts +10 -0
- package/dist/dts/styles/css-directive.d.ts +44 -6
- package/dist/dts/styles/css.d.ts +19 -3
- package/dist/dts/styles/element-styles.d.ts +49 -63
- package/dist/dts/styles/host.d.ts +68 -0
- package/dist/dts/templating/binding-signal.d.ts +21 -0
- package/dist/dts/templating/binding-two-way.d.ts +39 -0
- package/dist/dts/templating/binding.d.ts +101 -70
- package/dist/dts/templating/children.d.ts +18 -15
- package/dist/dts/templating/compiler.d.ts +46 -28
- package/dist/dts/templating/dom.d.ts +41 -0
- package/dist/dts/templating/html-directive.d.ts +239 -45
- package/dist/dts/templating/markup.d.ts +48 -0
- package/dist/dts/templating/node-observation.d.ts +45 -30
- package/dist/dts/templating/ref.d.ts +6 -20
- package/dist/dts/templating/render.d.ts +272 -0
- package/dist/dts/templating/repeat.d.ts +36 -33
- package/dist/dts/templating/slotted.d.ts +13 -14
- package/dist/dts/templating/template.d.ts +28 -22
- package/dist/dts/templating/view.d.ts +82 -24
- package/dist/dts/templating/when.d.ts +3 -3
- package/dist/dts/testing/exports.d.ts +3 -0
- package/dist/dts/testing/fakes.d.ts +4 -0
- package/dist/dts/testing/fixture.d.ts +84 -0
- package/dist/dts/testing/timeout.d.ts +7 -0
- package/dist/{tsdoc-metadata.json → dts/tsdoc-metadata.json} +1 -1
- package/dist/dts/utilities.d.ts +22 -0
- package/dist/esm/components/attributes.js +38 -28
- package/dist/esm/components/{controller.js → element-controller.js} +150 -140
- package/dist/esm/components/fast-definitions.js +48 -46
- package/dist/esm/components/fast-element.js +31 -12
- package/dist/esm/context.js +163 -0
- package/dist/esm/debug.js +61 -0
- package/dist/esm/di/di.js +1435 -0
- package/dist/esm/index.debug.js +2 -0
- package/dist/esm/index.js +20 -14
- package/dist/esm/index.rollup.debug.js +3 -0
- package/dist/esm/index.rollup.js +2 -0
- package/dist/esm/interfaces.js +12 -1
- package/dist/esm/metadata.js +60 -0
- package/dist/esm/observation/arrays.js +570 -0
- package/dist/esm/observation/notifier.js +27 -35
- package/dist/esm/observation/observable.js +116 -149
- package/dist/esm/observation/update-queue.js +67 -0
- package/dist/esm/pending-task.js +16 -0
- package/dist/esm/platform.js +60 -42
- package/dist/esm/polyfills.js +85 -0
- package/dist/esm/state/exports.js +3 -0
- package/dist/esm/state/reactive.js +34 -0
- package/dist/esm/state/state.js +148 -0
- package/dist/esm/state/visitor.js +28 -0
- package/dist/esm/state/watch.js +36 -0
- package/dist/esm/styles/css-directive.js +29 -13
- package/dist/esm/styles/css.js +29 -42
- package/dist/esm/styles/element-styles.js +79 -104
- package/dist/esm/styles/host.js +1 -0
- package/dist/esm/templating/binding-signal.js +83 -0
- package/dist/esm/templating/binding-two-way.js +103 -0
- package/dist/esm/templating/binding.js +189 -159
- package/dist/esm/templating/children.js +33 -23
- package/dist/esm/templating/compiler.js +258 -152
- package/dist/esm/templating/dom.js +49 -0
- package/dist/esm/templating/html-directive.js +193 -36
- package/dist/esm/templating/markup.js +75 -0
- package/dist/esm/templating/node-observation.js +51 -45
- package/dist/esm/templating/ref.js +8 -25
- package/dist/esm/templating/render.js +391 -0
- package/dist/esm/templating/repeat.js +83 -79
- package/dist/esm/templating/slotted.js +23 -20
- package/dist/esm/templating/template.js +51 -93
- package/dist/esm/templating/view.js +125 -46
- package/dist/esm/templating/when.js +6 -4
- package/dist/esm/testing/exports.js +3 -0
- package/dist/esm/testing/fakes.js +76 -0
- package/dist/esm/testing/fixture.js +86 -0
- package/dist/esm/testing/timeout.js +24 -0
- package/dist/esm/utilities.js +44 -0
- package/dist/fast-element.api.json +12153 -5373
- package/dist/fast-element.d.ts +1448 -696
- package/dist/fast-element.debug.js +4107 -0
- package/dist/fast-element.debug.min.js +1 -0
- package/dist/fast-element.js +3817 -4029
- package/dist/fast-element.min.js +1 -1
- package/dist/fast-element.untrimmed.d.ts +2814 -0
- package/docs/api-report.md +567 -254
- package/docs/fast-element-2-changes.md +15 -0
- package/karma.conf.cjs +6 -17
- package/package.json +76 -15
- package/dist/dts/dom.d.ts +0 -112
- package/dist/dts/observation/array-change-records.d.ts +0 -48
- package/dist/dts/observation/array-observer.d.ts +0 -9
- package/dist/dts/observation/behavior.d.ts +0 -19
- package/dist/esm/dom.js +0 -207
- package/dist/esm/observation/array-change-records.js +0 -326
- package/dist/esm/observation/array-observer.js +0 -177
|
@@ -1,18 +1,46 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FAST } from "../platform.js";
|
|
2
|
+
import "../interfaces.js";
|
|
3
|
+
const styleSheetCache = new Map();
|
|
4
|
+
let DefaultStyleStrategy;
|
|
5
|
+
function reduceStyles(styles) {
|
|
6
|
+
return styles
|
|
7
|
+
.map((x) => x instanceof ElementStyles ? reduceStyles(x.styles) : [x])
|
|
8
|
+
.reduce((prev, curr) => prev.concat(curr), []);
|
|
9
|
+
}
|
|
2
10
|
/**
|
|
3
11
|
* Represents styles that can be applied to a custom element.
|
|
4
12
|
* @public
|
|
5
13
|
*/
|
|
6
14
|
export class ElementStyles {
|
|
7
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Creates an instance of ElementStyles.
|
|
17
|
+
* @param styles - The styles that will be associated with elements.
|
|
18
|
+
*/
|
|
19
|
+
constructor(styles) {
|
|
20
|
+
this.styles = styles;
|
|
8
21
|
this.targets = new WeakSet();
|
|
22
|
+
this._strategy = null;
|
|
23
|
+
this.behaviors = styles
|
|
24
|
+
.map((x) => x instanceof ElementStyles ? x.behaviors : null)
|
|
25
|
+
.reduce((prev, curr) => (curr === null ? prev : prev === null ? curr : prev.concat(curr)), null);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Gets the StyleStrategy associated with these element styles.
|
|
29
|
+
*/
|
|
30
|
+
get strategy() {
|
|
31
|
+
if (this._strategy === null) {
|
|
32
|
+
this.withStrategy(DefaultStyleStrategy);
|
|
33
|
+
}
|
|
34
|
+
return this._strategy;
|
|
9
35
|
}
|
|
10
36
|
/** @internal */
|
|
11
37
|
addStylesTo(target) {
|
|
38
|
+
this.strategy.addStylesTo(target);
|
|
12
39
|
this.targets.add(target);
|
|
13
40
|
}
|
|
14
41
|
/** @internal */
|
|
15
42
|
removeStylesFrom(target) {
|
|
43
|
+
this.strategy.removeStylesFrom(target);
|
|
16
44
|
this.targets.delete(target);
|
|
17
45
|
}
|
|
18
46
|
/** @internal */
|
|
@@ -28,121 +56,68 @@ export class ElementStyles {
|
|
|
28
56
|
this.behaviors === null ? behaviors : this.behaviors.concat(behaviors);
|
|
29
57
|
return this;
|
|
30
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Sets the strategy that handles adding/removing these styles for an element.
|
|
61
|
+
* @param strategy - The strategy to use.
|
|
62
|
+
*/
|
|
63
|
+
withStrategy(Strategy) {
|
|
64
|
+
this._strategy = new Strategy(reduceStyles(this.styles));
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Sets the default strategy type to use when creating style strategies.
|
|
69
|
+
* @param Strategy - The strategy type to construct.
|
|
70
|
+
*/
|
|
71
|
+
static setDefaultStrategy(Strategy) {
|
|
72
|
+
DefaultStyleStrategy = Strategy;
|
|
73
|
+
}
|
|
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
|
+
}
|
|
31
88
|
}
|
|
32
89
|
/**
|
|
33
|
-
*
|
|
90
|
+
* Indicates whether the DOM supports the adoptedStyleSheets feature.
|
|
34
91
|
*/
|
|
35
|
-
ElementStyles.
|
|
36
|
-
|
|
37
|
-
const styleSheetCache = new Map();
|
|
38
|
-
return (styles) =>
|
|
39
|
-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
40
|
-
new AdoptedStyleSheetsStyles(styles, styleSheetCache);
|
|
41
|
-
}
|
|
42
|
-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
43
|
-
return (styles) => new StyleElementStyles(styles);
|
|
44
|
-
})();
|
|
45
|
-
function reduceStyles(styles) {
|
|
46
|
-
return styles
|
|
47
|
-
.map((x) => x instanceof ElementStyles ? reduceStyles(x.styles) : [x])
|
|
48
|
-
.reduce((prev, curr) => prev.concat(curr), []);
|
|
49
|
-
}
|
|
50
|
-
function reduceBehaviors(styles) {
|
|
51
|
-
return styles
|
|
52
|
-
.map((x) => (x instanceof ElementStyles ? x.behaviors : null))
|
|
53
|
-
.reduce((prev, curr) => {
|
|
54
|
-
if (curr === null) {
|
|
55
|
-
return prev;
|
|
56
|
-
}
|
|
57
|
-
if (prev === null) {
|
|
58
|
-
prev = [];
|
|
59
|
-
}
|
|
60
|
-
return prev.concat(curr);
|
|
61
|
-
}, null);
|
|
62
|
-
}
|
|
92
|
+
ElementStyles.supportsAdoptedStyleSheets = Array.isArray(document.adoptedStyleSheets) &&
|
|
93
|
+
"replace" in CSSStyleSheet.prototype;
|
|
63
94
|
/**
|
|
64
95
|
* https://wicg.github.io/construct-stylesheets/
|
|
65
96
|
* https://developers.google.com/web/updates/2019/02/constructable-stylesheets
|
|
66
97
|
*
|
|
67
98
|
* @internal
|
|
68
99
|
*/
|
|
69
|
-
export class
|
|
70
|
-
constructor(styles, styleSheetCache) {
|
|
71
|
-
super();
|
|
72
|
-
this.styles = styles;
|
|
73
|
-
this.styleSheetCache = styleSheetCache;
|
|
74
|
-
this._styleSheets = void 0;
|
|
75
|
-
this.behaviors = reduceBehaviors(styles);
|
|
76
|
-
}
|
|
77
|
-
get styleSheets() {
|
|
78
|
-
if (this._styleSheets === void 0) {
|
|
79
|
-
const styles = this.styles;
|
|
80
|
-
const styleSheetCache = this.styleSheetCache;
|
|
81
|
-
this._styleSheets = reduceStyles(styles).map((x) => {
|
|
82
|
-
if (x instanceof CSSStyleSheet) {
|
|
83
|
-
return x;
|
|
84
|
-
}
|
|
85
|
-
let sheet = styleSheetCache.get(x);
|
|
86
|
-
if (sheet === void 0) {
|
|
87
|
-
sheet = new CSSStyleSheet();
|
|
88
|
-
sheet.replaceSync(x);
|
|
89
|
-
styleSheetCache.set(x, sheet);
|
|
90
|
-
}
|
|
91
|
-
return sheet;
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
return this._styleSheets;
|
|
95
|
-
}
|
|
96
|
-
addStylesTo(target) {
|
|
97
|
-
target.adoptedStyleSheets = [...target.adoptedStyleSheets, ...this.styleSheets];
|
|
98
|
-
super.addStylesTo(target);
|
|
99
|
-
}
|
|
100
|
-
removeStylesFrom(target) {
|
|
101
|
-
const sourceSheets = this.styleSheets;
|
|
102
|
-
target.adoptedStyleSheets = target.adoptedStyleSheets.filter((x) => sourceSheets.indexOf(x) === -1);
|
|
103
|
-
super.removeStylesFrom(target);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
let styleClassId = 0;
|
|
107
|
-
function getNextStyleClass() {
|
|
108
|
-
return `fast-style-class-${++styleClassId}`;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* @internal
|
|
112
|
-
*/
|
|
113
|
-
export class StyleElementStyles extends ElementStyles {
|
|
100
|
+
export class AdoptedStyleSheetsStrategy {
|
|
114
101
|
constructor(styles) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
102
|
+
this.sheets = styles.map((x) => {
|
|
103
|
+
if (x instanceof CSSStyleSheet) {
|
|
104
|
+
return x;
|
|
105
|
+
}
|
|
106
|
+
let sheet = styleSheetCache.get(x);
|
|
107
|
+
if (sheet === void 0) {
|
|
108
|
+
sheet = new CSSStyleSheet();
|
|
109
|
+
sheet.replaceSync(x);
|
|
110
|
+
styleSheetCache.set(x, sheet);
|
|
111
|
+
}
|
|
112
|
+
return sheet;
|
|
113
|
+
});
|
|
121
114
|
}
|
|
122
115
|
addStylesTo(target) {
|
|
123
|
-
|
|
124
|
-
const styleClass = this.styleClass;
|
|
125
|
-
target = this.normalizeTarget(target);
|
|
126
|
-
for (let i = 0; i < styleSheets.length; i++) {
|
|
127
|
-
const element = document.createElement("style");
|
|
128
|
-
element.innerHTML = styleSheets[i];
|
|
129
|
-
element.className = styleClass;
|
|
130
|
-
target.append(element);
|
|
131
|
-
}
|
|
132
|
-
super.addStylesTo(target);
|
|
116
|
+
target.adoptedStyleSheets = [...target.adoptedStyleSheets, ...this.sheets];
|
|
133
117
|
}
|
|
134
118
|
removeStylesFrom(target) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
for (let i = 0, ii = styles.length; i < ii; ++i) {
|
|
138
|
-
target.removeChild(styles[i]);
|
|
139
|
-
}
|
|
140
|
-
super.removeStylesFrom(target);
|
|
141
|
-
}
|
|
142
|
-
isAttachedTo(target) {
|
|
143
|
-
return super.isAttachedTo(this.normalizeTarget(target));
|
|
144
|
-
}
|
|
145
|
-
normalizeTarget(target) {
|
|
146
|
-
return target === document ? document.body : target;
|
|
119
|
+
const sheets = this.sheets;
|
|
120
|
+
target.adoptedStyleSheets = target.adoptedStyleSheets.filter((x) => sheets.indexOf(x) === -1);
|
|
147
121
|
}
|
|
148
122
|
}
|
|
123
|
+
ElementStyles.setDefaultStrategy(FAST.getById(5 /* KernelServiceId.styleSheetStrategy */, () => AdoptedStyleSheetsStrategy));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,83 @@
|
|
|
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(found, 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
|
+
this.isNotBound = true;
|
|
44
|
+
}
|
|
45
|
+
bind(controller) {
|
|
46
|
+
if (this.isNotBound) {
|
|
47
|
+
Signal.subscribe(this.getSignal(controller), this);
|
|
48
|
+
controller.onUnbind(this);
|
|
49
|
+
this.isNotBound = false;
|
|
50
|
+
}
|
|
51
|
+
return this.dataBinding.evaluate(controller.source, controller.context);
|
|
52
|
+
}
|
|
53
|
+
unbind(controller) {
|
|
54
|
+
this.isNotBound = true;
|
|
55
|
+
Signal.unsubscribe(this.getSignal(controller), this);
|
|
56
|
+
}
|
|
57
|
+
handleChange() {
|
|
58
|
+
this.subscriber.handleChange(this.dataBinding.evaluate, this);
|
|
59
|
+
}
|
|
60
|
+
getSignal(controller) {
|
|
61
|
+
const options = this.dataBinding.options;
|
|
62
|
+
return isString(options)
|
|
63
|
+
? options
|
|
64
|
+
: options(controller.source, controller.context);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
class SignalBinding extends Binding {
|
|
68
|
+
createObserver(directive, subscriber) {
|
|
69
|
+
return new SignalObserver(this, subscriber);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Creates a signal binding configuration with the supplied options.
|
|
74
|
+
* @param expression - The binding to refresh when signaled.
|
|
75
|
+
* @param options - The signal name or a binding to use to retrieve the signal name.
|
|
76
|
+
* @returns A binding configuration.
|
|
77
|
+
* @public
|
|
78
|
+
*/
|
|
79
|
+
export function signal(expression, options) {
|
|
80
|
+
const binding = new SignalBinding(expression);
|
|
81
|
+
binding.options = options;
|
|
82
|
+
return binding;
|
|
83
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
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
|
+
export const TwoWaySettings = Object.freeze({
|
|
14
|
+
/**
|
|
15
|
+
* Configures two-way binding.
|
|
16
|
+
* @param settings - The settings to use for the two-way binding system.
|
|
17
|
+
*/
|
|
18
|
+
configure(settings) {
|
|
19
|
+
twoWaySettings = settings;
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
class TwoWayObserver {
|
|
23
|
+
constructor(directive, subscriber, dataBinding) {
|
|
24
|
+
this.directive = directive;
|
|
25
|
+
this.subscriber = subscriber;
|
|
26
|
+
this.dataBinding = dataBinding;
|
|
27
|
+
this.isNotBound = true;
|
|
28
|
+
this.notifier = Observable.binding(dataBinding.evaluate, this, dataBinding.isVolatile);
|
|
29
|
+
}
|
|
30
|
+
bind(controller) {
|
|
31
|
+
var _a;
|
|
32
|
+
if (!this.changeEvent) {
|
|
33
|
+
this.changeEvent =
|
|
34
|
+
(_a = this.dataBinding.options.changeEvent) !== null && _a !== void 0 ? _a : twoWaySettings.determineChangeEvent(this.directive, this.target);
|
|
35
|
+
}
|
|
36
|
+
if (this.isNotBound) {
|
|
37
|
+
this.target.addEventListener(this.changeEvent, this);
|
|
38
|
+
controller.onUnbind(this);
|
|
39
|
+
this.isNotBound = false;
|
|
40
|
+
}
|
|
41
|
+
return this.notifier.bind(controller);
|
|
42
|
+
}
|
|
43
|
+
unbind(controller) {
|
|
44
|
+
this.isNotBound = true;
|
|
45
|
+
this.target.removeEventListener(this.changeEvent, this);
|
|
46
|
+
}
|
|
47
|
+
handleChange(subject, args) {
|
|
48
|
+
this.subscriber.handleChange(this.dataBinding.evaluate, this);
|
|
49
|
+
}
|
|
50
|
+
handleEvent(event) {
|
|
51
|
+
const directive = this.directive;
|
|
52
|
+
const target = event.currentTarget;
|
|
53
|
+
const notifier = this.notifier;
|
|
54
|
+
const last = notifier.last; // using internal API!!!
|
|
55
|
+
if (!last) {
|
|
56
|
+
FAST.warn(1203 /* Message.twoWayBindingRequiresObservables */);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
let value;
|
|
60
|
+
switch (directive.aspectType) {
|
|
61
|
+
case 1:
|
|
62
|
+
value = target.getAttribute(directive.targetAspect);
|
|
63
|
+
break;
|
|
64
|
+
case 2:
|
|
65
|
+
value = target.hasAttribute(directive.targetAspect);
|
|
66
|
+
break;
|
|
67
|
+
case 4:
|
|
68
|
+
value = target.innerText;
|
|
69
|
+
break;
|
|
70
|
+
default:
|
|
71
|
+
value = target[directive.targetAspect];
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
last.propertySource[last.propertyName] = this.dataBinding.options.fromView(value);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
class TwoWayBinding extends Binding {
|
|
78
|
+
createObserver(directive, subscriber) {
|
|
79
|
+
return new TwoWayObserver(directive, subscriber, this);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Creates a default binding.
|
|
84
|
+
* @param expression - The binding to refresh when changed.
|
|
85
|
+
* @param optionsOrChangeEvent - The binding options or the name of the change event to use.
|
|
86
|
+
* @param isBindingVolatile - Indicates whether the binding is volatile or not.
|
|
87
|
+
* @returns A binding.
|
|
88
|
+
* @public
|
|
89
|
+
*/
|
|
90
|
+
export function twoWay(expression, optionsOrChangeEvent, isBindingVolatile = Observable.isVolatileBinding(expression)) {
|
|
91
|
+
if (isString(optionsOrChangeEvent)) {
|
|
92
|
+
optionsOrChangeEvent = { changeEvent: optionsOrChangeEvent };
|
|
93
|
+
}
|
|
94
|
+
if (!optionsOrChangeEvent) {
|
|
95
|
+
optionsOrChangeEvent = defaultOptions;
|
|
96
|
+
}
|
|
97
|
+
else if (!optionsOrChangeEvent.fromView) {
|
|
98
|
+
optionsOrChangeEvent.fromView = defaultOptions.fromView;
|
|
99
|
+
}
|
|
100
|
+
const binding = new TwoWayBinding(expression, isBindingVolatile);
|
|
101
|
+
binding.options = optionsOrChangeEvent;
|
|
102
|
+
return binding;
|
|
103
|
+
}
|