@microsoft/fast-element 2.0.0-beta.6 → 2.0.0-beta.8
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 +78 -0
- package/CHANGELOG.md +25 -1
- package/dist/dts/components/attributes.d.ts +10 -0
- package/dist/dts/components/{controller.d.ts → element-controller.d.ts} +24 -25
- package/dist/dts/components/fast-definitions.d.ts +28 -3
- package/dist/dts/components/fast-element.d.ts +2 -2
- package/dist/dts/di/di.d.ts +41 -0
- package/dist/dts/index.d.ts +2 -2
- package/dist/dts/observation/observable.d.ts +86 -47
- package/dist/dts/pending-task.d.ts +20 -0
- package/dist/dts/platform.d.ts +6 -0
- package/dist/dts/styles/css-directive.d.ts +2 -2
- package/dist/dts/styles/element-styles.d.ts +3 -3
- package/dist/dts/styles/host.d.ts +68 -0
- package/dist/dts/templating/binding-signal.d.ts +2 -2
- package/dist/dts/templating/binding-two-way.d.ts +11 -3
- package/dist/dts/templating/binding.d.ts +21 -119
- package/dist/dts/templating/children.d.ts +1 -1
- package/dist/dts/templating/html-directive.d.ts +69 -39
- package/dist/dts/templating/node-observation.d.ts +4 -5
- package/dist/dts/templating/ref.d.ts +5 -13
- package/dist/dts/templating/render.d.ts +15 -20
- package/dist/dts/templating/repeat.d.ts +11 -16
- package/dist/dts/templating/slotted.d.ts +1 -1
- package/dist/dts/templating/template.d.ts +4 -4
- package/dist/dts/templating/view.d.ts +68 -9
- package/dist/dts/templating/when.d.ts +1 -1
- package/dist/dts/testing/exports.d.ts +1 -0
- package/dist/dts/testing/fakes.d.ts +4 -0
- package/dist/dts/testing/fixture.d.ts +0 -6
- package/dist/esm/components/attributes.js +13 -4
- package/dist/esm/components/{controller.js → element-controller.js} +95 -105
- package/dist/esm/components/fast-definitions.js +3 -1
- package/dist/esm/components/fast-element.js +4 -4
- package/dist/esm/di/di.js +87 -3
- package/dist/esm/index.js +2 -1
- package/dist/esm/observation/observable.js +59 -126
- package/dist/esm/pending-task.js +16 -0
- package/dist/esm/platform.js +24 -0
- package/dist/esm/styles/css.js +4 -4
- package/dist/esm/{observation/behavior.js → styles/host.js} +0 -0
- package/dist/esm/templating/binding-signal.js +21 -17
- package/dist/esm/templating/binding-two-way.js +32 -27
- package/dist/esm/templating/binding.js +73 -177
- package/dist/esm/templating/html-directive.js +78 -7
- package/dist/esm/templating/node-observation.js +9 -8
- package/dist/esm/templating/ref.js +4 -12
- package/dist/esm/templating/render.js +30 -31
- package/dist/esm/templating/repeat.js +37 -38
- package/dist/esm/templating/template.js +3 -4
- package/dist/esm/templating/view.js +98 -29
- package/dist/esm/testing/exports.js +1 -0
- package/dist/esm/testing/fakes.js +76 -0
- package/dist/esm/testing/fixture.js +1 -3
- package/dist/fast-element.api.json +5720 -5385
- package/dist/fast-element.d.ts +510 -399
- package/dist/fast-element.debug.js +497 -514
- package/dist/fast-element.debug.min.js +1 -1
- package/dist/fast-element.js +497 -514
- package/dist/fast-element.min.js +1 -1
- package/dist/fast-element.untrimmed.d.ts +519 -405
- package/docs/api-report.md +197 -129
- package/package.json +5 -1
- package/dist/dts/observation/behavior.d.ts +0 -19
package/dist/fast-element.js
CHANGED
|
@@ -143,10 +143,34 @@ function createTypeRegistry() {
|
|
|
143
143
|
return typeToDefinition.get(key);
|
|
144
144
|
},
|
|
145
145
|
getForInstance(object) {
|
|
146
|
+
if (object === null || object === void 0) {
|
|
147
|
+
return void 0;
|
|
148
|
+
}
|
|
146
149
|
return typeToDefinition.get(object.constructor);
|
|
147
150
|
},
|
|
148
151
|
});
|
|
149
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Creates a function capable of locating metadata associated with a type.
|
|
155
|
+
* @returns A metadata locator function.
|
|
156
|
+
* @internal
|
|
157
|
+
*/
|
|
158
|
+
function createMetadataLocator() {
|
|
159
|
+
const metadataLookup = new WeakMap();
|
|
160
|
+
return function (target) {
|
|
161
|
+
let metadata = metadataLookup.get(target);
|
|
162
|
+
if (metadata === void 0) {
|
|
163
|
+
let currentTarget = Reflect.getPrototypeOf(target);
|
|
164
|
+
while (metadata === void 0 && currentTarget !== null) {
|
|
165
|
+
metadata = metadataLookup.get(currentTarget);
|
|
166
|
+
currentTarget = Reflect.getPrototypeOf(currentTarget);
|
|
167
|
+
}
|
|
168
|
+
metadata = metadata === void 0 ? [] : metadata.slice(0);
|
|
169
|
+
metadataLookup.set(target, metadata);
|
|
170
|
+
}
|
|
171
|
+
return metadata;
|
|
172
|
+
};
|
|
173
|
+
}
|
|
150
174
|
|
|
151
175
|
/**
|
|
152
176
|
* @internal
|
|
@@ -388,6 +412,21 @@ class PropertyChangeNotifier {
|
|
|
388
412
|
}
|
|
389
413
|
}
|
|
390
414
|
|
|
415
|
+
/**
|
|
416
|
+
* Describes how the source's lifetime relates to its controller's lifetime.
|
|
417
|
+
* @public
|
|
418
|
+
*/
|
|
419
|
+
const SourceLifetime = Object.freeze({
|
|
420
|
+
/**
|
|
421
|
+
* The source to controller lifetime relationship is unknown.
|
|
422
|
+
*/
|
|
423
|
+
unknown: void 0,
|
|
424
|
+
/**
|
|
425
|
+
* The source and controller lifetimes are coupled to one another.
|
|
426
|
+
* They can/will be GC'd together.
|
|
427
|
+
*/
|
|
428
|
+
coupled: 1,
|
|
429
|
+
});
|
|
391
430
|
/**
|
|
392
431
|
* Common Observable APIs.
|
|
393
432
|
* @public
|
|
@@ -396,7 +435,6 @@ const Observable = FAST.getById(2 /* KernelServiceId.observable */, () => {
|
|
|
396
435
|
const queueUpdate = Updates.enqueue;
|
|
397
436
|
const volatileRegex = /(:|&&|\|\||if)/;
|
|
398
437
|
const notifierLookup = new WeakMap();
|
|
399
|
-
const accessorLookup = new WeakMap();
|
|
400
438
|
let watcher = void 0;
|
|
401
439
|
let createArrayObserver = (array) => {
|
|
402
440
|
throw FAST.error(1101 /* Message.needsArrayObservation */);
|
|
@@ -411,19 +449,7 @@ const Observable = FAST.getById(2 /* KernelServiceId.observable */, () => {
|
|
|
411
449
|
}
|
|
412
450
|
return found;
|
|
413
451
|
}
|
|
414
|
-
|
|
415
|
-
let accessors = accessorLookup.get(target);
|
|
416
|
-
if (accessors === void 0) {
|
|
417
|
-
let currentTarget = Reflect.getPrototypeOf(target);
|
|
418
|
-
while (accessors === void 0 && currentTarget !== null) {
|
|
419
|
-
accessors = accessorLookup.get(currentTarget);
|
|
420
|
-
currentTarget = Reflect.getPrototypeOf(currentTarget);
|
|
421
|
-
}
|
|
422
|
-
accessors = accessors === void 0 ? [] : accessors.slice(0);
|
|
423
|
-
accessorLookup.set(target, accessors);
|
|
424
|
-
}
|
|
425
|
-
return accessors;
|
|
426
|
-
}
|
|
452
|
+
const getAccessors = createMetadataLocator();
|
|
427
453
|
class DefaultObservableAccessor {
|
|
428
454
|
constructor(name) {
|
|
429
455
|
this.name = name;
|
|
@@ -467,6 +493,22 @@ const Observable = FAST.getById(2 /* KernelServiceId.observable */, () => {
|
|
|
467
493
|
setMode(isAsync) {
|
|
468
494
|
this.isAsync = this.needsQueue = isAsync;
|
|
469
495
|
}
|
|
496
|
+
bind(controller) {
|
|
497
|
+
this.controller = controller;
|
|
498
|
+
const value = this.observe(controller.source, controller.context);
|
|
499
|
+
if (!controller.isBound && this.requiresUnbind(controller)) {
|
|
500
|
+
controller.onUnbind(this);
|
|
501
|
+
}
|
|
502
|
+
return value;
|
|
503
|
+
}
|
|
504
|
+
requiresUnbind(controller) {
|
|
505
|
+
return (controller.sourceLifetime !== SourceLifetime.coupled ||
|
|
506
|
+
this.first !== this.last ||
|
|
507
|
+
this.first.propertySource !== controller.source);
|
|
508
|
+
}
|
|
509
|
+
unbind(controller) {
|
|
510
|
+
this.dispose();
|
|
511
|
+
}
|
|
470
512
|
observe(source, context) {
|
|
471
513
|
if (this.needsRefresh && this.last !== null) {
|
|
472
514
|
this.dispose();
|
|
@@ -476,7 +518,7 @@ const Observable = FAST.getById(2 /* KernelServiceId.observable */, () => {
|
|
|
476
518
|
this.needsRefresh = this.isVolatileBinding;
|
|
477
519
|
let result;
|
|
478
520
|
try {
|
|
479
|
-
result = this.binding(source, context
|
|
521
|
+
result = this.binding(source, context);
|
|
480
522
|
}
|
|
481
523
|
finally {
|
|
482
524
|
watcher = previousWatcher;
|
|
@@ -667,123 +709,38 @@ const contextEvent = FAST.getById(3 /* KernelServiceId.contextEvent */, () => {
|
|
|
667
709
|
* Provides additional contextual information available to behaviors and expressions.
|
|
668
710
|
* @public
|
|
669
711
|
*/
|
|
670
|
-
|
|
671
|
-
constructor(parentSource = null, parentContext = null) {
|
|
672
|
-
/**
|
|
673
|
-
* The index of the current item within a repeat context.
|
|
674
|
-
*/
|
|
675
|
-
this.index = 0;
|
|
676
|
-
/**
|
|
677
|
-
* The length of the current collection within a repeat context.
|
|
678
|
-
*/
|
|
679
|
-
this.length = 0;
|
|
680
|
-
this.parent = parentSource;
|
|
681
|
-
this.parentContext = parentContext;
|
|
682
|
-
}
|
|
712
|
+
const ExecutionContext = Object.freeze({
|
|
683
713
|
/**
|
|
684
|
-
*
|
|
714
|
+
* A default execution context.
|
|
685
715
|
*/
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
*/
|
|
700
|
-
get isOdd() {
|
|
701
|
-
return this.index % 2 !== 0;
|
|
702
|
-
}
|
|
703
|
-
/**
|
|
704
|
-
* Indicates whether the current item within a repeat context
|
|
705
|
-
* is the first item in the collection.
|
|
706
|
-
*/
|
|
707
|
-
get isFirst() {
|
|
708
|
-
return this.index === 0;
|
|
709
|
-
}
|
|
710
|
-
/**
|
|
711
|
-
* Indicates whether the current item within a repeat context
|
|
712
|
-
* is somewhere in the middle of the collection.
|
|
713
|
-
*/
|
|
714
|
-
get isInMiddle() {
|
|
715
|
-
return !this.isFirst && !this.isLast;
|
|
716
|
-
}
|
|
717
|
-
/**
|
|
718
|
-
* Indicates whether the current item within a repeat context
|
|
719
|
-
* is the last item in the collection.
|
|
720
|
-
*/
|
|
721
|
-
get isLast() {
|
|
722
|
-
return this.index === this.length - 1;
|
|
723
|
-
}
|
|
724
|
-
/**
|
|
725
|
-
* Returns the typed event detail of a custom event.
|
|
726
|
-
*/
|
|
727
|
-
eventDetail() {
|
|
728
|
-
return this.event.detail;
|
|
729
|
-
}
|
|
730
|
-
/**
|
|
731
|
-
* Returns the typed event target of the event.
|
|
732
|
-
*/
|
|
733
|
-
eventTarget() {
|
|
734
|
-
return this.event.target;
|
|
735
|
-
}
|
|
736
|
-
/**
|
|
737
|
-
* Updates the position/size on a context associated with a list item.
|
|
738
|
-
* @param index - The new index of the item.
|
|
739
|
-
* @param length - The new length of the list.
|
|
740
|
-
*/
|
|
741
|
-
updatePosition(index, length) {
|
|
742
|
-
this.index = index;
|
|
743
|
-
this.length = length;
|
|
744
|
-
}
|
|
745
|
-
/**
|
|
746
|
-
* Creates a new execution context descendent from the current context.
|
|
747
|
-
* @param source - The source for the context if different than the parent.
|
|
748
|
-
* @returns A child execution context.
|
|
749
|
-
*/
|
|
750
|
-
createChildContext(parentSource) {
|
|
751
|
-
return new ExecutionContext(parentSource, this);
|
|
752
|
-
}
|
|
716
|
+
default: {
|
|
717
|
+
index: 0,
|
|
718
|
+
length: 0,
|
|
719
|
+
get event() {
|
|
720
|
+
return ExecutionContext.getEvent();
|
|
721
|
+
},
|
|
722
|
+
eventDetail() {
|
|
723
|
+
return this.event.detail;
|
|
724
|
+
},
|
|
725
|
+
eventTarget() {
|
|
726
|
+
return this.event.target;
|
|
727
|
+
},
|
|
728
|
+
},
|
|
753
729
|
/**
|
|
754
|
-
*
|
|
755
|
-
* @
|
|
756
|
-
* @param index - The index of the item in the list.
|
|
757
|
-
* @param length - The length of the list.
|
|
730
|
+
* Gets the current event.
|
|
731
|
+
* @returns An event object.
|
|
758
732
|
*/
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
childContext.length = length;
|
|
763
|
-
return childContext;
|
|
764
|
-
}
|
|
733
|
+
getEvent() {
|
|
734
|
+
return contextEvent.get();
|
|
735
|
+
},
|
|
765
736
|
/**
|
|
766
|
-
* Sets the
|
|
767
|
-
* @param event -
|
|
768
|
-
* @internal
|
|
737
|
+
* Sets the current event.
|
|
738
|
+
* @param event - An event object.
|
|
769
739
|
*/
|
|
770
|
-
|
|
740
|
+
setEvent(event) {
|
|
771
741
|
contextEvent.set(event);
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
* Creates a new root execution context.
|
|
775
|
-
* @returns A new execution context.
|
|
776
|
-
*/
|
|
777
|
-
static create() {
|
|
778
|
-
return new ExecutionContext();
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
/**
|
|
782
|
-
* The default execution context.
|
|
783
|
-
*/
|
|
784
|
-
ExecutionContext.default = new ExecutionContext();
|
|
785
|
-
Observable.defineProperty(ExecutionContext.prototype, "index");
|
|
786
|
-
Observable.defineProperty(ExecutionContext.prototype, "length");
|
|
742
|
+
},
|
|
743
|
+
});
|
|
787
744
|
|
|
788
745
|
/**
|
|
789
746
|
* A splice map is a representation of how a previous array of items
|
|
@@ -1581,11 +1538,11 @@ class CSSPartial {
|
|
|
1581
1538
|
}
|
|
1582
1539
|
return this.css;
|
|
1583
1540
|
}
|
|
1584
|
-
|
|
1585
|
-
|
|
1541
|
+
addedCallback(controller) {
|
|
1542
|
+
controller.addStyles(this.styles);
|
|
1586
1543
|
}
|
|
1587
|
-
|
|
1588
|
-
|
|
1544
|
+
removedCallback(controller) {
|
|
1545
|
+
controller.removeStyles(this.styles);
|
|
1589
1546
|
}
|
|
1590
1547
|
}
|
|
1591
1548
|
CSSDirective.define(CSSPartial);
|
|
@@ -1724,6 +1681,67 @@ const Parser = Object.freeze({
|
|
|
1724
1681
|
},
|
|
1725
1682
|
});
|
|
1726
1683
|
|
|
1684
|
+
/**
|
|
1685
|
+
* Bridges between ViewBehaviors and HostBehaviors, enabling a host to
|
|
1686
|
+
* control ViewBehaviors.
|
|
1687
|
+
* @public
|
|
1688
|
+
*/
|
|
1689
|
+
const ViewBehaviorOrchestrator = Object.freeze({
|
|
1690
|
+
/**
|
|
1691
|
+
* Creates a ViewBehaviorOrchestrator.
|
|
1692
|
+
* @param source - The source to to associate behaviors with.
|
|
1693
|
+
* @returns A ViewBehaviorOrchestrator.
|
|
1694
|
+
*/
|
|
1695
|
+
create(source) {
|
|
1696
|
+
const behaviors = [];
|
|
1697
|
+
const targets = {};
|
|
1698
|
+
let unbindables = null;
|
|
1699
|
+
let isConnected = false;
|
|
1700
|
+
return {
|
|
1701
|
+
source,
|
|
1702
|
+
context: ExecutionContext.default,
|
|
1703
|
+
targets,
|
|
1704
|
+
get isBound() {
|
|
1705
|
+
return isConnected;
|
|
1706
|
+
},
|
|
1707
|
+
addBehaviorFactory(factory, target) {
|
|
1708
|
+
const nodeId = factory.nodeId || (factory.nodeId = nextId());
|
|
1709
|
+
factory.id || (factory.id = nextId());
|
|
1710
|
+
this.addTarget(nodeId, target);
|
|
1711
|
+
this.addBehavior(factory.createBehavior());
|
|
1712
|
+
},
|
|
1713
|
+
addTarget(nodeId, target) {
|
|
1714
|
+
targets[nodeId] = target;
|
|
1715
|
+
},
|
|
1716
|
+
addBehavior(behavior) {
|
|
1717
|
+
behaviors.push(behavior);
|
|
1718
|
+
if (isConnected) {
|
|
1719
|
+
behavior.bind(this);
|
|
1720
|
+
}
|
|
1721
|
+
},
|
|
1722
|
+
onUnbind(unbindable) {
|
|
1723
|
+
if (unbindables === null) {
|
|
1724
|
+
unbindables = [];
|
|
1725
|
+
}
|
|
1726
|
+
unbindables.push(unbindable);
|
|
1727
|
+
},
|
|
1728
|
+
connectedCallback(controller) {
|
|
1729
|
+
if (!isConnected) {
|
|
1730
|
+
isConnected = true;
|
|
1731
|
+
behaviors.forEach(x => x.bind(this));
|
|
1732
|
+
}
|
|
1733
|
+
},
|
|
1734
|
+
disconnectedCallback(controller) {
|
|
1735
|
+
if (isConnected) {
|
|
1736
|
+
isConnected = false;
|
|
1737
|
+
if (unbindables !== null) {
|
|
1738
|
+
unbindables.forEach(x => x.unbind(this));
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
},
|
|
1742
|
+
};
|
|
1743
|
+
},
|
|
1744
|
+
});
|
|
1727
1745
|
const registry = createTypeRegistry();
|
|
1728
1746
|
/**
|
|
1729
1747
|
* Instructs the template engine to apply behavior to a node.
|
|
@@ -1769,6 +1787,15 @@ function htmlDirective(options) {
|
|
|
1769
1787
|
* @public
|
|
1770
1788
|
*/
|
|
1771
1789
|
class Binding {
|
|
1790
|
+
/**
|
|
1791
|
+
* Creates a binding.
|
|
1792
|
+
* @param evaluate - Evaluates the binding.
|
|
1793
|
+
* @param isVolatile - Indicates whether the binding is volatile.
|
|
1794
|
+
*/
|
|
1795
|
+
constructor(evaluate, isVolatile = false) {
|
|
1796
|
+
this.evaluate = evaluate;
|
|
1797
|
+
this.isVolatile = isVolatile;
|
|
1798
|
+
}
|
|
1772
1799
|
}
|
|
1773
1800
|
/**
|
|
1774
1801
|
* The type of HTML aspect to target.
|
|
@@ -1868,13 +1895,6 @@ class StatelessAttachedAttributeDirective {
|
|
|
1868
1895
|
*/
|
|
1869
1896
|
this.id = nextId();
|
|
1870
1897
|
}
|
|
1871
|
-
/**
|
|
1872
|
-
* Creates a behavior.
|
|
1873
|
-
* @param targets - The targets available for behaviors to be attached to.
|
|
1874
|
-
*/
|
|
1875
|
-
createBehavior(targets) {
|
|
1876
|
-
return this;
|
|
1877
|
-
}
|
|
1878
1898
|
/**
|
|
1879
1899
|
* Creates a placeholder string based on the directive's index within the template.
|
|
1880
1900
|
* @param index - The index of the directive within the template.
|
|
@@ -1884,6 +1904,13 @@ class StatelessAttachedAttributeDirective {
|
|
|
1884
1904
|
createHTML(add) {
|
|
1885
1905
|
return Markup.attribute(add(this));
|
|
1886
1906
|
}
|
|
1907
|
+
/**
|
|
1908
|
+
* Creates a behavior.
|
|
1909
|
+
* @param targets - The targets available for behaviors to be attached to.
|
|
1910
|
+
*/
|
|
1911
|
+
createBehavior() {
|
|
1912
|
+
return this;
|
|
1913
|
+
}
|
|
1887
1914
|
}
|
|
1888
1915
|
|
|
1889
1916
|
const createInnerHTMLBinding = globalThis.TrustedHTML
|
|
@@ -1896,29 +1923,19 @@ const createInnerHTMLBinding = globalThis.TrustedHTML
|
|
|
1896
1923
|
}
|
|
1897
1924
|
: (binding) => binding;
|
|
1898
1925
|
class OnChangeBinding extends Binding {
|
|
1899
|
-
constructor(evaluate, isVolatile) {
|
|
1900
|
-
super();
|
|
1901
|
-
this.evaluate = evaluate;
|
|
1902
|
-
this.isVolatile = isVolatile;
|
|
1903
|
-
}
|
|
1904
1926
|
createObserver(_, subscriber) {
|
|
1905
1927
|
return Observable.binding(this.evaluate, subscriber, this.isVolatile);
|
|
1906
1928
|
}
|
|
1907
1929
|
}
|
|
1908
1930
|
class OneTimeBinding extends Binding {
|
|
1909
|
-
constructor(evaluate) {
|
|
1910
|
-
super();
|
|
1911
|
-
this.evaluate = evaluate;
|
|
1912
|
-
}
|
|
1913
1931
|
createObserver() {
|
|
1914
1932
|
return this;
|
|
1915
1933
|
}
|
|
1916
|
-
|
|
1917
|
-
return this.evaluate(source, context);
|
|
1934
|
+
bind(controller) {
|
|
1935
|
+
return this.evaluate(controller.source, controller.context);
|
|
1918
1936
|
}
|
|
1919
|
-
dispose() { }
|
|
1920
1937
|
}
|
|
1921
|
-
function
|
|
1938
|
+
function updateContent(target, aspect, value, controller) {
|
|
1922
1939
|
// If there's no actual value, then this equates to the
|
|
1923
1940
|
// empty string for the purposes of content bindings.
|
|
1924
1941
|
if (value === null || value === undefined) {
|
|
@@ -1950,14 +1967,14 @@ function updateContentTarget(target, aspect, value, source, context) {
|
|
|
1950
1967
|
// and that there's actually no need to compose it.
|
|
1951
1968
|
if (!view.isComposed) {
|
|
1952
1969
|
view.isComposed = true;
|
|
1953
|
-
view.bind(source
|
|
1970
|
+
view.bind(controller.source);
|
|
1954
1971
|
view.insertBefore(target);
|
|
1955
1972
|
target.$fastView = view;
|
|
1956
1973
|
target.$fastTemplate = value;
|
|
1957
1974
|
}
|
|
1958
1975
|
else if (view.needsBindOnly) {
|
|
1959
1976
|
view.needsBindOnly = false;
|
|
1960
|
-
view.bind(source
|
|
1977
|
+
view.bind(controller.source);
|
|
1961
1978
|
}
|
|
1962
1979
|
}
|
|
1963
1980
|
else {
|
|
@@ -1977,10 +1994,9 @@ function updateContentTarget(target, aspect, value, source, context) {
|
|
|
1977
1994
|
target.textContent = value;
|
|
1978
1995
|
}
|
|
1979
1996
|
}
|
|
1980
|
-
function
|
|
1997
|
+
function updateTokenList(target, aspect, value) {
|
|
1981
1998
|
var _a;
|
|
1982
|
-
const
|
|
1983
|
-
const lookup = `${directive.id}-t`;
|
|
1999
|
+
const lookup = `${this.id}-t`;
|
|
1984
2000
|
const state = (_a = target[lookup]) !== null && _a !== void 0 ? _a : (target[lookup] = { c: 0, v: Object.create(null) });
|
|
1985
2001
|
const versions = state.v;
|
|
1986
2002
|
let currentVersion = state.c;
|
|
@@ -2010,154 +2026,8 @@ function updateTokenListTarget(target, aspect, value) {
|
|
|
2010
2026
|
}
|
|
2011
2027
|
}
|
|
2012
2028
|
}
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
* @public
|
|
2016
|
-
*/
|
|
2017
|
-
class BindingBehavior {
|
|
2018
|
-
/**
|
|
2019
|
-
* Creates an instance of ChangeBinding.
|
|
2020
|
-
* @param directive - The directive that has the configuration for this behavior.
|
|
2021
|
-
* @param updateTarget - The function used to update the target with the latest value.
|
|
2022
|
-
*/
|
|
2023
|
-
constructor(directive, updateTarget) {
|
|
2024
|
-
this.directive = directive;
|
|
2025
|
-
this.updateTarget = updateTarget;
|
|
2026
|
-
this.observerProperty = `${directive.id}-o`;
|
|
2027
|
-
}
|
|
2028
|
-
/**
|
|
2029
|
-
* Bind this behavior to the source.
|
|
2030
|
-
* @param source - The source to bind to.
|
|
2031
|
-
* @param context - The execution context that the binding is operating within.
|
|
2032
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
2033
|
-
*/
|
|
2034
|
-
bind(source, context, targets) {
|
|
2035
|
-
const directive = this.directive;
|
|
2036
|
-
const target = targets[directive.nodeId];
|
|
2037
|
-
const observer = this.getObserver(target);
|
|
2038
|
-
observer.target = target;
|
|
2039
|
-
observer.source = source;
|
|
2040
|
-
observer.context = context;
|
|
2041
|
-
this.updateTarget(target, directive.targetAspect, observer.observe(source, context), source, context);
|
|
2042
|
-
}
|
|
2043
|
-
/**
|
|
2044
|
-
* Unbinds this behavior from the source.
|
|
2045
|
-
* @param source - The source to unbind from.
|
|
2046
|
-
* @param context - The execution context that the binding is operating within.
|
|
2047
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
2048
|
-
*/
|
|
2049
|
-
unbind(source, context, targets) {
|
|
2050
|
-
const target = targets[this.directive.nodeId];
|
|
2051
|
-
const observer = this.getObserver(target);
|
|
2052
|
-
observer.dispose();
|
|
2053
|
-
observer.target = null;
|
|
2054
|
-
observer.source = null;
|
|
2055
|
-
observer.context = null;
|
|
2056
|
-
}
|
|
2057
|
-
/** @internal */
|
|
2058
|
-
handleChange(binding, observer) {
|
|
2059
|
-
const target = observer.target;
|
|
2060
|
-
const source = observer.source;
|
|
2061
|
-
const context = observer.context;
|
|
2062
|
-
this.updateTarget(target, this.directive.targetAspect, observer.observe(source, context), source, context);
|
|
2063
|
-
}
|
|
2064
|
-
/**
|
|
2065
|
-
* Returns the binding observer used to update the node.
|
|
2066
|
-
* @param target - The target node.
|
|
2067
|
-
* @returns A BindingObserver.
|
|
2068
|
-
*/
|
|
2069
|
-
getObserver(target) {
|
|
2070
|
-
var _a;
|
|
2071
|
-
return ((_a = target[this.observerProperty]) !== null && _a !== void 0 ? _a : (target[this.observerProperty] = this.directive.dataBinding.createObserver(this.directive, this)));
|
|
2072
|
-
}
|
|
2073
|
-
/**
|
|
2074
|
-
* Creates a behavior.
|
|
2075
|
-
* @param targets - The targets available for behaviors to be attached to.
|
|
2076
|
-
*/
|
|
2077
|
-
createBehavior(targets) {
|
|
2078
|
-
return this;
|
|
2079
|
-
}
|
|
2080
|
-
}
|
|
2081
|
-
/**
|
|
2082
|
-
* A special binding behavior that can bind node content.
|
|
2083
|
-
* @public
|
|
2084
|
-
*/
|
|
2085
|
-
class ContentBehavior extends BindingBehavior {
|
|
2086
|
-
/**
|
|
2087
|
-
* Unbinds this behavior from the source.
|
|
2088
|
-
* @param source - The source to unbind from.
|
|
2089
|
-
* @param context - The execution context that the binding is operating within.
|
|
2090
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
2091
|
-
*/
|
|
2092
|
-
unbind(source, context, targets) {
|
|
2093
|
-
super.unbind(source, context, targets);
|
|
2094
|
-
const target = targets[this.directive.nodeId];
|
|
2095
|
-
const view = target.$fastView;
|
|
2096
|
-
if (view !== void 0 && view.isComposed) {
|
|
2097
|
-
view.unbind();
|
|
2098
|
-
view.needsBindOnly = true;
|
|
2099
|
-
}
|
|
2100
|
-
}
|
|
2101
|
-
}
|
|
2102
|
-
/**
|
|
2103
|
-
* A binding behavior for handling events.
|
|
2104
|
-
* @public
|
|
2105
|
-
*/
|
|
2106
|
-
class EventBehavior {
|
|
2107
|
-
/**
|
|
2108
|
-
* Creates an instance of EventBinding.
|
|
2109
|
-
* @param directive - The directive that has the configuration for this behavior.
|
|
2110
|
-
*/
|
|
2111
|
-
constructor(directive) {
|
|
2112
|
-
this.directive = directive;
|
|
2113
|
-
this.sourceProperty = `${directive.id}-s`;
|
|
2114
|
-
this.contextProperty = `${directive.id}-c`;
|
|
2115
|
-
}
|
|
2116
|
-
/**
|
|
2117
|
-
* Bind this behavior to the source.
|
|
2118
|
-
* @param source - The source to bind to.
|
|
2119
|
-
* @param context - The execution context that the binding is operating within.
|
|
2120
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
2121
|
-
*/
|
|
2122
|
-
bind(source, context, targets) {
|
|
2123
|
-
const directive = this.directive;
|
|
2124
|
-
const target = targets[directive.nodeId];
|
|
2125
|
-
target[this.sourceProperty] = source;
|
|
2126
|
-
target[this.contextProperty] = context;
|
|
2127
|
-
target.addEventListener(directive.targetAspect, this, directive.dataBinding.options);
|
|
2128
|
-
}
|
|
2129
|
-
/**
|
|
2130
|
-
* Unbinds this behavior from the source.
|
|
2131
|
-
* @param source - The source to unbind from.
|
|
2132
|
-
* @param context - The execution context that the binding is operating within.
|
|
2133
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
2134
|
-
*/
|
|
2135
|
-
unbind(source, context, targets) {
|
|
2136
|
-
const directive = this.directive;
|
|
2137
|
-
const target = targets[directive.nodeId];
|
|
2138
|
-
target[this.sourceProperty] = target[this.contextProperty] = null;
|
|
2139
|
-
target.removeEventListener(directive.targetAspect, this, directive.dataBinding.options);
|
|
2140
|
-
}
|
|
2141
|
-
/**
|
|
2142
|
-
* Creates a behavior.
|
|
2143
|
-
* @param targets - The targets available for behaviors to be attached to.
|
|
2144
|
-
*/
|
|
2145
|
-
createBehavior(targets) {
|
|
2146
|
-
return this;
|
|
2147
|
-
}
|
|
2148
|
-
/**
|
|
2149
|
-
* @internal
|
|
2150
|
-
*/
|
|
2151
|
-
handleEvent(event) {
|
|
2152
|
-
const target = event.currentTarget;
|
|
2153
|
-
ExecutionContext.setEvent(event);
|
|
2154
|
-
const result = this.directive.dataBinding.evaluate(target[this.sourceProperty], target[this.contextProperty]);
|
|
2155
|
-
ExecutionContext.setEvent(null);
|
|
2156
|
-
if (result !== true) {
|
|
2157
|
-
event.preventDefault();
|
|
2158
|
-
}
|
|
2159
|
-
}
|
|
2160
|
-
}
|
|
2029
|
+
const setProperty = (t, a, v) => (t[a] = v);
|
|
2030
|
+
const eventTarget = () => void 0;
|
|
2161
2031
|
/**
|
|
2162
2032
|
* A directive that applies bindings.
|
|
2163
2033
|
* @public
|
|
@@ -2169,7 +2039,7 @@ class HTMLBindingDirective {
|
|
|
2169
2039
|
*/
|
|
2170
2040
|
constructor(dataBinding) {
|
|
2171
2041
|
this.dataBinding = dataBinding;
|
|
2172
|
-
this.
|
|
2042
|
+
this.updateTarget = null;
|
|
2173
2043
|
/**
|
|
2174
2044
|
* The unique id of the factory.
|
|
2175
2045
|
*/
|
|
@@ -2178,6 +2048,9 @@ class HTMLBindingDirective {
|
|
|
2178
2048
|
* The type of aspect to target.
|
|
2179
2049
|
*/
|
|
2180
2050
|
this.aspectType = Aspect.content;
|
|
2051
|
+
/** @internal */
|
|
2052
|
+
this.bind = this.bindDefault;
|
|
2053
|
+
this.data = `${this.id}-d`;
|
|
2181
2054
|
}
|
|
2182
2055
|
/**
|
|
2183
2056
|
* Creates HTML to be used within a template.
|
|
@@ -2188,37 +2061,87 @@ class HTMLBindingDirective {
|
|
|
2188
2061
|
}
|
|
2189
2062
|
/**
|
|
2190
2063
|
* Creates a behavior.
|
|
2191
|
-
* @param targets - The targets available for behaviors to be attached to.
|
|
2192
2064
|
*/
|
|
2193
|
-
createBehavior(
|
|
2194
|
-
if (this.
|
|
2065
|
+
createBehavior() {
|
|
2066
|
+
if (this.updateTarget === null) {
|
|
2195
2067
|
if (this.targetAspect === "innerHTML") {
|
|
2196
2068
|
this.dataBinding.evaluate = createInnerHTMLBinding(this.dataBinding.evaluate);
|
|
2197
2069
|
}
|
|
2198
2070
|
switch (this.aspectType) {
|
|
2199
2071
|
case 1:
|
|
2200
|
-
this.
|
|
2072
|
+
this.updateTarget = DOM.setAttribute;
|
|
2201
2073
|
break;
|
|
2202
2074
|
case 2:
|
|
2203
|
-
this.
|
|
2075
|
+
this.updateTarget = DOM.setBooleanAttribute;
|
|
2204
2076
|
break;
|
|
2205
2077
|
case 3:
|
|
2206
|
-
this.
|
|
2078
|
+
this.updateTarget = setProperty;
|
|
2207
2079
|
break;
|
|
2208
2080
|
case 4:
|
|
2209
|
-
this.
|
|
2081
|
+
this.bind = this.bindContent;
|
|
2082
|
+
this.updateTarget = updateContent;
|
|
2210
2083
|
break;
|
|
2211
2084
|
case 5:
|
|
2212
|
-
this.
|
|
2085
|
+
this.updateTarget = updateTokenList;
|
|
2213
2086
|
break;
|
|
2214
2087
|
case 6:
|
|
2215
|
-
this.
|
|
2088
|
+
this.bind = this.bindEvent;
|
|
2089
|
+
this.updateTarget = eventTarget;
|
|
2216
2090
|
break;
|
|
2217
2091
|
default:
|
|
2218
2092
|
throw FAST.error(1205 /* Message.unsupportedBindingBehavior */);
|
|
2219
2093
|
}
|
|
2220
2094
|
}
|
|
2221
|
-
return this
|
|
2095
|
+
return this;
|
|
2096
|
+
}
|
|
2097
|
+
/** @internal */
|
|
2098
|
+
bindDefault(controller) {
|
|
2099
|
+
var _a;
|
|
2100
|
+
const target = controller.targets[this.nodeId];
|
|
2101
|
+
const observer = (_a = target[this.data]) !== null && _a !== void 0 ? _a : (target[this.data] = this.dataBinding.createObserver(this, this));
|
|
2102
|
+
observer.target = target;
|
|
2103
|
+
observer.controller = controller;
|
|
2104
|
+
this.updateTarget(target, this.targetAspect, observer.bind(controller), controller);
|
|
2105
|
+
if (this.updateTarget === updateContent) {
|
|
2106
|
+
controller.onUnbind(this);
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
/** @internal */
|
|
2110
|
+
bindContent(controller) {
|
|
2111
|
+
this.bindDefault(controller);
|
|
2112
|
+
controller.onUnbind(this);
|
|
2113
|
+
}
|
|
2114
|
+
/** @internal */
|
|
2115
|
+
bindEvent(controller) {
|
|
2116
|
+
const target = controller.targets[this.nodeId];
|
|
2117
|
+
target[this.data] = controller;
|
|
2118
|
+
target.addEventListener(this.targetAspect, this, this.dataBinding.options);
|
|
2119
|
+
}
|
|
2120
|
+
/** @internal */
|
|
2121
|
+
unbind(controller) {
|
|
2122
|
+
const target = controller.targets[this.nodeId];
|
|
2123
|
+
const view = target.$fastView;
|
|
2124
|
+
if (view !== void 0 && view.isComposed) {
|
|
2125
|
+
view.unbind();
|
|
2126
|
+
view.needsBindOnly = true;
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
/** @internal */
|
|
2130
|
+
handleEvent(event) {
|
|
2131
|
+
const target = event.currentTarget;
|
|
2132
|
+
ExecutionContext.setEvent(event);
|
|
2133
|
+
const controller = target[this.data];
|
|
2134
|
+
const result = this.dataBinding.evaluate(controller.source, controller.context);
|
|
2135
|
+
ExecutionContext.setEvent(null);
|
|
2136
|
+
if (result !== true) {
|
|
2137
|
+
event.preventDefault();
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
/** @internal */
|
|
2141
|
+
handleChange(binding, observer) {
|
|
2142
|
+
const target = observer.target;
|
|
2143
|
+
const controller = observer.controller;
|
|
2144
|
+
this.updateTarget(target, this.targetAspect, observer.bind(controller), controller);
|
|
2222
2145
|
}
|
|
2223
2146
|
}
|
|
2224
2147
|
HTMLDirective.define(HTMLBindingDirective, { aspected: true });
|
|
@@ -2293,17 +2216,83 @@ class HTMLView {
|
|
|
2293
2216
|
this.factories = factories;
|
|
2294
2217
|
this.targets = targets;
|
|
2295
2218
|
this.behaviors = null;
|
|
2219
|
+
this.unbindables = [];
|
|
2296
2220
|
/**
|
|
2297
2221
|
* The data that the view is bound to.
|
|
2298
2222
|
*/
|
|
2299
2223
|
this.source = null;
|
|
2224
|
+
this.isBound = false;
|
|
2225
|
+
this.selfContained = false;
|
|
2300
2226
|
/**
|
|
2301
|
-
* The
|
|
2227
|
+
* The index of the current item within a repeat context.
|
|
2228
|
+
*/
|
|
2229
|
+
this.index = 0;
|
|
2230
|
+
/**
|
|
2231
|
+
* The length of the current collection within a repeat context.
|
|
2302
2232
|
*/
|
|
2303
|
-
this.
|
|
2233
|
+
this.length = 0;
|
|
2304
2234
|
this.firstChild = fragment.firstChild;
|
|
2305
2235
|
this.lastChild = fragment.lastChild;
|
|
2306
2236
|
}
|
|
2237
|
+
/**
|
|
2238
|
+
* The execution context the view is running within.
|
|
2239
|
+
*/
|
|
2240
|
+
get context() {
|
|
2241
|
+
return this;
|
|
2242
|
+
}
|
|
2243
|
+
/**
|
|
2244
|
+
* The current event within an event handler.
|
|
2245
|
+
*/
|
|
2246
|
+
get event() {
|
|
2247
|
+
return ExecutionContext.getEvent();
|
|
2248
|
+
}
|
|
2249
|
+
/**
|
|
2250
|
+
* Indicates whether the current item within a repeat context
|
|
2251
|
+
* has an even index.
|
|
2252
|
+
*/
|
|
2253
|
+
get isEven() {
|
|
2254
|
+
return this.index % 2 === 0;
|
|
2255
|
+
}
|
|
2256
|
+
/**
|
|
2257
|
+
* Indicates whether the current item within a repeat context
|
|
2258
|
+
* has an odd index.
|
|
2259
|
+
*/
|
|
2260
|
+
get isOdd() {
|
|
2261
|
+
return this.index % 2 !== 0;
|
|
2262
|
+
}
|
|
2263
|
+
/**
|
|
2264
|
+
* Indicates whether the current item within a repeat context
|
|
2265
|
+
* is the first item in the collection.
|
|
2266
|
+
*/
|
|
2267
|
+
get isFirst() {
|
|
2268
|
+
return this.index === 0;
|
|
2269
|
+
}
|
|
2270
|
+
/**
|
|
2271
|
+
* Indicates whether the current item within a repeat context
|
|
2272
|
+
* is somewhere in the middle of the collection.
|
|
2273
|
+
*/
|
|
2274
|
+
get isInMiddle() {
|
|
2275
|
+
return !this.isFirst && !this.isLast;
|
|
2276
|
+
}
|
|
2277
|
+
/**
|
|
2278
|
+
* Indicates whether the current item within a repeat context
|
|
2279
|
+
* is the last item in the collection.
|
|
2280
|
+
*/
|
|
2281
|
+
get isLast() {
|
|
2282
|
+
return this.index === this.length - 1;
|
|
2283
|
+
}
|
|
2284
|
+
/**
|
|
2285
|
+
* Returns the typed event detail of a custom event.
|
|
2286
|
+
*/
|
|
2287
|
+
eventDetail() {
|
|
2288
|
+
return this.event.detail;
|
|
2289
|
+
}
|
|
2290
|
+
/**
|
|
2291
|
+
* Returns the typed event target of the event.
|
|
2292
|
+
*/
|
|
2293
|
+
eventTarget() {
|
|
2294
|
+
return this.event.target;
|
|
2295
|
+
}
|
|
2307
2296
|
/**
|
|
2308
2297
|
* Appends the view's DOM nodes to the referenced node.
|
|
2309
2298
|
* @param node - The parent node to append the view's DOM nodes to.
|
|
@@ -2358,58 +2347,58 @@ class HTMLView {
|
|
|
2358
2347
|
removeNodeSequence(this.firstChild, this.lastChild);
|
|
2359
2348
|
this.unbind();
|
|
2360
2349
|
}
|
|
2350
|
+
onUnbind(behavior) {
|
|
2351
|
+
this.unbindables.push(behavior);
|
|
2352
|
+
}
|
|
2361
2353
|
/**
|
|
2362
2354
|
* Binds a view's behaviors to its binding source.
|
|
2363
2355
|
* @param source - The binding source for the view's binding behaviors.
|
|
2364
2356
|
* @param context - The execution context to run the behaviors within.
|
|
2365
2357
|
*/
|
|
2366
|
-
bind(source
|
|
2367
|
-
|
|
2368
|
-
const oldSource = this.source;
|
|
2369
|
-
if (oldSource === source) {
|
|
2358
|
+
bind(source) {
|
|
2359
|
+
if (this.source === source) {
|
|
2370
2360
|
return;
|
|
2371
2361
|
}
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
if (oldSource !== null) {
|
|
2376
|
-
for (let i = 0, ii = behaviors.length; i < ii; ++i) {
|
|
2377
|
-
const current = behaviors[i];
|
|
2378
|
-
current.unbind(oldSource, context, targets);
|
|
2379
|
-
current.bind(source, context, targets);
|
|
2380
|
-
}
|
|
2381
|
-
}
|
|
2382
|
-
else if (behaviors === null) {
|
|
2362
|
+
let behaviors = this.behaviors;
|
|
2363
|
+
if (behaviors === null) {
|
|
2364
|
+
this.source = source;
|
|
2383
2365
|
this.behaviors = behaviors = new Array(this.factories.length);
|
|
2384
2366
|
const factories = this.factories;
|
|
2385
2367
|
for (let i = 0, ii = factories.length; i < ii; ++i) {
|
|
2386
|
-
const behavior = factories[i].createBehavior(
|
|
2387
|
-
behavior.bind(
|
|
2368
|
+
const behavior = factories[i].createBehavior();
|
|
2369
|
+
behavior.bind(this);
|
|
2388
2370
|
behaviors[i] = behavior;
|
|
2389
2371
|
}
|
|
2390
2372
|
}
|
|
2391
2373
|
else {
|
|
2374
|
+
if (this.source !== null) {
|
|
2375
|
+
this.evaluateUnbindables();
|
|
2376
|
+
}
|
|
2377
|
+
this.isBound = false;
|
|
2378
|
+
this.source = source;
|
|
2392
2379
|
for (let i = 0, ii = behaviors.length; i < ii; ++i) {
|
|
2393
|
-
behaviors[i].bind(
|
|
2380
|
+
behaviors[i].bind(this);
|
|
2394
2381
|
}
|
|
2395
2382
|
}
|
|
2383
|
+
this.isBound = true;
|
|
2396
2384
|
}
|
|
2397
2385
|
/**
|
|
2398
2386
|
* Unbinds a view's behaviors from its binding source.
|
|
2399
2387
|
*/
|
|
2400
2388
|
unbind() {
|
|
2401
|
-
|
|
2402
|
-
if (oldSource === null) {
|
|
2389
|
+
if (!this.isBound || this.source === null) {
|
|
2403
2390
|
return;
|
|
2404
2391
|
}
|
|
2405
|
-
|
|
2406
|
-
const context = this.context;
|
|
2407
|
-
const behaviors = this.behaviors;
|
|
2408
|
-
for (let i = 0, ii = behaviors.length; i < ii; ++i) {
|
|
2409
|
-
behaviors[i].unbind(oldSource, context, targets);
|
|
2410
|
-
}
|
|
2392
|
+
this.evaluateUnbindables();
|
|
2411
2393
|
this.source = null;
|
|
2412
|
-
this.
|
|
2394
|
+
this.isBound = false;
|
|
2395
|
+
}
|
|
2396
|
+
evaluateUnbindables() {
|
|
2397
|
+
const unbindables = this.unbindables;
|
|
2398
|
+
for (let i = 0, ii = unbindables.length; i < ii; ++i) {
|
|
2399
|
+
unbindables[i].unbind(this);
|
|
2400
|
+
}
|
|
2401
|
+
unbindables.length = 0;
|
|
2413
2402
|
}
|
|
2414
2403
|
/**
|
|
2415
2404
|
* Efficiently disposes of a contiguous range of synthetic view instances.
|
|
@@ -2425,6 +2414,8 @@ class HTMLView {
|
|
|
2425
2414
|
}
|
|
2426
2415
|
}
|
|
2427
2416
|
}
|
|
2417
|
+
Observable.defineProperty(HTMLView.prototype, "index");
|
|
2418
|
+
Observable.defineProperty(HTMLView.prototype, "length");
|
|
2428
2419
|
|
|
2429
2420
|
const targetIdFrom = (parentId, nodeIndex) => `${parentId}.${nodeIndex}`;
|
|
2430
2421
|
const descriptorCache = {};
|
|
@@ -2745,9 +2736,9 @@ class ViewTemplate {
|
|
|
2745
2736
|
* @param hostBindingTarget - An HTML element to target the host bindings at if different from the
|
|
2746
2737
|
* host that the template is being attached to.
|
|
2747
2738
|
*/
|
|
2748
|
-
render(source, host, hostBindingTarget
|
|
2749
|
-
const view = this.create(hostBindingTarget
|
|
2750
|
-
view.bind(source
|
|
2739
|
+
render(source, host, hostBindingTarget) {
|
|
2740
|
+
const view = this.create(hostBindingTarget);
|
|
2741
|
+
view.bind(source);
|
|
2751
2742
|
view.appendTo(host);
|
|
2752
2743
|
return view;
|
|
2753
2744
|
}
|
|
@@ -2824,20 +2815,12 @@ function html(strings, ...values) {
|
|
|
2824
2815
|
*/
|
|
2825
2816
|
class RefDirective extends StatelessAttachedAttributeDirective {
|
|
2826
2817
|
/**
|
|
2827
|
-
* Bind this behavior
|
|
2828
|
-
* @param
|
|
2829
|
-
* @param context - The execution context that the binding is operating within.
|
|
2830
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
2818
|
+
* Bind this behavior.
|
|
2819
|
+
* @param controller - The view controller that manages the lifecycle of this behavior.
|
|
2831
2820
|
*/
|
|
2832
|
-
bind(
|
|
2833
|
-
source[this.options] = targets[this.nodeId];
|
|
2821
|
+
bind(controller) {
|
|
2822
|
+
controller.source[this.options] = controller.targets[this.nodeId];
|
|
2834
2823
|
}
|
|
2835
|
-
/**
|
|
2836
|
-
* Unbinds this behavior from the source.
|
|
2837
|
-
* @param source - The source to unbind from.
|
|
2838
|
-
*/
|
|
2839
|
-
/* eslint-disable-next-line @typescript-eslint/no-empty-function */
|
|
2840
|
-
unbind() { }
|
|
2841
2824
|
}
|
|
2842
2825
|
HTMLDirective.define(RefDirective);
|
|
2843
2826
|
/**
|
|
@@ -2866,11 +2849,17 @@ const defaultRepeatOptions = Object.freeze({
|
|
|
2866
2849
|
positioning: false,
|
|
2867
2850
|
recycle: true,
|
|
2868
2851
|
});
|
|
2869
|
-
function bindWithoutPositioning(view, items, index,
|
|
2870
|
-
view.
|
|
2852
|
+
function bindWithoutPositioning(view, items, index, controller) {
|
|
2853
|
+
view.context.parent = controller.source;
|
|
2854
|
+
view.context.parentContext = controller.context;
|
|
2855
|
+
view.bind(items[index]);
|
|
2871
2856
|
}
|
|
2872
|
-
function bindWithPositioning(view, items, index,
|
|
2873
|
-
view.
|
|
2857
|
+
function bindWithPositioning(view, items, index, controller) {
|
|
2858
|
+
view.context.parent = controller.source;
|
|
2859
|
+
view.context.parentContext = controller.context;
|
|
2860
|
+
view.context.length = items.length;
|
|
2861
|
+
view.context.index = index;
|
|
2862
|
+
view.bind(items[index]);
|
|
2874
2863
|
}
|
|
2875
2864
|
/**
|
|
2876
2865
|
* A behavior that renders a template for each item in an array.
|
|
@@ -2886,15 +2875,11 @@ class RepeatBehavior {
|
|
|
2886
2875
|
* @param isTemplateBindingVolatile - Indicates whether the template binding has volatile dependencies.
|
|
2887
2876
|
* @param options - Options used to turn on special repeat features.
|
|
2888
2877
|
*/
|
|
2889
|
-
constructor(directive
|
|
2878
|
+
constructor(directive) {
|
|
2890
2879
|
this.directive = directive;
|
|
2891
|
-
this.location = location;
|
|
2892
|
-
this.source = null;
|
|
2893
2880
|
this.views = [];
|
|
2894
2881
|
this.items = null;
|
|
2895
2882
|
this.itemsObserver = null;
|
|
2896
|
-
this.context = void 0;
|
|
2897
|
-
this.childContext = void 0;
|
|
2898
2883
|
this.bindView = bindWithoutPositioning;
|
|
2899
2884
|
this.itemsBindingObserver = directive.dataBinding.createObserver(directive, this);
|
|
2900
2885
|
this.templateBindingObserver = directive.templateBinding.createObserver(directive, this);
|
|
@@ -2903,32 +2888,26 @@ class RepeatBehavior {
|
|
|
2903
2888
|
}
|
|
2904
2889
|
}
|
|
2905
2890
|
/**
|
|
2906
|
-
* Bind this behavior
|
|
2907
|
-
* @param
|
|
2908
|
-
* @param context - The execution context that the binding is operating within.
|
|
2891
|
+
* Bind this behavior.
|
|
2892
|
+
* @param controller - The view controller that manages the lifecycle of this behavior.
|
|
2909
2893
|
*/
|
|
2910
|
-
bind(
|
|
2911
|
-
this.
|
|
2912
|
-
this.
|
|
2913
|
-
this.
|
|
2914
|
-
this.
|
|
2915
|
-
this.template = this.templateBindingObserver.observe(source, this.context);
|
|
2894
|
+
bind(controller) {
|
|
2895
|
+
this.location = controller.targets[this.directive.nodeId];
|
|
2896
|
+
this.controller = controller;
|
|
2897
|
+
this.items = this.itemsBindingObserver.bind(controller);
|
|
2898
|
+
this.template = this.templateBindingObserver.bind(controller);
|
|
2916
2899
|
this.observeItems(true);
|
|
2917
2900
|
this.refreshAllViews();
|
|
2901
|
+
controller.onUnbind(this);
|
|
2918
2902
|
}
|
|
2919
2903
|
/**
|
|
2920
|
-
* Unbinds this behavior
|
|
2921
|
-
* @param source - The source to unbind from.
|
|
2904
|
+
* Unbinds this behavior.
|
|
2922
2905
|
*/
|
|
2923
2906
|
unbind() {
|
|
2924
|
-
this.source = null;
|
|
2925
|
-
this.items = null;
|
|
2926
2907
|
if (this.itemsObserver !== null) {
|
|
2927
2908
|
this.itemsObserver.unsubscribe(this);
|
|
2928
2909
|
}
|
|
2929
2910
|
this.unbindAllViews();
|
|
2930
|
-
this.itemsBindingObserver.dispose();
|
|
2931
|
-
this.templateBindingObserver.dispose();
|
|
2932
2911
|
}
|
|
2933
2912
|
/**
|
|
2934
2913
|
* Handles changes in the array, its items, and the repeat template.
|
|
@@ -2937,12 +2916,12 @@ class RepeatBehavior {
|
|
|
2937
2916
|
*/
|
|
2938
2917
|
handleChange(source, args) {
|
|
2939
2918
|
if (args === this.itemsBindingObserver) {
|
|
2940
|
-
this.items = this.itemsBindingObserver.
|
|
2919
|
+
this.items = this.itemsBindingObserver.bind(this.controller);
|
|
2941
2920
|
this.observeItems();
|
|
2942
2921
|
this.refreshAllViews();
|
|
2943
2922
|
}
|
|
2944
2923
|
else if (args === this.templateBindingObserver) {
|
|
2945
|
-
this.template = this.templateBindingObserver.
|
|
2924
|
+
this.template = this.templateBindingObserver.bind(this.controller);
|
|
2946
2925
|
this.refreshAllViews(true);
|
|
2947
2926
|
}
|
|
2948
2927
|
else if (!args[0]) {
|
|
@@ -2972,10 +2951,10 @@ class RepeatBehavior {
|
|
|
2972
2951
|
}
|
|
2973
2952
|
updateViews(splices) {
|
|
2974
2953
|
const views = this.views;
|
|
2975
|
-
const childContext = this.childContext;
|
|
2976
2954
|
const bindView = this.bindView;
|
|
2977
2955
|
const items = this.items;
|
|
2978
2956
|
const template = this.template;
|
|
2957
|
+
const controller = this.controller;
|
|
2979
2958
|
const recycle = this.directive.options.recycle;
|
|
2980
2959
|
const leftoverViews = [];
|
|
2981
2960
|
let leftoverIndex = 0;
|
|
@@ -2987,13 +2966,14 @@ class RepeatBehavior {
|
|
|
2987
2966
|
let addIndex = splice.index;
|
|
2988
2967
|
const end = addIndex + splice.addedCount;
|
|
2989
2968
|
const removedViews = views.splice(splice.index, removed.length);
|
|
2990
|
-
|
|
2969
|
+
const totalAvailableViews = (availableViews =
|
|
2970
|
+
leftoverViews.length + removedViews.length);
|
|
2991
2971
|
for (; addIndex < end; ++addIndex) {
|
|
2992
2972
|
const neighbor = views[addIndex];
|
|
2993
2973
|
const location = neighbor ? neighbor.firstChild : this.location;
|
|
2994
2974
|
let view;
|
|
2995
2975
|
if (recycle && availableViews > 0) {
|
|
2996
|
-
if (removeIndex <=
|
|
2976
|
+
if (removeIndex <= totalAvailableViews && removedViews.length > 0) {
|
|
2997
2977
|
view = removedViews[removeIndex];
|
|
2998
2978
|
removeIndex++;
|
|
2999
2979
|
}
|
|
@@ -3007,7 +2987,7 @@ class RepeatBehavior {
|
|
|
3007
2987
|
view = template.create();
|
|
3008
2988
|
}
|
|
3009
2989
|
views.splice(addIndex, 0, view);
|
|
3010
|
-
bindView(view, items, addIndex,
|
|
2990
|
+
bindView(view, items, addIndex, controller);
|
|
3011
2991
|
view.insertBefore(location);
|
|
3012
2992
|
}
|
|
3013
2993
|
if (removedViews[removeIndex]) {
|
|
@@ -3019,7 +2999,9 @@ class RepeatBehavior {
|
|
|
3019
2999
|
}
|
|
3020
3000
|
if (this.directive.options.positioning) {
|
|
3021
3001
|
for (let i = 0, ii = views.length; i < ii; ++i) {
|
|
3022
|
-
views[i].context
|
|
3002
|
+
const context = views[i].context;
|
|
3003
|
+
context.length = i;
|
|
3004
|
+
context.index = ii;
|
|
3023
3005
|
}
|
|
3024
3006
|
}
|
|
3025
3007
|
}
|
|
@@ -3028,7 +3010,7 @@ class RepeatBehavior {
|
|
|
3028
3010
|
const template = this.template;
|
|
3029
3011
|
const location = this.location;
|
|
3030
3012
|
const bindView = this.bindView;
|
|
3031
|
-
const
|
|
3013
|
+
const controller = this.controller;
|
|
3032
3014
|
let itemsLength = items.length;
|
|
3033
3015
|
let views = this.views;
|
|
3034
3016
|
let viewsLength = views.length;
|
|
@@ -3042,7 +3024,7 @@ class RepeatBehavior {
|
|
|
3042
3024
|
this.views = views = new Array(itemsLength);
|
|
3043
3025
|
for (let i = 0; i < itemsLength; ++i) {
|
|
3044
3026
|
const view = template.create();
|
|
3045
|
-
bindView(view, items, i,
|
|
3027
|
+
bindView(view, items, i, controller);
|
|
3046
3028
|
views[i] = view;
|
|
3047
3029
|
view.insertBefore(location);
|
|
3048
3030
|
}
|
|
@@ -3053,11 +3035,11 @@ class RepeatBehavior {
|
|
|
3053
3035
|
for (; i < itemsLength; ++i) {
|
|
3054
3036
|
if (i < viewsLength) {
|
|
3055
3037
|
const view = views[i];
|
|
3056
|
-
bindView(view, items, i,
|
|
3038
|
+
bindView(view, items, i, controller);
|
|
3057
3039
|
}
|
|
3058
3040
|
else {
|
|
3059
3041
|
const view = template.create();
|
|
3060
|
-
bindView(view, items, i,
|
|
3042
|
+
bindView(view, items, i, controller);
|
|
3061
3043
|
views.push(view);
|
|
3062
3044
|
view.insertBefore(location);
|
|
3063
3045
|
}
|
|
@@ -3107,8 +3089,8 @@ class RepeatDirective {
|
|
|
3107
3089
|
* Creates a behavior for the provided target node.
|
|
3108
3090
|
* @param target - The node instance to create the behavior for.
|
|
3109
3091
|
*/
|
|
3110
|
-
createBehavior(
|
|
3111
|
-
return new RepeatBehavior(this
|
|
3092
|
+
createBehavior() {
|
|
3093
|
+
return new RepeatBehavior(this);
|
|
3112
3094
|
}
|
|
3113
3095
|
}
|
|
3114
3096
|
HTMLDirective.define(RepeatDirective);
|
|
@@ -3152,11 +3134,12 @@ class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
|
3152
3134
|
* @param context - The execution context that the binding is operating within.
|
|
3153
3135
|
* @param targets - The targets that behaviors in a view can attach to.
|
|
3154
3136
|
*/
|
|
3155
|
-
bind(
|
|
3156
|
-
const target = targets[this.nodeId];
|
|
3157
|
-
target[this.sourceProperty] = source;
|
|
3158
|
-
this.updateTarget(source, this.computeNodes(target));
|
|
3137
|
+
bind(controller) {
|
|
3138
|
+
const target = controller.targets[this.nodeId];
|
|
3139
|
+
target[this.sourceProperty] = controller.source;
|
|
3140
|
+
this.updateTarget(controller.source, this.computeNodes(target));
|
|
3159
3141
|
this.observe(target);
|
|
3142
|
+
controller.onUnbind(this);
|
|
3160
3143
|
}
|
|
3161
3144
|
/**
|
|
3162
3145
|
* Unbinds this behavior from the source.
|
|
@@ -3164,9 +3147,9 @@ class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
|
3164
3147
|
* @param context - The execution context that the binding is operating within.
|
|
3165
3148
|
* @param targets - The targets that behaviors in a view can attach to.
|
|
3166
3149
|
*/
|
|
3167
|
-
unbind(
|
|
3168
|
-
const target = targets[this.nodeId];
|
|
3169
|
-
this.updateTarget(source, emptyArray);
|
|
3150
|
+
unbind(controller) {
|
|
3151
|
+
const target = controller.targets[this.nodeId];
|
|
3152
|
+
this.updateTarget(controller.source, emptyArray);
|
|
3170
3153
|
this.disconnect(target);
|
|
3171
3154
|
target[this.sourceProperty] = null;
|
|
3172
3155
|
}
|
|
@@ -3315,6 +3298,16 @@ function children(propertyOrOptions) {
|
|
|
3315
3298
|
|
|
3316
3299
|
const booleanMode = "boolean";
|
|
3317
3300
|
const reflectMode = "reflect";
|
|
3301
|
+
/**
|
|
3302
|
+
* Metadata used to configure a custom attribute's behavior.
|
|
3303
|
+
* @public
|
|
3304
|
+
*/
|
|
3305
|
+
const AttributeConfiguration = Object.freeze({
|
|
3306
|
+
/**
|
|
3307
|
+
* Locates all attribute configurations associated with a type.
|
|
3308
|
+
*/
|
|
3309
|
+
locate: createMetadataLocator(),
|
|
3310
|
+
});
|
|
3318
3311
|
/**
|
|
3319
3312
|
* A {@link ValueConverter} that converts to and from `boolean` values.
|
|
3320
3313
|
* @remarks
|
|
@@ -3452,7 +3445,7 @@ class AttributeDefinition {
|
|
|
3452
3445
|
*/
|
|
3453
3446
|
static collect(Owner, ...attributeLists) {
|
|
3454
3447
|
const attributes = [];
|
|
3455
|
-
attributeLists.push(Owner
|
|
3448
|
+
attributeLists.push(AttributeConfiguration.locate(Owner));
|
|
3456
3449
|
for (let i = 0, ii = attributeLists.length; i < ii; ++i) {
|
|
3457
3450
|
const list = attributeLists[i];
|
|
3458
3451
|
if (list === void 0) {
|
|
@@ -3482,9 +3475,7 @@ function attr(configOrTarget, prop) {
|
|
|
3482
3475
|
// - @attr({...opts})
|
|
3483
3476
|
config.property = $prop;
|
|
3484
3477
|
}
|
|
3485
|
-
|
|
3486
|
-
($target.constructor.attributes = []);
|
|
3487
|
-
attributes.push(config);
|
|
3478
|
+
AttributeConfiguration.locate($target.constructor).push(config);
|
|
3488
3479
|
}
|
|
3489
3480
|
if (arguments.length > 1) {
|
|
3490
3481
|
// Non invocation:
|
|
@@ -3509,6 +3500,7 @@ const fastElementRegistry = FAST.getById(4 /* KernelServiceId.elementRegistry */
|
|
|
3509
3500
|
*/
|
|
3510
3501
|
class FASTElementDefinition {
|
|
3511
3502
|
constructor(type, nameOrConfig = type.definition) {
|
|
3503
|
+
var _a;
|
|
3512
3504
|
this.platformDefined = false;
|
|
3513
3505
|
if (isString(nameOrConfig)) {
|
|
3514
3506
|
nameOrConfig = { name: nameOrConfig };
|
|
@@ -3516,6 +3508,7 @@ class FASTElementDefinition {
|
|
|
3516
3508
|
this.type = type;
|
|
3517
3509
|
this.name = nameOrConfig.name;
|
|
3518
3510
|
this.template = nameOrConfig.template;
|
|
3511
|
+
this.registry = (_a = nameOrConfig.registry) !== null && _a !== void 0 ? _a : customElements;
|
|
3519
3512
|
const proto = type.prototype;
|
|
3520
3513
|
const attributes = AttributeDefinition.collect(type, nameOrConfig.attributes);
|
|
3521
3514
|
const observedAttributes = new Array(attributes.length);
|
|
@@ -3560,7 +3553,7 @@ class FASTElementDefinition {
|
|
|
3560
3553
|
* @remarks
|
|
3561
3554
|
* This operation is idempotent per registry.
|
|
3562
3555
|
*/
|
|
3563
|
-
define(registry =
|
|
3556
|
+
define(registry = this.registry) {
|
|
3564
3557
|
const type = this.type;
|
|
3565
3558
|
if (!registry.get(this.name)) {
|
|
3566
3559
|
this.platformDefined = true;
|
|
@@ -3594,22 +3587,22 @@ FASTElementDefinition.getByType = fastElementRegistry.getByType;
|
|
|
3594
3587
|
*/
|
|
3595
3588
|
FASTElementDefinition.getForInstance = fastElementRegistry.getForInstance;
|
|
3596
3589
|
|
|
3597
|
-
const shadowRoots = new WeakMap();
|
|
3598
3590
|
const defaultEventOptions = {
|
|
3599
3591
|
bubbles: true,
|
|
3600
3592
|
composed: true,
|
|
3601
3593
|
cancelable: true,
|
|
3602
3594
|
};
|
|
3595
|
+
const isConnectedPropertyName = "isConnected";
|
|
3596
|
+
const shadowRoots = new WeakMap();
|
|
3603
3597
|
function getShadowRoot(element) {
|
|
3604
3598
|
var _a, _b;
|
|
3605
3599
|
return (_b = (_a = element.shadowRoot) !== null && _a !== void 0 ? _a : shadowRoots.get(element)) !== null && _b !== void 0 ? _b : null;
|
|
3606
3600
|
}
|
|
3607
|
-
const isConnectedPropertyName = "isConnected";
|
|
3608
3601
|
/**
|
|
3609
3602
|
* Controls the lifecycle and rendering of a `FASTElement`.
|
|
3610
3603
|
* @public
|
|
3611
3604
|
*/
|
|
3612
|
-
class
|
|
3605
|
+
class ElementController extends PropertyChangeNotifier {
|
|
3613
3606
|
/**
|
|
3614
3607
|
* Creates a Controller to control the specified element.
|
|
3615
3608
|
* @param element - The element to be controlled by this controller.
|
|
@@ -3620,12 +3613,12 @@ class Controller extends PropertyChangeNotifier {
|
|
|
3620
3613
|
constructor(element, definition) {
|
|
3621
3614
|
super(element);
|
|
3622
3615
|
this.boundObservables = null;
|
|
3623
|
-
this.behaviors = null;
|
|
3624
3616
|
this.needsInitialization = true;
|
|
3625
3617
|
this.hasExistingShadowRoot = false;
|
|
3626
3618
|
this._template = null;
|
|
3627
|
-
this._styles = null;
|
|
3628
3619
|
this._isConnected = false;
|
|
3620
|
+
this.behaviors = null;
|
|
3621
|
+
this._mainStyles = null;
|
|
3629
3622
|
/**
|
|
3630
3623
|
* This allows Observable.getNotifier(...) to return the Controller
|
|
3631
3624
|
* when the notifier for the Controller itself is being requested. The
|
|
@@ -3641,7 +3634,7 @@ class Controller extends PropertyChangeNotifier {
|
|
|
3641
3634
|
* If `null` then the element is managing its own rendering.
|
|
3642
3635
|
*/
|
|
3643
3636
|
this.view = null;
|
|
3644
|
-
this.
|
|
3637
|
+
this.source = element;
|
|
3645
3638
|
this.definition = definition;
|
|
3646
3639
|
const shadowOptions = definition.shadowOptions;
|
|
3647
3640
|
if (shadowOptions !== void 0) {
|
|
@@ -3695,9 +3688,9 @@ class Controller extends PropertyChangeNotifier {
|
|
|
3695
3688
|
// 1. Template overrides take top precedence.
|
|
3696
3689
|
if (this._template === null) {
|
|
3697
3690
|
const definition = this.definition;
|
|
3698
|
-
if (this.
|
|
3691
|
+
if (this.source.resolveTemplate) {
|
|
3699
3692
|
// 2. Allow for element instance overrides next.
|
|
3700
|
-
this._template = this.
|
|
3693
|
+
this._template = this.source.resolveTemplate();
|
|
3701
3694
|
}
|
|
3702
3695
|
else if (definition.template) {
|
|
3703
3696
|
// 3. Default to the static definition.
|
|
@@ -3716,48 +3709,92 @@ class Controller extends PropertyChangeNotifier {
|
|
|
3716
3709
|
}
|
|
3717
3710
|
}
|
|
3718
3711
|
/**
|
|
3719
|
-
*
|
|
3720
|
-
*
|
|
3721
|
-
* This value can only be accurately read after connect but can be set at any time.
|
|
3712
|
+
* The main set of styles used for the component, independent
|
|
3713
|
+
* of any dynamically added styles.
|
|
3722
3714
|
*/
|
|
3723
|
-
get
|
|
3715
|
+
get mainStyles() {
|
|
3724
3716
|
var _a;
|
|
3725
3717
|
// 1. Styles overrides take top precedence.
|
|
3726
|
-
if (this.
|
|
3718
|
+
if (this._mainStyles === null) {
|
|
3727
3719
|
const definition = this.definition;
|
|
3728
|
-
if (this.
|
|
3720
|
+
if (this.source.resolveStyles) {
|
|
3729
3721
|
// 2. Allow for element instance overrides next.
|
|
3730
|
-
this.
|
|
3722
|
+
this._mainStyles = this.source.resolveStyles();
|
|
3731
3723
|
}
|
|
3732
3724
|
else if (definition.styles) {
|
|
3733
3725
|
// 3. Default to the static definition.
|
|
3734
|
-
this.
|
|
3726
|
+
this._mainStyles = (_a = definition.styles) !== null && _a !== void 0 ? _a : null;
|
|
3735
3727
|
}
|
|
3736
3728
|
}
|
|
3737
|
-
return this.
|
|
3729
|
+
return this._mainStyles;
|
|
3738
3730
|
}
|
|
3739
|
-
set
|
|
3740
|
-
if (this.
|
|
3731
|
+
set mainStyles(value) {
|
|
3732
|
+
if (this._mainStyles === value) {
|
|
3741
3733
|
return;
|
|
3742
3734
|
}
|
|
3743
|
-
if (this.
|
|
3744
|
-
this.removeStyles(this.
|
|
3735
|
+
if (this._mainStyles !== null) {
|
|
3736
|
+
this.removeStyles(this._mainStyles);
|
|
3745
3737
|
}
|
|
3746
|
-
this.
|
|
3738
|
+
this._mainStyles = value;
|
|
3747
3739
|
if (!this.needsInitialization) {
|
|
3748
3740
|
this.addStyles(value);
|
|
3749
3741
|
}
|
|
3750
3742
|
}
|
|
3743
|
+
/**
|
|
3744
|
+
* Adds the behavior to the component.
|
|
3745
|
+
* @param behavior - The behavior to add.
|
|
3746
|
+
*/
|
|
3747
|
+
addBehavior(behavior) {
|
|
3748
|
+
var _a, _b;
|
|
3749
|
+
const targetBehaviors = (_a = this.behaviors) !== null && _a !== void 0 ? _a : (this.behaviors = new Map());
|
|
3750
|
+
const count = (_b = targetBehaviors.get(behavior)) !== null && _b !== void 0 ? _b : 0;
|
|
3751
|
+
if (count === 0) {
|
|
3752
|
+
targetBehaviors.set(behavior, 1);
|
|
3753
|
+
behavior.addedCallback && behavior.addedCallback(this);
|
|
3754
|
+
if (behavior.connectedCallback && this.isConnected) {
|
|
3755
|
+
behavior.connectedCallback(this);
|
|
3756
|
+
}
|
|
3757
|
+
}
|
|
3758
|
+
else {
|
|
3759
|
+
targetBehaviors.set(behavior, count + 1);
|
|
3760
|
+
}
|
|
3761
|
+
}
|
|
3762
|
+
/**
|
|
3763
|
+
* Removes the behavior from the component.
|
|
3764
|
+
* @param behavior - The behavior to remove.
|
|
3765
|
+
* @param force - Forces removal even if this behavior was added more than once.
|
|
3766
|
+
*/
|
|
3767
|
+
removeBehavior(behavior, force = false) {
|
|
3768
|
+
const targetBehaviors = this.behaviors;
|
|
3769
|
+
if (targetBehaviors === null) {
|
|
3770
|
+
return;
|
|
3771
|
+
}
|
|
3772
|
+
const count = targetBehaviors.get(behavior);
|
|
3773
|
+
if (count === void 0) {
|
|
3774
|
+
return;
|
|
3775
|
+
}
|
|
3776
|
+
if (count === 1 || force) {
|
|
3777
|
+
targetBehaviors.delete(behavior);
|
|
3778
|
+
if (behavior.disconnectedCallback && this.isConnected) {
|
|
3779
|
+
behavior.disconnectedCallback(this);
|
|
3780
|
+
}
|
|
3781
|
+
behavior.removedCallback && behavior.removedCallback(this);
|
|
3782
|
+
}
|
|
3783
|
+
else {
|
|
3784
|
+
targetBehaviors.set(behavior, count - 1);
|
|
3785
|
+
}
|
|
3786
|
+
}
|
|
3751
3787
|
/**
|
|
3752
3788
|
* Adds styles to this element. Providing an HTMLStyleElement will attach the element instance to the shadowRoot.
|
|
3753
3789
|
* @param styles - The styles to add.
|
|
3754
3790
|
*/
|
|
3755
3791
|
addStyles(styles) {
|
|
3792
|
+
var _a;
|
|
3756
3793
|
if (!styles) {
|
|
3757
3794
|
return;
|
|
3758
3795
|
}
|
|
3759
|
-
const
|
|
3760
|
-
|
|
3796
|
+
const source = this.source;
|
|
3797
|
+
const target = (_a = getShadowRoot(source)) !== null && _a !== void 0 ? _a : source.getRootNode();
|
|
3761
3798
|
if (styles instanceof HTMLElement) {
|
|
3762
3799
|
target.append(styles);
|
|
3763
3800
|
}
|
|
@@ -3765,7 +3802,9 @@ class Controller extends PropertyChangeNotifier {
|
|
|
3765
3802
|
const sourceBehaviors = styles.behaviors;
|
|
3766
3803
|
styles.addStylesTo(target);
|
|
3767
3804
|
if (sourceBehaviors !== null) {
|
|
3768
|
-
|
|
3805
|
+
for (let i = 0, ii = sourceBehaviors.length; i < ii; ++i) {
|
|
3806
|
+
this.addBehavior(sourceBehaviors[i]);
|
|
3807
|
+
}
|
|
3769
3808
|
}
|
|
3770
3809
|
}
|
|
3771
3810
|
}
|
|
@@ -3774,11 +3813,12 @@ class Controller extends PropertyChangeNotifier {
|
|
|
3774
3813
|
* @param styles - the styles to remove.
|
|
3775
3814
|
*/
|
|
3776
3815
|
removeStyles(styles) {
|
|
3816
|
+
var _a;
|
|
3777
3817
|
if (!styles) {
|
|
3778
3818
|
return;
|
|
3779
3819
|
}
|
|
3780
|
-
const
|
|
3781
|
-
|
|
3820
|
+
const source = this.source;
|
|
3821
|
+
const target = (_a = getShadowRoot(source)) !== null && _a !== void 0 ? _a : source.getRootNode();
|
|
3782
3822
|
if (styles instanceof HTMLElement) {
|
|
3783
3823
|
target.removeChild(styles);
|
|
3784
3824
|
}
|
|
@@ -3786,85 +3826,29 @@ class Controller extends PropertyChangeNotifier {
|
|
|
3786
3826
|
const sourceBehaviors = styles.behaviors;
|
|
3787
3827
|
styles.removeStylesFrom(target);
|
|
3788
3828
|
if (sourceBehaviors !== null) {
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
}
|
|
3793
|
-
/**
|
|
3794
|
-
* Adds behaviors to this element.
|
|
3795
|
-
* @param behaviors - The behaviors to add.
|
|
3796
|
-
*/
|
|
3797
|
-
addBehaviors(behaviors) {
|
|
3798
|
-
var _a;
|
|
3799
|
-
const targetBehaviors = (_a = this.behaviors) !== null && _a !== void 0 ? _a : (this.behaviors = new Map());
|
|
3800
|
-
const length = behaviors.length;
|
|
3801
|
-
const behaviorsToBind = [];
|
|
3802
|
-
for (let i = 0; i < length; ++i) {
|
|
3803
|
-
const behavior = behaviors[i];
|
|
3804
|
-
if (targetBehaviors.has(behavior)) {
|
|
3805
|
-
targetBehaviors.set(behavior, targetBehaviors.get(behavior) + 1);
|
|
3806
|
-
}
|
|
3807
|
-
else {
|
|
3808
|
-
targetBehaviors.set(behavior, 1);
|
|
3809
|
-
behaviorsToBind.push(behavior);
|
|
3810
|
-
}
|
|
3811
|
-
}
|
|
3812
|
-
if (this._isConnected) {
|
|
3813
|
-
const element = this.element;
|
|
3814
|
-
const context = ExecutionContext.default;
|
|
3815
|
-
for (let i = 0; i < behaviorsToBind.length; ++i) {
|
|
3816
|
-
behaviorsToBind[i].bind(element, context);
|
|
3817
|
-
}
|
|
3818
|
-
}
|
|
3819
|
-
}
|
|
3820
|
-
/**
|
|
3821
|
-
* Removes behaviors from this element.
|
|
3822
|
-
* @param behaviors - The behaviors to remove.
|
|
3823
|
-
* @param force - Forces unbinding of behaviors.
|
|
3824
|
-
*/
|
|
3825
|
-
removeBehaviors(behaviors, force = false) {
|
|
3826
|
-
const targetBehaviors = this.behaviors;
|
|
3827
|
-
if (targetBehaviors === null) {
|
|
3828
|
-
return;
|
|
3829
|
-
}
|
|
3830
|
-
const length = behaviors.length;
|
|
3831
|
-
const behaviorsToUnbind = [];
|
|
3832
|
-
for (let i = 0; i < length; ++i) {
|
|
3833
|
-
const behavior = behaviors[i];
|
|
3834
|
-
if (targetBehaviors.has(behavior)) {
|
|
3835
|
-
const count = targetBehaviors.get(behavior) - 1;
|
|
3836
|
-
count === 0 || force
|
|
3837
|
-
? targetBehaviors.delete(behavior) && behaviorsToUnbind.push(behavior)
|
|
3838
|
-
: targetBehaviors.set(behavior, count);
|
|
3839
|
-
}
|
|
3840
|
-
}
|
|
3841
|
-
if (this._isConnected) {
|
|
3842
|
-
const element = this.element;
|
|
3843
|
-
const context = ExecutionContext.default;
|
|
3844
|
-
for (let i = 0; i < behaviorsToUnbind.length; ++i) {
|
|
3845
|
-
behaviorsToUnbind[i].unbind(element, context);
|
|
3829
|
+
for (let i = 0, ii = sourceBehaviors.length; i < ii; ++i) {
|
|
3830
|
+
this.addBehavior(sourceBehaviors[i]);
|
|
3831
|
+
}
|
|
3846
3832
|
}
|
|
3847
3833
|
}
|
|
3848
3834
|
}
|
|
3849
3835
|
/**
|
|
3850
3836
|
* Runs connected lifecycle behavior on the associated element.
|
|
3851
3837
|
*/
|
|
3852
|
-
|
|
3838
|
+
connect() {
|
|
3853
3839
|
if (this._isConnected) {
|
|
3854
3840
|
return;
|
|
3855
3841
|
}
|
|
3856
|
-
const element = this.element;
|
|
3857
|
-
const context = ExecutionContext.default;
|
|
3858
3842
|
if (this.needsInitialization) {
|
|
3859
3843
|
this.finishInitialization();
|
|
3860
3844
|
}
|
|
3861
3845
|
else if (this.view !== null) {
|
|
3862
|
-
this.view.bind(
|
|
3846
|
+
this.view.bind(this.source);
|
|
3863
3847
|
}
|
|
3864
3848
|
const behaviors = this.behaviors;
|
|
3865
3849
|
if (behaviors !== null) {
|
|
3866
|
-
for (const
|
|
3867
|
-
|
|
3850
|
+
for (const key of behaviors.keys()) {
|
|
3851
|
+
key.connectedCallback && key.connectedCallback(this);
|
|
3868
3852
|
}
|
|
3869
3853
|
}
|
|
3870
3854
|
this.setIsConnected(true);
|
|
@@ -3872,21 +3856,18 @@ class Controller extends PropertyChangeNotifier {
|
|
|
3872
3856
|
/**
|
|
3873
3857
|
* Runs disconnected lifecycle behavior on the associated element.
|
|
3874
3858
|
*/
|
|
3875
|
-
|
|
3859
|
+
disconnect() {
|
|
3876
3860
|
if (!this._isConnected) {
|
|
3877
3861
|
return;
|
|
3878
3862
|
}
|
|
3879
3863
|
this.setIsConnected(false);
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
view.unbind();
|
|
3864
|
+
if (this.view !== null) {
|
|
3865
|
+
this.view.unbind();
|
|
3883
3866
|
}
|
|
3884
3867
|
const behaviors = this.behaviors;
|
|
3885
3868
|
if (behaviors !== null) {
|
|
3886
|
-
const
|
|
3887
|
-
|
|
3888
|
-
for (const behavior of behaviors.keys()) {
|
|
3889
|
-
behavior.unbind(element, context);
|
|
3869
|
+
for (const key of behaviors.keys()) {
|
|
3870
|
+
key.disconnectedCallback && key.disconnectedCallback(this);
|
|
3890
3871
|
}
|
|
3891
3872
|
}
|
|
3892
3873
|
}
|
|
@@ -3899,7 +3880,7 @@ class Controller extends PropertyChangeNotifier {
|
|
|
3899
3880
|
onAttributeChangedCallback(name, oldValue, newValue) {
|
|
3900
3881
|
const attrDef = this.definition.attributeLookup[name];
|
|
3901
3882
|
if (attrDef !== void 0) {
|
|
3902
|
-
attrDef.onAttributeChangedCallback(this.
|
|
3883
|
+
attrDef.onAttributeChangedCallback(this.source, newValue);
|
|
3903
3884
|
}
|
|
3904
3885
|
}
|
|
3905
3886
|
/**
|
|
@@ -3912,12 +3893,12 @@ class Controller extends PropertyChangeNotifier {
|
|
|
3912
3893
|
*/
|
|
3913
3894
|
emit(type, detail, options) {
|
|
3914
3895
|
if (this._isConnected) {
|
|
3915
|
-
return this.
|
|
3896
|
+
return this.source.dispatchEvent(new CustomEvent(type, Object.assign(Object.assign({ detail }, defaultEventOptions), options)));
|
|
3916
3897
|
}
|
|
3917
3898
|
return false;
|
|
3918
3899
|
}
|
|
3919
3900
|
finishInitialization() {
|
|
3920
|
-
const element = this.
|
|
3901
|
+
const element = this.source;
|
|
3921
3902
|
const boundObservables = this.boundObservables;
|
|
3922
3903
|
// If we have any observables that were bound, re-apply their values.
|
|
3923
3904
|
if (boundObservables !== null) {
|
|
@@ -3929,15 +3910,15 @@ class Controller extends PropertyChangeNotifier {
|
|
|
3929
3910
|
this.boundObservables = null;
|
|
3930
3911
|
}
|
|
3931
3912
|
this.renderTemplate(this.template);
|
|
3932
|
-
this.addStyles(this.
|
|
3913
|
+
this.addStyles(this.mainStyles);
|
|
3933
3914
|
this.needsInitialization = false;
|
|
3934
3915
|
}
|
|
3935
3916
|
renderTemplate(template) {
|
|
3936
3917
|
var _a;
|
|
3937
|
-
const element = this.element;
|
|
3938
3918
|
// When getting the host to render to, we start by looking
|
|
3939
3919
|
// up the shadow root. If there isn't one, then that means
|
|
3940
3920
|
// we're doing a Light DOM render to the element's direct children.
|
|
3921
|
+
const element = this.source;
|
|
3941
3922
|
const host = (_a = getShadowRoot(element)) !== null && _a !== void 0 ? _a : element;
|
|
3942
3923
|
if (this.view !== null) {
|
|
3943
3924
|
// If there's already a view, we need to unbind and remove through dispose.
|
|
@@ -3954,6 +3935,8 @@ class Controller extends PropertyChangeNotifier {
|
|
|
3954
3935
|
if (template) {
|
|
3955
3936
|
// If a new template was provided, render it.
|
|
3956
3937
|
this.view = template.render(element, host, element);
|
|
3938
|
+
this.view.sourceLifetime =
|
|
3939
|
+
SourceLifetime.coupled;
|
|
3957
3940
|
}
|
|
3958
3941
|
}
|
|
3959
3942
|
/**
|
|
@@ -3973,7 +3956,7 @@ class Controller extends PropertyChangeNotifier {
|
|
|
3973
3956
|
if (definition === void 0) {
|
|
3974
3957
|
throw FAST.error(1401 /* Message.missingElementDefinition */);
|
|
3975
3958
|
}
|
|
3976
|
-
return (element.$fastController = new
|
|
3959
|
+
return (element.$fastController = new ElementController(element, definition));
|
|
3977
3960
|
}
|
|
3978
3961
|
}
|
|
3979
3962
|
|
|
@@ -3983,16 +3966,16 @@ function createFASTElement(BaseType) {
|
|
|
3983
3966
|
constructor() {
|
|
3984
3967
|
/* eslint-disable-next-line */
|
|
3985
3968
|
super();
|
|
3986
|
-
|
|
3969
|
+
ElementController.forCustomElement(this);
|
|
3987
3970
|
}
|
|
3988
3971
|
$emit(type, detail, options) {
|
|
3989
3972
|
return this.$fastController.emit(type, detail, options);
|
|
3990
3973
|
}
|
|
3991
3974
|
connectedCallback() {
|
|
3992
|
-
this.$fastController.
|
|
3975
|
+
this.$fastController.connect();
|
|
3993
3976
|
}
|
|
3994
3977
|
disconnectedCallback() {
|
|
3995
|
-
this.$fastController.
|
|
3978
|
+
this.$fastController.disconnect();
|
|
3996
3979
|
}
|
|
3997
3980
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
3998
3981
|
this.$fastController.onAttributeChangedCallback(name, oldValue, newValue);
|
|
@@ -4052,4 +4035,4 @@ function customElement(nameOrDef) {
|
|
|
4052
4035
|
};
|
|
4053
4036
|
}
|
|
4054
4037
|
|
|
4055
|
-
export { AdoptedStyleSheetsStrategy, ArrayObserver, Aspect, AttributeDefinition, Binding,
|
|
4038
|
+
export { AdoptedStyleSheetsStrategy, ArrayObserver, Aspect, AttributeConfiguration, AttributeDefinition, Binding, CSSDirective, ChildrenDirective, Compiler, DOM, ElementController, ElementStyles, ExecutionContext, FAST, FASTElement, FASTElementDefinition, HTMLBindingDirective, HTMLDirective, HTMLView, Markup, NodeObservationDirective, Observable, Parser, PropertyChangeNotifier, RefDirective, RepeatBehavior, RepeatDirective, SlottedDirective, SourceLifetime, Splice, SpliceStrategy, SpliceStrategySupport, StatelessAttachedAttributeDirective, SubscriberSet, Updates, ViewBehaviorOrchestrator, ViewTemplate, attr, bind, booleanConverter, children, createMetadataLocator, createTypeRegistry, css, cssDirective, cssPartial, customElement, elements, emptyArray, html, htmlDirective, lengthOf, listener, normalizeBinding, nullableNumberConverter, observable, oneTime, ref, repeat, slotted, volatile, when };
|