@microsoft/fast-element 2.0.1 → 2.2.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/ARCHITECTURE_FASTELEMENT.md +63 -0
- package/ARCHITECTURE_HTML_TAGGED_TEMPLATE_LITERAL.md +34 -0
- package/ARCHITECTURE_INTRO.md +10 -0
- package/ARCHITECTURE_OVERVIEW.md +52 -0
- package/ARCHITECTURE_UPDATES.md +11 -0
- package/CHANGELOG.json +39 -1
- package/CHANGELOG.md +18 -2
- package/dist/dts/components/element-controller.d.ts +2 -1
- package/dist/dts/components/fast-definitions.d.ts +8 -1
- package/dist/dts/index.d.ts +2 -2
- package/dist/dts/observation/arrays.d.ts +40 -0
- package/dist/dts/templating/repeat.d.ts +4 -3
- package/dist/esm/components/element-controller.js +9 -2
- package/dist/esm/components/fast-definitions.js +19 -2
- package/dist/esm/debug.js +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/observation/arrays.js +91 -8
- package/dist/esm/templating/repeat.js +25 -2
- package/dist/fast-element.api.json +306 -9
- package/dist/fast-element.debug.js +166 -14
- package/dist/fast-element.debug.min.js +2 -2
- package/dist/fast-element.js +165 -13
- package/dist/fast-element.min.js +2 -2
- package/dist/fast-element.untrimmed.d.ts +73 -4
- package/docs/api-report.api.md +39 -3
- package/package.json +1 -1
package/dist/fast-element.js
CHANGED
|
@@ -1232,6 +1232,19 @@ class Splice {
|
|
|
1232
1232
|
return this;
|
|
1233
1233
|
}
|
|
1234
1234
|
}
|
|
1235
|
+
/**
|
|
1236
|
+
* A sort array indicates new index positions of array items.
|
|
1237
|
+
* @public
|
|
1238
|
+
*/
|
|
1239
|
+
class Sort {
|
|
1240
|
+
/**
|
|
1241
|
+
* Creates a sort update.
|
|
1242
|
+
* @param sorted - The updated index of sorted items.
|
|
1243
|
+
*/
|
|
1244
|
+
constructor(sorted) {
|
|
1245
|
+
this.sorted = sorted;
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1235
1248
|
/**
|
|
1236
1249
|
* Indicates what level of feature support the splice
|
|
1237
1250
|
* strategy provides.
|
|
@@ -1550,7 +1563,7 @@ function project(array, changes) {
|
|
|
1550
1563
|
* splices needed to represent the change from the old array to the new array.
|
|
1551
1564
|
* @public
|
|
1552
1565
|
*/
|
|
1553
|
-
let
|
|
1566
|
+
let defaultMutationStrategy = Object.freeze({
|
|
1554
1567
|
support: SpliceStrategySupport.optimized,
|
|
1555
1568
|
normalize(previous, current, changes) {
|
|
1556
1569
|
if (previous === void 0) {
|
|
@@ -1576,7 +1589,12 @@ let defaultSpliceStrategy = Object.freeze({
|
|
|
1576
1589
|
},
|
|
1577
1590
|
reverse(array, observer, reverse, args) {
|
|
1578
1591
|
const result = reverse.apply(array, args);
|
|
1579
|
-
|
|
1592
|
+
array.sorted++;
|
|
1593
|
+
const sortedItems = [];
|
|
1594
|
+
for (let i = array.length - 1; i >= 0; i--) {
|
|
1595
|
+
sortedItems.push(i);
|
|
1596
|
+
}
|
|
1597
|
+
observer.addSort(new Sort(sortedItems));
|
|
1580
1598
|
return result;
|
|
1581
1599
|
},
|
|
1582
1600
|
shift(array, observer, shift, args) {
|
|
@@ -1588,8 +1606,20 @@ let defaultSpliceStrategy = Object.freeze({
|
|
|
1588
1606
|
return result;
|
|
1589
1607
|
},
|
|
1590
1608
|
sort(array, observer, sort, args) {
|
|
1609
|
+
const map = new Map();
|
|
1610
|
+
for (let i = 0, ii = array.length; i < ii; ++i) {
|
|
1611
|
+
const mapValue = map.get(array[i]) || [];
|
|
1612
|
+
map.set(array[i], [...mapValue, i]);
|
|
1613
|
+
}
|
|
1591
1614
|
const result = sort.apply(array, args);
|
|
1592
|
-
|
|
1615
|
+
array.sorted++;
|
|
1616
|
+
const sortedItems = [];
|
|
1617
|
+
for (let i = 0, ii = array.length; i < ii; ++i) {
|
|
1618
|
+
const indexs = map.get(array[i]);
|
|
1619
|
+
sortedItems.push(indexs[0]);
|
|
1620
|
+
map.set(array[i], indexs.splice(1));
|
|
1621
|
+
}
|
|
1622
|
+
observer.addSort(new Sort(sortedItems));
|
|
1593
1623
|
return result;
|
|
1594
1624
|
},
|
|
1595
1625
|
splice(array, observer, splice, args) {
|
|
@@ -1617,13 +1647,14 @@ const SpliceStrategy = Object.freeze({
|
|
|
1617
1647
|
* @param strategy - The splice strategy to use.
|
|
1618
1648
|
*/
|
|
1619
1649
|
setDefaultStrategy(strategy) {
|
|
1620
|
-
|
|
1650
|
+
defaultMutationStrategy = strategy;
|
|
1621
1651
|
},
|
|
1622
1652
|
});
|
|
1623
|
-
function setNonEnumerable(target, property, value) {
|
|
1653
|
+
function setNonEnumerable(target, property, value, writable = true) {
|
|
1624
1654
|
Reflect.defineProperty(target, property, {
|
|
1625
1655
|
value,
|
|
1626
1656
|
enumerable: false,
|
|
1657
|
+
writable,
|
|
1627
1658
|
});
|
|
1628
1659
|
}
|
|
1629
1660
|
class DefaultArrayObserver extends SubscriberSet {
|
|
@@ -1631,9 +1662,11 @@ class DefaultArrayObserver extends SubscriberSet {
|
|
|
1631
1662
|
super(subject);
|
|
1632
1663
|
this.oldCollection = void 0;
|
|
1633
1664
|
this.splices = void 0;
|
|
1665
|
+
this.sorts = void 0;
|
|
1634
1666
|
this.needsQueue = true;
|
|
1635
1667
|
this._strategy = null;
|
|
1636
1668
|
this._lengthObserver = void 0;
|
|
1669
|
+
this._sortObserver = void 0;
|
|
1637
1670
|
this.call = this.flush;
|
|
1638
1671
|
setNonEnumerable(subject, "$fastController", this);
|
|
1639
1672
|
}
|
|
@@ -1660,6 +1693,23 @@ class DefaultArrayObserver extends SubscriberSet {
|
|
|
1660
1693
|
}
|
|
1661
1694
|
return observer;
|
|
1662
1695
|
}
|
|
1696
|
+
get sortObserver() {
|
|
1697
|
+
let observer = this._sortObserver;
|
|
1698
|
+
if (observer === void 0) {
|
|
1699
|
+
const array = this.subject;
|
|
1700
|
+
this._sortObserver = observer = {
|
|
1701
|
+
sorted: array.sorted,
|
|
1702
|
+
handleChange() {
|
|
1703
|
+
if (this.sorted !== array.sorted) {
|
|
1704
|
+
this.sorted = array.sorted;
|
|
1705
|
+
Observable.notify(observer, "sorted");
|
|
1706
|
+
}
|
|
1707
|
+
},
|
|
1708
|
+
};
|
|
1709
|
+
this.subscribe(observer);
|
|
1710
|
+
}
|
|
1711
|
+
return observer;
|
|
1712
|
+
}
|
|
1663
1713
|
subscribe(subscriber) {
|
|
1664
1714
|
this.flush();
|
|
1665
1715
|
super.subscribe(subscriber);
|
|
@@ -1673,6 +1723,15 @@ class DefaultArrayObserver extends SubscriberSet {
|
|
|
1673
1723
|
}
|
|
1674
1724
|
this.enqueue();
|
|
1675
1725
|
}
|
|
1726
|
+
addSort(sort) {
|
|
1727
|
+
if (this.sorts === void 0) {
|
|
1728
|
+
this.sorts = [sort];
|
|
1729
|
+
}
|
|
1730
|
+
else {
|
|
1731
|
+
this.sorts.push(sort);
|
|
1732
|
+
}
|
|
1733
|
+
this.enqueue();
|
|
1734
|
+
}
|
|
1676
1735
|
reset(oldCollection) {
|
|
1677
1736
|
this.oldCollection = oldCollection;
|
|
1678
1737
|
this.enqueue();
|
|
@@ -1680,14 +1739,18 @@ class DefaultArrayObserver extends SubscriberSet {
|
|
|
1680
1739
|
flush() {
|
|
1681
1740
|
var _a;
|
|
1682
1741
|
const splices = this.splices;
|
|
1742
|
+
const sorts = this.sorts;
|
|
1683
1743
|
const oldCollection = this.oldCollection;
|
|
1684
|
-
if (splices === void 0 && oldCollection === void 0) {
|
|
1744
|
+
if (splices === void 0 && oldCollection === void 0 && sorts === void 0) {
|
|
1685
1745
|
return;
|
|
1686
1746
|
}
|
|
1687
1747
|
this.needsQueue = true;
|
|
1688
1748
|
this.splices = void 0;
|
|
1749
|
+
this.sorts = void 0;
|
|
1689
1750
|
this.oldCollection = void 0;
|
|
1690
|
-
|
|
1751
|
+
sorts !== void 0
|
|
1752
|
+
? this.notify(sorts)
|
|
1753
|
+
: this.notify(((_a = this._strategy) !== null && _a !== void 0 ? _a : defaultMutationStrategy).normalize(oldCollection, this.subject, splices));
|
|
1691
1754
|
}
|
|
1692
1755
|
enqueue() {
|
|
1693
1756
|
if (this.needsQueue) {
|
|
@@ -1702,6 +1765,7 @@ let enabled = false;
|
|
|
1702
1765
|
* @public
|
|
1703
1766
|
*/
|
|
1704
1767
|
const ArrayObserver = Object.freeze({
|
|
1768
|
+
sorted: 0,
|
|
1705
1769
|
/**
|
|
1706
1770
|
* Enables the array observation mechanism.
|
|
1707
1771
|
* @remarks
|
|
@@ -1718,6 +1782,7 @@ const ArrayObserver = Object.freeze({
|
|
|
1718
1782
|
const proto = Array.prototype;
|
|
1719
1783
|
if (!proto.$fastPatch) {
|
|
1720
1784
|
setNonEnumerable(proto, "$fastPatch", 1);
|
|
1785
|
+
setNonEnumerable(proto, "sorted", 0);
|
|
1721
1786
|
[
|
|
1722
1787
|
proto.pop,
|
|
1723
1788
|
proto.push,
|
|
@@ -1732,7 +1797,7 @@ const ArrayObserver = Object.freeze({
|
|
|
1732
1797
|
const o = this.$fastController;
|
|
1733
1798
|
return o === void 0
|
|
1734
1799
|
? method.apply(this, args)
|
|
1735
|
-
: ((_a = o.strategy) !== null && _a !== void 0 ? _a :
|
|
1800
|
+
: ((_a = o.strategy) !== null && _a !== void 0 ? _a : defaultMutationStrategy)[method.name](this, o, method, args);
|
|
1736
1801
|
};
|
|
1737
1802
|
});
|
|
1738
1803
|
}
|
|
@@ -1756,6 +1821,24 @@ function lengthOf(array) {
|
|
|
1756
1821
|
Observable.track(arrayObserver.lengthObserver, "length");
|
|
1757
1822
|
return array.length;
|
|
1758
1823
|
}
|
|
1824
|
+
/**
|
|
1825
|
+
* Enables observing the sorted property of an array.
|
|
1826
|
+
* @param array - The array to observe the sorted property of.
|
|
1827
|
+
* @returns The sorted property.
|
|
1828
|
+
* @public
|
|
1829
|
+
*/
|
|
1830
|
+
function sortedCount(array) {
|
|
1831
|
+
if (!array) {
|
|
1832
|
+
return 0;
|
|
1833
|
+
}
|
|
1834
|
+
let arrayObserver = array.$fastController;
|
|
1835
|
+
if (arrayObserver === void 0) {
|
|
1836
|
+
ArrayObserver.enable();
|
|
1837
|
+
arrayObserver = Observable.getNotifier(array);
|
|
1838
|
+
}
|
|
1839
|
+
Observable.track(arrayObserver.sortObserver, "sorted");
|
|
1840
|
+
return array.sorted;
|
|
1841
|
+
}
|
|
1759
1842
|
|
|
1760
1843
|
/**
|
|
1761
1844
|
* Captures a binding expression along with related information and capabilities.
|
|
@@ -3860,8 +3943,11 @@ class RepeatBehavior {
|
|
|
3860
3943
|
else if (args[0].reset) {
|
|
3861
3944
|
this.refreshAllViews();
|
|
3862
3945
|
}
|
|
3946
|
+
else if (args[0].sorted) {
|
|
3947
|
+
this.updateSortedViews(args);
|
|
3948
|
+
}
|
|
3863
3949
|
else {
|
|
3864
|
-
this.
|
|
3950
|
+
this.updateSplicedViews(args);
|
|
3865
3951
|
}
|
|
3866
3952
|
}
|
|
3867
3953
|
observeItems(force = false) {
|
|
@@ -3879,7 +3965,27 @@ class RepeatBehavior {
|
|
|
3879
3965
|
newObserver.subscribe(this);
|
|
3880
3966
|
}
|
|
3881
3967
|
}
|
|
3882
|
-
|
|
3968
|
+
updateSortedViews(sorts) {
|
|
3969
|
+
const views = this.views;
|
|
3970
|
+
for (let i = 0, ii = sorts.length; i < ii; ++i) {
|
|
3971
|
+
const sortedItems = sorts[i].sorted.slice();
|
|
3972
|
+
const unsortedItems = sortedItems.slice().sort();
|
|
3973
|
+
for (let j = 0, jj = sortedItems.length; j < jj; ++j) {
|
|
3974
|
+
const sortedIndex = sortedItems.find(value => sortedItems[j] === unsortedItems[value]);
|
|
3975
|
+
if (sortedIndex !== j) {
|
|
3976
|
+
const removedItems = unsortedItems.splice(sortedIndex, 1);
|
|
3977
|
+
unsortedItems.splice(j, 0, ...removedItems);
|
|
3978
|
+
const neighbor = views[j];
|
|
3979
|
+
const location = neighbor ? neighbor.firstChild : this.location;
|
|
3980
|
+
views[sortedIndex].remove();
|
|
3981
|
+
views[sortedIndex].insertBefore(location);
|
|
3982
|
+
const removedViews = views.splice(sortedIndex, 1);
|
|
3983
|
+
views.splice(j, 0, ...removedViews);
|
|
3984
|
+
}
|
|
3985
|
+
}
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
updateSplicedViews(splices) {
|
|
3883
3989
|
const views = this.views;
|
|
3884
3990
|
const bindView = this.bindView;
|
|
3885
3991
|
const items = this.items;
|
|
@@ -4313,6 +4419,37 @@ function children(propertyOrOptions) {
|
|
|
4313
4419
|
return new ChildrenDirective(propertyOrOptions);
|
|
4314
4420
|
}
|
|
4315
4421
|
|
|
4422
|
+
/******************************************************************************
|
|
4423
|
+
Copyright (c) Microsoft Corporation.
|
|
4424
|
+
|
|
4425
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
4426
|
+
purpose with or without fee is hereby granted.
|
|
4427
|
+
|
|
4428
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
4429
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
4430
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
4431
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
4432
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
4433
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
4434
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
4435
|
+
***************************************************************************** */
|
|
4436
|
+
|
|
4437
|
+
function __decorate(decorators, target, key, desc) {
|
|
4438
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4439
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4440
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4441
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4442
|
+
}
|
|
4443
|
+
|
|
4444
|
+
function __metadata(metadataKey, metadataValue) {
|
|
4445
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
|
4446
|
+
}
|
|
4447
|
+
|
|
4448
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
4449
|
+
var e = new Error(message);
|
|
4450
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
4451
|
+
};
|
|
4452
|
+
|
|
4316
4453
|
const booleanMode = "boolean";
|
|
4317
4454
|
const reflectMode = "reflect";
|
|
4318
4455
|
/**
|
|
@@ -4524,6 +4661,10 @@ function attr(configOrTarget, prop) {
|
|
|
4524
4661
|
const defaultShadowOptions = { mode: "open" };
|
|
4525
4662
|
const defaultElementOptions = {};
|
|
4526
4663
|
const fastElementBaseTypes = new Set();
|
|
4664
|
+
/**
|
|
4665
|
+
* The FAST custom element registry
|
|
4666
|
+
* @internal
|
|
4667
|
+
*/
|
|
4527
4668
|
const fastElementRegistry = FAST.getById(KernelServiceId.elementRegistry, () => createTypeRegistry());
|
|
4528
4669
|
/**
|
|
4529
4670
|
* Defines metadata for a FASTElement.
|
|
@@ -4624,6 +4765,10 @@ FASTElementDefinition.getByType = fastElementRegistry.getByType;
|
|
|
4624
4765
|
* @param instance - The custom element instance to retrieve the definition for.
|
|
4625
4766
|
*/
|
|
4626
4767
|
FASTElementDefinition.getForInstance = fastElementRegistry.getForInstance;
|
|
4768
|
+
__decorate([
|
|
4769
|
+
observable,
|
|
4770
|
+
__metadata("design:type", Object)
|
|
4771
|
+
], FASTElementDefinition.prototype, "template", void 0);
|
|
4627
4772
|
|
|
4628
4773
|
/**
|
|
4629
4774
|
* A Behavior that enables advanced rendering.
|
|
@@ -5542,20 +5687,27 @@ class ElementController extends PropertyChangeNotifier {
|
|
|
5542
5687
|
/**
|
|
5543
5688
|
* Locates or creates a controller for the specified element.
|
|
5544
5689
|
* @param element - The element to return the controller for.
|
|
5690
|
+
* @param override - Reset the controller even if one has been defined.
|
|
5545
5691
|
* @remarks
|
|
5546
5692
|
* The specified element must have a {@link FASTElementDefinition}
|
|
5547
5693
|
* registered either through the use of the {@link customElement}
|
|
5548
5694
|
* decorator or a call to `FASTElement.define`.
|
|
5549
5695
|
*/
|
|
5550
|
-
static forCustomElement(element) {
|
|
5696
|
+
static forCustomElement(element, override = false) {
|
|
5551
5697
|
const controller = element.$fastController;
|
|
5552
|
-
if (controller !== void 0) {
|
|
5698
|
+
if (controller !== void 0 && !override) {
|
|
5553
5699
|
return controller;
|
|
5554
5700
|
}
|
|
5555
5701
|
const definition = FASTElementDefinition.getForInstance(element);
|
|
5556
5702
|
if (definition === void 0) {
|
|
5557
5703
|
throw FAST.error(1401 /* Message.missingElementDefinition */);
|
|
5558
5704
|
}
|
|
5705
|
+
Observable.getNotifier(definition).subscribe({
|
|
5706
|
+
handleChange: () => {
|
|
5707
|
+
ElementController.forCustomElement(element, true);
|
|
5708
|
+
element.$fastController.connect();
|
|
5709
|
+
},
|
|
5710
|
+
}, "template");
|
|
5559
5711
|
return (element.$fastController = new elementControllerStrategy(element, definition));
|
|
5560
5712
|
}
|
|
5561
5713
|
/**
|
|
@@ -5850,4 +6002,4 @@ function customElement(nameOrDef) {
|
|
|
5850
6002
|
|
|
5851
6003
|
DOM.setPolicy(DOMPolicy.create());
|
|
5852
6004
|
|
|
5853
|
-
export { ArrayObserver, AttributeConfiguration, AttributeDefinition, Binding, CSSBindingDirective, CSSDirective, ChildrenDirective, Compiler, DOM, DOMAspect, ElementController, ElementStyles, ExecutionContext, FAST, FASTElement, FASTElementDefinition, HTMLBindingDirective, HTMLDirective, HTMLView, HydratableElementController, HydrationBindingError, InlineTemplateDirective, Markup, NodeObservationDirective, Observable, Parser, PropertyChangeNotifier, RefDirective, RenderBehavior, RenderDirective, RepeatBehavior, RepeatDirective, SlottedDirective, SourceLifetime, Splice, SpliceStrategy, SpliceStrategySupport, StatelessAttachedAttributeDirective, SubscriberSet, Updates, ViewTemplate, attr, booleanConverter, children, css, cssDirective, customElement, elements, emptyArray, html, htmlDirective, lengthOf, listener, normalizeBinding$1 as normalizeBinding, nullableBooleanConverter, nullableNumberConverter, observable, oneTime, oneWay, ref, render, repeat, slotted, volatile, when };
|
|
6005
|
+
export { ArrayObserver, AttributeConfiguration, AttributeDefinition, Binding, CSSBindingDirective, CSSDirective, ChildrenDirective, Compiler, DOM, DOMAspect, ElementController, ElementStyles, ExecutionContext, FAST, FASTElement, FASTElementDefinition, HTMLBindingDirective, HTMLDirective, HTMLView, HydratableElementController, HydrationBindingError, InlineTemplateDirective, Markup, NodeObservationDirective, Observable, Parser, PropertyChangeNotifier, RefDirective, RenderBehavior, RenderDirective, RepeatBehavior, RepeatDirective, SlottedDirective, Sort, SourceLifetime, Splice, SpliceStrategy, SpliceStrategySupport, StatelessAttachedAttributeDirective, SubscriberSet, Updates, ViewTemplate, attr, booleanConverter, children, css, cssDirective, customElement, elements, emptyArray, fastElementRegistry, html, htmlDirective, lengthOf, listener, normalizeBinding$1 as normalizeBinding, nullableBooleanConverter, nullableNumberConverter, observable, oneTime, oneWay, ref, render, repeat, slotted, sortedCount, volatile, when };
|