@microsoft/fast-element 1.7.1 → 1.9.0
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 +30 -0
- package/CHANGELOG.json +73 -1
- package/CHANGELOG.md +26 -2
- package/dist/dts/components/attributes.d.ts +1 -1
- package/dist/dts/components/controller.d.ts +6 -6
- package/dist/dts/components/fast-definitions.d.ts +5 -5
- package/dist/dts/components/fast-element.d.ts +2 -2
- package/dist/dts/dom.d.ts +4 -4
- package/dist/dts/index.d.ts +26 -26
- package/dist/dts/observation/behavior.d.ts +1 -1
- package/dist/dts/observation/observable.d.ts +51 -50
- package/dist/dts/platform.d.ts +37 -0
- package/dist/dts/styles/css-directive.d.ts +2 -2
- package/dist/dts/styles/css.d.ts +2 -2
- package/dist/dts/styles/element-styles.d.ts +1 -1
- package/dist/dts/templating/binding.d.ts +3 -3
- package/dist/dts/templating/children.d.ts +2 -2
- package/dist/dts/templating/compiler.d.ts +1 -1
- package/dist/dts/templating/html-directive.d.ts +1 -1
- package/dist/dts/templating/node-observation.d.ts +1 -1
- package/dist/dts/templating/ref.d.ts +2 -2
- package/dist/dts/templating/repeat.d.ts +6 -6
- package/dist/dts/templating/slotted.d.ts +2 -2
- package/dist/dts/templating/template.d.ts +3 -3
- package/dist/dts/templating/view.d.ts +2 -2
- package/dist/dts/templating/when.d.ts +2 -2
- package/dist/esm/components/attributes.js +2 -2
- package/dist/esm/components/controller.js +4 -4
- package/dist/esm/components/fast-definitions.js +31 -14
- package/dist/esm/components/fast-element.js +2 -2
- package/dist/esm/dom.js +55 -50
- package/dist/esm/index.js +23 -23
- package/dist/esm/observation/array-change-records.js +1 -1
- package/dist/esm/observation/array-observer.js +12 -6
- package/dist/esm/observation/observable.js +244 -236
- package/dist/esm/platform.js +23 -0
- package/dist/esm/styles/css.js +2 -2
- package/dist/esm/styles/element-styles.js +1 -1
- package/dist/esm/templating/binding.js +5 -5
- package/dist/esm/templating/children.js +2 -2
- package/dist/esm/templating/compiler.js +2 -2
- package/dist/esm/templating/html-directive.js +1 -1
- package/dist/esm/templating/node-observation.js +2 -2
- package/dist/esm/templating/ref.js +1 -1
- package/dist/esm/templating/repeat.js +6 -6
- package/dist/esm/templating/slotted.js +2 -2
- package/dist/esm/templating/template.js +6 -6
- package/dist/fast-element.api.json +43 -48
- package/dist/fast-element.d.ts +53 -13
- package/dist/fast-element.js +428 -344
- package/dist/fast-element.min.js +1 -1
- package/docs/api-report.md +39 -12
- package/docs/guide/observables-and-state.md +10 -8
- package/docs/guide/using-directives.md +1 -1
- package/karma.conf.cjs +152 -0
- package/package.json +11 -10
|
@@ -1,55 +1,20 @@
|
|
|
1
|
-
import { DOM } from "../dom";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
const notifierLookup = new WeakMap();
|
|
5
|
-
const accessorLookup = new WeakMap();
|
|
6
|
-
let watcher = void 0;
|
|
7
|
-
let createArrayObserver = (array) => {
|
|
8
|
-
throw new Error("Must call enableArrayObservation before observing arrays.");
|
|
9
|
-
};
|
|
10
|
-
class DefaultObservableAccessor {
|
|
11
|
-
constructor(name) {
|
|
12
|
-
this.name = name;
|
|
13
|
-
this.field = `_${name}`;
|
|
14
|
-
this.callback = `${name}Changed`;
|
|
15
|
-
}
|
|
16
|
-
getValue(source) {
|
|
17
|
-
if (watcher !== void 0) {
|
|
18
|
-
watcher.watch(source, this.name);
|
|
19
|
-
}
|
|
20
|
-
return source[this.field];
|
|
21
|
-
}
|
|
22
|
-
setValue(source, newValue) {
|
|
23
|
-
const field = this.field;
|
|
24
|
-
const oldValue = source[field];
|
|
25
|
-
if (oldValue !== newValue) {
|
|
26
|
-
source[field] = newValue;
|
|
27
|
-
const callback = source[this.callback];
|
|
28
|
-
if (typeof callback === "function") {
|
|
29
|
-
callback.call(source, oldValue, newValue);
|
|
30
|
-
}
|
|
31
|
-
/* eslint-disable-next-line @typescript-eslint/no-use-before-define */
|
|
32
|
-
getNotifier(source).notify(this.name);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
1
|
+
import { DOM } from "../dom.js";
|
|
2
|
+
import { FAST } from "../platform.js";
|
|
3
|
+
import { PropertyChangeNotifier, SubscriberSet } from "./notifier.js";
|
|
36
4
|
/**
|
|
37
5
|
* Common Observable APIs.
|
|
38
6
|
* @public
|
|
39
7
|
*/
|
|
40
|
-
export const Observable =
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
* @param source - The object or Array to get the notifier for.
|
|
51
|
-
*/
|
|
52
|
-
getNotifier(source) {
|
|
8
|
+
export const Observable = FAST.getById(2 /* observable */, () => {
|
|
9
|
+
const volatileRegex = /(:|&&|\|\||if)/;
|
|
10
|
+
const notifierLookup = new WeakMap();
|
|
11
|
+
const accessorLookup = new WeakMap();
|
|
12
|
+
const queueUpdate = DOM.queueUpdate;
|
|
13
|
+
let watcher = void 0;
|
|
14
|
+
let createArrayObserver = (array) => {
|
|
15
|
+
throw new Error("Must call enableArrayObservation before observing arrays.");
|
|
16
|
+
};
|
|
17
|
+
function getNotifier(source) {
|
|
53
18
|
let found = source.$fastController || notifierLookup.get(source);
|
|
54
19
|
if (found === void 0) {
|
|
55
20
|
if (Array.isArray(source)) {
|
|
@@ -60,62 +25,8 @@ export const Observable = Object.freeze({
|
|
|
60
25
|
}
|
|
61
26
|
}
|
|
62
27
|
return found;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
* Records a property change for a source object.
|
|
66
|
-
* @param source - The object to record the change against.
|
|
67
|
-
* @param propertyName - The property to track as changed.
|
|
68
|
-
*/
|
|
69
|
-
track(source, propertyName) {
|
|
70
|
-
if (watcher !== void 0) {
|
|
71
|
-
watcher.watch(source, propertyName);
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
/**
|
|
75
|
-
* Notifies watchers that the currently executing property getter or function is volatile
|
|
76
|
-
* with respect to its observable dependencies.
|
|
77
|
-
*/
|
|
78
|
-
trackVolatile() {
|
|
79
|
-
if (watcher !== void 0) {
|
|
80
|
-
watcher.needsRefresh = true;
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
/**
|
|
84
|
-
* Notifies subscribers of a source object of changes.
|
|
85
|
-
* @param source - the object to notify of changes.
|
|
86
|
-
* @param args - The change args to pass to subscribers.
|
|
87
|
-
*/
|
|
88
|
-
notify(source, args) {
|
|
89
|
-
/* eslint-disable-next-line @typescript-eslint/no-use-before-define */
|
|
90
|
-
getNotifier(source).notify(args);
|
|
91
|
-
},
|
|
92
|
-
/**
|
|
93
|
-
* Defines an observable property on an object or prototype.
|
|
94
|
-
* @param target - The target object to define the observable on.
|
|
95
|
-
* @param nameOrAccessor - The name of the property to define as observable;
|
|
96
|
-
* or a custom accessor that specifies the property name and accessor implementation.
|
|
97
|
-
*/
|
|
98
|
-
defineProperty(target, nameOrAccessor) {
|
|
99
|
-
if (typeof nameOrAccessor === "string") {
|
|
100
|
-
nameOrAccessor = new DefaultObservableAccessor(nameOrAccessor);
|
|
101
|
-
}
|
|
102
|
-
this.getAccessors(target).push(nameOrAccessor);
|
|
103
|
-
Reflect.defineProperty(target, nameOrAccessor.name, {
|
|
104
|
-
enumerable: true,
|
|
105
|
-
get: function () {
|
|
106
|
-
return nameOrAccessor.getValue(this);
|
|
107
|
-
},
|
|
108
|
-
set: function (newValue) {
|
|
109
|
-
nameOrAccessor.setValue(this, newValue);
|
|
110
|
-
},
|
|
111
|
-
});
|
|
112
|
-
},
|
|
113
|
-
/**
|
|
114
|
-
* Finds all the observable accessors defined on the target,
|
|
115
|
-
* including its prototype chain.
|
|
116
|
-
* @param target - The target object to search for accessor on.
|
|
117
|
-
*/
|
|
118
|
-
getAccessors(target) {
|
|
28
|
+
}
|
|
29
|
+
function getAccessors(target) {
|
|
119
30
|
let accessors = accessorLookup.get(target);
|
|
120
31
|
if (accessors === void 0) {
|
|
121
32
|
let currentTarget = Reflect.getPrototypeOf(target);
|
|
@@ -132,30 +43,215 @@ export const Observable = Object.freeze({
|
|
|
132
43
|
accessorLookup.set(target, accessors);
|
|
133
44
|
}
|
|
134
45
|
return accessors;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
46
|
+
}
|
|
47
|
+
class DefaultObservableAccessor {
|
|
48
|
+
constructor(name) {
|
|
49
|
+
this.name = name;
|
|
50
|
+
this.field = `_${name}`;
|
|
51
|
+
this.callback = `${name}Changed`;
|
|
52
|
+
}
|
|
53
|
+
getValue(source) {
|
|
54
|
+
if (watcher !== void 0) {
|
|
55
|
+
watcher.watch(source, this.name);
|
|
56
|
+
}
|
|
57
|
+
return source[this.field];
|
|
58
|
+
}
|
|
59
|
+
setValue(source, newValue) {
|
|
60
|
+
const field = this.field;
|
|
61
|
+
const oldValue = source[field];
|
|
62
|
+
if (oldValue !== newValue) {
|
|
63
|
+
source[field] = newValue;
|
|
64
|
+
const callback = source[this.callback];
|
|
65
|
+
if (typeof callback === "function") {
|
|
66
|
+
callback.call(source, oldValue, newValue);
|
|
67
|
+
}
|
|
68
|
+
getNotifier(source).notify(this.name);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
class BindingObserverImplementation extends SubscriberSet {
|
|
73
|
+
constructor(binding, initialSubscriber, isVolatileBinding = false) {
|
|
74
|
+
super(binding, initialSubscriber);
|
|
75
|
+
this.binding = binding;
|
|
76
|
+
this.isVolatileBinding = isVolatileBinding;
|
|
77
|
+
this.needsRefresh = true;
|
|
78
|
+
this.needsQueue = true;
|
|
79
|
+
this.first = this;
|
|
80
|
+
this.last = null;
|
|
81
|
+
this.propertySource = void 0;
|
|
82
|
+
this.propertyName = void 0;
|
|
83
|
+
this.notifier = void 0;
|
|
84
|
+
this.next = void 0;
|
|
85
|
+
}
|
|
86
|
+
observe(source, context) {
|
|
87
|
+
if (this.needsRefresh && this.last !== null) {
|
|
88
|
+
this.disconnect();
|
|
89
|
+
}
|
|
90
|
+
const previousWatcher = watcher;
|
|
91
|
+
watcher = this.needsRefresh ? this : void 0;
|
|
92
|
+
this.needsRefresh = this.isVolatileBinding;
|
|
93
|
+
const result = this.binding(source, context);
|
|
94
|
+
watcher = previousWatcher;
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
disconnect() {
|
|
98
|
+
if (this.last !== null) {
|
|
99
|
+
let current = this.first;
|
|
100
|
+
while (current !== void 0) {
|
|
101
|
+
current.notifier.unsubscribe(this, current.propertyName);
|
|
102
|
+
current = current.next;
|
|
103
|
+
}
|
|
104
|
+
this.last = null;
|
|
105
|
+
this.needsRefresh = this.needsQueue = true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
watch(propertySource, propertyName) {
|
|
109
|
+
const prev = this.last;
|
|
110
|
+
const notifier = getNotifier(propertySource);
|
|
111
|
+
const current = prev === null ? this.first : {};
|
|
112
|
+
current.propertySource = propertySource;
|
|
113
|
+
current.propertyName = propertyName;
|
|
114
|
+
current.notifier = notifier;
|
|
115
|
+
notifier.subscribe(this, propertyName);
|
|
116
|
+
if (prev !== null) {
|
|
117
|
+
if (!this.needsRefresh) {
|
|
118
|
+
// Declaring the variable prior to assignment below circumvents
|
|
119
|
+
// a bug in Angular's optimization process causing infinite recursion
|
|
120
|
+
// of this watch() method. Details https://github.com/microsoft/fast/issues/4969
|
|
121
|
+
let prevValue;
|
|
122
|
+
watcher = void 0;
|
|
123
|
+
/* eslint-disable-next-line */
|
|
124
|
+
prevValue = prev.propertySource[prev.propertyName];
|
|
125
|
+
watcher = this;
|
|
126
|
+
if (propertySource === prevValue) {
|
|
127
|
+
this.needsRefresh = true;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
prev.next = current;
|
|
131
|
+
}
|
|
132
|
+
this.last = current;
|
|
133
|
+
}
|
|
134
|
+
handleChange() {
|
|
135
|
+
if (this.needsQueue) {
|
|
136
|
+
this.needsQueue = false;
|
|
137
|
+
queueUpdate(this);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
call() {
|
|
141
|
+
if (this.last !== null) {
|
|
142
|
+
this.needsQueue = true;
|
|
143
|
+
this.notify(this);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
records() {
|
|
147
|
+
let next = this.first;
|
|
148
|
+
return {
|
|
149
|
+
next: () => {
|
|
150
|
+
const current = next;
|
|
151
|
+
if (current === undefined) {
|
|
152
|
+
return { value: void 0, done: true };
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
next = next.next;
|
|
156
|
+
return {
|
|
157
|
+
value: current,
|
|
158
|
+
done: false,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
[Symbol.iterator]: function () {
|
|
163
|
+
return this;
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return Object.freeze({
|
|
169
|
+
/**
|
|
170
|
+
* @internal
|
|
171
|
+
* @param factory - The factory used to create array observers.
|
|
172
|
+
*/
|
|
173
|
+
setArrayObserverFactory(factory) {
|
|
174
|
+
createArrayObserver = factory;
|
|
175
|
+
},
|
|
176
|
+
/**
|
|
177
|
+
* Gets a notifier for an object or Array.
|
|
178
|
+
* @param source - The object or Array to get the notifier for.
|
|
179
|
+
*/
|
|
180
|
+
getNotifier,
|
|
181
|
+
/**
|
|
182
|
+
* Records a property change for a source object.
|
|
183
|
+
* @param source - The object to record the change against.
|
|
184
|
+
* @param propertyName - The property to track as changed.
|
|
185
|
+
*/
|
|
186
|
+
track(source, propertyName) {
|
|
187
|
+
if (watcher !== void 0) {
|
|
188
|
+
watcher.watch(source, propertyName);
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
/**
|
|
192
|
+
* Notifies watchers that the currently executing property getter or function is volatile
|
|
193
|
+
* with respect to its observable dependencies.
|
|
194
|
+
*/
|
|
195
|
+
trackVolatile() {
|
|
196
|
+
if (watcher !== void 0) {
|
|
197
|
+
watcher.needsRefresh = true;
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
/**
|
|
201
|
+
* Notifies subscribers of a source object of changes.
|
|
202
|
+
* @param source - the object to notify of changes.
|
|
203
|
+
* @param args - The change args to pass to subscribers.
|
|
204
|
+
*/
|
|
205
|
+
notify(source, args) {
|
|
206
|
+
getNotifier(source).notify(args);
|
|
207
|
+
},
|
|
208
|
+
/**
|
|
209
|
+
* Defines an observable property on an object or prototype.
|
|
210
|
+
* @param target - The target object to define the observable on.
|
|
211
|
+
* @param nameOrAccessor - The name of the property to define as observable;
|
|
212
|
+
* or a custom accessor that specifies the property name and accessor implementation.
|
|
213
|
+
*/
|
|
214
|
+
defineProperty(target, nameOrAccessor) {
|
|
215
|
+
if (typeof nameOrAccessor === "string") {
|
|
216
|
+
nameOrAccessor = new DefaultObservableAccessor(nameOrAccessor);
|
|
217
|
+
}
|
|
218
|
+
getAccessors(target).push(nameOrAccessor);
|
|
219
|
+
Reflect.defineProperty(target, nameOrAccessor.name, {
|
|
220
|
+
enumerable: true,
|
|
221
|
+
get: function () {
|
|
222
|
+
return nameOrAccessor.getValue(this);
|
|
223
|
+
},
|
|
224
|
+
set: function (newValue) {
|
|
225
|
+
nameOrAccessor.setValue(this, newValue);
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
},
|
|
229
|
+
/**
|
|
230
|
+
* Finds all the observable accessors defined on the target,
|
|
231
|
+
* including its prototype chain.
|
|
232
|
+
* @param target - The target object to search for accessor on.
|
|
233
|
+
*/
|
|
234
|
+
getAccessors,
|
|
235
|
+
/**
|
|
236
|
+
* Creates a {@link BindingObserver} that can watch the
|
|
237
|
+
* provided {@link Binding} for changes.
|
|
238
|
+
* @param binding - The binding to observe.
|
|
239
|
+
* @param initialSubscriber - An initial subscriber to changes in the binding value.
|
|
240
|
+
* @param isVolatileBinding - Indicates whether the binding's dependency list must be re-evaluated on every value evaluation.
|
|
241
|
+
*/
|
|
242
|
+
binding(binding, initialSubscriber, isVolatileBinding = this.isVolatileBinding(binding)) {
|
|
243
|
+
return new BindingObserverImplementation(binding, initialSubscriber, isVolatileBinding);
|
|
244
|
+
},
|
|
245
|
+
/**
|
|
246
|
+
* Determines whether a binding expression is volatile and needs to have its dependency list re-evaluated
|
|
247
|
+
* on every evaluation of the value.
|
|
248
|
+
* @param binding - The binding to inspect.
|
|
249
|
+
*/
|
|
250
|
+
isVolatileBinding(binding) {
|
|
251
|
+
return volatileRegex.test(binding.toString());
|
|
252
|
+
},
|
|
253
|
+
});
|
|
155
254
|
});
|
|
156
|
-
const getNotifier = Observable.getNotifier;
|
|
157
|
-
const trackVolatile = Observable.trackVolatile;
|
|
158
|
-
const queueUpdate = DOM.queueUpdate;
|
|
159
255
|
/**
|
|
160
256
|
* Decorator: Defines an observable property on the target.
|
|
161
257
|
* @param target - The target to define the observable on.
|
|
@@ -175,19 +271,22 @@ export function observable(target, nameOrAccessor) {
|
|
|
175
271
|
export function volatile(target, name, descriptor) {
|
|
176
272
|
return Object.assign({}, descriptor, {
|
|
177
273
|
get: function () {
|
|
178
|
-
trackVolatile();
|
|
274
|
+
Observable.trackVolatile();
|
|
179
275
|
return descriptor.get.apply(this);
|
|
180
276
|
},
|
|
181
277
|
});
|
|
182
278
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
279
|
+
const contextEvent = FAST.getById(3 /* contextEvent */, () => {
|
|
280
|
+
let current = null;
|
|
281
|
+
return {
|
|
282
|
+
get() {
|
|
283
|
+
return current;
|
|
284
|
+
},
|
|
285
|
+
set(event) {
|
|
286
|
+
current = event;
|
|
287
|
+
},
|
|
288
|
+
};
|
|
289
|
+
});
|
|
191
290
|
/**
|
|
192
291
|
* Provides additional contextual information available to behaviors and expressions.
|
|
193
292
|
* @public
|
|
@@ -215,7 +314,7 @@ export class ExecutionContext {
|
|
|
215
314
|
* The current event within an event handler.
|
|
216
315
|
*/
|
|
217
316
|
get event() {
|
|
218
|
-
return
|
|
317
|
+
return contextEvent.get();
|
|
219
318
|
}
|
|
220
319
|
/**
|
|
221
320
|
* Indicates whether the current item within a repeat context
|
|
@@ -252,6 +351,14 @@ export class ExecutionContext {
|
|
|
252
351
|
get isLast() {
|
|
253
352
|
return this.index === this.length - 1;
|
|
254
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* Sets the event for the current execution context.
|
|
356
|
+
* @param event - The event to set.
|
|
357
|
+
* @internal
|
|
358
|
+
*/
|
|
359
|
+
static setEvent(event) {
|
|
360
|
+
contextEvent.set(event);
|
|
361
|
+
}
|
|
255
362
|
}
|
|
256
363
|
Observable.defineProperty(ExecutionContext.prototype, "index");
|
|
257
364
|
Observable.defineProperty(ExecutionContext.prototype, "length");
|
|
@@ -260,102 +367,3 @@ Observable.defineProperty(ExecutionContext.prototype, "length");
|
|
|
260
367
|
* @public
|
|
261
368
|
*/
|
|
262
369
|
export const defaultExecutionContext = Object.seal(new ExecutionContext());
|
|
263
|
-
class BindingObserverImplementation extends SubscriberSet {
|
|
264
|
-
constructor(binding, initialSubscriber, isVolatileBinding = false) {
|
|
265
|
-
super(binding, initialSubscriber);
|
|
266
|
-
this.binding = binding;
|
|
267
|
-
this.isVolatileBinding = isVolatileBinding;
|
|
268
|
-
this.needsRefresh = true;
|
|
269
|
-
this.needsQueue = true;
|
|
270
|
-
this.first = this;
|
|
271
|
-
this.last = null;
|
|
272
|
-
this.propertySource = void 0;
|
|
273
|
-
this.propertyName = void 0;
|
|
274
|
-
this.notifier = void 0;
|
|
275
|
-
this.next = void 0;
|
|
276
|
-
}
|
|
277
|
-
observe(source, context) {
|
|
278
|
-
if (this.needsRefresh && this.last !== null) {
|
|
279
|
-
this.disconnect();
|
|
280
|
-
}
|
|
281
|
-
const previousWatcher = watcher;
|
|
282
|
-
watcher = this.needsRefresh ? this : void 0;
|
|
283
|
-
this.needsRefresh = this.isVolatileBinding;
|
|
284
|
-
const result = this.binding(source, context);
|
|
285
|
-
watcher = previousWatcher;
|
|
286
|
-
return result;
|
|
287
|
-
}
|
|
288
|
-
disconnect() {
|
|
289
|
-
if (this.last !== null) {
|
|
290
|
-
let current = this.first;
|
|
291
|
-
while (current !== void 0) {
|
|
292
|
-
current.notifier.unsubscribe(this, current.propertyName);
|
|
293
|
-
current = current.next;
|
|
294
|
-
}
|
|
295
|
-
this.last = null;
|
|
296
|
-
this.needsRefresh = this.needsQueue = true;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
/** @internal */
|
|
300
|
-
watch(propertySource, propertyName) {
|
|
301
|
-
const prev = this.last;
|
|
302
|
-
const notifier = getNotifier(propertySource);
|
|
303
|
-
const current = prev === null ? this.first : {};
|
|
304
|
-
current.propertySource = propertySource;
|
|
305
|
-
current.propertyName = propertyName;
|
|
306
|
-
current.notifier = notifier;
|
|
307
|
-
notifier.subscribe(this, propertyName);
|
|
308
|
-
if (prev !== null) {
|
|
309
|
-
if (!this.needsRefresh) {
|
|
310
|
-
// Declaring the variable prior to assignment below circumvents
|
|
311
|
-
// a bug in Angular's optimization process causing infinite recursion
|
|
312
|
-
// of this watch() method. Details https://github.com/microsoft/fast/issues/4969
|
|
313
|
-
let prevValue;
|
|
314
|
-
watcher = void 0;
|
|
315
|
-
/* eslint-disable-next-line */
|
|
316
|
-
prevValue = prev.propertySource[prev.propertyName];
|
|
317
|
-
watcher = this;
|
|
318
|
-
if (propertySource === prevValue) {
|
|
319
|
-
this.needsRefresh = true;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
prev.next = current;
|
|
323
|
-
}
|
|
324
|
-
this.last = current;
|
|
325
|
-
}
|
|
326
|
-
/** @internal */
|
|
327
|
-
handleChange() {
|
|
328
|
-
if (this.needsQueue) {
|
|
329
|
-
this.needsQueue = false;
|
|
330
|
-
queueUpdate(this);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
/** @internal */
|
|
334
|
-
call() {
|
|
335
|
-
if (this.last !== null) {
|
|
336
|
-
this.needsQueue = true;
|
|
337
|
-
this.notify(this);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
records() {
|
|
341
|
-
let next = this.first;
|
|
342
|
-
return {
|
|
343
|
-
next: () => {
|
|
344
|
-
const current = next;
|
|
345
|
-
if (current === undefined) {
|
|
346
|
-
return { value: void 0, done: true };
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
next = next.next;
|
|
350
|
-
return {
|
|
351
|
-
value: current,
|
|
352
|
-
done: false,
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
},
|
|
356
|
-
[Symbol.iterator]: function () {
|
|
357
|
-
return this;
|
|
358
|
-
},
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
}
|
package/dist/esm/platform.js
CHANGED
|
@@ -36,6 +36,29 @@ export const $global = (function () {
|
|
|
36
36
|
if ($global.trustedTypes === void 0) {
|
|
37
37
|
$global.trustedTypes = { createPolicy: (n, r) => r };
|
|
38
38
|
}
|
|
39
|
+
const propConfig = {
|
|
40
|
+
configurable: false,
|
|
41
|
+
enumerable: false,
|
|
42
|
+
writable: false,
|
|
43
|
+
};
|
|
44
|
+
if ($global.FAST === void 0) {
|
|
45
|
+
Reflect.defineProperty($global, "FAST", Object.assign({ value: Object.create(null) }, propConfig));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The FAST global.
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
export const FAST = $global.FAST;
|
|
52
|
+
if (FAST.getById === void 0) {
|
|
53
|
+
const storage = Object.create(null);
|
|
54
|
+
Reflect.defineProperty(FAST, "getById", Object.assign({ value(id, initialize) {
|
|
55
|
+
let found = storage[id];
|
|
56
|
+
if (found === void 0) {
|
|
57
|
+
found = initialize ? (storage[id] = initialize()) : null;
|
|
58
|
+
}
|
|
59
|
+
return found;
|
|
60
|
+
} }, propConfig));
|
|
61
|
+
}
|
|
39
62
|
/**
|
|
40
63
|
* A readonly, empty array.
|
|
41
64
|
* @remarks
|
package/dist/esm/styles/css.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CSSDirective } from "./css-directive";
|
|
2
|
-
import { ElementStyles } from "./element-styles";
|
|
1
|
+
import { CSSDirective } from "./css-directive.js";
|
|
2
|
+
import { ElementStyles } from "./element-styles.js";
|
|
3
3
|
function collectStyles(strings, values) {
|
|
4
4
|
const styles = [];
|
|
5
5
|
let cssString = "";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { DOM } from "../dom";
|
|
2
|
-
import {
|
|
3
|
-
import { TargetedHTMLDirective } from "./html-directive";
|
|
1
|
+
import { DOM } from "../dom.js";
|
|
2
|
+
import { ExecutionContext, Observable, } from "../observation/observable.js";
|
|
3
|
+
import { TargetedHTMLDirective } from "./html-directive.js";
|
|
4
4
|
function normalBind(source, context) {
|
|
5
5
|
this.source = source;
|
|
6
6
|
this.context = context;
|
|
@@ -242,9 +242,9 @@ export class BindingBehavior {
|
|
|
242
242
|
}
|
|
243
243
|
/** @internal */
|
|
244
244
|
handleEvent(event) {
|
|
245
|
-
|
|
245
|
+
ExecutionContext.setEvent(event);
|
|
246
246
|
const result = this.binding(this.source, this.context);
|
|
247
|
-
|
|
247
|
+
ExecutionContext.setEvent(null);
|
|
248
248
|
if (result !== true) {
|
|
249
249
|
event.preventDefault();
|
|
250
250
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AttachedBehaviorHTMLDirective } from "./html-directive";
|
|
2
|
-
import { NodeObservationBehavior } from "./node-observation";
|
|
1
|
+
import { AttachedBehaviorHTMLDirective } from "./html-directive.js";
|
|
2
|
+
import { NodeObservationBehavior } from "./node-observation.js";
|
|
3
3
|
/**
|
|
4
4
|
* The runtime behavior for child node observation.
|
|
5
5
|
* @public
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { _interpolationEnd, _interpolationStart, DOM } from "../dom";
|
|
2
|
-
import { HTMLBindingDirective } from "./binding";
|
|
1
|
+
import { _interpolationEnd, _interpolationStart, DOM } from "../dom.js";
|
|
2
|
+
import { HTMLBindingDirective } from "./binding.js";
|
|
3
3
|
let sharedContext = null;
|
|
4
4
|
class CompilationContext {
|
|
5
5
|
addFactory(factory) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Observable } from "../observation/observable";
|
|
2
|
-
import { emptyArray } from "../platform";
|
|
1
|
+
import { Observable } from "../observation/observable.js";
|
|
2
|
+
import { emptyArray } from "../platform.js";
|
|
3
3
|
/**
|
|
4
4
|
* Creates a function that can be used to filter a Node array, selecting only elements.
|
|
5
5
|
* @param selector - An optional selector to restrict the filter to.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { DOM } from "../dom";
|
|
2
|
-
import { Observable, } from "../observation/observable";
|
|
3
|
-
import { enableArrayObservation } from "../observation/array-observer";
|
|
4
|
-
import { emptyArray } from "../platform";
|
|
5
|
-
import { HTMLDirective } from "./html-directive";
|
|
6
|
-
import { HTMLView } from "./view";
|
|
1
|
+
import { DOM } from "../dom.js";
|
|
2
|
+
import { Observable, } from "../observation/observable.js";
|
|
3
|
+
import { enableArrayObservation } from "../observation/array-observer.js";
|
|
4
|
+
import { emptyArray } from "../platform.js";
|
|
5
|
+
import { HTMLDirective } from "./html-directive.js";
|
|
6
|
+
import { HTMLView } from "./view.js";
|
|
7
7
|
const defaultRepeatOptions = Object.freeze({
|
|
8
8
|
positioning: false,
|
|
9
9
|
recycle: true,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AttachedBehaviorHTMLDirective } from "./html-directive";
|
|
2
|
-
import { NodeObservationBehavior } from "./node-observation";
|
|
1
|
+
import { AttachedBehaviorHTMLDirective } from "./html-directive.js";
|
|
2
|
+
import { NodeObservationBehavior } from "./node-observation.js";
|
|
3
3
|
/**
|
|
4
4
|
* The runtime behavior for slotted node observation.
|
|
5
5
|
* @public
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { DOM } from "../dom";
|
|
2
|
-
import { defaultExecutionContext } from "../observation/observable";
|
|
3
|
-
import { compileTemplate } from "./compiler";
|
|
4
|
-
import { HTMLView } from "./view";
|
|
5
|
-
import { HTMLDirective, TargetedHTMLDirective, } from "./html-directive";
|
|
6
|
-
import { HTMLBindingDirective } from "./binding";
|
|
1
|
+
import { DOM } from "../dom.js";
|
|
2
|
+
import { defaultExecutionContext } from "../observation/observable.js";
|
|
3
|
+
import { compileTemplate } from "./compiler.js";
|
|
4
|
+
import { HTMLView } from "./view.js";
|
|
5
|
+
import { HTMLDirective, TargetedHTMLDirective, } from "./html-directive.js";
|
|
6
|
+
import { HTMLBindingDirective } from "./binding.js";
|
|
7
7
|
/**
|
|
8
8
|
* A template capable of creating HTMLView instances or rendering directly to DOM.
|
|
9
9
|
* @public
|