@microsoft/fast-element 2.0.0-beta.4 → 2.0.0-beta.5
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 +51 -0
- package/CHANGELOG.md +15 -1
- package/dist/dts/components/fast-element.d.ts +4 -20
- package/dist/dts/di/di.d.ts +4 -0
- package/dist/dts/interfaces.d.ts +2 -1
- package/dist/esm/components/fast-element.js +4 -3
- package/dist/esm/debug.js +1 -0
- package/dist/esm/di/di.js +4 -2
- package/dist/esm/observation/arrays.js +303 -2
- package/dist/esm/observation/observable.js +7 -2
- package/dist/esm/templating/repeat.js +4 -1
- package/dist/esm/templating/view.js +3 -1
- package/dist/fast-element.api.json +11 -47
- package/dist/fast-element.d.ts +5 -20
- package/dist/fast-element.debug.js +322 -9
- package/dist/fast-element.debug.min.js +1 -1
- package/dist/fast-element.js +321 -9
- package/dist/fast-element.min.js +1 -1
- package/dist/fast-element.untrimmed.d.ts +5 -20
- package/docs/api-report.md +6 -7
- package/package.json +3 -6
- package/dist/dts/observation/splice-strategies.d.ts +0 -13
- package/dist/esm/observation/splice-strategies.js +0 -400
package/CHANGELOG.json
CHANGED
|
@@ -1,6 +1,57 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microsoft/fast-element",
|
|
3
3
|
"entries": [
|
|
4
|
+
{
|
|
5
|
+
"date": "Thu, 18 Aug 2022 20:46:10 GMT",
|
|
6
|
+
"tag": "@microsoft/fast-element_v2.0.0-beta.5",
|
|
7
|
+
"version": "2.0.0-beta.5",
|
|
8
|
+
"comments": {
|
|
9
|
+
"prerelease": [
|
|
10
|
+
{
|
|
11
|
+
"author": "nicholasrice@users.noreply.github.com",
|
|
12
|
+
"package": "@microsoft/fast-element",
|
|
13
|
+
"commit": "218cfc014f5c76464493725f83bd883e8b07defa",
|
|
14
|
+
"comment": "Fix ExpressionObserer bug where watcher was not reset if the binding threw"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"author": "prudepixie@users.noreply.github.com",
|
|
18
|
+
"package": "@microsoft/fast-element",
|
|
19
|
+
"commit": "fdd4514664691021a5673934c95acf31a8e73416",
|
|
20
|
+
"comment": "make insertbefore noop in view"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"author": "prudepixie@users.noreply.github.com",
|
|
24
|
+
"package": "@microsoft/fast-element",
|
|
25
|
+
"commit": "eb8d5a59f645b85567adadac41a3bfa66001f941",
|
|
26
|
+
"comment": "make sure default options for recycle gets set in different scenarios"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"author": "roeisenb@microsoft.com",
|
|
30
|
+
"package": "@microsoft/fast-element",
|
|
31
|
+
"commit": "ac3954c97acd3bd549a27829593855c431a24027",
|
|
32
|
+
"comment": "refactor: remove dependency of DI on FASTElement"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"author": "32497422+KingOfTac@users.noreply.github.com",
|
|
36
|
+
"package": "@microsoft/fast-element",
|
|
37
|
+
"commit": "29308db7920baaaac5b31b206d551669e165bc06",
|
|
38
|
+
"comment": "add subpath export for package.json to packages"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"author": "prudepixie@users.noreply.github.com",
|
|
42
|
+
"package": "@microsoft/fast-element",
|
|
43
|
+
"commit": "775d51602cba544347ec1e57fdb4fea248d1b1b5",
|
|
44
|
+
"comment": "change default array strategy to merge strategy, update repeat directive"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"author": "nicholasrice@users.noreply.github.com",
|
|
48
|
+
"package": "@microsoft/fast-element",
|
|
49
|
+
"commit": "aeac1198f427c33f789a2d869f58549ea5bfea57",
|
|
50
|
+
"comment": "assert FASTElement's type so that instanceof behavior is consistent with other class implementations"
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
},
|
|
4
55
|
{
|
|
5
56
|
"date": "Mon, 18 Jul 2022 21:10:01 GMT",
|
|
6
57
|
"tag": "@microsoft/fast-element_v2.0.0-beta.4",
|
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
# Change Log - @microsoft/fast-element
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Thu, 18 Aug 2022 20:46:10 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## 2.0.0-beta.5
|
|
8
|
+
|
|
9
|
+
Thu, 18 Aug 2022 20:46:10 GMT
|
|
10
|
+
|
|
11
|
+
### Changes
|
|
12
|
+
|
|
13
|
+
- Fix ExpressionObserer bug where watcher was not reset if the binding threw (nicholasrice@users.noreply.github.com)
|
|
14
|
+
- make insertbefore noop in view (prudepixie@users.noreply.github.com)
|
|
15
|
+
- make sure default options for recycle gets set in different scenarios (prudepixie@users.noreply.github.com)
|
|
16
|
+
- refactor: remove dependency of DI on FASTElement (roeisenb@microsoft.com)
|
|
17
|
+
- add subpath export for package.json to packages (32497422+KingOfTac@users.noreply.github.com)
|
|
18
|
+
- change default array strategy to merge strategy, update repeat directive (prudepixie@users.noreply.github.com)
|
|
19
|
+
- assert FASTElement's type so that instanceof behavior is consistent with other class implementations (nicholasrice@users.noreply.github.com)
|
|
20
|
+
|
|
7
21
|
## 2.0.0-beta.4
|
|
8
22
|
|
|
9
23
|
Mon, 18 Jul 2022 21:10:01 GMT
|
|
@@ -49,33 +49,17 @@ declare function compose<TType extends Constructable<HTMLElement> = Constructabl
|
|
|
49
49
|
declare function compose<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(type: TType, nameOrDef?: string | PartialFASTElementDefinition): FASTElementDefinition<TType>;
|
|
50
50
|
declare function define<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(this: TType, nameOrDef: string | PartialFASTElementDefinition): TType;
|
|
51
51
|
declare function define<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(type: TType, nameOrDef?: string | PartialFASTElementDefinition): TType;
|
|
52
|
+
declare function from<TBase extends typeof HTMLElement>(BaseType: TBase): new () => InstanceType<TBase> & FASTElement;
|
|
52
53
|
/**
|
|
53
54
|
* A minimal base class for FASTElements that also provides
|
|
54
55
|
* static helpers for working with FASTElements.
|
|
55
56
|
* @public
|
|
56
57
|
*/
|
|
57
|
-
export declare const FASTElement:
|
|
58
|
-
|
|
59
|
-
* Creates a new FASTElement base class inherited from the
|
|
60
|
-
* provided base type.
|
|
61
|
-
* @param BaseType - The base element type to inherit from.
|
|
62
|
-
*/
|
|
63
|
-
from<TBase extends {
|
|
64
|
-
new (): HTMLElement;
|
|
65
|
-
prototype: HTMLElement;
|
|
66
|
-
}>(BaseType: TBase): new () => InstanceType<TBase> & FASTElement;
|
|
67
|
-
/**
|
|
68
|
-
* Defines a platform custom element based on the provided type and definition.
|
|
69
|
-
* @param type - The custom element type to define.
|
|
70
|
-
* @param nameOrDef - The name of the element to define or a definition object
|
|
71
|
-
* that describes the element to define.
|
|
72
|
-
*/
|
|
58
|
+
export declare const FASTElement: {
|
|
59
|
+
new (): FASTElement;
|
|
73
60
|
define: typeof define;
|
|
74
|
-
/**
|
|
75
|
-
* Defines metadata for a FASTElement which can be used to later define the element.
|
|
76
|
-
* @public
|
|
77
|
-
*/
|
|
78
61
|
compose: typeof compose;
|
|
62
|
+
from: typeof from;
|
|
79
63
|
};
|
|
80
64
|
/**
|
|
81
65
|
* Decorator: Defines a platform custom element based on `FASTElement`.
|
package/dist/dts/di/di.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Big thanks to https://github.com/fkleuver and the https://github.com/aurelia/aurelia project
|
|
3
|
+
* for the bulk of this code and many of the associated tests.
|
|
4
|
+
*/
|
|
1
5
|
import { ContextDecorator } from "../context.js";
|
|
2
6
|
import { Constructable } from "../interfaces.js";
|
|
3
7
|
/**
|
package/dist/dts/interfaces.d.ts
CHANGED
|
@@ -35,6 +35,9 @@ function define(type, nameOrDef) {
|
|
|
35
35
|
}
|
|
36
36
|
return FASTElementDefinition.compose(this, type).define().type;
|
|
37
37
|
}
|
|
38
|
+
function from(BaseType) {
|
|
39
|
+
return createFASTElement(BaseType);
|
|
40
|
+
}
|
|
38
41
|
/**
|
|
39
42
|
* A minimal base class for FASTElements that also provides
|
|
40
43
|
* static helpers for working with FASTElements.
|
|
@@ -46,9 +49,7 @@ export const FASTElement = Object.assign(createFASTElement(HTMLElement), {
|
|
|
46
49
|
* provided base type.
|
|
47
50
|
* @param BaseType - The base element type to inherit from.
|
|
48
51
|
*/
|
|
49
|
-
from
|
|
50
|
-
return createFASTElement(BaseType);
|
|
51
|
-
},
|
|
52
|
+
from,
|
|
52
53
|
/**
|
|
53
54
|
* Defines a platform custom element based on the provided type and definition.
|
|
54
55
|
* @param type - The custom element type to define.
|
package/dist/esm/debug.js
CHANGED
|
@@ -28,6 +28,7 @@ const debugMessages = {
|
|
|
28
28
|
[1511 /* invalidKey */]: "Key/value cannot be null or undefined. Are you trying to inject/register something that doesn't exist with DI?",
|
|
29
29
|
[1512 /* noDefaultResolver */]: "'${key}' not registered. Did you forget to add @singleton()?",
|
|
30
30
|
[1513 /* cyclicDependency */]: "Cyclic dependency found '${name}'.",
|
|
31
|
+
[1514 /* connectUpdateRequiresController */]: "Injected properties that are updated on changes to DOM connectivity require the target object to be an instance of FASTElement.",
|
|
31
32
|
};
|
|
32
33
|
const allPlaceholders = /(\$\{\w+?})/g;
|
|
33
34
|
const placeholder = /\$\{(\w+?)}/g;
|
package/dist/esm/di/di.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Big thanks to https://github.com/fkleuver and the https://github.com/aurelia/aurelia project
|
|
3
3
|
* for the bulk of this code and many of the associated tests.
|
|
4
4
|
*/
|
|
5
|
-
import { FASTElement } from "../components/fast-element.js";
|
|
6
5
|
import { Context } from "../context.js";
|
|
7
6
|
import "../interfaces.js";
|
|
8
7
|
import { Metadata } from "../metadata.js";
|
|
@@ -372,8 +371,11 @@ export const DI = Object.freeze({
|
|
|
372
371
|
: DI.getOrCreateDOMContainer();
|
|
373
372
|
value = container.get(key);
|
|
374
373
|
this[diPropertyKey] = value;
|
|
375
|
-
if (respectConnection
|
|
374
|
+
if (respectConnection) {
|
|
376
375
|
const notifier = this.$fastController;
|
|
376
|
+
if (!notifier) {
|
|
377
|
+
throw FAST.error(1514 /* Message.connectUpdateRequiresController */);
|
|
378
|
+
}
|
|
377
379
|
const handleChange = () => {
|
|
378
380
|
const newContainer = DI.findResponsibleContainer(this);
|
|
379
381
|
const newValue = newContainer.get(key);
|
|
@@ -67,10 +67,311 @@ export const SpliceStrategySupport = Object.freeze({
|
|
|
67
67
|
const reset = new Splice(0, emptyArray, 0);
|
|
68
68
|
reset.reset = true;
|
|
69
69
|
const resetSplices = [reset];
|
|
70
|
+
// Note: This function is *based* on the computation of the Levenshtein
|
|
71
|
+
// "edit" distance. The one change is that "updates" are treated as two
|
|
72
|
+
// edits - not one. With Array splices, an update is really a delete
|
|
73
|
+
// followed by an add. By retaining this, we optimize for "keeping" the
|
|
74
|
+
// maximum array items in the original array. For example:
|
|
75
|
+
//
|
|
76
|
+
// 'xxxx123' to '123yyyy'
|
|
77
|
+
//
|
|
78
|
+
// With 1-edit updates, the shortest path would be just to update all seven
|
|
79
|
+
// characters. With 2-edit updates, we delete 4, leave 3, and add 4. This
|
|
80
|
+
// leaves the substring '123' intact.
|
|
81
|
+
function calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd) {
|
|
82
|
+
// "Deletion" columns
|
|
83
|
+
const rowCount = oldEnd - oldStart + 1;
|
|
84
|
+
const columnCount = currentEnd - currentStart + 1;
|
|
85
|
+
const distances = new Array(rowCount);
|
|
86
|
+
let north;
|
|
87
|
+
let west;
|
|
88
|
+
// "Addition" rows. Initialize null column.
|
|
89
|
+
for (let i = 0; i < rowCount; ++i) {
|
|
90
|
+
distances[i] = new Array(columnCount);
|
|
91
|
+
distances[i][0] = i;
|
|
92
|
+
}
|
|
93
|
+
// Initialize null row
|
|
94
|
+
for (let j = 0; j < columnCount; ++j) {
|
|
95
|
+
distances[0][j] = j;
|
|
96
|
+
}
|
|
97
|
+
for (let i = 1; i < rowCount; ++i) {
|
|
98
|
+
for (let j = 1; j < columnCount; ++j) {
|
|
99
|
+
if (current[currentStart + j - 1] === old[oldStart + i - 1]) {
|
|
100
|
+
distances[i][j] = distances[i - 1][j - 1];
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
north = distances[i - 1][j] + 1;
|
|
104
|
+
west = distances[i][j - 1] + 1;
|
|
105
|
+
distances[i][j] = north < west ? north : west;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return distances;
|
|
110
|
+
}
|
|
111
|
+
// This starts at the final weight, and walks "backward" by finding
|
|
112
|
+
// the minimum previous weight recursively until the origin of the weight
|
|
113
|
+
// matrix.
|
|
114
|
+
function spliceOperationsFromEditDistances(distances) {
|
|
115
|
+
let i = distances.length - 1;
|
|
116
|
+
let j = distances[0].length - 1;
|
|
117
|
+
let current = distances[i][j];
|
|
118
|
+
const edits = [];
|
|
119
|
+
while (i > 0 || j > 0) {
|
|
120
|
+
if (i === 0) {
|
|
121
|
+
edits.push(2 /* Edit.add */);
|
|
122
|
+
j--;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (j === 0) {
|
|
126
|
+
edits.push(3 /* Edit.delete */);
|
|
127
|
+
i--;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const northWest = distances[i - 1][j - 1];
|
|
131
|
+
const west = distances[i - 1][j];
|
|
132
|
+
const north = distances[i][j - 1];
|
|
133
|
+
let min;
|
|
134
|
+
if (west < north) {
|
|
135
|
+
min = west < northWest ? west : northWest;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
min = north < northWest ? north : northWest;
|
|
139
|
+
}
|
|
140
|
+
if (min === northWest) {
|
|
141
|
+
if (northWest === current) {
|
|
142
|
+
edits.push(0 /* Edit.leave */);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
edits.push(1 /* Edit.update */);
|
|
146
|
+
current = northWest;
|
|
147
|
+
}
|
|
148
|
+
i--;
|
|
149
|
+
j--;
|
|
150
|
+
}
|
|
151
|
+
else if (min === west) {
|
|
152
|
+
edits.push(3 /* Edit.delete */);
|
|
153
|
+
i--;
|
|
154
|
+
current = west;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
edits.push(2 /* Edit.add */);
|
|
158
|
+
j--;
|
|
159
|
+
current = north;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return edits.reverse();
|
|
163
|
+
}
|
|
164
|
+
function sharedPrefix(current, old, searchLength) {
|
|
165
|
+
for (let i = 0; i < searchLength; ++i) {
|
|
166
|
+
if (current[i] !== old[i]) {
|
|
167
|
+
return i;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return searchLength;
|
|
171
|
+
}
|
|
172
|
+
function sharedSuffix(current, old, searchLength) {
|
|
173
|
+
let index1 = current.length;
|
|
174
|
+
let index2 = old.length;
|
|
175
|
+
let count = 0;
|
|
176
|
+
while (count < searchLength && current[--index1] === old[--index2]) {
|
|
177
|
+
count++;
|
|
178
|
+
}
|
|
179
|
+
return count;
|
|
180
|
+
}
|
|
181
|
+
function intersect(start1, end1, start2, end2) {
|
|
182
|
+
// Disjoint
|
|
183
|
+
if (end1 < start2 || end2 < start1) {
|
|
184
|
+
return -1;
|
|
185
|
+
}
|
|
186
|
+
// Adjacent
|
|
187
|
+
if (end1 === start2 || end2 === start1) {
|
|
188
|
+
return 0;
|
|
189
|
+
}
|
|
190
|
+
// Non-zero intersect, span1 first
|
|
191
|
+
if (start1 < start2) {
|
|
192
|
+
if (end1 < end2) {
|
|
193
|
+
return end1 - start2; // Overlap
|
|
194
|
+
}
|
|
195
|
+
return end2 - start2; // Contained
|
|
196
|
+
}
|
|
197
|
+
// Non-zero intersect, span2 first
|
|
198
|
+
if (end2 < end1) {
|
|
199
|
+
return end2 - start1; // Overlap
|
|
200
|
+
}
|
|
201
|
+
return end1 - start1; // Contained
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* @remarks
|
|
205
|
+
* Lacking individual splice mutation information, the minimal set of
|
|
206
|
+
* splices can be synthesized given the previous state and final state of an
|
|
207
|
+
* array. The basic approach is to calculate the edit distance matrix and
|
|
208
|
+
* choose the shortest path through it.
|
|
209
|
+
*
|
|
210
|
+
* Complexity: O(l * p)
|
|
211
|
+
* l: The length of the current array
|
|
212
|
+
* p: The length of the old array
|
|
213
|
+
*/
|
|
214
|
+
function calc(current, currentStart, currentEnd, old, oldStart, oldEnd) {
|
|
215
|
+
let prefixCount = 0;
|
|
216
|
+
let suffixCount = 0;
|
|
217
|
+
const minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);
|
|
218
|
+
if (currentStart === 0 && oldStart === 0) {
|
|
219
|
+
prefixCount = sharedPrefix(current, old, minLength);
|
|
220
|
+
}
|
|
221
|
+
if (currentEnd === current.length && oldEnd === old.length) {
|
|
222
|
+
suffixCount = sharedSuffix(current, old, minLength - prefixCount);
|
|
223
|
+
}
|
|
224
|
+
currentStart += prefixCount;
|
|
225
|
+
oldStart += prefixCount;
|
|
226
|
+
currentEnd -= suffixCount;
|
|
227
|
+
oldEnd -= suffixCount;
|
|
228
|
+
if (currentEnd - currentStart === 0 && oldEnd - oldStart === 0) {
|
|
229
|
+
return emptyArray;
|
|
230
|
+
}
|
|
231
|
+
if (currentStart === currentEnd) {
|
|
232
|
+
const splice = new Splice(currentStart, [], 0);
|
|
233
|
+
while (oldStart < oldEnd) {
|
|
234
|
+
splice.removed.push(old[oldStart++]);
|
|
235
|
+
}
|
|
236
|
+
return [splice];
|
|
237
|
+
}
|
|
238
|
+
else if (oldStart === oldEnd) {
|
|
239
|
+
return [new Splice(currentStart, [], currentEnd - currentStart)];
|
|
240
|
+
}
|
|
241
|
+
const ops = spliceOperationsFromEditDistances(calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));
|
|
242
|
+
const splices = [];
|
|
243
|
+
let splice = void 0;
|
|
244
|
+
let index = currentStart;
|
|
245
|
+
let oldIndex = oldStart;
|
|
246
|
+
for (let i = 0; i < ops.length; ++i) {
|
|
247
|
+
switch (ops[i]) {
|
|
248
|
+
case 0 /* Edit.leave */:
|
|
249
|
+
if (splice !== void 0) {
|
|
250
|
+
splices.push(splice);
|
|
251
|
+
splice = void 0;
|
|
252
|
+
}
|
|
253
|
+
index++;
|
|
254
|
+
oldIndex++;
|
|
255
|
+
break;
|
|
256
|
+
case 1 /* Edit.update */:
|
|
257
|
+
if (splice === void 0) {
|
|
258
|
+
splice = new Splice(index, [], 0);
|
|
259
|
+
}
|
|
260
|
+
splice.addedCount++;
|
|
261
|
+
index++;
|
|
262
|
+
splice.removed.push(old[oldIndex]);
|
|
263
|
+
oldIndex++;
|
|
264
|
+
break;
|
|
265
|
+
case 2 /* Edit.add */:
|
|
266
|
+
if (splice === void 0) {
|
|
267
|
+
splice = new Splice(index, [], 0);
|
|
268
|
+
}
|
|
269
|
+
splice.addedCount++;
|
|
270
|
+
index++;
|
|
271
|
+
break;
|
|
272
|
+
case 3 /* Edit.delete */:
|
|
273
|
+
if (splice === void 0) {
|
|
274
|
+
splice = new Splice(index, [], 0);
|
|
275
|
+
}
|
|
276
|
+
splice.removed.push(old[oldIndex]);
|
|
277
|
+
oldIndex++;
|
|
278
|
+
break;
|
|
279
|
+
// no default
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (splice !== void 0) {
|
|
283
|
+
splices.push(splice);
|
|
284
|
+
}
|
|
285
|
+
return splices;
|
|
286
|
+
}
|
|
287
|
+
function merge(splice, splices) {
|
|
288
|
+
let inserted = false;
|
|
289
|
+
let insertionOffset = 0;
|
|
290
|
+
for (let i = 0; i < splices.length; i++) {
|
|
291
|
+
const current = splices[i];
|
|
292
|
+
current.index += insertionOffset;
|
|
293
|
+
if (inserted) {
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
const intersectCount = intersect(splice.index, splice.index + splice.removed.length, current.index, current.index + current.addedCount);
|
|
297
|
+
if (intersectCount >= 0) {
|
|
298
|
+
// Merge the two splices
|
|
299
|
+
splices.splice(i, 1);
|
|
300
|
+
i--;
|
|
301
|
+
insertionOffset -= current.addedCount - current.removed.length;
|
|
302
|
+
splice.addedCount += current.addedCount - intersectCount;
|
|
303
|
+
const deleteCount = splice.removed.length + current.removed.length - intersectCount;
|
|
304
|
+
if (!splice.addedCount && !deleteCount) {
|
|
305
|
+
// merged splice is a noop. discard.
|
|
306
|
+
inserted = true;
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
let currentRemoved = current.removed;
|
|
310
|
+
if (splice.index < current.index) {
|
|
311
|
+
// some prefix of splice.removed is prepended to current.removed.
|
|
312
|
+
const prepend = splice.removed.slice(0, current.index - splice.index);
|
|
313
|
+
prepend.push(...currentRemoved);
|
|
314
|
+
currentRemoved = prepend;
|
|
315
|
+
}
|
|
316
|
+
if (splice.index + splice.removed.length >
|
|
317
|
+
current.index + current.addedCount) {
|
|
318
|
+
// some suffix of splice.removed is appended to current.removed.
|
|
319
|
+
const append = splice.removed.slice(current.index + current.addedCount - splice.index);
|
|
320
|
+
currentRemoved.push(...append);
|
|
321
|
+
}
|
|
322
|
+
splice.removed = currentRemoved;
|
|
323
|
+
if (current.index < splice.index) {
|
|
324
|
+
splice.index = current.index;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
else if (splice.index < current.index) {
|
|
329
|
+
// Insert splice here.
|
|
330
|
+
inserted = true;
|
|
331
|
+
splices.splice(i, 0, splice);
|
|
332
|
+
i++;
|
|
333
|
+
const offset = splice.addedCount - splice.removed.length;
|
|
334
|
+
current.index += offset;
|
|
335
|
+
insertionOffset += offset;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
if (!inserted) {
|
|
339
|
+
splices.push(splice);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
function project(array, changes) {
|
|
343
|
+
let splices = [];
|
|
344
|
+
const initialSplices = [];
|
|
345
|
+
for (let i = 0, ii = changes.length; i < ii; i++) {
|
|
346
|
+
merge(changes[i], initialSplices);
|
|
347
|
+
}
|
|
348
|
+
for (let i = 0, ii = initialSplices.length; i < ii; ++i) {
|
|
349
|
+
const splice = initialSplices[i];
|
|
350
|
+
if (splice.addedCount === 1 && splice.removed.length === 1) {
|
|
351
|
+
if (splice.removed[0] !== array[splice.index]) {
|
|
352
|
+
splices.push(splice);
|
|
353
|
+
}
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
splices = splices.concat(calc(array, splice.index, splice.index + splice.addedCount, splice.removed, 0, splice.removed.length));
|
|
357
|
+
}
|
|
358
|
+
return splices;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* A SpliceStrategy that attempts to merge all splices into the minimal set of
|
|
362
|
+
* splices needed to represent the change from the old array to the new array.
|
|
363
|
+
* @public
|
|
364
|
+
*/
|
|
70
365
|
let defaultSpliceStrategy = Object.freeze({
|
|
71
|
-
support: SpliceStrategySupport.
|
|
366
|
+
support: SpliceStrategySupport.optimized,
|
|
72
367
|
normalize(previous, current, changes) {
|
|
73
|
-
|
|
368
|
+
if (previous === void 0) {
|
|
369
|
+
if (changes === void 0) {
|
|
370
|
+
return emptyArray;
|
|
371
|
+
}
|
|
372
|
+
return changes.length > 1 ? project(current, changes) : changes;
|
|
373
|
+
}
|
|
374
|
+
return resetSplices;
|
|
74
375
|
},
|
|
75
376
|
pop(array, observer, pop, args) {
|
|
76
377
|
const notEmpty = array.length > 0;
|
|
@@ -88,8 +88,13 @@ export const Observable = FAST.getById(2 /* KernelServiceId.observable */, () =>
|
|
|
88
88
|
const previousWatcher = watcher;
|
|
89
89
|
watcher = this.needsRefresh ? this : void 0;
|
|
90
90
|
this.needsRefresh = this.isVolatileBinding;
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
let result;
|
|
92
|
+
try {
|
|
93
|
+
result = this.binding(source, context !== null && context !== void 0 ? context : ExecutionContext.default);
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
watcher = previousWatcher;
|
|
97
|
+
}
|
|
93
98
|
return result;
|
|
94
99
|
}
|
|
95
100
|
dispose() {
|
|
@@ -88,6 +88,9 @@ export class RepeatBehavior {
|
|
|
88
88
|
this.template = this.templateBindingObserver.observe(this.source, this.context);
|
|
89
89
|
this.refreshAllViews(true);
|
|
90
90
|
}
|
|
91
|
+
else if (!args[0]) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
91
94
|
else if (args[0].reset) {
|
|
92
95
|
this.refreshAllViews();
|
|
93
96
|
}
|
|
@@ -263,5 +266,5 @@ HTMLDirective.define(RepeatDirective);
|
|
|
263
266
|
export function repeat(items, template, options = defaultRepeatOptions) {
|
|
264
267
|
const dataBinding = normalizeBinding(items);
|
|
265
268
|
const templateBinding = normalizeBinding(template);
|
|
266
|
-
return new RepeatDirective(dataBinding, templateBinding, options);
|
|
269
|
+
return new RepeatDirective(dataBinding, templateBinding, Object.assign(Object.assign({}, defaultRepeatOptions), options));
|
|
267
270
|
}
|
|
@@ -51,8 +51,10 @@ export class HTMLView {
|
|
|
51
51
|
node.parentNode.insertBefore(this.fragment, node);
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
|
-
const parentNode = node.parentNode;
|
|
55
54
|
const end = this.lastChild;
|
|
55
|
+
if (node.previousSibling === end)
|
|
56
|
+
return;
|
|
57
|
+
const parentNode = node.parentNode;
|
|
56
58
|
let current = this.firstChild;
|
|
57
59
|
let next;
|
|
58
60
|
while (current !== end) {
|
|
@@ -7424,52 +7424,7 @@
|
|
|
7424
7424
|
},
|
|
7425
7425
|
{
|
|
7426
7426
|
"kind": "Content",
|
|
7427
|
-
"text": "
|
|
7428
|
-
},
|
|
7429
|
-
{
|
|
7430
|
-
"kind": "Reference",
|
|
7431
|
-
"text": "HTMLElement",
|
|
7432
|
-
"canonicalReference": "!HTMLElement:interface"
|
|
7433
|
-
},
|
|
7434
|
-
{
|
|
7435
|
-
"kind": "Content",
|
|
7436
|
-
"text": " & "
|
|
7437
|
-
},
|
|
7438
|
-
{
|
|
7439
|
-
"kind": "Reference",
|
|
7440
|
-
"text": "FASTElement",
|
|
7441
|
-
"canonicalReference": "@microsoft/fast-element!FASTElement:interface"
|
|
7442
|
-
},
|
|
7443
|
-
{
|
|
7444
|
-
"kind": "Content",
|
|
7445
|
-
"text": ") & {\n from<TBase extends {\n new (): "
|
|
7446
|
-
},
|
|
7447
|
-
{
|
|
7448
|
-
"kind": "Reference",
|
|
7449
|
-
"text": "HTMLElement",
|
|
7450
|
-
"canonicalReference": "!HTMLElement:interface"
|
|
7451
|
-
},
|
|
7452
|
-
{
|
|
7453
|
-
"kind": "Content",
|
|
7454
|
-
"text": ";\n prototype: "
|
|
7455
|
-
},
|
|
7456
|
-
{
|
|
7457
|
-
"kind": "Reference",
|
|
7458
|
-
"text": "HTMLElement",
|
|
7459
|
-
"canonicalReference": "!HTMLElement:interface"
|
|
7460
|
-
},
|
|
7461
|
-
{
|
|
7462
|
-
"kind": "Content",
|
|
7463
|
-
"text": ";\n }>(BaseType: TBase): new () => "
|
|
7464
|
-
},
|
|
7465
|
-
{
|
|
7466
|
-
"kind": "Reference",
|
|
7467
|
-
"text": "InstanceType",
|
|
7468
|
-
"canonicalReference": "!InstanceType:type"
|
|
7469
|
-
},
|
|
7470
|
-
{
|
|
7471
|
-
"kind": "Content",
|
|
7472
|
-
"text": "<TBase> & "
|
|
7427
|
+
"text": "{\n new (): "
|
|
7473
7428
|
},
|
|
7474
7429
|
{
|
|
7475
7430
|
"kind": "Reference",
|
|
@@ -7494,6 +7449,15 @@
|
|
|
7494
7449
|
"text": "compose",
|
|
7495
7450
|
"canonicalReference": "@microsoft/fast-element!~compose:function"
|
|
7496
7451
|
},
|
|
7452
|
+
{
|
|
7453
|
+
"kind": "Content",
|
|
7454
|
+
"text": ";\n from: typeof "
|
|
7455
|
+
},
|
|
7456
|
+
{
|
|
7457
|
+
"kind": "Reference",
|
|
7458
|
+
"text": "from",
|
|
7459
|
+
"canonicalReference": "@microsoft/fast-element!~from:function"
|
|
7460
|
+
},
|
|
7497
7461
|
{
|
|
7498
7462
|
"kind": "Content",
|
|
7499
7463
|
"text": ";\n}"
|
|
@@ -7503,7 +7467,7 @@
|
|
|
7503
7467
|
"name": "FASTElement",
|
|
7504
7468
|
"variableTypeTokenRange": {
|
|
7505
7469
|
"startIndex": 1,
|
|
7506
|
-
"endIndex":
|
|
7470
|
+
"endIndex": 10
|
|
7507
7471
|
}
|
|
7508
7472
|
},
|
|
7509
7473
|
{
|
package/dist/fast-element.d.ts
CHANGED
|
@@ -1157,28 +1157,11 @@ export declare interface FASTElement extends HTMLElement {
|
|
|
1157
1157
|
* static helpers for working with FASTElements.
|
|
1158
1158
|
* @public
|
|
1159
1159
|
*/
|
|
1160
|
-
export declare const FASTElement:
|
|
1161
|
-
|
|
1162
|
-
* Creates a new FASTElement base class inherited from the
|
|
1163
|
-
* provided base type.
|
|
1164
|
-
* @param BaseType - The base element type to inherit from.
|
|
1165
|
-
*/
|
|
1166
|
-
from<TBase extends {
|
|
1167
|
-
new (): HTMLElement;
|
|
1168
|
-
prototype: HTMLElement;
|
|
1169
|
-
}>(BaseType: TBase): new () => InstanceType<TBase> & FASTElement;
|
|
1170
|
-
/**
|
|
1171
|
-
* Defines a platform custom element based on the provided type and definition.
|
|
1172
|
-
* @param type - The custom element type to define.
|
|
1173
|
-
* @param nameOrDef - The name of the element to define or a definition object
|
|
1174
|
-
* that describes the element to define.
|
|
1175
|
-
*/
|
|
1160
|
+
export declare const FASTElement: {
|
|
1161
|
+
new (): FASTElement;
|
|
1176
1162
|
define: typeof define;
|
|
1177
|
-
/**
|
|
1178
|
-
* Defines metadata for a FASTElement which can be used to later define the element.
|
|
1179
|
-
* @public
|
|
1180
|
-
*/
|
|
1181
1163
|
compose: typeof compose;
|
|
1164
|
+
from: typeof from;
|
|
1182
1165
|
};
|
|
1183
1166
|
|
|
1184
1167
|
/**
|
|
@@ -1256,6 +1239,8 @@ export declare class FASTElementDefinition<TType extends Constructable<HTMLEleme
|
|
|
1256
1239
|
|
|
1257
1240
|
/* Excluded from this release type: FASTGlobal */
|
|
1258
1241
|
|
|
1242
|
+
declare function from<TBase extends typeof HTMLElement>(BaseType: TBase): new () => InstanceType<TBase> & FASTElement;
|
|
1243
|
+
|
|
1259
1244
|
/**
|
|
1260
1245
|
* Transforms a template literal string into a ViewTemplate.
|
|
1261
1246
|
* @param strings - The string fragments that are interpolated with the values.
|