@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
package/dist/fast-element.js
CHANGED
|
@@ -41,6 +41,41 @@ if ($global.trustedTypes === void 0) {
|
|
|
41
41
|
createPolicy: (n, r) => r
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
const propConfig = {
|
|
46
|
+
configurable: false,
|
|
47
|
+
enumerable: false,
|
|
48
|
+
writable: false
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
if ($global.FAST === void 0) {
|
|
52
|
+
Reflect.defineProperty($global, "FAST", Object.assign({
|
|
53
|
+
value: Object.create(null)
|
|
54
|
+
}, propConfig));
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The FAST global.
|
|
58
|
+
* @internal
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
const FAST = $global.FAST;
|
|
63
|
+
|
|
64
|
+
if (FAST.getById === void 0) {
|
|
65
|
+
const storage = Object.create(null);
|
|
66
|
+
Reflect.defineProperty(FAST, "getById", Object.assign({
|
|
67
|
+
value(id, initialize) {
|
|
68
|
+
let found = storage[id];
|
|
69
|
+
|
|
70
|
+
if (found === void 0) {
|
|
71
|
+
found = initialize ? storage[id] = initialize() : null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return found;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
}, propConfig));
|
|
78
|
+
}
|
|
44
79
|
/**
|
|
45
80
|
* A readonly, empty array.
|
|
46
81
|
* @remarks
|
|
@@ -52,33 +87,75 @@ if ($global.trustedTypes === void 0) {
|
|
|
52
87
|
|
|
53
88
|
const emptyArray = Object.freeze([]);
|
|
54
89
|
|
|
55
|
-
const updateQueue =
|
|
56
|
-
/*
|
|
90
|
+
const updateQueue = $global.FAST.getById(1
|
|
91
|
+
/* updateQueue */
|
|
92
|
+
, () => {
|
|
93
|
+
const tasks = [];
|
|
94
|
+
const pendingErrors = [];
|
|
57
95
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
96
|
+
function throwFirstError() {
|
|
97
|
+
if (pendingErrors.length) {
|
|
98
|
+
throw pendingErrors.shift();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
62
101
|
|
|
63
|
-
|
|
102
|
+
function tryRunTask(task) {
|
|
103
|
+
try {
|
|
104
|
+
task.call();
|
|
105
|
+
} catch (error) {
|
|
106
|
+
pendingErrors.push(error);
|
|
107
|
+
setTimeout(throwFirstError, 0);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
64
110
|
|
|
65
|
-
|
|
111
|
+
function process() {
|
|
112
|
+
const capacity = 1024;
|
|
113
|
+
let index = 0;
|
|
66
114
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
115
|
+
while (index < tasks.length) {
|
|
116
|
+
tryRunTask(tasks[index]);
|
|
117
|
+
index++; // Prevent leaking memory for long chains of recursive calls to `DOM.queueUpdate`.
|
|
118
|
+
// If we call `DOM.queueUpdate` within a task scheduled by `DOM.queueUpdate`, the queue will
|
|
119
|
+
// grow, but to avoid an O(n) walk for every task we execute, we don't
|
|
120
|
+
// shift tasks off the queue after they have been executed.
|
|
121
|
+
// Instead, we periodically shift 1024 tasks off the queue.
|
|
122
|
+
|
|
123
|
+
if (index > capacity) {
|
|
124
|
+
// Manually shift all values starting at the index back to the
|
|
125
|
+
// beginning of the queue.
|
|
126
|
+
for (let scan = 0, newLength = tasks.length - index; scan < newLength; scan++) {
|
|
127
|
+
tasks[scan] = tasks[scan + index];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
tasks.length -= index;
|
|
131
|
+
index = 0;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
tasks.length = 0;
|
|
70
136
|
}
|
|
71
|
-
}
|
|
72
137
|
|
|
73
|
-
function
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
138
|
+
function enqueue(callable) {
|
|
139
|
+
if (tasks.length < 1) {
|
|
140
|
+
$global.requestAnimationFrame(process);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
tasks.push(callable);
|
|
79
144
|
}
|
|
80
|
-
}
|
|
81
145
|
|
|
146
|
+
return Object.freeze({
|
|
147
|
+
enqueue,
|
|
148
|
+
process
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
/* eslint-disable */
|
|
152
|
+
|
|
153
|
+
const fastHTMLPolicy = $global.trustedTypes.createPolicy("fast-html", {
|
|
154
|
+
createHTML: html => html
|
|
155
|
+
});
|
|
156
|
+
/* eslint-enable */
|
|
157
|
+
|
|
158
|
+
let htmlPolicy = fastHTMLPolicy;
|
|
82
159
|
const marker = `fast-${Math.random().toString(36).substring(2, 8)}`;
|
|
83
160
|
/** @internal */
|
|
84
161
|
|
|
@@ -176,13 +253,7 @@ const DOM = Object.freeze({
|
|
|
176
253
|
* Schedules DOM update work in the next async batch.
|
|
177
254
|
* @param callable - The callable function or object to queue.
|
|
178
255
|
*/
|
|
179
|
-
queueUpdate
|
|
180
|
-
if (updateQueue.length < 1) {
|
|
181
|
-
window.requestAnimationFrame(DOM.processUpdates);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
updateQueue.push(callable);
|
|
185
|
-
},
|
|
256
|
+
queueUpdate: updateQueue.enqueue,
|
|
186
257
|
|
|
187
258
|
/**
|
|
188
259
|
* Immediately processes all work previously scheduled
|
|
@@ -191,40 +262,13 @@ const DOM = Object.freeze({
|
|
|
191
262
|
* This also forces nextUpdate promises
|
|
192
263
|
* to resolve.
|
|
193
264
|
*/
|
|
194
|
-
processUpdates
|
|
195
|
-
const capacity = 1024;
|
|
196
|
-
let index = 0;
|
|
197
|
-
|
|
198
|
-
while (index < updateQueue.length) {
|
|
199
|
-
tryRunTask(updateQueue[index]);
|
|
200
|
-
index++; // Prevent leaking memory for long chains of recursive calls to `DOM.queueUpdate`.
|
|
201
|
-
// If we call `DOM.queueUpdate` within a task scheduled by `DOM.queueUpdate`, the queue will
|
|
202
|
-
// grow, but to avoid an O(n) walk for every task we execute, we don't
|
|
203
|
-
// shift tasks off the queue after they have been executed.
|
|
204
|
-
// Instead, we periodically shift 1024 tasks off the queue.
|
|
205
|
-
|
|
206
|
-
if (index > capacity) {
|
|
207
|
-
// Manually shift all values starting at the index back to the
|
|
208
|
-
// beginning of the queue.
|
|
209
|
-
for (let scan = 0, newLength = updateQueue.length - index; scan < newLength; scan++) {
|
|
210
|
-
updateQueue[scan] = updateQueue[scan + index];
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
updateQueue.length -= index;
|
|
214
|
-
index = 0;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
updateQueue.length = 0;
|
|
219
|
-
},
|
|
265
|
+
processUpdates: updateQueue.process,
|
|
220
266
|
|
|
221
267
|
/**
|
|
222
268
|
* Resolves with the next DOM update.
|
|
223
269
|
*/
|
|
224
270
|
nextUpdate() {
|
|
225
|
-
return new Promise(
|
|
226
|
-
DOM.queueUpdate(resolve);
|
|
227
|
-
});
|
|
271
|
+
return new Promise(updateQueue.enqueue);
|
|
228
272
|
},
|
|
229
273
|
|
|
230
274
|
/**
|
|
@@ -484,69 +528,25 @@ class PropertyChangeNotifier {
|
|
|
484
528
|
|
|
485
529
|
}
|
|
486
530
|
|
|
487
|
-
const volatileRegex = /(:|&&|\|\||if)/;
|
|
488
|
-
const notifierLookup = new WeakMap();
|
|
489
|
-
const accessorLookup = new WeakMap();
|
|
490
|
-
let watcher = void 0;
|
|
491
|
-
|
|
492
|
-
let createArrayObserver = array => {
|
|
493
|
-
throw new Error("Must call enableArrayObservation before observing arrays.");
|
|
494
|
-
};
|
|
495
|
-
|
|
496
|
-
class DefaultObservableAccessor {
|
|
497
|
-
constructor(name) {
|
|
498
|
-
this.name = name;
|
|
499
|
-
this.field = `_${name}`;
|
|
500
|
-
this.callback = `${name}Changed`;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
getValue(source) {
|
|
504
|
-
if (watcher !== void 0) {
|
|
505
|
-
watcher.watch(source, this.name);
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
return source[this.field];
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
setValue(source, newValue) {
|
|
512
|
-
const field = this.field;
|
|
513
|
-
const oldValue = source[field];
|
|
514
|
-
|
|
515
|
-
if (oldValue !== newValue) {
|
|
516
|
-
source[field] = newValue;
|
|
517
|
-
const callback = source[this.callback];
|
|
518
|
-
|
|
519
|
-
if (typeof callback === "function") {
|
|
520
|
-
callback.call(source, oldValue, newValue);
|
|
521
|
-
}
|
|
522
|
-
/* eslint-disable-next-line @typescript-eslint/no-use-before-define */
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
getNotifier(source).notify(this.name);
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
}
|
|
530
531
|
/**
|
|
531
532
|
* Common Observable APIs.
|
|
532
533
|
* @public
|
|
533
534
|
*/
|
|
534
535
|
|
|
536
|
+
const Observable = FAST.getById(2
|
|
537
|
+
/* observable */
|
|
538
|
+
, () => {
|
|
539
|
+
const volatileRegex = /(:|&&|\|\||if)/;
|
|
540
|
+
const notifierLookup = new WeakMap();
|
|
541
|
+
const accessorLookup = new WeakMap();
|
|
542
|
+
const queueUpdate = DOM.queueUpdate;
|
|
543
|
+
let watcher = void 0;
|
|
544
|
+
|
|
545
|
+
let createArrayObserver = array => {
|
|
546
|
+
throw new Error("Must call enableArrayObservation before observing arrays.");
|
|
547
|
+
};
|
|
535
548
|
|
|
536
|
-
|
|
537
|
-
/**
|
|
538
|
-
* @internal
|
|
539
|
-
* @param factory - The factory used to create array observers.
|
|
540
|
-
*/
|
|
541
|
-
setArrayObserverFactory(factory) {
|
|
542
|
-
createArrayObserver = factory;
|
|
543
|
-
},
|
|
544
|
-
|
|
545
|
-
/**
|
|
546
|
-
* Gets a notifier for an object or Array.
|
|
547
|
-
* @param source - The object or Array to get the notifier for.
|
|
548
|
-
*/
|
|
549
|
-
getNotifier(source) {
|
|
549
|
+
function getNotifier(source) {
|
|
550
550
|
let found = source.$fastController || notifierLookup.get(source);
|
|
551
551
|
|
|
552
552
|
if (found === void 0) {
|
|
@@ -558,68 +558,9 @@ const Observable = Object.freeze({
|
|
|
558
558
|
}
|
|
559
559
|
|
|
560
560
|
return found;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
/**
|
|
564
|
-
* Records a property change for a source object.
|
|
565
|
-
* @param source - The object to record the change against.
|
|
566
|
-
* @param propertyName - The property to track as changed.
|
|
567
|
-
*/
|
|
568
|
-
track(source, propertyName) {
|
|
569
|
-
if (watcher !== void 0) {
|
|
570
|
-
watcher.watch(source, propertyName);
|
|
571
|
-
}
|
|
572
|
-
},
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* Notifies watchers that the currently executing property getter or function is volatile
|
|
576
|
-
* with respect to its observable dependencies.
|
|
577
|
-
*/
|
|
578
|
-
trackVolatile() {
|
|
579
|
-
if (watcher !== void 0) {
|
|
580
|
-
watcher.needsRefresh = true;
|
|
581
|
-
}
|
|
582
|
-
},
|
|
583
|
-
|
|
584
|
-
/**
|
|
585
|
-
* Notifies subscribers of a source object of changes.
|
|
586
|
-
* @param source - the object to notify of changes.
|
|
587
|
-
* @param args - The change args to pass to subscribers.
|
|
588
|
-
*/
|
|
589
|
-
notify(source, args) {
|
|
590
|
-
/* eslint-disable-next-line @typescript-eslint/no-use-before-define */
|
|
591
|
-
getNotifier(source).notify(args);
|
|
592
|
-
},
|
|
593
|
-
|
|
594
|
-
/**
|
|
595
|
-
* Defines an observable property on an object or prototype.
|
|
596
|
-
* @param target - The target object to define the observable on.
|
|
597
|
-
* @param nameOrAccessor - The name of the property to define as observable;
|
|
598
|
-
* or a custom accessor that specifies the property name and accessor implementation.
|
|
599
|
-
*/
|
|
600
|
-
defineProperty(target, nameOrAccessor) {
|
|
601
|
-
if (typeof nameOrAccessor === "string") {
|
|
602
|
-
nameOrAccessor = new DefaultObservableAccessor(nameOrAccessor);
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
this.getAccessors(target).push(nameOrAccessor);
|
|
606
|
-
Reflect.defineProperty(target, nameOrAccessor.name, {
|
|
607
|
-
enumerable: true,
|
|
608
|
-
get: function () {
|
|
609
|
-
return nameOrAccessor.getValue(this);
|
|
610
|
-
},
|
|
611
|
-
set: function (newValue) {
|
|
612
|
-
nameOrAccessor.setValue(this, newValue);
|
|
613
|
-
}
|
|
614
|
-
});
|
|
615
|
-
},
|
|
561
|
+
}
|
|
616
562
|
|
|
617
|
-
|
|
618
|
-
* Finds all the observable accessors defined on the target,
|
|
619
|
-
* including its prototype chain.
|
|
620
|
-
* @param target - The target object to search for accessor on.
|
|
621
|
-
*/
|
|
622
|
-
getAccessors(target) {
|
|
563
|
+
function getAccessors(target) {
|
|
623
564
|
let accessors = accessorLookup.get(target);
|
|
624
565
|
|
|
625
566
|
if (accessors === void 0) {
|
|
@@ -640,33 +581,253 @@ const Observable = Object.freeze({
|
|
|
640
581
|
}
|
|
641
582
|
|
|
642
583
|
return accessors;
|
|
643
|
-
}
|
|
584
|
+
}
|
|
644
585
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
586
|
+
class DefaultObservableAccessor {
|
|
587
|
+
constructor(name) {
|
|
588
|
+
this.name = name;
|
|
589
|
+
this.field = `_${name}`;
|
|
590
|
+
this.callback = `${name}Changed`;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
getValue(source) {
|
|
594
|
+
if (watcher !== void 0) {
|
|
595
|
+
watcher.watch(source, this.name);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
return source[this.field];
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
setValue(source, newValue) {
|
|
602
|
+
const field = this.field;
|
|
603
|
+
const oldValue = source[field];
|
|
604
|
+
|
|
605
|
+
if (oldValue !== newValue) {
|
|
606
|
+
source[field] = newValue;
|
|
607
|
+
const callback = source[this.callback];
|
|
608
|
+
|
|
609
|
+
if (typeof callback === "function") {
|
|
610
|
+
callback.call(source, oldValue, newValue);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
getNotifier(source).notify(this.name);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
656
616
|
|
|
657
|
-
/**
|
|
658
|
-
* Determines whether a binding expression is volatile and needs to have its dependency list re-evaluated
|
|
659
|
-
* on every evaluation of the value.
|
|
660
|
-
* @param binding - The binding to inspect.
|
|
661
|
-
*/
|
|
662
|
-
isVolatileBinding(binding) {
|
|
663
|
-
return volatileRegex.test(binding.toString());
|
|
664
617
|
}
|
|
665
618
|
|
|
619
|
+
class BindingObserverImplementation extends SubscriberSet {
|
|
620
|
+
constructor(binding, initialSubscriber, isVolatileBinding = false) {
|
|
621
|
+
super(binding, initialSubscriber);
|
|
622
|
+
this.binding = binding;
|
|
623
|
+
this.isVolatileBinding = isVolatileBinding;
|
|
624
|
+
this.needsRefresh = true;
|
|
625
|
+
this.needsQueue = true;
|
|
626
|
+
this.first = this;
|
|
627
|
+
this.last = null;
|
|
628
|
+
this.propertySource = void 0;
|
|
629
|
+
this.propertyName = void 0;
|
|
630
|
+
this.notifier = void 0;
|
|
631
|
+
this.next = void 0;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
observe(source, context) {
|
|
635
|
+
if (this.needsRefresh && this.last !== null) {
|
|
636
|
+
this.disconnect();
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
const previousWatcher = watcher;
|
|
640
|
+
watcher = this.needsRefresh ? this : void 0;
|
|
641
|
+
this.needsRefresh = this.isVolatileBinding;
|
|
642
|
+
const result = this.binding(source, context);
|
|
643
|
+
watcher = previousWatcher;
|
|
644
|
+
return result;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
disconnect() {
|
|
648
|
+
if (this.last !== null) {
|
|
649
|
+
let current = this.first;
|
|
650
|
+
|
|
651
|
+
while (current !== void 0) {
|
|
652
|
+
current.notifier.unsubscribe(this, current.propertyName);
|
|
653
|
+
current = current.next;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
this.last = null;
|
|
657
|
+
this.needsRefresh = this.needsQueue = true;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
watch(propertySource, propertyName) {
|
|
662
|
+
const prev = this.last;
|
|
663
|
+
const notifier = getNotifier(propertySource);
|
|
664
|
+
const current = prev === null ? this.first : {};
|
|
665
|
+
current.propertySource = propertySource;
|
|
666
|
+
current.propertyName = propertyName;
|
|
667
|
+
current.notifier = notifier;
|
|
668
|
+
notifier.subscribe(this, propertyName);
|
|
669
|
+
|
|
670
|
+
if (prev !== null) {
|
|
671
|
+
if (!this.needsRefresh) {
|
|
672
|
+
// Declaring the variable prior to assignment below circumvents
|
|
673
|
+
// a bug in Angular's optimization process causing infinite recursion
|
|
674
|
+
// of this watch() method. Details https://github.com/microsoft/fast/issues/4969
|
|
675
|
+
let prevValue;
|
|
676
|
+
watcher = void 0;
|
|
677
|
+
/* eslint-disable-next-line */
|
|
678
|
+
|
|
679
|
+
prevValue = prev.propertySource[prev.propertyName];
|
|
680
|
+
watcher = this;
|
|
681
|
+
|
|
682
|
+
if (propertySource === prevValue) {
|
|
683
|
+
this.needsRefresh = true;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
prev.next = current;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
this.last = current;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
handleChange() {
|
|
694
|
+
if (this.needsQueue) {
|
|
695
|
+
this.needsQueue = false;
|
|
696
|
+
queueUpdate(this);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
call() {
|
|
701
|
+
if (this.last !== null) {
|
|
702
|
+
this.needsQueue = true;
|
|
703
|
+
this.notify(this);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
records() {
|
|
708
|
+
let next = this.first;
|
|
709
|
+
return {
|
|
710
|
+
next: () => {
|
|
711
|
+
const current = next;
|
|
712
|
+
|
|
713
|
+
if (current === undefined) {
|
|
714
|
+
return {
|
|
715
|
+
value: void 0,
|
|
716
|
+
done: true
|
|
717
|
+
};
|
|
718
|
+
} else {
|
|
719
|
+
next = next.next;
|
|
720
|
+
return {
|
|
721
|
+
value: current,
|
|
722
|
+
done: false
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
},
|
|
726
|
+
[Symbol.iterator]: function () {
|
|
727
|
+
return this;
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
return Object.freeze({
|
|
735
|
+
/**
|
|
736
|
+
* @internal
|
|
737
|
+
* @param factory - The factory used to create array observers.
|
|
738
|
+
*/
|
|
739
|
+
setArrayObserverFactory(factory) {
|
|
740
|
+
createArrayObserver = factory;
|
|
741
|
+
},
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* Gets a notifier for an object or Array.
|
|
745
|
+
* @param source - The object or Array to get the notifier for.
|
|
746
|
+
*/
|
|
747
|
+
getNotifier,
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Records a property change for a source object.
|
|
751
|
+
* @param source - The object to record the change against.
|
|
752
|
+
* @param propertyName - The property to track as changed.
|
|
753
|
+
*/
|
|
754
|
+
track(source, propertyName) {
|
|
755
|
+
if (watcher !== void 0) {
|
|
756
|
+
watcher.watch(source, propertyName);
|
|
757
|
+
}
|
|
758
|
+
},
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Notifies watchers that the currently executing property getter or function is volatile
|
|
762
|
+
* with respect to its observable dependencies.
|
|
763
|
+
*/
|
|
764
|
+
trackVolatile() {
|
|
765
|
+
if (watcher !== void 0) {
|
|
766
|
+
watcher.needsRefresh = true;
|
|
767
|
+
}
|
|
768
|
+
},
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* Notifies subscribers of a source object of changes.
|
|
772
|
+
* @param source - the object to notify of changes.
|
|
773
|
+
* @param args - The change args to pass to subscribers.
|
|
774
|
+
*/
|
|
775
|
+
notify(source, args) {
|
|
776
|
+
getNotifier(source).notify(args);
|
|
777
|
+
},
|
|
778
|
+
|
|
779
|
+
/**
|
|
780
|
+
* Defines an observable property on an object or prototype.
|
|
781
|
+
* @param target - The target object to define the observable on.
|
|
782
|
+
* @param nameOrAccessor - The name of the property to define as observable;
|
|
783
|
+
* or a custom accessor that specifies the property name and accessor implementation.
|
|
784
|
+
*/
|
|
785
|
+
defineProperty(target, nameOrAccessor) {
|
|
786
|
+
if (typeof nameOrAccessor === "string") {
|
|
787
|
+
nameOrAccessor = new DefaultObservableAccessor(nameOrAccessor);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
getAccessors(target).push(nameOrAccessor);
|
|
791
|
+
Reflect.defineProperty(target, nameOrAccessor.name, {
|
|
792
|
+
enumerable: true,
|
|
793
|
+
get: function () {
|
|
794
|
+
return nameOrAccessor.getValue(this);
|
|
795
|
+
},
|
|
796
|
+
set: function (newValue) {
|
|
797
|
+
nameOrAccessor.setValue(this, newValue);
|
|
798
|
+
}
|
|
799
|
+
});
|
|
800
|
+
},
|
|
801
|
+
|
|
802
|
+
/**
|
|
803
|
+
* Finds all the observable accessors defined on the target,
|
|
804
|
+
* including its prototype chain.
|
|
805
|
+
* @param target - The target object to search for accessor on.
|
|
806
|
+
*/
|
|
807
|
+
getAccessors,
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* Creates a {@link BindingObserver} that can watch the
|
|
811
|
+
* provided {@link Binding} for changes.
|
|
812
|
+
* @param binding - The binding to observe.
|
|
813
|
+
* @param initialSubscriber - An initial subscriber to changes in the binding value.
|
|
814
|
+
* @param isVolatileBinding - Indicates whether the binding's dependency list must be re-evaluated on every value evaluation.
|
|
815
|
+
*/
|
|
816
|
+
binding(binding, initialSubscriber, isVolatileBinding = this.isVolatileBinding(binding)) {
|
|
817
|
+
return new BindingObserverImplementation(binding, initialSubscriber, isVolatileBinding);
|
|
818
|
+
},
|
|
819
|
+
|
|
820
|
+
/**
|
|
821
|
+
* Determines whether a binding expression is volatile and needs to have its dependency list re-evaluated
|
|
822
|
+
* on every evaluation of the value.
|
|
823
|
+
* @param binding - The binding to inspect.
|
|
824
|
+
*/
|
|
825
|
+
isVolatileBinding(binding) {
|
|
826
|
+
return volatileRegex.test(binding.toString());
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
});
|
|
666
830
|
});
|
|
667
|
-
const getNotifier = Observable.getNotifier;
|
|
668
|
-
const trackVolatile = Observable.trackVolatile;
|
|
669
|
-
const queueUpdate = DOM.queueUpdate;
|
|
670
831
|
/**
|
|
671
832
|
* Decorator: Defines an observable property on the target.
|
|
672
833
|
* @param target - The target to define the observable on.
|
|
@@ -688,20 +849,26 @@ function observable(target, nameOrAccessor) {
|
|
|
688
849
|
function volatile(target, name, descriptor) {
|
|
689
850
|
return Object.assign({}, descriptor, {
|
|
690
851
|
get: function () {
|
|
691
|
-
trackVolatile();
|
|
852
|
+
Observable.trackVolatile();
|
|
692
853
|
return descriptor.get.apply(this);
|
|
693
854
|
}
|
|
694
855
|
});
|
|
695
856
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
857
|
+
const contextEvent = FAST.getById(3
|
|
858
|
+
/* contextEvent */
|
|
859
|
+
, () => {
|
|
860
|
+
let current = null;
|
|
861
|
+
return {
|
|
862
|
+
get() {
|
|
863
|
+
return current;
|
|
864
|
+
},
|
|
701
865
|
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
}
|
|
866
|
+
set(event) {
|
|
867
|
+
current = event;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
};
|
|
871
|
+
});
|
|
705
872
|
/**
|
|
706
873
|
* Provides additional contextual information available to behaviors and expressions.
|
|
707
874
|
* @public
|
|
@@ -735,7 +902,7 @@ class ExecutionContext {
|
|
|
735
902
|
|
|
736
903
|
|
|
737
904
|
get event() {
|
|
738
|
-
return
|
|
905
|
+
return contextEvent.get();
|
|
739
906
|
}
|
|
740
907
|
/**
|
|
741
908
|
* Indicates whether the current item within a repeat context
|
|
@@ -782,6 +949,16 @@ class ExecutionContext {
|
|
|
782
949
|
get isLast() {
|
|
783
950
|
return this.index === this.length - 1;
|
|
784
951
|
}
|
|
952
|
+
/**
|
|
953
|
+
* Sets the event for the current execution context.
|
|
954
|
+
* @param event - The event to set.
|
|
955
|
+
* @internal
|
|
956
|
+
*/
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
static setEvent(event) {
|
|
960
|
+
contextEvent.set(event);
|
|
961
|
+
}
|
|
785
962
|
|
|
786
963
|
}
|
|
787
964
|
Observable.defineProperty(ExecutionContext.prototype, "index");
|
|
@@ -793,127 +970,6 @@ Observable.defineProperty(ExecutionContext.prototype, "length");
|
|
|
793
970
|
|
|
794
971
|
const defaultExecutionContext = Object.seal(new ExecutionContext());
|
|
795
972
|
|
|
796
|
-
class BindingObserverImplementation extends SubscriberSet {
|
|
797
|
-
constructor(binding, initialSubscriber, isVolatileBinding = false) {
|
|
798
|
-
super(binding, initialSubscriber);
|
|
799
|
-
this.binding = binding;
|
|
800
|
-
this.isVolatileBinding = isVolatileBinding;
|
|
801
|
-
this.needsRefresh = true;
|
|
802
|
-
this.needsQueue = true;
|
|
803
|
-
this.first = this;
|
|
804
|
-
this.last = null;
|
|
805
|
-
this.propertySource = void 0;
|
|
806
|
-
this.propertyName = void 0;
|
|
807
|
-
this.notifier = void 0;
|
|
808
|
-
this.next = void 0;
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
observe(source, context) {
|
|
812
|
-
if (this.needsRefresh && this.last !== null) {
|
|
813
|
-
this.disconnect();
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
const previousWatcher = watcher;
|
|
817
|
-
watcher = this.needsRefresh ? this : void 0;
|
|
818
|
-
this.needsRefresh = this.isVolatileBinding;
|
|
819
|
-
const result = this.binding(source, context);
|
|
820
|
-
watcher = previousWatcher;
|
|
821
|
-
return result;
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
disconnect() {
|
|
825
|
-
if (this.last !== null) {
|
|
826
|
-
let current = this.first;
|
|
827
|
-
|
|
828
|
-
while (current !== void 0) {
|
|
829
|
-
current.notifier.unsubscribe(this, current.propertyName);
|
|
830
|
-
current = current.next;
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
this.last = null;
|
|
834
|
-
this.needsRefresh = this.needsQueue = true;
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
/** @internal */
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
watch(propertySource, propertyName) {
|
|
841
|
-
const prev = this.last;
|
|
842
|
-
const notifier = getNotifier(propertySource);
|
|
843
|
-
const current = prev === null ? this.first : {};
|
|
844
|
-
current.propertySource = propertySource;
|
|
845
|
-
current.propertyName = propertyName;
|
|
846
|
-
current.notifier = notifier;
|
|
847
|
-
notifier.subscribe(this, propertyName);
|
|
848
|
-
|
|
849
|
-
if (prev !== null) {
|
|
850
|
-
if (!this.needsRefresh) {
|
|
851
|
-
// Declaring the variable prior to assignment below circumvents
|
|
852
|
-
// a bug in Angular's optimization process causing infinite recursion
|
|
853
|
-
// of this watch() method. Details https://github.com/microsoft/fast/issues/4969
|
|
854
|
-
let prevValue;
|
|
855
|
-
watcher = void 0;
|
|
856
|
-
/* eslint-disable-next-line */
|
|
857
|
-
|
|
858
|
-
prevValue = prev.propertySource[prev.propertyName];
|
|
859
|
-
watcher = this;
|
|
860
|
-
|
|
861
|
-
if (propertySource === prevValue) {
|
|
862
|
-
this.needsRefresh = true;
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
prev.next = current;
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
this.last = current;
|
|
870
|
-
}
|
|
871
|
-
/** @internal */
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
handleChange() {
|
|
875
|
-
if (this.needsQueue) {
|
|
876
|
-
this.needsQueue = false;
|
|
877
|
-
queueUpdate(this);
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
/** @internal */
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
call() {
|
|
884
|
-
if (this.last !== null) {
|
|
885
|
-
this.needsQueue = true;
|
|
886
|
-
this.notify(this);
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
records() {
|
|
891
|
-
let next = this.first;
|
|
892
|
-
return {
|
|
893
|
-
next: () => {
|
|
894
|
-
const current = next;
|
|
895
|
-
|
|
896
|
-
if (current === undefined) {
|
|
897
|
-
return {
|
|
898
|
-
value: void 0,
|
|
899
|
-
done: true
|
|
900
|
-
};
|
|
901
|
-
} else {
|
|
902
|
-
next = next.next;
|
|
903
|
-
return {
|
|
904
|
-
value: current,
|
|
905
|
-
done: false
|
|
906
|
-
};
|
|
907
|
-
}
|
|
908
|
-
},
|
|
909
|
-
[Symbol.iterator]: function () {
|
|
910
|
-
return this;
|
|
911
|
-
}
|
|
912
|
-
};
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
}
|
|
916
|
-
|
|
917
973
|
/**
|
|
918
974
|
* Instructs the template engine to apply behavior to a node.
|
|
919
975
|
* @public
|
|
@@ -1276,9 +1332,9 @@ class BindingBehavior {
|
|
|
1276
1332
|
|
|
1277
1333
|
|
|
1278
1334
|
handleEvent(event) {
|
|
1279
|
-
|
|
1335
|
+
ExecutionContext.setEvent(event);
|
|
1280
1336
|
const result = this.binding(this.source, this.context);
|
|
1281
|
-
|
|
1337
|
+
ExecutionContext.setEvent(null);
|
|
1282
1338
|
|
|
1283
1339
|
if (result !== true) {
|
|
1284
1340
|
event.preventDefault();
|
|
@@ -2274,7 +2330,26 @@ const defaultShadowOptions = {
|
|
|
2274
2330
|
mode: "open"
|
|
2275
2331
|
};
|
|
2276
2332
|
const defaultElementOptions = {};
|
|
2277
|
-
const
|
|
2333
|
+
const fastRegistry = FAST.getById(4
|
|
2334
|
+
/* elementRegistry */
|
|
2335
|
+
, () => {
|
|
2336
|
+
const typeToDefinition = new Map();
|
|
2337
|
+
return Object.freeze({
|
|
2338
|
+
register(definition) {
|
|
2339
|
+
if (typeToDefinition.has(definition.type)) {
|
|
2340
|
+
return false;
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2343
|
+
typeToDefinition.set(definition.type, definition);
|
|
2344
|
+
return true;
|
|
2345
|
+
},
|
|
2346
|
+
|
|
2347
|
+
getByType(key) {
|
|
2348
|
+
return typeToDefinition.get(key);
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
});
|
|
2352
|
+
});
|
|
2278
2353
|
/**
|
|
2279
2354
|
* Defines metadata for a FASTElement.
|
|
2280
2355
|
* @public
|
|
@@ -2317,6 +2392,14 @@ class FASTElementDefinition {
|
|
|
2317
2392
|
this.elementOptions = nameOrConfig.elementOptions === void 0 ? defaultElementOptions : Object.assign(Object.assign({}, defaultElementOptions), nameOrConfig.elementOptions);
|
|
2318
2393
|
this.styles = nameOrConfig.styles === void 0 ? void 0 : Array.isArray(nameOrConfig.styles) ? ElementStyles.create(nameOrConfig.styles) : nameOrConfig.styles instanceof ElementStyles ? nameOrConfig.styles : ElementStyles.create([nameOrConfig.styles]);
|
|
2319
2394
|
}
|
|
2395
|
+
/**
|
|
2396
|
+
* Indicates if this element has been defined in at least one registry.
|
|
2397
|
+
*/
|
|
2398
|
+
|
|
2399
|
+
|
|
2400
|
+
get isDefined() {
|
|
2401
|
+
return !!fastRegistry.getByType(this.type);
|
|
2402
|
+
}
|
|
2320
2403
|
/**
|
|
2321
2404
|
* Defines a custom element based on this definition.
|
|
2322
2405
|
* @param registry - The element registry to define the element in.
|
|
@@ -2326,7 +2409,7 @@ class FASTElementDefinition {
|
|
|
2326
2409
|
define(registry = customElements) {
|
|
2327
2410
|
const type = this.type;
|
|
2328
2411
|
|
|
2329
|
-
if (
|
|
2412
|
+
if (fastRegistry.register(this)) {
|
|
2330
2413
|
const attributes = this.attributes;
|
|
2331
2414
|
const proto = type.prototype;
|
|
2332
2415
|
|
|
@@ -2338,8 +2421,6 @@ class FASTElementDefinition {
|
|
|
2338
2421
|
value: this.observedAttributes,
|
|
2339
2422
|
enumerable: true
|
|
2340
2423
|
});
|
|
2341
|
-
fastDefinitions.set(type, this);
|
|
2342
|
-
this.isDefined = true;
|
|
2343
2424
|
}
|
|
2344
2425
|
|
|
2345
2426
|
if (!registry.get(this.name)) {
|
|
@@ -2348,17 +2429,14 @@ class FASTElementDefinition {
|
|
|
2348
2429
|
|
|
2349
2430
|
return this;
|
|
2350
2431
|
}
|
|
2351
|
-
/**
|
|
2352
|
-
* Gets the element definition associated with the specified type.
|
|
2353
|
-
* @param type - The custom element type to retrieve the definition for.
|
|
2354
|
-
*/
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
static forType(type) {
|
|
2358
|
-
return fastDefinitions.get(type);
|
|
2359
|
-
}
|
|
2360
2432
|
|
|
2361
2433
|
}
|
|
2434
|
+
/**
|
|
2435
|
+
* Gets the element definition associated with the specified type.
|
|
2436
|
+
* @param type - The custom element type to retrieve the definition for.
|
|
2437
|
+
*/
|
|
2438
|
+
|
|
2439
|
+
FASTElementDefinition.forType = fastRegistry.getByType;
|
|
2362
2440
|
|
|
2363
2441
|
const shadowRoots = new WeakMap();
|
|
2364
2442
|
const defaultEventOptions = {
|
|
@@ -3434,7 +3512,10 @@ class ArrayObserver extends SubscriberSet {
|
|
|
3434
3512
|
this.splices = void 0;
|
|
3435
3513
|
this.needsQueue = true;
|
|
3436
3514
|
this.call = this.flush;
|
|
3437
|
-
source
|
|
3515
|
+
Reflect.defineProperty(source, "$fastController", {
|
|
3516
|
+
value: this,
|
|
3517
|
+
enumerable: false
|
|
3518
|
+
});
|
|
3438
3519
|
}
|
|
3439
3520
|
|
|
3440
3521
|
addSplice(splice) {
|
|
@@ -3505,7 +3586,10 @@ function enableArrayObservation() {
|
|
|
3505
3586
|
return;
|
|
3506
3587
|
}
|
|
3507
3588
|
|
|
3508
|
-
proto
|
|
3589
|
+
Reflect.defineProperty(proto, "$fastPatch", {
|
|
3590
|
+
value: 1,
|
|
3591
|
+
enumerable: false
|
|
3592
|
+
});
|
|
3509
3593
|
const pop = proto.pop;
|
|
3510
3594
|
const push = proto.push;
|
|
3511
3595
|
const reverse = proto.reverse;
|
|
@@ -4157,4 +4241,4 @@ function children(propertyOrOptions) {
|
|
|
4157
4241
|
return new AttachedBehaviorHTMLDirective("fast-children", ChildrenBehavior, propertyOrOptions);
|
|
4158
4242
|
}
|
|
4159
4243
|
|
|
4160
|
-
export { $global, AttachedBehaviorHTMLDirective, AttributeDefinition, BindingBehavior, CSSDirective, ChildrenBehavior, Controller, DOM, ElementStyles, ExecutionContext, FASTElement, FASTElementDefinition, HTMLBindingDirective, HTMLDirective, HTMLView, Observable, PropertyChangeNotifier, RefBehavior, RepeatBehavior, RepeatDirective, SlottedBehavior, SubscriberSet, TargetedHTMLDirective, ViewTemplate, attr, booleanConverter, children, compileTemplate, css, cssPartial, customElement, defaultExecutionContext, elements, emptyArray, enableArrayObservation, html, nullableNumberConverter, observable, ref, repeat,
|
|
4244
|
+
export { $global, AttachedBehaviorHTMLDirective, AttributeDefinition, BindingBehavior, CSSDirective, ChildrenBehavior, Controller, DOM, ElementStyles, ExecutionContext, FAST, FASTElement, FASTElementDefinition, HTMLBindingDirective, HTMLDirective, HTMLView, Observable, PropertyChangeNotifier, RefBehavior, RepeatBehavior, RepeatDirective, SlottedBehavior, SubscriberSet, TargetedHTMLDirective, ViewTemplate, attr, booleanConverter, children, compileTemplate, css, cssPartial, customElement, defaultExecutionContext, elements, emptyArray, enableArrayObservation, html, nullableNumberConverter, observable, ref, repeat, slotted, volatile, when };
|