@microsoft/fast-element 2.0.0-beta.3 → 2.0.0-beta.6
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 +147 -0
- package/CHANGELOG.md +42 -1
- package/dist/dts/components/fast-definitions.d.ts +9 -8
- package/dist/dts/components/fast-element.d.ts +12 -24
- package/dist/dts/context.d.ts +1 -1
- package/dist/dts/di/di.d.ts +858 -0
- package/dist/dts/interfaces.d.ts +43 -7
- package/dist/dts/observation/observable.d.ts +19 -13
- package/dist/dts/state/exports.d.ts +3 -0
- package/dist/dts/state/reactive.d.ts +8 -0
- package/dist/dts/state/state.d.ts +141 -0
- package/dist/dts/state/visitor.d.ts +6 -0
- package/dist/dts/state/watch.d.ts +10 -0
- package/dist/dts/styles/element-styles.d.ts +6 -0
- package/dist/dts/templating/binding-signal.d.ts +10 -27
- package/dist/dts/templating/binding-two-way.d.ts +16 -41
- package/dist/dts/templating/binding.d.ts +79 -118
- package/dist/dts/templating/html-directive.d.ts +28 -2
- package/dist/dts/templating/render.d.ts +277 -0
- package/dist/dts/templating/repeat.d.ts +12 -16
- package/dist/dts/templating/template.d.ts +3 -3
- package/dist/dts/templating/when.d.ts +3 -3
- package/dist/dts/testing/exports.d.ts +2 -0
- package/dist/dts/testing/fixture.d.ts +90 -0
- package/dist/dts/testing/timeout.d.ts +7 -0
- package/dist/dts/utilities.d.ts +0 -18
- package/dist/esm/components/fast-definitions.js +25 -27
- package/dist/esm/components/fast-element.js +20 -11
- package/dist/esm/context.js +5 -1
- package/dist/esm/debug.js +35 -4
- package/dist/esm/di/di.js +1351 -0
- package/dist/esm/interfaces.js +4 -0
- package/dist/esm/observation/arrays.js +303 -2
- package/dist/esm/observation/observable.js +11 -6
- package/dist/esm/platform.js +1 -1
- package/dist/esm/state/exports.js +3 -0
- package/dist/esm/state/reactive.js +34 -0
- package/dist/esm/state/state.js +148 -0
- package/dist/esm/state/visitor.js +28 -0
- package/dist/esm/state/watch.js +36 -0
- package/dist/esm/styles/element-styles.js +14 -0
- package/dist/esm/templating/binding-signal.js +56 -61
- package/dist/esm/templating/binding-two-way.js +51 -35
- package/dist/esm/templating/binding.js +137 -156
- package/dist/esm/templating/compiler.js +29 -7
- package/dist/esm/templating/html-directive.js +12 -1
- package/dist/esm/templating/render.js +392 -0
- package/dist/esm/templating/repeat.js +57 -40
- package/dist/esm/templating/template.js +8 -5
- package/dist/esm/templating/view.js +3 -1
- package/dist/esm/templating/when.js +5 -4
- package/dist/esm/testing/exports.js +2 -0
- package/dist/esm/testing/fixture.js +88 -0
- package/dist/esm/testing/timeout.js +24 -0
- package/dist/esm/utilities.js +0 -95
- package/dist/fast-element.api.json +2827 -2757
- package/dist/fast-element.d.ts +215 -229
- package/dist/fast-element.debug.js +650 -256
- package/dist/fast-element.debug.min.js +1 -1
- package/dist/fast-element.js +615 -252
- package/dist/fast-element.min.js +1 -1
- package/dist/fast-element.untrimmed.d.ts +223 -234
- package/docs/api-report.md +87 -90
- package/package.json +18 -9
- package/dist/dts/hooks.d.ts +0 -20
- package/dist/dts/observation/splice-strategies.d.ts +0 -13
- package/dist/esm/hooks.js +0 -32
- package/dist/esm/observation/splice-strategies.js +0 -400
|
@@ -98,19 +98,50 @@ const debugMessages = {
|
|
|
98
98
|
[1201 /* onlySetHTMLPolicyOnce */]: "The HTML policy can only be set once.",
|
|
99
99
|
[1202 /* bindingInnerHTMLRequiresTrustedTypes */]: "To bind innerHTML, you must use a TrustedTypesPolicy.",
|
|
100
100
|
[1203 /* twoWayBindingRequiresObservables */]: "View=>Model update skipped. To use twoWay binding, the target property must be observable.",
|
|
101
|
+
[1204 /* hostBindingWithoutHost */]: "No host element is present. Cannot bind host with ${name}.",
|
|
102
|
+
[1205 /* unsupportedBindingBehavior */]: "The requested binding behavior is not supported by the binding engine.",
|
|
101
103
|
[1401 /* missingElementDefinition */]: "Missing FASTElement definition.",
|
|
104
|
+
[1501 /* noRegistrationForContext */]: "No registration for Context/Interface '${name}'.",
|
|
105
|
+
[1502 /* noFactoryForResolver */]: "Dependency injection resolver for '${key}' returned a null factory.",
|
|
106
|
+
[1503 /* invalidResolverStrategy */]: "Invalid dependency injection resolver strategy specified '${strategy}'.",
|
|
107
|
+
[1504 /* cannotAutoregisterDependency */]: "Unable to autoregister dependency.",
|
|
108
|
+
[1505 /* cannotResolveKey */]: "Unable to resolve dependency injection key '${key}'.",
|
|
109
|
+
[1506 /* cannotConstructNativeFunction */]: "'${name}' is a native function and therefore cannot be safely constructed by DI. If this is intentional, please use a callback or cachedCallback resolver.",
|
|
110
|
+
[1507 /* cannotJITRegisterNonConstructor */]: "Attempted to jitRegister something that is not a constructor '${value}'. Did you forget to register this dependency?",
|
|
111
|
+
[1508 /* cannotJITRegisterIntrinsic */]: "Attempted to jitRegister an intrinsic type '${value}'. Did you forget to add @inject(Key)?",
|
|
112
|
+
[1509 /* cannotJITRegisterInterface */]: "Attempted to jitRegister an interface '${value}'.",
|
|
113
|
+
[1510 /* invalidResolver */]: "A valid resolver was not returned from the register method.",
|
|
114
|
+
[1511 /* invalidKey */]: "Key/value cannot be null or undefined. Are you trying to inject/register something that doesn't exist with DI?",
|
|
115
|
+
[1512 /* noDefaultResolver */]: "'${key}' not registered. Did you forget to add @singleton()?",
|
|
116
|
+
[1513 /* cyclicDependency */]: "Cyclic dependency found '${name}'.",
|
|
117
|
+
[1514 /* connectUpdateRequiresController */]: "Injected properties that are updated on changes to DOM connectivity require the target object to be an instance of FASTElement.",
|
|
102
118
|
};
|
|
119
|
+
const allPlaceholders = /(\$\{\w+?})/g;
|
|
120
|
+
const placeholder = /\$\{(\w+?)}/g;
|
|
121
|
+
const noValues = Object.freeze({});
|
|
122
|
+
function formatMessage(message, values) {
|
|
123
|
+
return message
|
|
124
|
+
.split(allPlaceholders)
|
|
125
|
+
.map(v => {
|
|
126
|
+
var _a;
|
|
127
|
+
const replaced = v.replace(placeholder, "$1");
|
|
128
|
+
return String((_a = values[replaced]) !== null && _a !== void 0 ? _a : v);
|
|
129
|
+
})
|
|
130
|
+
.join("");
|
|
131
|
+
}
|
|
103
132
|
Object.assign(FAST$1, {
|
|
104
133
|
addMessages(messages) {
|
|
105
134
|
Object.assign(debugMessages, messages);
|
|
106
135
|
},
|
|
107
|
-
warn(code,
|
|
136
|
+
warn(code, values = noValues) {
|
|
108
137
|
var _a;
|
|
109
|
-
|
|
138
|
+
const message = (_a = debugMessages[code]) !== null && _a !== void 0 ? _a : "Unknown Warning";
|
|
139
|
+
console.warn(formatMessage(message, values));
|
|
110
140
|
},
|
|
111
|
-
error(code,
|
|
141
|
+
error(code, values = noValues) {
|
|
112
142
|
var _a;
|
|
113
|
-
|
|
143
|
+
const message = (_a = debugMessages[code]) !== null && _a !== void 0 ? _a : "Unknown Error";
|
|
144
|
+
return new Error(formatMessage(message, values));
|
|
114
145
|
},
|
|
115
146
|
});
|
|
116
147
|
|
|
@@ -142,7 +173,7 @@ if (FAST.error === void 0) {
|
|
|
142
173
|
Object.assign(FAST, {
|
|
143
174
|
warn() { },
|
|
144
175
|
error(code) {
|
|
145
|
-
return new Error(`
|
|
176
|
+
return new Error(`Error ${code}`);
|
|
146
177
|
},
|
|
147
178
|
addMessages() { },
|
|
148
179
|
});
|
|
@@ -479,7 +510,7 @@ const Observable = FAST.getById(2 /* KernelServiceId.observable */, () => {
|
|
|
479
510
|
}
|
|
480
511
|
}
|
|
481
512
|
}
|
|
482
|
-
class
|
|
513
|
+
class ExpressionNotifierImplementation extends SubscriberSet {
|
|
483
514
|
constructor(binding, initialSubscriber, isVolatileBinding = false) {
|
|
484
515
|
super(binding, initialSubscriber);
|
|
485
516
|
this.binding = binding;
|
|
@@ -504,8 +535,13 @@ const Observable = FAST.getById(2 /* KernelServiceId.observable */, () => {
|
|
|
504
535
|
const previousWatcher = watcher;
|
|
505
536
|
watcher = this.needsRefresh ? this : void 0;
|
|
506
537
|
this.needsRefresh = this.isVolatileBinding;
|
|
507
|
-
|
|
508
|
-
|
|
538
|
+
let result;
|
|
539
|
+
try {
|
|
540
|
+
result = this.binding(source, context !== null && context !== void 0 ? context : ExecutionContext.default);
|
|
541
|
+
}
|
|
542
|
+
finally {
|
|
543
|
+
watcher = previousWatcher;
|
|
544
|
+
}
|
|
509
545
|
return result;
|
|
510
546
|
}
|
|
511
547
|
dispose() {
|
|
@@ -634,14 +670,14 @@ const Observable = FAST.getById(2 /* KernelServiceId.observable */, () => {
|
|
|
634
670
|
*/
|
|
635
671
|
getAccessors,
|
|
636
672
|
/**
|
|
637
|
-
* Creates a {@link
|
|
638
|
-
* provided {@link
|
|
673
|
+
* Creates a {@link ExpressionNotifier} that can watch the
|
|
674
|
+
* provided {@link Expression} for changes.
|
|
639
675
|
* @param binding - The binding to observe.
|
|
640
676
|
* @param initialSubscriber - An initial subscriber to changes in the binding value.
|
|
641
677
|
* @param isVolatileBinding - Indicates whether the binding's dependency list must be re-evaluated on every value evaluation.
|
|
642
678
|
*/
|
|
643
679
|
binding(binding, initialSubscriber, isVolatileBinding = this.isVolatileBinding(binding)) {
|
|
644
|
-
return new
|
|
680
|
+
return new ExpressionNotifierImplementation(binding, initialSubscriber, isVolatileBinding);
|
|
645
681
|
},
|
|
646
682
|
/**
|
|
647
683
|
* Determines whether a binding expression is volatile and needs to have its dependency list re-evaluated
|
|
@@ -875,10 +911,311 @@ const SpliceStrategySupport = Object.freeze({
|
|
|
875
911
|
const reset = new Splice(0, emptyArray, 0);
|
|
876
912
|
reset.reset = true;
|
|
877
913
|
const resetSplices = [reset];
|
|
914
|
+
// Note: This function is *based* on the computation of the Levenshtein
|
|
915
|
+
// "edit" distance. The one change is that "updates" are treated as two
|
|
916
|
+
// edits - not one. With Array splices, an update is really a delete
|
|
917
|
+
// followed by an add. By retaining this, we optimize for "keeping" the
|
|
918
|
+
// maximum array items in the original array. For example:
|
|
919
|
+
//
|
|
920
|
+
// 'xxxx123' to '123yyyy'
|
|
921
|
+
//
|
|
922
|
+
// With 1-edit updates, the shortest path would be just to update all seven
|
|
923
|
+
// characters. With 2-edit updates, we delete 4, leave 3, and add 4. This
|
|
924
|
+
// leaves the substring '123' intact.
|
|
925
|
+
function calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd) {
|
|
926
|
+
// "Deletion" columns
|
|
927
|
+
const rowCount = oldEnd - oldStart + 1;
|
|
928
|
+
const columnCount = currentEnd - currentStart + 1;
|
|
929
|
+
const distances = new Array(rowCount);
|
|
930
|
+
let north;
|
|
931
|
+
let west;
|
|
932
|
+
// "Addition" rows. Initialize null column.
|
|
933
|
+
for (let i = 0; i < rowCount; ++i) {
|
|
934
|
+
distances[i] = new Array(columnCount);
|
|
935
|
+
distances[i][0] = i;
|
|
936
|
+
}
|
|
937
|
+
// Initialize null row
|
|
938
|
+
for (let j = 0; j < columnCount; ++j) {
|
|
939
|
+
distances[0][j] = j;
|
|
940
|
+
}
|
|
941
|
+
for (let i = 1; i < rowCount; ++i) {
|
|
942
|
+
for (let j = 1; j < columnCount; ++j) {
|
|
943
|
+
if (current[currentStart + j - 1] === old[oldStart + i - 1]) {
|
|
944
|
+
distances[i][j] = distances[i - 1][j - 1];
|
|
945
|
+
}
|
|
946
|
+
else {
|
|
947
|
+
north = distances[i - 1][j] + 1;
|
|
948
|
+
west = distances[i][j - 1] + 1;
|
|
949
|
+
distances[i][j] = north < west ? north : west;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
return distances;
|
|
954
|
+
}
|
|
955
|
+
// This starts at the final weight, and walks "backward" by finding
|
|
956
|
+
// the minimum previous weight recursively until the origin of the weight
|
|
957
|
+
// matrix.
|
|
958
|
+
function spliceOperationsFromEditDistances(distances) {
|
|
959
|
+
let i = distances.length - 1;
|
|
960
|
+
let j = distances[0].length - 1;
|
|
961
|
+
let current = distances[i][j];
|
|
962
|
+
const edits = [];
|
|
963
|
+
while (i > 0 || j > 0) {
|
|
964
|
+
if (i === 0) {
|
|
965
|
+
edits.push(2 /* Edit.add */);
|
|
966
|
+
j--;
|
|
967
|
+
continue;
|
|
968
|
+
}
|
|
969
|
+
if (j === 0) {
|
|
970
|
+
edits.push(3 /* Edit.delete */);
|
|
971
|
+
i--;
|
|
972
|
+
continue;
|
|
973
|
+
}
|
|
974
|
+
const northWest = distances[i - 1][j - 1];
|
|
975
|
+
const west = distances[i - 1][j];
|
|
976
|
+
const north = distances[i][j - 1];
|
|
977
|
+
let min;
|
|
978
|
+
if (west < north) {
|
|
979
|
+
min = west < northWest ? west : northWest;
|
|
980
|
+
}
|
|
981
|
+
else {
|
|
982
|
+
min = north < northWest ? north : northWest;
|
|
983
|
+
}
|
|
984
|
+
if (min === northWest) {
|
|
985
|
+
if (northWest === current) {
|
|
986
|
+
edits.push(0 /* Edit.leave */);
|
|
987
|
+
}
|
|
988
|
+
else {
|
|
989
|
+
edits.push(1 /* Edit.update */);
|
|
990
|
+
current = northWest;
|
|
991
|
+
}
|
|
992
|
+
i--;
|
|
993
|
+
j--;
|
|
994
|
+
}
|
|
995
|
+
else if (min === west) {
|
|
996
|
+
edits.push(3 /* Edit.delete */);
|
|
997
|
+
i--;
|
|
998
|
+
current = west;
|
|
999
|
+
}
|
|
1000
|
+
else {
|
|
1001
|
+
edits.push(2 /* Edit.add */);
|
|
1002
|
+
j--;
|
|
1003
|
+
current = north;
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
return edits.reverse();
|
|
1007
|
+
}
|
|
1008
|
+
function sharedPrefix(current, old, searchLength) {
|
|
1009
|
+
for (let i = 0; i < searchLength; ++i) {
|
|
1010
|
+
if (current[i] !== old[i]) {
|
|
1011
|
+
return i;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
return searchLength;
|
|
1015
|
+
}
|
|
1016
|
+
function sharedSuffix(current, old, searchLength) {
|
|
1017
|
+
let index1 = current.length;
|
|
1018
|
+
let index2 = old.length;
|
|
1019
|
+
let count = 0;
|
|
1020
|
+
while (count < searchLength && current[--index1] === old[--index2]) {
|
|
1021
|
+
count++;
|
|
1022
|
+
}
|
|
1023
|
+
return count;
|
|
1024
|
+
}
|
|
1025
|
+
function intersect(start1, end1, start2, end2) {
|
|
1026
|
+
// Disjoint
|
|
1027
|
+
if (end1 < start2 || end2 < start1) {
|
|
1028
|
+
return -1;
|
|
1029
|
+
}
|
|
1030
|
+
// Adjacent
|
|
1031
|
+
if (end1 === start2 || end2 === start1) {
|
|
1032
|
+
return 0;
|
|
1033
|
+
}
|
|
1034
|
+
// Non-zero intersect, span1 first
|
|
1035
|
+
if (start1 < start2) {
|
|
1036
|
+
if (end1 < end2) {
|
|
1037
|
+
return end1 - start2; // Overlap
|
|
1038
|
+
}
|
|
1039
|
+
return end2 - start2; // Contained
|
|
1040
|
+
}
|
|
1041
|
+
// Non-zero intersect, span2 first
|
|
1042
|
+
if (end2 < end1) {
|
|
1043
|
+
return end2 - start1; // Overlap
|
|
1044
|
+
}
|
|
1045
|
+
return end1 - start1; // Contained
|
|
1046
|
+
}
|
|
1047
|
+
/**
|
|
1048
|
+
* @remarks
|
|
1049
|
+
* Lacking individual splice mutation information, the minimal set of
|
|
1050
|
+
* splices can be synthesized given the previous state and final state of an
|
|
1051
|
+
* array. The basic approach is to calculate the edit distance matrix and
|
|
1052
|
+
* choose the shortest path through it.
|
|
1053
|
+
*
|
|
1054
|
+
* Complexity: O(l * p)
|
|
1055
|
+
* l: The length of the current array
|
|
1056
|
+
* p: The length of the old array
|
|
1057
|
+
*/
|
|
1058
|
+
function calc(current, currentStart, currentEnd, old, oldStart, oldEnd) {
|
|
1059
|
+
let prefixCount = 0;
|
|
1060
|
+
let suffixCount = 0;
|
|
1061
|
+
const minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);
|
|
1062
|
+
if (currentStart === 0 && oldStart === 0) {
|
|
1063
|
+
prefixCount = sharedPrefix(current, old, minLength);
|
|
1064
|
+
}
|
|
1065
|
+
if (currentEnd === current.length && oldEnd === old.length) {
|
|
1066
|
+
suffixCount = sharedSuffix(current, old, minLength - prefixCount);
|
|
1067
|
+
}
|
|
1068
|
+
currentStart += prefixCount;
|
|
1069
|
+
oldStart += prefixCount;
|
|
1070
|
+
currentEnd -= suffixCount;
|
|
1071
|
+
oldEnd -= suffixCount;
|
|
1072
|
+
if (currentEnd - currentStart === 0 && oldEnd - oldStart === 0) {
|
|
1073
|
+
return emptyArray;
|
|
1074
|
+
}
|
|
1075
|
+
if (currentStart === currentEnd) {
|
|
1076
|
+
const splice = new Splice(currentStart, [], 0);
|
|
1077
|
+
while (oldStart < oldEnd) {
|
|
1078
|
+
splice.removed.push(old[oldStart++]);
|
|
1079
|
+
}
|
|
1080
|
+
return [splice];
|
|
1081
|
+
}
|
|
1082
|
+
else if (oldStart === oldEnd) {
|
|
1083
|
+
return [new Splice(currentStart, [], currentEnd - currentStart)];
|
|
1084
|
+
}
|
|
1085
|
+
const ops = spliceOperationsFromEditDistances(calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));
|
|
1086
|
+
const splices = [];
|
|
1087
|
+
let splice = void 0;
|
|
1088
|
+
let index = currentStart;
|
|
1089
|
+
let oldIndex = oldStart;
|
|
1090
|
+
for (let i = 0; i < ops.length; ++i) {
|
|
1091
|
+
switch (ops[i]) {
|
|
1092
|
+
case 0 /* Edit.leave */:
|
|
1093
|
+
if (splice !== void 0) {
|
|
1094
|
+
splices.push(splice);
|
|
1095
|
+
splice = void 0;
|
|
1096
|
+
}
|
|
1097
|
+
index++;
|
|
1098
|
+
oldIndex++;
|
|
1099
|
+
break;
|
|
1100
|
+
case 1 /* Edit.update */:
|
|
1101
|
+
if (splice === void 0) {
|
|
1102
|
+
splice = new Splice(index, [], 0);
|
|
1103
|
+
}
|
|
1104
|
+
splice.addedCount++;
|
|
1105
|
+
index++;
|
|
1106
|
+
splice.removed.push(old[oldIndex]);
|
|
1107
|
+
oldIndex++;
|
|
1108
|
+
break;
|
|
1109
|
+
case 2 /* Edit.add */:
|
|
1110
|
+
if (splice === void 0) {
|
|
1111
|
+
splice = new Splice(index, [], 0);
|
|
1112
|
+
}
|
|
1113
|
+
splice.addedCount++;
|
|
1114
|
+
index++;
|
|
1115
|
+
break;
|
|
1116
|
+
case 3 /* Edit.delete */:
|
|
1117
|
+
if (splice === void 0) {
|
|
1118
|
+
splice = new Splice(index, [], 0);
|
|
1119
|
+
}
|
|
1120
|
+
splice.removed.push(old[oldIndex]);
|
|
1121
|
+
oldIndex++;
|
|
1122
|
+
break;
|
|
1123
|
+
// no default
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
if (splice !== void 0) {
|
|
1127
|
+
splices.push(splice);
|
|
1128
|
+
}
|
|
1129
|
+
return splices;
|
|
1130
|
+
}
|
|
1131
|
+
function merge(splice, splices) {
|
|
1132
|
+
let inserted = false;
|
|
1133
|
+
let insertionOffset = 0;
|
|
1134
|
+
for (let i = 0; i < splices.length; i++) {
|
|
1135
|
+
const current = splices[i];
|
|
1136
|
+
current.index += insertionOffset;
|
|
1137
|
+
if (inserted) {
|
|
1138
|
+
continue;
|
|
1139
|
+
}
|
|
1140
|
+
const intersectCount = intersect(splice.index, splice.index + splice.removed.length, current.index, current.index + current.addedCount);
|
|
1141
|
+
if (intersectCount >= 0) {
|
|
1142
|
+
// Merge the two splices
|
|
1143
|
+
splices.splice(i, 1);
|
|
1144
|
+
i--;
|
|
1145
|
+
insertionOffset -= current.addedCount - current.removed.length;
|
|
1146
|
+
splice.addedCount += current.addedCount - intersectCount;
|
|
1147
|
+
const deleteCount = splice.removed.length + current.removed.length - intersectCount;
|
|
1148
|
+
if (!splice.addedCount && !deleteCount) {
|
|
1149
|
+
// merged splice is a noop. discard.
|
|
1150
|
+
inserted = true;
|
|
1151
|
+
}
|
|
1152
|
+
else {
|
|
1153
|
+
let currentRemoved = current.removed;
|
|
1154
|
+
if (splice.index < current.index) {
|
|
1155
|
+
// some prefix of splice.removed is prepended to current.removed.
|
|
1156
|
+
const prepend = splice.removed.slice(0, current.index - splice.index);
|
|
1157
|
+
prepend.push(...currentRemoved);
|
|
1158
|
+
currentRemoved = prepend;
|
|
1159
|
+
}
|
|
1160
|
+
if (splice.index + splice.removed.length >
|
|
1161
|
+
current.index + current.addedCount) {
|
|
1162
|
+
// some suffix of splice.removed is appended to current.removed.
|
|
1163
|
+
const append = splice.removed.slice(current.index + current.addedCount - splice.index);
|
|
1164
|
+
currentRemoved.push(...append);
|
|
1165
|
+
}
|
|
1166
|
+
splice.removed = currentRemoved;
|
|
1167
|
+
if (current.index < splice.index) {
|
|
1168
|
+
splice.index = current.index;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
else if (splice.index < current.index) {
|
|
1173
|
+
// Insert splice here.
|
|
1174
|
+
inserted = true;
|
|
1175
|
+
splices.splice(i, 0, splice);
|
|
1176
|
+
i++;
|
|
1177
|
+
const offset = splice.addedCount - splice.removed.length;
|
|
1178
|
+
current.index += offset;
|
|
1179
|
+
insertionOffset += offset;
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
if (!inserted) {
|
|
1183
|
+
splices.push(splice);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
function project(array, changes) {
|
|
1187
|
+
let splices = [];
|
|
1188
|
+
const initialSplices = [];
|
|
1189
|
+
for (let i = 0, ii = changes.length; i < ii; i++) {
|
|
1190
|
+
merge(changes[i], initialSplices);
|
|
1191
|
+
}
|
|
1192
|
+
for (let i = 0, ii = initialSplices.length; i < ii; ++i) {
|
|
1193
|
+
const splice = initialSplices[i];
|
|
1194
|
+
if (splice.addedCount === 1 && splice.removed.length === 1) {
|
|
1195
|
+
if (splice.removed[0] !== array[splice.index]) {
|
|
1196
|
+
splices.push(splice);
|
|
1197
|
+
}
|
|
1198
|
+
continue;
|
|
1199
|
+
}
|
|
1200
|
+
splices = splices.concat(calc(array, splice.index, splice.index + splice.addedCount, splice.removed, 0, splice.removed.length));
|
|
1201
|
+
}
|
|
1202
|
+
return splices;
|
|
1203
|
+
}
|
|
1204
|
+
/**
|
|
1205
|
+
* A SpliceStrategy that attempts to merge all splices into the minimal set of
|
|
1206
|
+
* splices needed to represent the change from the old array to the new array.
|
|
1207
|
+
* @public
|
|
1208
|
+
*/
|
|
878
1209
|
let defaultSpliceStrategy = Object.freeze({
|
|
879
|
-
support: SpliceStrategySupport.
|
|
1210
|
+
support: SpliceStrategySupport.optimized,
|
|
880
1211
|
normalize(previous, current, changes) {
|
|
881
|
-
|
|
1212
|
+
if (previous === void 0) {
|
|
1213
|
+
if (changes === void 0) {
|
|
1214
|
+
return emptyArray;
|
|
1215
|
+
}
|
|
1216
|
+
return changes.length > 1 ? project(current, changes) : changes;
|
|
1217
|
+
}
|
|
1218
|
+
return resetSplices;
|
|
882
1219
|
},
|
|
883
1220
|
pop(array, observer, pop, args) {
|
|
884
1221
|
const notEmpty = array.length > 0;
|
|
@@ -1147,6 +1484,20 @@ class ElementStyles {
|
|
|
1147
1484
|
static setDefaultStrategy(Strategy) {
|
|
1148
1485
|
DefaultStyleStrategy = Strategy;
|
|
1149
1486
|
}
|
|
1487
|
+
/**
|
|
1488
|
+
* Normalizes a set of composable style options.
|
|
1489
|
+
* @param styles - The style options to normalize.
|
|
1490
|
+
* @returns A singular ElementStyles instance or undefined.
|
|
1491
|
+
*/
|
|
1492
|
+
static normalize(styles) {
|
|
1493
|
+
return styles === void 0
|
|
1494
|
+
? void 0
|
|
1495
|
+
: Array.isArray(styles)
|
|
1496
|
+
? new ElementStyles(styles)
|
|
1497
|
+
: styles instanceof ElementStyles
|
|
1498
|
+
? styles
|
|
1499
|
+
: new ElementStyles([styles]);
|
|
1500
|
+
}
|
|
1150
1501
|
}
|
|
1151
1502
|
/**
|
|
1152
1503
|
* Indicates whether the DOM supports the adoptedStyleSheets feature.
|
|
@@ -1473,6 +1824,13 @@ function htmlDirective(options) {
|
|
|
1473
1824
|
HTMLDirective.define(type, options);
|
|
1474
1825
|
};
|
|
1475
1826
|
}
|
|
1827
|
+
/**
|
|
1828
|
+
* Captures a binding expression along with related information and capabilities.
|
|
1829
|
+
*
|
|
1830
|
+
* @public
|
|
1831
|
+
*/
|
|
1832
|
+
class Binding {
|
|
1833
|
+
}
|
|
1476
1834
|
/**
|
|
1477
1835
|
* The type of HTML aspect to target.
|
|
1478
1836
|
* @public
|
|
@@ -1566,6 +1924,10 @@ class StatelessAttachedAttributeDirective {
|
|
|
1566
1924
|
*/
|
|
1567
1925
|
constructor(options) {
|
|
1568
1926
|
this.options = options;
|
|
1927
|
+
/**
|
|
1928
|
+
* The unique id of the factory.
|
|
1929
|
+
*/
|
|
1930
|
+
this.id = nextId();
|
|
1569
1931
|
}
|
|
1570
1932
|
/**
|
|
1571
1933
|
* Creates a behavior.
|
|
@@ -1594,99 +1956,28 @@ const createInnerHTMLBinding = globalThis.TrustedHTML
|
|
|
1594
1956
|
throw FAST.error(1202 /* Message.bindingInnerHTMLRequiresTrustedTypes */);
|
|
1595
1957
|
}
|
|
1596
1958
|
: (binding) => binding;
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
/**
|
|
1603
|
-
* Creates a binding mode based on the supplied behavior types.
|
|
1604
|
-
* @param UpdateType - The base behavior type used to update aspects.
|
|
1605
|
-
* @param EventType - The base behavior type used to respond to events.
|
|
1606
|
-
* @returns A new binding mode.
|
|
1607
|
-
*/
|
|
1608
|
-
define(UpdateType, EventType = EventBinding) {
|
|
1609
|
-
return Object.freeze({
|
|
1610
|
-
[1]: d => new UpdateType(d, DOM.setAttribute),
|
|
1611
|
-
[2]: d => new UpdateType(d, DOM.setBooleanAttribute),
|
|
1612
|
-
[3]: d => new UpdateType(d, (t, a, v) => (t[a] = v)),
|
|
1613
|
-
[4]: d => new (createContentBinding(UpdateType))(d, updateContentTarget),
|
|
1614
|
-
[5]: d => new UpdateType(d, updateTokenListTarget),
|
|
1615
|
-
[6]: d => new EventType(d),
|
|
1616
|
-
});
|
|
1617
|
-
},
|
|
1618
|
-
});
|
|
1619
|
-
/**
|
|
1620
|
-
* Describes the configuration for a binding expression.
|
|
1621
|
-
* @public
|
|
1622
|
-
*/
|
|
1623
|
-
const BindingConfig = Object.freeze({
|
|
1624
|
-
/**
|
|
1625
|
-
* Creates a binding configuration based on the provided mode and options.
|
|
1626
|
-
* @param mode - The mode to use for the configuration.
|
|
1627
|
-
* @param defaultOptions - The default options to use for the configuration.
|
|
1628
|
-
* @returns A new binding configuration.
|
|
1629
|
-
*/
|
|
1630
|
-
define(mode, defaultOptions) {
|
|
1631
|
-
const config = (options) => {
|
|
1632
|
-
return {
|
|
1633
|
-
mode: config.mode,
|
|
1634
|
-
options: Object.assign({}, defaultOptions, options),
|
|
1635
|
-
};
|
|
1636
|
-
};
|
|
1637
|
-
config.options = defaultOptions;
|
|
1638
|
-
config.mode = mode;
|
|
1639
|
-
return config;
|
|
1640
|
-
},
|
|
1641
|
-
});
|
|
1642
|
-
/**
|
|
1643
|
-
* A base binding behavior for DOM updates.
|
|
1644
|
-
* @public
|
|
1645
|
-
*/
|
|
1646
|
-
class UpdateBinding {
|
|
1647
|
-
/**
|
|
1648
|
-
* Creates an instance of UpdateBinding.
|
|
1649
|
-
* @param directive - The directive that has the configuration for this behavior.
|
|
1650
|
-
* @param updateTarget - The function used to update the target with the latest value.
|
|
1651
|
-
*/
|
|
1652
|
-
constructor(directive, updateTarget) {
|
|
1653
|
-
this.directive = directive;
|
|
1654
|
-
this.updateTarget = updateTarget;
|
|
1959
|
+
class OnChangeBinding extends Binding {
|
|
1960
|
+
constructor(evaluate, isVolatile) {
|
|
1961
|
+
super();
|
|
1962
|
+
this.evaluate = evaluate;
|
|
1963
|
+
this.isVolatile = isVolatile;
|
|
1655
1964
|
}
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
* @param source - The source to bind to.
|
|
1659
|
-
* @param context - The execution context that the binding is operating within.
|
|
1660
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
1661
|
-
*/
|
|
1662
|
-
bind(source, context, targets) { }
|
|
1663
|
-
/**
|
|
1664
|
-
* Unbinds this behavior from the source.
|
|
1665
|
-
* @param source - The source to unbind from.
|
|
1666
|
-
* @param context - The execution context that the binding is operating within.
|
|
1667
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
1668
|
-
*/
|
|
1669
|
-
unbind(source, context, targets) { }
|
|
1670
|
-
/**
|
|
1671
|
-
* Creates a behavior.
|
|
1672
|
-
* @param targets - The targets available for behaviors to be attached to.
|
|
1673
|
-
*/
|
|
1674
|
-
createBehavior(targets) {
|
|
1675
|
-
return this;
|
|
1965
|
+
createObserver(_, subscriber) {
|
|
1966
|
+
return Observable.binding(this.evaluate, subscriber, this.isVolatile);
|
|
1676
1967
|
}
|
|
1677
1968
|
}
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
}
|
|
1969
|
+
class OneTimeBinding extends Binding {
|
|
1970
|
+
constructor(evaluate) {
|
|
1971
|
+
super();
|
|
1972
|
+
this.evaluate = evaluate;
|
|
1973
|
+
}
|
|
1974
|
+
createObserver() {
|
|
1975
|
+
return this;
|
|
1976
|
+
}
|
|
1977
|
+
observe(source, context) {
|
|
1978
|
+
return this.evaluate(source, context);
|
|
1979
|
+
}
|
|
1980
|
+
dispose() { }
|
|
1690
1981
|
}
|
|
1691
1982
|
function updateContentTarget(target, aspect, value, source, context) {
|
|
1692
1983
|
// If there's no actual value, then this equates to the
|
|
@@ -1694,7 +1985,7 @@ function updateContentTarget(target, aspect, value, source, context) {
|
|
|
1694
1985
|
if (value === null || value === undefined) {
|
|
1695
1986
|
value = "";
|
|
1696
1987
|
}
|
|
1697
|
-
// If the value has a "create" method, then it's a
|
|
1988
|
+
// If the value has a "create" method, then it's a ContentTemplate.
|
|
1698
1989
|
if (value.create) {
|
|
1699
1990
|
target.textContent = "";
|
|
1700
1991
|
let view = target.$fastView;
|
|
@@ -1780,46 +2071,21 @@ function updateTokenListTarget(target, aspect, value) {
|
|
|
1780
2071
|
}
|
|
1781
2072
|
}
|
|
1782
2073
|
}
|
|
1783
|
-
/**
|
|
1784
|
-
* A binding behavior for one-time bindings.
|
|
1785
|
-
* @public
|
|
1786
|
-
*/
|
|
1787
|
-
class OneTimeBinding extends UpdateBinding {
|
|
1788
|
-
/**
|
|
1789
|
-
* Bind this behavior to the source.
|
|
1790
|
-
* @param source - The source to bind to.
|
|
1791
|
-
* @param context - The execution context that the binding is operating within.
|
|
1792
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
1793
|
-
*/
|
|
1794
|
-
bind(source, context, targets) {
|
|
1795
|
-
const directive = this.directive;
|
|
1796
|
-
this.updateTarget(targets[directive.nodeId], directive.targetAspect, directive.binding(source, context), source, context);
|
|
1797
|
-
}
|
|
1798
|
-
}
|
|
1799
2074
|
/**
|
|
1800
2075
|
* A binding behavior for bindings that change.
|
|
1801
2076
|
* @public
|
|
1802
2077
|
*/
|
|
1803
|
-
class
|
|
2078
|
+
class BindingBehavior {
|
|
1804
2079
|
/**
|
|
1805
2080
|
* Creates an instance of ChangeBinding.
|
|
1806
2081
|
* @param directive - The directive that has the configuration for this behavior.
|
|
1807
2082
|
* @param updateTarget - The function used to update the target with the latest value.
|
|
1808
2083
|
*/
|
|
1809
2084
|
constructor(directive, updateTarget) {
|
|
1810
|
-
|
|
1811
|
-
this.
|
|
2085
|
+
this.directive = directive;
|
|
2086
|
+
this.updateTarget = updateTarget;
|
|
1812
2087
|
this.observerProperty = `${directive.id}-o`;
|
|
1813
2088
|
}
|
|
1814
|
-
/**
|
|
1815
|
-
* Returns the binding observer used to update the node.
|
|
1816
|
-
* @param target - The target node.
|
|
1817
|
-
* @returns A BindingObserver.
|
|
1818
|
-
*/
|
|
1819
|
-
getObserver(target) {
|
|
1820
|
-
var _a;
|
|
1821
|
-
return ((_a = target[this.observerProperty]) !== null && _a !== void 0 ? _a : (target[this.observerProperty] = Observable.binding(this.directive.binding, this, this.isBindingVolatile)));
|
|
1822
|
-
}
|
|
1823
2089
|
/**
|
|
1824
2090
|
* Bind this behavior to the source.
|
|
1825
2091
|
* @param source - The source to bind to.
|
|
@@ -1856,12 +2122,49 @@ class ChangeBinding extends UpdateBinding {
|
|
|
1856
2122
|
const context = observer.context;
|
|
1857
2123
|
this.updateTarget(target, this.directive.targetAspect, observer.observe(source, context), source, context);
|
|
1858
2124
|
}
|
|
2125
|
+
/**
|
|
2126
|
+
* Returns the binding observer used to update the node.
|
|
2127
|
+
* @param target - The target node.
|
|
2128
|
+
* @returns A BindingObserver.
|
|
2129
|
+
*/
|
|
2130
|
+
getObserver(target) {
|
|
2131
|
+
var _a;
|
|
2132
|
+
return ((_a = target[this.observerProperty]) !== null && _a !== void 0 ? _a : (target[this.observerProperty] = this.directive.dataBinding.createObserver(this.directive, this)));
|
|
2133
|
+
}
|
|
2134
|
+
/**
|
|
2135
|
+
* Creates a behavior.
|
|
2136
|
+
* @param targets - The targets available for behaviors to be attached to.
|
|
2137
|
+
*/
|
|
2138
|
+
createBehavior(targets) {
|
|
2139
|
+
return this;
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
/**
|
|
2143
|
+
* A special binding behavior that can bind node content.
|
|
2144
|
+
* @public
|
|
2145
|
+
*/
|
|
2146
|
+
class ContentBehavior extends BindingBehavior {
|
|
2147
|
+
/**
|
|
2148
|
+
* Unbinds this behavior from the source.
|
|
2149
|
+
* @param source - The source to unbind from.
|
|
2150
|
+
* @param context - The execution context that the binding is operating within.
|
|
2151
|
+
* @param targets - The targets that behaviors in a view can attach to.
|
|
2152
|
+
*/
|
|
2153
|
+
unbind(source, context, targets) {
|
|
2154
|
+
super.unbind(source, context, targets);
|
|
2155
|
+
const target = targets[this.directive.nodeId];
|
|
2156
|
+
const view = target.$fastView;
|
|
2157
|
+
if (view !== void 0 && view.isComposed) {
|
|
2158
|
+
view.unbind();
|
|
2159
|
+
view.needsBindOnly = true;
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
1859
2162
|
}
|
|
1860
2163
|
/**
|
|
1861
2164
|
* A binding behavior for handling events.
|
|
1862
2165
|
* @public
|
|
1863
2166
|
*/
|
|
1864
|
-
class
|
|
2167
|
+
class EventBehavior {
|
|
1865
2168
|
/**
|
|
1866
2169
|
* Creates an instance of EventBinding.
|
|
1867
2170
|
* @param directive - The directive that has the configuration for this behavior.
|
|
@@ -1882,7 +2185,7 @@ class EventBinding {
|
|
|
1882
2185
|
const target = targets[directive.nodeId];
|
|
1883
2186
|
target[this.sourceProperty] = source;
|
|
1884
2187
|
target[this.contextProperty] = context;
|
|
1885
|
-
target.addEventListener(directive.targetAspect, this, directive.options);
|
|
2188
|
+
target.addEventListener(directive.targetAspect, this, directive.dataBinding.options);
|
|
1886
2189
|
}
|
|
1887
2190
|
/**
|
|
1888
2191
|
* Unbinds this behavior from the source.
|
|
@@ -1894,7 +2197,7 @@ class EventBinding {
|
|
|
1894
2197
|
const directive = this.directive;
|
|
1895
2198
|
const target = targets[directive.nodeId];
|
|
1896
2199
|
target[this.sourceProperty] = target[this.contextProperty] = null;
|
|
1897
|
-
target.removeEventListener(directive.targetAspect, this, directive.options);
|
|
2200
|
+
target.removeEventListener(directive.targetAspect, this, directive.dataBinding.options);
|
|
1898
2201
|
}
|
|
1899
2202
|
/**
|
|
1900
2203
|
* Creates a behavior.
|
|
@@ -1909,25 +2212,13 @@ class EventBinding {
|
|
|
1909
2212
|
handleEvent(event) {
|
|
1910
2213
|
const target = event.currentTarget;
|
|
1911
2214
|
ExecutionContext.setEvent(event);
|
|
1912
|
-
const result = this.directive.
|
|
2215
|
+
const result = this.directive.dataBinding.evaluate(target[this.sourceProperty], target[this.contextProperty]);
|
|
1913
2216
|
ExecutionContext.setEvent(null);
|
|
1914
2217
|
if (result !== true) {
|
|
1915
2218
|
event.preventDefault();
|
|
1916
2219
|
}
|
|
1917
2220
|
}
|
|
1918
2221
|
}
|
|
1919
|
-
/**
|
|
1920
|
-
* The default onChange binding configuration.
|
|
1921
|
-
* @public
|
|
1922
|
-
*/
|
|
1923
|
-
const onChange = BindingConfig.define(BindingMode.define(ChangeBinding), {});
|
|
1924
|
-
/**
|
|
1925
|
-
* The default onTime binding configuration.
|
|
1926
|
-
* @public
|
|
1927
|
-
*/
|
|
1928
|
-
const oneTime = BindingConfig.define(BindingMode.define(OneTimeBinding), {
|
|
1929
|
-
once: true,
|
|
1930
|
-
});
|
|
1931
2222
|
/**
|
|
1932
2223
|
* A directive that applies bindings.
|
|
1933
2224
|
* @public
|
|
@@ -1935,15 +2226,15 @@ const oneTime = BindingConfig.define(BindingMode.define(OneTimeBinding), {
|
|
|
1935
2226
|
class HTMLBindingDirective {
|
|
1936
2227
|
/**
|
|
1937
2228
|
* Creates an instance of HTMLBindingDirective.
|
|
1938
|
-
* @param
|
|
1939
|
-
* @param mode - The binding mode to use when applying the binding.
|
|
1940
|
-
* @param options - The options to configure the binding with.
|
|
2229
|
+
* @param dataBinding - The binding configuration to apply.
|
|
1941
2230
|
*/
|
|
1942
|
-
constructor(
|
|
1943
|
-
this.
|
|
1944
|
-
this.mode = mode;
|
|
1945
|
-
this.options = options;
|
|
2231
|
+
constructor(dataBinding) {
|
|
2232
|
+
this.dataBinding = dataBinding;
|
|
1946
2233
|
this.factory = null;
|
|
2234
|
+
/**
|
|
2235
|
+
* The unique id of the factory.
|
|
2236
|
+
*/
|
|
2237
|
+
this.id = nextId();
|
|
1947
2238
|
/**
|
|
1948
2239
|
* The type of aspect to target.
|
|
1949
2240
|
*/
|
|
@@ -1963,26 +2254,78 @@ class HTMLBindingDirective {
|
|
|
1963
2254
|
createBehavior(targets) {
|
|
1964
2255
|
if (this.factory == null) {
|
|
1965
2256
|
if (this.targetAspect === "innerHTML") {
|
|
1966
|
-
this.
|
|
2257
|
+
this.dataBinding.evaluate = createInnerHTMLBinding(this.dataBinding.evaluate);
|
|
2258
|
+
}
|
|
2259
|
+
switch (this.aspectType) {
|
|
2260
|
+
case 1:
|
|
2261
|
+
this.factory = new BindingBehavior(this, DOM.setAttribute);
|
|
2262
|
+
break;
|
|
2263
|
+
case 2:
|
|
2264
|
+
this.factory = new BindingBehavior(this, DOM.setBooleanAttribute);
|
|
2265
|
+
break;
|
|
2266
|
+
case 3:
|
|
2267
|
+
this.factory = new BindingBehavior(this, (t, a, v) => (t[a] = v));
|
|
2268
|
+
break;
|
|
2269
|
+
case 4:
|
|
2270
|
+
this.factory = new ContentBehavior(this, updateContentTarget);
|
|
2271
|
+
break;
|
|
2272
|
+
case 5:
|
|
2273
|
+
this.factory = new BindingBehavior(this, updateTokenListTarget);
|
|
2274
|
+
break;
|
|
2275
|
+
case 6:
|
|
2276
|
+
this.factory = new EventBehavior(this);
|
|
2277
|
+
break;
|
|
2278
|
+
default:
|
|
2279
|
+
throw FAST.error(1205 /* Message.unsupportedBindingBehavior */);
|
|
1967
2280
|
}
|
|
1968
|
-
this.factory = this.mode[this.aspectType](this);
|
|
1969
2281
|
}
|
|
1970
2282
|
return this.factory.createBehavior(targets);
|
|
1971
2283
|
}
|
|
1972
2284
|
}
|
|
1973
2285
|
HTMLDirective.define(HTMLBindingDirective, { aspected: true });
|
|
1974
2286
|
/**
|
|
1975
|
-
* Creates
|
|
1976
|
-
* @param binding - The binding
|
|
1977
|
-
* @param
|
|
1978
|
-
* @returns A binding
|
|
2287
|
+
* Creates an standard binding.
|
|
2288
|
+
* @param binding - The binding to refresh when changed.
|
|
2289
|
+
* @param isVolatile - Indicates whether the binding is volatile or not.
|
|
2290
|
+
* @returns A binding configuration.
|
|
1979
2291
|
* @public
|
|
1980
2292
|
*/
|
|
1981
|
-
function bind(binding,
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
2293
|
+
function bind(binding, isVolatile = Observable.isVolatileBinding(binding)) {
|
|
2294
|
+
return new OnChangeBinding(binding, isVolatile);
|
|
2295
|
+
}
|
|
2296
|
+
/**
|
|
2297
|
+
* Creates a one time binding
|
|
2298
|
+
* @param binding - The binding to refresh when signaled.
|
|
2299
|
+
* @returns A binding configuration.
|
|
2300
|
+
* @public
|
|
2301
|
+
*/
|
|
2302
|
+
function oneTime(binding) {
|
|
2303
|
+
return new OneTimeBinding(binding);
|
|
2304
|
+
}
|
|
2305
|
+
/**
|
|
2306
|
+
* Creates an event listener binding.
|
|
2307
|
+
* @param binding - The binding to invoke when the event is raised.
|
|
2308
|
+
* @param options - Event listener options.
|
|
2309
|
+
* @returns A binding configuration.
|
|
2310
|
+
* @public
|
|
2311
|
+
*/
|
|
2312
|
+
function listener(binding, options) {
|
|
2313
|
+
const config = new OnChangeBinding(binding, false);
|
|
2314
|
+
config.options = options;
|
|
2315
|
+
return config;
|
|
2316
|
+
}
|
|
2317
|
+
/**
|
|
2318
|
+
* Normalizes the input value into a binding.
|
|
2319
|
+
* @param value - The value to create the default binding for.
|
|
2320
|
+
* @returns A binding configuration for the provided value.
|
|
2321
|
+
* @public
|
|
2322
|
+
*/
|
|
2323
|
+
function normalizeBinding(value) {
|
|
2324
|
+
return isFunction(value)
|
|
2325
|
+
? bind(value)
|
|
2326
|
+
: value instanceof Binding
|
|
2327
|
+
? value
|
|
2328
|
+
: oneTime(() => value);
|
|
1986
2329
|
}
|
|
1987
2330
|
|
|
1988
2331
|
function removeNodeSequence(firstNode, lastNode) {
|
|
@@ -2038,8 +2381,10 @@ class HTMLView {
|
|
|
2038
2381
|
node.parentNode.insertBefore(this.fragment, node);
|
|
2039
2382
|
}
|
|
2040
2383
|
else {
|
|
2041
|
-
const parentNode = node.parentNode;
|
|
2042
2384
|
const end = this.lastChild;
|
|
2385
|
+
if (node.previousSibling === end)
|
|
2386
|
+
return;
|
|
2387
|
+
const parentNode = node.parentNode;
|
|
2043
2388
|
let current = this.firstChild;
|
|
2044
2389
|
let next;
|
|
2045
2390
|
while (current !== end) {
|
|
@@ -2149,6 +2494,22 @@ const next = {
|
|
|
2149
2494
|
index: 0,
|
|
2150
2495
|
node: null,
|
|
2151
2496
|
};
|
|
2497
|
+
function tryWarn(name) {
|
|
2498
|
+
if (!name.startsWith("fast-")) {
|
|
2499
|
+
FAST.warn(1204 /* Message.hostBindingWithoutHost */, { name });
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
const warningHost = new Proxy(document.createElement("div"), {
|
|
2503
|
+
get(target, property) {
|
|
2504
|
+
tryWarn(property);
|
|
2505
|
+
const value = Reflect.get(target, property);
|
|
2506
|
+
return isFunction(value) ? value.bind(target) : value;
|
|
2507
|
+
},
|
|
2508
|
+
set(target, property, value) {
|
|
2509
|
+
tryWarn(property);
|
|
2510
|
+
return Reflect.set(target, property, value);
|
|
2511
|
+
},
|
|
2512
|
+
});
|
|
2152
2513
|
class CompilationContext {
|
|
2153
2514
|
constructor(fragment, directives) {
|
|
2154
2515
|
this.fragment = fragment;
|
|
@@ -2199,7 +2560,7 @@ class CompilationContext {
|
|
|
2199
2560
|
const fragment = this.fragment.cloneNode(true);
|
|
2200
2561
|
const targets = Object.create(this.proto);
|
|
2201
2562
|
targets.r = fragment;
|
|
2202
|
-
targets.h = hostBindingTarget !== null && hostBindingTarget !== void 0 ? hostBindingTarget :
|
|
2563
|
+
targets.h = hostBindingTarget !== null && hostBindingTarget !== void 0 ? hostBindingTarget : warningHost;
|
|
2203
2564
|
for (const id of this.nodeIds) {
|
|
2204
2565
|
targets[id]; // trigger locator
|
|
2205
2566
|
}
|
|
@@ -2216,7 +2577,7 @@ function compileAttributes(context, parentId, node, nodeId, nodeIndex, includeBa
|
|
|
2216
2577
|
let result = null;
|
|
2217
2578
|
if (parseResult === null) {
|
|
2218
2579
|
if (includeBasicValues) {
|
|
2219
|
-
result =
|
|
2580
|
+
result = new HTMLBindingDirective(oneTime(() => attrValue));
|
|
2220
2581
|
Aspect.assign(result, attr.name);
|
|
2221
2582
|
}
|
|
2222
2583
|
}
|
|
@@ -2386,22 +2747,28 @@ const Compiler = {
|
|
|
2386
2747
|
return parts[0];
|
|
2387
2748
|
}
|
|
2388
2749
|
let sourceAspect;
|
|
2750
|
+
let binding;
|
|
2751
|
+
let isVolatile = false;
|
|
2389
2752
|
const partCount = parts.length;
|
|
2390
2753
|
const finalParts = parts.map((x) => {
|
|
2391
2754
|
if (isString(x)) {
|
|
2392
2755
|
return () => x;
|
|
2393
2756
|
}
|
|
2394
2757
|
sourceAspect = x.sourceAspect || sourceAspect;
|
|
2395
|
-
|
|
2758
|
+
binding = x.dataBinding || binding;
|
|
2759
|
+
isVolatile = isVolatile || x.dataBinding.isVolatile;
|
|
2760
|
+
return x.dataBinding.evaluate;
|
|
2396
2761
|
});
|
|
2397
|
-
const
|
|
2762
|
+
const expression = (scope, context) => {
|
|
2398
2763
|
let output = "";
|
|
2399
2764
|
for (let i = 0; i < partCount; ++i) {
|
|
2400
2765
|
output += finalParts[i](scope, context);
|
|
2401
2766
|
}
|
|
2402
2767
|
return output;
|
|
2403
2768
|
};
|
|
2404
|
-
|
|
2769
|
+
binding.evaluate = expression;
|
|
2770
|
+
binding.isVolatile = isVolatile;
|
|
2771
|
+
const directive = new HTMLBindingDirective(binding);
|
|
2405
2772
|
Aspect.assign(directive, sourceAspect);
|
|
2406
2773
|
return directive;
|
|
2407
2774
|
},
|
|
@@ -2481,12 +2848,12 @@ function html(strings, ...values) {
|
|
|
2481
2848
|
let definition;
|
|
2482
2849
|
html += currentString;
|
|
2483
2850
|
if (isFunction(currentValue)) {
|
|
2484
|
-
html += createAspectedHTML(bind(currentValue), currentString, add);
|
|
2851
|
+
html += createAspectedHTML(new HTMLBindingDirective(bind(currentValue)), currentString, add);
|
|
2485
2852
|
}
|
|
2486
2853
|
else if (isString(currentValue)) {
|
|
2487
2854
|
const match = lastAttributeNameRegex.exec(currentString);
|
|
2488
2855
|
if (match !== null) {
|
|
2489
|
-
const directive =
|
|
2856
|
+
const directive = new HTMLBindingDirective(oneTime(() => currentValue));
|
|
2490
2857
|
Aspect.assign(directive, match[2]);
|
|
2491
2858
|
html += directive.createHTML(add);
|
|
2492
2859
|
}
|
|
@@ -2494,8 +2861,11 @@ function html(strings, ...values) {
|
|
|
2494
2861
|
html += currentValue;
|
|
2495
2862
|
}
|
|
2496
2863
|
}
|
|
2864
|
+
else if (currentValue instanceof Binding) {
|
|
2865
|
+
html += createAspectedHTML(new HTMLBindingDirective(currentValue), currentString, add);
|
|
2866
|
+
}
|
|
2497
2867
|
else if ((definition = HTMLDirective.getForInstance(currentValue)) === void 0) {
|
|
2498
|
-
html += createAspectedHTML(
|
|
2868
|
+
html += createAspectedHTML(new HTMLBindingDirective(oneTime(() => currentValue)), currentString, add);
|
|
2499
2869
|
}
|
|
2500
2870
|
else {
|
|
2501
2871
|
if (definition.aspected) {
|
|
@@ -2540,16 +2910,17 @@ const ref = (propertyName) => new RefDirective(propertyName);
|
|
|
2540
2910
|
|
|
2541
2911
|
/**
|
|
2542
2912
|
* A directive that enables basic conditional rendering in a template.
|
|
2543
|
-
* @param
|
|
2913
|
+
* @param condition - The condition to test for rendering.
|
|
2544
2914
|
* @param templateOrTemplateBinding - The template or a binding that gets
|
|
2545
2915
|
* the template to render when the condition is true.
|
|
2546
2916
|
* @public
|
|
2547
2917
|
*/
|
|
2548
|
-
function when(
|
|
2549
|
-
const
|
|
2918
|
+
function when(condition, templateOrTemplateBinding) {
|
|
2919
|
+
const dataBinding = isFunction(condition) ? condition : () => condition;
|
|
2920
|
+
const templateBinding = isFunction(templateOrTemplateBinding)
|
|
2550
2921
|
? templateOrTemplateBinding
|
|
2551
2922
|
: () => templateOrTemplateBinding;
|
|
2552
|
-
return (source, context) =>
|
|
2923
|
+
return (source, context) => dataBinding(source, context) ? templateBinding(source, context) : null;
|
|
2553
2924
|
}
|
|
2554
2925
|
|
|
2555
2926
|
const defaultRepeatOptions = Object.freeze({
|
|
@@ -2570,17 +2941,15 @@ class RepeatBehavior {
|
|
|
2570
2941
|
/**
|
|
2571
2942
|
* Creates an instance of RepeatBehavior.
|
|
2572
2943
|
* @param location - The location in the DOM to render the repeat.
|
|
2573
|
-
* @param
|
|
2944
|
+
* @param dataBinding - The array to render.
|
|
2574
2945
|
* @param isItemsBindingVolatile - Indicates whether the items binding has volatile dependencies.
|
|
2575
2946
|
* @param templateBinding - The template to render for each item.
|
|
2576
2947
|
* @param isTemplateBindingVolatile - Indicates whether the template binding has volatile dependencies.
|
|
2577
2948
|
* @param options - Options used to turn on special repeat features.
|
|
2578
2949
|
*/
|
|
2579
|
-
constructor(
|
|
2950
|
+
constructor(directive, location) {
|
|
2951
|
+
this.directive = directive;
|
|
2580
2952
|
this.location = location;
|
|
2581
|
-
this.itemsBinding = itemsBinding;
|
|
2582
|
-
this.templateBinding = templateBinding;
|
|
2583
|
-
this.options = options;
|
|
2584
2953
|
this.source = null;
|
|
2585
2954
|
this.views = [];
|
|
2586
2955
|
this.items = null;
|
|
@@ -2588,9 +2957,9 @@ class RepeatBehavior {
|
|
|
2588
2957
|
this.context = void 0;
|
|
2589
2958
|
this.childContext = void 0;
|
|
2590
2959
|
this.bindView = bindWithoutPositioning;
|
|
2591
|
-
this.itemsBindingObserver =
|
|
2592
|
-
this.templateBindingObserver =
|
|
2593
|
-
if (options.positioning) {
|
|
2960
|
+
this.itemsBindingObserver = directive.dataBinding.createObserver(directive, this);
|
|
2961
|
+
this.templateBindingObserver = directive.templateBinding.createObserver(directive, this);
|
|
2962
|
+
if (directive.options.positioning) {
|
|
2594
2963
|
this.bindView = bindWithPositioning;
|
|
2595
2964
|
}
|
|
2596
2965
|
}
|
|
@@ -2628,15 +2997,18 @@ class RepeatBehavior {
|
|
|
2628
2997
|
* @param args - The details about what was changed.
|
|
2629
2998
|
*/
|
|
2630
2999
|
handleChange(source, args) {
|
|
2631
|
-
if (
|
|
3000
|
+
if (args === this.itemsBindingObserver) {
|
|
2632
3001
|
this.items = this.itemsBindingObserver.observe(this.source, this.context);
|
|
2633
3002
|
this.observeItems();
|
|
2634
3003
|
this.refreshAllViews();
|
|
2635
3004
|
}
|
|
2636
|
-
else if (
|
|
3005
|
+
else if (args === this.templateBindingObserver) {
|
|
2637
3006
|
this.template = this.templateBindingObserver.observe(this.source, this.context);
|
|
2638
3007
|
this.refreshAllViews(true);
|
|
2639
3008
|
}
|
|
3009
|
+
else if (!args[0]) {
|
|
3010
|
+
return;
|
|
3011
|
+
}
|
|
2640
3012
|
else if (args[0].reset) {
|
|
2641
3013
|
this.refreshAllViews();
|
|
2642
3014
|
}
|
|
@@ -2662,36 +3034,51 @@ class RepeatBehavior {
|
|
|
2662
3034
|
updateViews(splices) {
|
|
2663
3035
|
const views = this.views;
|
|
2664
3036
|
const childContext = this.childContext;
|
|
2665
|
-
const totalRemoved = [];
|
|
2666
3037
|
const bindView = this.bindView;
|
|
2667
|
-
let removeDelta = 0;
|
|
2668
|
-
for (let i = 0, ii = splices.length; i < ii; ++i) {
|
|
2669
|
-
const splice = splices[i];
|
|
2670
|
-
const removed = splice.removed;
|
|
2671
|
-
totalRemoved.push(...views.splice(splice.index + removeDelta, removed.length));
|
|
2672
|
-
removeDelta -= splice.addedCount;
|
|
2673
|
-
}
|
|
2674
3038
|
const items = this.items;
|
|
2675
3039
|
const template = this.template;
|
|
3040
|
+
const recycle = this.directive.options.recycle;
|
|
3041
|
+
const leftoverViews = [];
|
|
3042
|
+
let leftoverIndex = 0;
|
|
3043
|
+
let availableViews = 0;
|
|
2676
3044
|
for (let i = 0, ii = splices.length; i < ii; ++i) {
|
|
2677
3045
|
const splice = splices[i];
|
|
3046
|
+
const removed = splice.removed;
|
|
3047
|
+
let removeIndex = 0;
|
|
2678
3048
|
let addIndex = splice.index;
|
|
2679
3049
|
const end = addIndex + splice.addedCount;
|
|
3050
|
+
const removedViews = views.splice(splice.index, removed.length);
|
|
3051
|
+
availableViews = leftoverViews.length + removedViews.length;
|
|
2680
3052
|
for (; addIndex < end; ++addIndex) {
|
|
2681
3053
|
const neighbor = views[addIndex];
|
|
2682
3054
|
const location = neighbor ? neighbor.firstChild : this.location;
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
3055
|
+
let view;
|
|
3056
|
+
if (recycle && availableViews > 0) {
|
|
3057
|
+
if (removeIndex <= availableViews && removedViews.length > 0) {
|
|
3058
|
+
view = removedViews[removeIndex];
|
|
3059
|
+
removeIndex++;
|
|
3060
|
+
}
|
|
3061
|
+
else {
|
|
3062
|
+
view = leftoverViews[leftoverIndex];
|
|
3063
|
+
leftoverIndex++;
|
|
3064
|
+
}
|
|
3065
|
+
availableViews--;
|
|
3066
|
+
}
|
|
3067
|
+
else {
|
|
3068
|
+
view = template.create();
|
|
3069
|
+
}
|
|
2686
3070
|
views.splice(addIndex, 0, view);
|
|
2687
3071
|
bindView(view, items, addIndex, childContext);
|
|
2688
3072
|
view.insertBefore(location);
|
|
2689
3073
|
}
|
|
3074
|
+
if (removedViews[removeIndex]) {
|
|
3075
|
+
leftoverViews.push(...removedViews.slice(removeIndex));
|
|
3076
|
+
}
|
|
2690
3077
|
}
|
|
2691
|
-
for (let i =
|
|
2692
|
-
|
|
3078
|
+
for (let i = leftoverIndex, ii = leftoverViews.length; i < ii; ++i) {
|
|
3079
|
+
leftoverViews[i].dispose();
|
|
2693
3080
|
}
|
|
2694
|
-
if (this.options.positioning) {
|
|
3081
|
+
if (this.directive.options.positioning) {
|
|
2695
3082
|
for (let i = 0, ii = views.length; i < ii; ++i) {
|
|
2696
3083
|
views[i].context.updatePosition(i, ii);
|
|
2697
3084
|
}
|
|
@@ -2706,7 +3093,7 @@ class RepeatBehavior {
|
|
|
2706
3093
|
let itemsLength = items.length;
|
|
2707
3094
|
let views = this.views;
|
|
2708
3095
|
let viewsLength = views.length;
|
|
2709
|
-
if (itemsLength === 0 || templateChanged || !this.options.recycle) {
|
|
3096
|
+
if (itemsLength === 0 || templateChanged || !this.directive.options.recycle) {
|
|
2710
3097
|
// all views need to be removed
|
|
2711
3098
|
HTMLView.disposeContiguousBatch(views);
|
|
2712
3099
|
viewsLength = 0;
|
|
@@ -2756,17 +3143,19 @@ class RepeatBehavior {
|
|
|
2756
3143
|
class RepeatDirective {
|
|
2757
3144
|
/**
|
|
2758
3145
|
* Creates an instance of RepeatDirective.
|
|
2759
|
-
* @param
|
|
3146
|
+
* @param dataBinding - The binding that provides the array to render.
|
|
2760
3147
|
* @param templateBinding - The template binding used to obtain a template to render for each item in the array.
|
|
2761
3148
|
* @param options - Options used to turn on special repeat features.
|
|
2762
3149
|
*/
|
|
2763
|
-
constructor(
|
|
2764
|
-
this.
|
|
3150
|
+
constructor(dataBinding, templateBinding, options) {
|
|
3151
|
+
this.dataBinding = dataBinding;
|
|
2765
3152
|
this.templateBinding = templateBinding;
|
|
2766
3153
|
this.options = options;
|
|
3154
|
+
/**
|
|
3155
|
+
* The unique id of the factory.
|
|
3156
|
+
*/
|
|
3157
|
+
this.id = nextId();
|
|
2767
3158
|
ArrayObserver.enable();
|
|
2768
|
-
this.isItemsBindingVolatile = Observable.isVolatileBinding(itemsBinding);
|
|
2769
|
-
this.isTemplateBindingVolatile = Observable.isVolatileBinding(templateBinding);
|
|
2770
3159
|
}
|
|
2771
3160
|
/**
|
|
2772
3161
|
* Creates a placeholder string based on the directive's index within the template.
|
|
@@ -2780,23 +3169,22 @@ class RepeatDirective {
|
|
|
2780
3169
|
* @param target - The node instance to create the behavior for.
|
|
2781
3170
|
*/
|
|
2782
3171
|
createBehavior(targets) {
|
|
2783
|
-
return new RepeatBehavior(targets[this.nodeId]
|
|
3172
|
+
return new RepeatBehavior(this, targets[this.nodeId]);
|
|
2784
3173
|
}
|
|
2785
3174
|
}
|
|
2786
3175
|
HTMLDirective.define(RepeatDirective);
|
|
2787
3176
|
/**
|
|
2788
3177
|
* A directive that enables list rendering.
|
|
2789
|
-
* @param
|
|
2790
|
-
* @param
|
|
3178
|
+
* @param items - The array to render.
|
|
3179
|
+
* @param template - The template or a template binding used obtain a template
|
|
2791
3180
|
* to render for each item in the array.
|
|
2792
3181
|
* @param options - Options used to turn on special repeat features.
|
|
2793
3182
|
* @public
|
|
2794
3183
|
*/
|
|
2795
|
-
function repeat(
|
|
2796
|
-
const
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
return new RepeatDirective(itemsBinding, templateBinding, options);
|
|
3184
|
+
function repeat(items, template, options = defaultRepeatOptions) {
|
|
3185
|
+
const dataBinding = normalizeBinding(items);
|
|
3186
|
+
const templateBinding = normalizeBinding(template);
|
|
3187
|
+
return new RepeatDirective(dataBinding, templateBinding, Object.assign(Object.assign({}, defaultRepeatOptions), options));
|
|
2800
3188
|
}
|
|
2801
3189
|
|
|
2802
3190
|
const selectElements = (value) => value.nodeType === 1;
|
|
@@ -3181,19 +3569,15 @@ const fastElementRegistry = FAST.getById(4 /* KernelServiceId.elementRegistry */
|
|
|
3181
3569
|
* @public
|
|
3182
3570
|
*/
|
|
3183
3571
|
class FASTElementDefinition {
|
|
3184
|
-
/**
|
|
3185
|
-
* Creates an instance of FASTElementDefinition.
|
|
3186
|
-
* @param type - The type this definition is being created for.
|
|
3187
|
-
* @param nameOrConfig - The name of the element to define or a config object
|
|
3188
|
-
* that describes the element to define.
|
|
3189
|
-
*/
|
|
3190
3572
|
constructor(type, nameOrConfig = type.definition) {
|
|
3573
|
+
this.platformDefined = false;
|
|
3191
3574
|
if (isString(nameOrConfig)) {
|
|
3192
3575
|
nameOrConfig = { name: nameOrConfig };
|
|
3193
3576
|
}
|
|
3194
3577
|
this.type = type;
|
|
3195
3578
|
this.name = nameOrConfig.name;
|
|
3196
3579
|
this.template = nameOrConfig.template;
|
|
3580
|
+
const proto = type.prototype;
|
|
3197
3581
|
const attributes = AttributeDefinition.collect(type, nameOrConfig.attributes);
|
|
3198
3582
|
const observedAttributes = new Array(attributes.length);
|
|
3199
3583
|
const propertyLookup = {};
|
|
@@ -3203,9 +3587,13 @@ class FASTElementDefinition {
|
|
|
3203
3587
|
observedAttributes[i] = current.attribute;
|
|
3204
3588
|
propertyLookup[current.name] = current;
|
|
3205
3589
|
attributeLookup[current.attribute] = current;
|
|
3590
|
+
Observable.defineProperty(proto, current);
|
|
3206
3591
|
}
|
|
3592
|
+
Reflect.defineProperty(type, "observedAttributes", {
|
|
3593
|
+
value: observedAttributes,
|
|
3594
|
+
enumerable: true,
|
|
3595
|
+
});
|
|
3207
3596
|
this.attributes = attributes;
|
|
3208
|
-
this.observedAttributes = observedAttributes;
|
|
3209
3597
|
this.propertyLookup = propertyLookup;
|
|
3210
3598
|
this.attributeLookup = attributeLookup;
|
|
3211
3599
|
this.shadowOptions =
|
|
@@ -3218,20 +3606,14 @@ class FASTElementDefinition {
|
|
|
3218
3606
|
nameOrConfig.elementOptions === void 0
|
|
3219
3607
|
? defaultElementOptions
|
|
3220
3608
|
: Object.assign(Object.assign({}, defaultElementOptions), nameOrConfig.elementOptions);
|
|
3221
|
-
this.styles =
|
|
3222
|
-
|
|
3223
|
-
? void 0
|
|
3224
|
-
: Array.isArray(nameOrConfig.styles)
|
|
3225
|
-
? new ElementStyles(nameOrConfig.styles)
|
|
3226
|
-
: nameOrConfig.styles instanceof ElementStyles
|
|
3227
|
-
? nameOrConfig.styles
|
|
3228
|
-
: new ElementStyles([nameOrConfig.styles]);
|
|
3609
|
+
this.styles = ElementStyles.normalize(nameOrConfig.styles);
|
|
3610
|
+
fastElementRegistry.register(this);
|
|
3229
3611
|
}
|
|
3230
3612
|
/**
|
|
3231
3613
|
* Indicates if this element has been defined in at least one registry.
|
|
3232
3614
|
*/
|
|
3233
3615
|
get isDefined() {
|
|
3234
|
-
return
|
|
3616
|
+
return this.platformDefined;
|
|
3235
3617
|
}
|
|
3236
3618
|
/**
|
|
3237
3619
|
* Defines a custom element based on this definition.
|
|
@@ -3241,22 +3623,26 @@ class FASTElementDefinition {
|
|
|
3241
3623
|
*/
|
|
3242
3624
|
define(registry = customElements) {
|
|
3243
3625
|
const type = this.type;
|
|
3244
|
-
if (fastElementRegistry.register(this)) {
|
|
3245
|
-
const attributes = this.attributes;
|
|
3246
|
-
const proto = type.prototype;
|
|
3247
|
-
for (let i = 0, ii = attributes.length; i < ii; ++i) {
|
|
3248
|
-
Observable.defineProperty(proto, attributes[i]);
|
|
3249
|
-
}
|
|
3250
|
-
Reflect.defineProperty(type, "observedAttributes", {
|
|
3251
|
-
value: this.observedAttributes,
|
|
3252
|
-
enumerable: true,
|
|
3253
|
-
});
|
|
3254
|
-
}
|
|
3255
3626
|
if (!registry.get(this.name)) {
|
|
3627
|
+
this.platformDefined = true;
|
|
3256
3628
|
registry.define(this.name, type, this.elementOptions);
|
|
3257
3629
|
}
|
|
3258
3630
|
return this;
|
|
3259
3631
|
}
|
|
3632
|
+
/**
|
|
3633
|
+
* Creates an instance of FASTElementDefinition.
|
|
3634
|
+
* @param type - The type this definition is being created for.
|
|
3635
|
+
* @param nameOrDef - The name of the element to define or a config object
|
|
3636
|
+
* that describes the element to define.
|
|
3637
|
+
*/
|
|
3638
|
+
static compose(type, nameOrDef) {
|
|
3639
|
+
const found = fastElementRegistry.getByType(type);
|
|
3640
|
+
if (found) {
|
|
3641
|
+
return new FASTElementDefinition(class extends type {
|
|
3642
|
+
}, nameOrDef);
|
|
3643
|
+
}
|
|
3644
|
+
return new FASTElementDefinition(type, nameOrDef);
|
|
3645
|
+
}
|
|
3260
3646
|
}
|
|
3261
3647
|
/**
|
|
3262
3648
|
* Gets the element definition associated with the specified type.
|
|
@@ -3674,6 +4060,21 @@ function createFASTElement(BaseType) {
|
|
|
3674
4060
|
}
|
|
3675
4061
|
};
|
|
3676
4062
|
}
|
|
4063
|
+
function compose(type, nameOrDef) {
|
|
4064
|
+
if (isFunction(type)) {
|
|
4065
|
+
return FASTElementDefinition.compose(type, nameOrDef);
|
|
4066
|
+
}
|
|
4067
|
+
return FASTElementDefinition.compose(this, type);
|
|
4068
|
+
}
|
|
4069
|
+
function define(type, nameOrDef) {
|
|
4070
|
+
if (isFunction(type)) {
|
|
4071
|
+
return FASTElementDefinition.compose(type, nameOrDef).define().type;
|
|
4072
|
+
}
|
|
4073
|
+
return FASTElementDefinition.compose(this, type).define().type;
|
|
4074
|
+
}
|
|
4075
|
+
function from(BaseType) {
|
|
4076
|
+
return createFASTElement(BaseType);
|
|
4077
|
+
}
|
|
3677
4078
|
/**
|
|
3678
4079
|
* A minimal base class for FASTElements that also provides
|
|
3679
4080
|
* static helpers for working with FASTElements.
|
|
@@ -3685,26 +4086,19 @@ const FASTElement = Object.assign(createFASTElement(HTMLElement), {
|
|
|
3685
4086
|
* provided base type.
|
|
3686
4087
|
* @param BaseType - The base element type to inherit from.
|
|
3687
4088
|
*/
|
|
3688
|
-
from
|
|
3689
|
-
return createFASTElement(BaseType);
|
|
3690
|
-
},
|
|
4089
|
+
from,
|
|
3691
4090
|
/**
|
|
3692
4091
|
* Defines a platform custom element based on the provided type and definition.
|
|
3693
4092
|
* @param type - The custom element type to define.
|
|
3694
4093
|
* @param nameOrDef - The name of the element to define or a definition object
|
|
3695
4094
|
* that describes the element to define.
|
|
3696
4095
|
*/
|
|
3697
|
-
define
|
|
3698
|
-
return this.metadata(type, nameOrDef).define().type;
|
|
3699
|
-
},
|
|
4096
|
+
define,
|
|
3700
4097
|
/**
|
|
3701
4098
|
* Defines metadata for a FASTElement which can be used to later define the element.
|
|
3702
|
-
* IMPORTANT: This API will be renamed to "compose" in a future beta.
|
|
3703
4099
|
* @public
|
|
3704
4100
|
*/
|
|
3705
|
-
|
|
3706
|
-
return new FASTElementDefinition(type, nameOrDef);
|
|
3707
|
-
},
|
|
4101
|
+
compose,
|
|
3708
4102
|
});
|
|
3709
4103
|
/**
|
|
3710
4104
|
* Decorator: Defines a platform custom element based on `FASTElement`.
|
|
@@ -3715,8 +4109,8 @@ const FASTElement = Object.assign(createFASTElement(HTMLElement), {
|
|
|
3715
4109
|
function customElement(nameOrDef) {
|
|
3716
4110
|
/* eslint-disable-next-line @typescript-eslint/explicit-function-return-type */
|
|
3717
4111
|
return function (type) {
|
|
3718
|
-
|
|
4112
|
+
define(type, nameOrDef);
|
|
3719
4113
|
};
|
|
3720
4114
|
}
|
|
3721
4115
|
|
|
3722
|
-
export { AdoptedStyleSheetsStrategy, ArrayObserver, Aspect, AttributeDefinition,
|
|
4116
|
+
export { AdoptedStyleSheetsStrategy, ArrayObserver, Aspect, AttributeDefinition, Binding, BindingBehavior, CSSDirective, ChildrenDirective, Compiler, ContentBehavior, Controller, DOM, ElementStyles, EventBehavior, ExecutionContext, FAST, FASTElement, FASTElementDefinition, HTMLBindingDirective, HTMLDirective, HTMLView, Markup, NodeObservationDirective, Observable, Parser, PropertyChangeNotifier, RefDirective, RepeatBehavior, RepeatDirective, SlottedDirective, Splice, SpliceStrategy, SpliceStrategySupport, StatelessAttachedAttributeDirective, SubscriberSet, Updates, ViewTemplate, attr, bind, booleanConverter, children, createTypeRegistry, css, cssDirective, cssPartial, customElement, elements, emptyArray, html, htmlDirective, lengthOf, listener, normalizeBinding, nullableNumberConverter, observable, oneTime, ref, repeat, slotted, volatile, when };
|