foldkit 0.128.1 → 0.130.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/THIRD-PARTY-NOTICES.md +30 -0
- package/dist/brand/brand.d.ts +25 -0
- package/dist/brand/brand.d.ts.map +1 -0
- package/dist/brand/brand.js +50 -0
- package/dist/brand/index.d.ts +2 -0
- package/dist/brand/index.d.ts.map +1 -0
- package/dist/brand/index.js +1 -0
- package/dist/brand/public.d.ts +2 -0
- package/dist/brand/public.d.ts.map +1 -0
- package/dist/brand/public.js +1 -0
- package/dist/canvas/view.d.ts.map +1 -1
- package/dist/canvas/view.js +1 -1
- package/dist/command/index.d.ts +6 -1
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/interruptible/index.d.ts +2 -0
- package/dist/command/interruptible/index.d.ts.map +1 -0
- package/dist/command/interruptible/index.js +1 -0
- package/dist/command/interruptible/interruptible.d.ts +177 -0
- package/dist/command/interruptible/interruptible.d.ts.map +1 -0
- package/dist/command/interruptible/interruptible.js +155 -0
- package/dist/command/interruptible/public.d.ts +3 -0
- package/dist/command/interruptible/public.d.ts.map +1 -0
- package/dist/command/interruptible/public.js +1 -0
- package/dist/command/public.d.ts +1 -0
- package/dist/command/public.d.ts.map +1 -1
- package/dist/command/public.js +1 -0
- package/dist/devTools/protocol.d.ts +1 -1
- package/dist/devTools/protocol.d.ts.map +1 -1
- package/dist/devTools/protocol.js +1 -1
- package/dist/devTools/store.js +2 -2
- package/dist/devTools/webSocketBridge.d.ts +1 -1
- package/dist/devTools/webSocketBridge.js +1 -1
- package/dist/html/index.d.ts +18 -18
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +530 -460
- package/dist/html/lazy.d.ts +1 -1
- package/dist/html/lazy.d.ts.map +1 -1
- package/dist/html/lazy.js +11 -2
- package/dist/propsModule.d.ts +1 -1
- package/dist/propsModule.d.ts.map +1 -1
- package/dist/propsModule.js +6 -1
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +472 -279
- package/dist/snabbdom/attributes.d.ts +4 -0
- package/dist/snabbdom/attributes.d.ts.map +1 -0
- package/dist/snabbdom/attributes.js +63 -0
- package/dist/snabbdom/class.d.ts +4 -0
- package/dist/snabbdom/class.d.ts.map +1 -0
- package/dist/snabbdom/class.js +31 -0
- package/dist/snabbdom/dataset.d.ts +4 -0
- package/dist/snabbdom/dataset.d.ts.map +1 -0
- package/dist/snabbdom/dataset.js +42 -0
- package/dist/snabbdom/eventlisteners.d.ts +11 -0
- package/dist/snabbdom/eventlisteners.d.ts.map +1 -0
- package/dist/snabbdom/eventlisteners.js +85 -0
- package/dist/snabbdom/h.d.ts +11 -0
- package/dist/snabbdom/h.d.ts.map +1 -0
- package/dist/snabbdom/h.js +61 -0
- package/dist/snabbdom/hooks.d.ts +24 -0
- package/dist/snabbdom/hooks.d.ts.map +1 -0
- package/dist/snabbdom/hooks.js +1 -0
- package/dist/snabbdom/htmldomapi.d.ts +34 -0
- package/dist/snabbdom/htmldomapi.d.ts.map +1 -0
- package/dist/snabbdom/htmldomapi.js +111 -0
- package/dist/snabbdom/index.d.ts +15 -0
- package/dist/snabbdom/index.d.ts.map +1 -0
- package/dist/snabbdom/index.js +9 -0
- package/dist/snabbdom/init.d.ts +14 -0
- package/dist/snabbdom/init.d.ts.map +1 -0
- package/dist/snabbdom/init.js +486 -0
- package/dist/snabbdom/is.d.ts +3 -0
- package/dist/snabbdom/is.d.ts.map +1 -0
- package/dist/snabbdom/is.js +7 -0
- package/dist/snabbdom/module.d.ts +11 -0
- package/dist/snabbdom/module.d.ts.map +1 -0
- package/dist/snabbdom/module.js +1 -0
- package/dist/snabbdom/props.d.ts +2 -0
- package/dist/snabbdom/props.d.ts.map +1 -0
- package/dist/snabbdom/props.js +1 -0
- package/dist/snabbdom/style.d.ts +9 -0
- package/dist/snabbdom/style.d.ts.map +1 -0
- package/dist/snabbdom/style.js +123 -0
- package/dist/snabbdom/tovnode.d.ts +4 -0
- package/dist/snabbdom/tovnode.d.ts.map +1 -0
- package/dist/snabbdom/tovnode.js +69 -0
- package/dist/snabbdom/vnode.d.ts +46 -0
- package/dist/snabbdom/vnode.d.ts.map +1 -0
- package/dist/snabbdom/vnode.js +13 -0
- package/dist/test/apps/uploads.d.ts +81 -0
- package/dist/test/apps/uploads.d.ts.map +1 -0
- package/dist/test/apps/uploads.js +102 -0
- package/dist/test/internal.d.ts +16 -2
- package/dist/test/internal.d.ts.map +1 -1
- package/dist/test/internal.js +20 -4
- package/dist/vdom.d.ts +2 -2
- package/dist/vdom.d.ts.map +1 -1
- package/dist/vdom.js +1 -1
- package/package.json +7 -5
- package/dist/runtime/messagePriority.d.ts +0 -17
- package/dist/runtime/messagePriority.d.ts.map +0 -1
- package/dist/runtime/messagePriority.js +0 -33
- package/dist/runtime/renderLoop.d.ts +0 -27
- package/dist/runtime/renderLoop.d.ts.map +0 -1
- package/dist/runtime/renderLoop.js +0 -25
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/consistent-type-assertions */
|
|
2
|
+
import { htmlDomApi } from './htmldomapi.js';
|
|
3
|
+
import * as is from './is.js';
|
|
4
|
+
import { vnode, vnodeDataMaskKey } from './vnode.js';
|
|
5
|
+
const emptyNode = vnode('', {}, [], undefined, undefined);
|
|
6
|
+
function sameVnode(vnode1, vnode2) {
|
|
7
|
+
if (vnode1 === vnode2) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
if (vnode1.sel !== vnode2.sel) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
if (vnode1.key !== vnode2.key) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
if (vnode1.identity !== vnode2.identity) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
if (vnode1.data?.is !== vnode2.data?.is) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return vnode1.sel !== undefined || typeof vnode1.text === typeof vnode2.text;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* @todo Remove this function when the document fragment is considered stable.
|
|
26
|
+
*/
|
|
27
|
+
function documentFragmentIsNotSupported() {
|
|
28
|
+
throw new Error('The document fragment is not supported on this platform.');
|
|
29
|
+
}
|
|
30
|
+
function isElement(api, vnode) {
|
|
31
|
+
return api.isElement(vnode);
|
|
32
|
+
}
|
|
33
|
+
function isDocumentFragment(api, vnode) {
|
|
34
|
+
return api.isDocumentFragment?.(vnode) ?? false;
|
|
35
|
+
}
|
|
36
|
+
function createKeyToPreviousIndex(children, beginIndex, endIndex) {
|
|
37
|
+
const map = new Map();
|
|
38
|
+
for (let childIndex = beginIndex; childIndex <= endIndex; ++childIndex) {
|
|
39
|
+
const key = children[childIndex]?.key;
|
|
40
|
+
if (key !== undefined) {
|
|
41
|
+
map.set(key, childIndex);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return map;
|
|
45
|
+
}
|
|
46
|
+
const hooks = [
|
|
47
|
+
'create',
|
|
48
|
+
'update',
|
|
49
|
+
'remove',
|
|
50
|
+
'destroy',
|
|
51
|
+
'pre',
|
|
52
|
+
'post',
|
|
53
|
+
];
|
|
54
|
+
let duplicateKeyWarningOverride = undefined;
|
|
55
|
+
/** Overrides the `import.meta.hot` gate on the dev-only duplicate sibling key
|
|
56
|
+
* warning so unit tests can force it on or off. Pass `undefined` to restore
|
|
57
|
+
* the gate. Internal, test-only. */
|
|
58
|
+
export const __overrideDuplicateKeyWarning = (isActive) => {
|
|
59
|
+
duplicateKeyWarningOverride = isActive;
|
|
60
|
+
};
|
|
61
|
+
// NOTE: `import.meta` is read through a structural cast rather than the
|
|
62
|
+
// vite/client `ImportMeta` augmentation so repo-internal programs that
|
|
63
|
+
// typecheck this source without vite types (internal/lustre-benchmark) still
|
|
64
|
+
// compile. The emitted JS is a plain `import.meta.hot` access either way.
|
|
65
|
+
const isDuplicateKeyWarningActive = () => duplicateKeyWarningOverride ?? !!import.meta.hot;
|
|
66
|
+
export function init(modules, domApi, options) {
|
|
67
|
+
const moduleHooks = {
|
|
68
|
+
create: [],
|
|
69
|
+
update: [],
|
|
70
|
+
remove: [],
|
|
71
|
+
destroy: [],
|
|
72
|
+
pre: [],
|
|
73
|
+
post: [],
|
|
74
|
+
};
|
|
75
|
+
const moduleDataMasks = {
|
|
76
|
+
create: [],
|
|
77
|
+
update: [],
|
|
78
|
+
destroy: [],
|
|
79
|
+
};
|
|
80
|
+
const api = domApi !== undefined ? domApi : htmlDomApi;
|
|
81
|
+
let isDuplicateKeyWarningIssued = false;
|
|
82
|
+
for (const hook of hooks) {
|
|
83
|
+
for (const module of modules) {
|
|
84
|
+
const currentHook = module[hook];
|
|
85
|
+
if (currentHook !== undefined) {
|
|
86
|
+
;
|
|
87
|
+
moduleHooks[hook].push(currentHook);
|
|
88
|
+
if (hook === 'create' || hook === 'update' || hook === 'destroy') {
|
|
89
|
+
moduleDataMasks[hook].push(module.dataMask);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function emptyNodeAt(element) {
|
|
95
|
+
const id = element.id ? '#' + element.id : '';
|
|
96
|
+
// element.className doesn't return a string when element is an SVG element inside a shadowRoot.
|
|
97
|
+
// https://stackoverflow.com/questions/29454340/detecting-classname-of-svganimatedstring
|
|
98
|
+
const classes = element.getAttribute('class');
|
|
99
|
+
const classSelector = classes ? '.' + classes.split(' ').join('.') : '';
|
|
100
|
+
return vnode(api.tagName(element).toLowerCase() + id + classSelector, {}, [], undefined, element);
|
|
101
|
+
}
|
|
102
|
+
function emptyDocumentFragmentAt(fragment) {
|
|
103
|
+
return vnode(undefined, {}, [], undefined, fragment);
|
|
104
|
+
}
|
|
105
|
+
function createRemoveCallback(childElement, listeners) {
|
|
106
|
+
return function removeCallback() {
|
|
107
|
+
if (--listeners === 0) {
|
|
108
|
+
const parent = api.parentNode(childElement);
|
|
109
|
+
if (parent !== null) {
|
|
110
|
+
api.removeChild(parent, childElement);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function createElm(vnode, insertedVnodeQueue) {
|
|
116
|
+
const data = vnode.data;
|
|
117
|
+
const hook = data?.hook;
|
|
118
|
+
hook?.init?.(vnode);
|
|
119
|
+
const children = vnode.children;
|
|
120
|
+
const selector = vnode.sel;
|
|
121
|
+
if (selector === '!') {
|
|
122
|
+
vnode.text ??= '';
|
|
123
|
+
vnode.elm = api.createComment(vnode.text);
|
|
124
|
+
}
|
|
125
|
+
else if (selector === '') {
|
|
126
|
+
// textNode has no selector
|
|
127
|
+
vnode.elm = api.createTextNode(vnode.text);
|
|
128
|
+
}
|
|
129
|
+
else if (selector !== undefined) {
|
|
130
|
+
// Parse selector
|
|
131
|
+
const hashIndex = selector.indexOf('#');
|
|
132
|
+
const dotIndex = selector.indexOf('.', hashIndex);
|
|
133
|
+
const hash = hashIndex > 0 ? hashIndex : selector.length;
|
|
134
|
+
const dot = dotIndex > 0 ? dotIndex : selector.length;
|
|
135
|
+
const tagName = hashIndex !== -1 || dotIndex !== -1
|
|
136
|
+
? selector.slice(0, Math.min(hash, dot))
|
|
137
|
+
: selector;
|
|
138
|
+
const namespace = data?.ns;
|
|
139
|
+
const element = namespace === undefined
|
|
140
|
+
? api.createElement(tagName, data)
|
|
141
|
+
: api.createElementNS(namespace, tagName, data);
|
|
142
|
+
vnode.elm = element;
|
|
143
|
+
if (hash < dot) {
|
|
144
|
+
element.setAttribute('id', selector.slice(hash + 1, dot));
|
|
145
|
+
}
|
|
146
|
+
if (dotIndex > 0) {
|
|
147
|
+
element.setAttribute('class', selector.slice(dot + 1).replace(/\./g, ' '));
|
|
148
|
+
}
|
|
149
|
+
const dataMask = data?.[vnodeDataMaskKey];
|
|
150
|
+
for (let moduleIndex = 0; moduleIndex < moduleHooks.create.length; ++moduleIndex) {
|
|
151
|
+
const moduleDataMask = moduleDataMasks.create[moduleIndex];
|
|
152
|
+
if (moduleDataMask === undefined ||
|
|
153
|
+
dataMask === undefined ||
|
|
154
|
+
(dataMask & moduleDataMask) !== 0) {
|
|
155
|
+
moduleHooks.create[moduleIndex](emptyNode, vnode);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (is.primitive(vnode.text) &&
|
|
159
|
+
(!is.array(children) || children.length === 0)) {
|
|
160
|
+
// allow h1 and similar nodes to be created w/ text and empty child list
|
|
161
|
+
api.appendChild(element, api.createTextNode(vnode.text));
|
|
162
|
+
}
|
|
163
|
+
if (is.array(children)) {
|
|
164
|
+
for (let childIndex = 0; childIndex < children.length; ++childIndex) {
|
|
165
|
+
const child = children[childIndex];
|
|
166
|
+
if (child != null) {
|
|
167
|
+
api.appendChild(element, createElm(child, insertedVnodeQueue));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (hook !== undefined) {
|
|
172
|
+
hook.create?.(emptyNode, vnode);
|
|
173
|
+
if (hook.insert !== undefined) {
|
|
174
|
+
insertedVnodeQueue.push(vnode);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else if (options?.experimental?.fragments && vnode.children) {
|
|
179
|
+
vnode.elm = (api.createDocumentFragment ?? documentFragmentIsNotSupported)();
|
|
180
|
+
const dataMask = data?.[vnodeDataMaskKey];
|
|
181
|
+
for (let moduleIndex = 0; moduleIndex < moduleHooks.create.length; ++moduleIndex) {
|
|
182
|
+
const moduleDataMask = moduleDataMasks.create[moduleIndex];
|
|
183
|
+
if (moduleDataMask === undefined ||
|
|
184
|
+
dataMask === undefined ||
|
|
185
|
+
(dataMask & moduleDataMask) !== 0) {
|
|
186
|
+
moduleHooks.create[moduleIndex](emptyNode, vnode);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
for (let childIndex = 0; childIndex < vnode.children.length; ++childIndex) {
|
|
190
|
+
const child = vnode.children[childIndex];
|
|
191
|
+
if (child != null) {
|
|
192
|
+
api.appendChild(vnode.elm, createElm(child, insertedVnodeQueue));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
vnode.elm = api.createTextNode(vnode.text);
|
|
198
|
+
}
|
|
199
|
+
return vnode.elm;
|
|
200
|
+
}
|
|
201
|
+
function addVnodes(parentElement, before, vnodes, startIndex, endIndex, insertedVnodeQueue) {
|
|
202
|
+
for (; startIndex <= endIndex; ++startIndex) {
|
|
203
|
+
const child = vnodes[startIndex];
|
|
204
|
+
if (child != null) {
|
|
205
|
+
api.insertBefore(parentElement, createElm(child, insertedVnodeQueue), before);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function invokeDestroyHook(vnode) {
|
|
210
|
+
const data = vnode.data;
|
|
211
|
+
if (data !== undefined) {
|
|
212
|
+
data?.hook?.destroy?.(vnode);
|
|
213
|
+
const dataMask = data[vnodeDataMaskKey];
|
|
214
|
+
for (let moduleIndex = 0; moduleIndex < moduleHooks.destroy.length; ++moduleIndex) {
|
|
215
|
+
const moduleDataMask = moduleDataMasks.destroy[moduleIndex];
|
|
216
|
+
if (moduleDataMask === undefined ||
|
|
217
|
+
dataMask === undefined ||
|
|
218
|
+
(dataMask & moduleDataMask) !== 0) {
|
|
219
|
+
moduleHooks.destroy[moduleIndex](vnode);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (vnode.children !== undefined) {
|
|
223
|
+
for (let childIndex = 0; childIndex < vnode.children.length; ++childIndex) {
|
|
224
|
+
const child = vnode.children[childIndex];
|
|
225
|
+
if (child != null && typeof child !== 'string') {
|
|
226
|
+
invokeDestroyHook(child);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function removeVnodes(parentElement, vnodes, startIndex, endIndex) {
|
|
233
|
+
for (; startIndex <= endIndex; ++startIndex) {
|
|
234
|
+
let listeners;
|
|
235
|
+
const child = vnodes[startIndex];
|
|
236
|
+
if (child != null) {
|
|
237
|
+
if (child.sel !== undefined) {
|
|
238
|
+
invokeDestroyHook(child);
|
|
239
|
+
listeners = moduleHooks.remove.length + 1;
|
|
240
|
+
const removeCallback = createRemoveCallback(child.elm, listeners);
|
|
241
|
+
for (let moduleIndex = 0; moduleIndex < moduleHooks.remove.length; ++moduleIndex) {
|
|
242
|
+
moduleHooks.remove[moduleIndex](child, removeCallback);
|
|
243
|
+
}
|
|
244
|
+
const removeHook = child.data?.hook?.remove;
|
|
245
|
+
if (removeHook !== undefined) {
|
|
246
|
+
removeHook(child, removeCallback);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
removeCallback();
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
else if (child.children) {
|
|
253
|
+
// Fragment node
|
|
254
|
+
invokeDestroyHook(child);
|
|
255
|
+
removeVnodes(parentElement, child.children, 0, child.children.length - 1);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
// Text node
|
|
259
|
+
api.removeChild(parentElement, child.elm);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
function warnOnDuplicateKeys(children, beginIndex, endIndex, parentElement) {
|
|
265
|
+
if (!isDuplicateKeyWarningActive() || isDuplicateKeyWarningIssued) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const seenKeys = new Set();
|
|
269
|
+
for (let childIndex = beginIndex; childIndex <= endIndex; ++childIndex) {
|
|
270
|
+
const key = children[childIndex]?.key;
|
|
271
|
+
if (key === undefined) {
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
if (seenKeys.has(key)) {
|
|
275
|
+
isDuplicateKeyWarningIssued = true;
|
|
276
|
+
const parentSelector = api.isElement(parentElement)
|
|
277
|
+
? api.tagName(parentElement).toLowerCase()
|
|
278
|
+
: String(parentElement.nodeName).toLowerCase();
|
|
279
|
+
console.warn(`[foldkit] Duplicate key "${String(key)}" among children of ` +
|
|
280
|
+
`<${parentSelector}>. Keys must be unique among siblings; duplicates ` +
|
|
281
|
+
'make sibling matching ambiguous and can patch the wrong element.');
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
seenKeys.add(key);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function updateChildren(parentElement, previousChildren, nextChildren, insertedVnodeQueue) {
|
|
288
|
+
if (previousChildren.length === 0 && nextChildren.length === 0) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
warnOnDuplicateKeys(nextChildren, 0, nextChildren.length - 1, parentElement);
|
|
292
|
+
let previousStartIndex = 0;
|
|
293
|
+
let nextStartIndex = 0;
|
|
294
|
+
let previousEndIndex = previousChildren.length - 1;
|
|
295
|
+
let nextEndIndex = nextChildren.length - 1;
|
|
296
|
+
while (previousStartIndex <= previousEndIndex &&
|
|
297
|
+
nextStartIndex <= nextEndIndex &&
|
|
298
|
+
previousChildren[previousStartIndex] === nextChildren[nextStartIndex]) {
|
|
299
|
+
previousStartIndex += 1;
|
|
300
|
+
nextStartIndex += 1;
|
|
301
|
+
}
|
|
302
|
+
while (previousStartIndex <= previousEndIndex &&
|
|
303
|
+
nextStartIndex <= nextEndIndex &&
|
|
304
|
+
previousChildren[previousEndIndex] === nextChildren[nextEndIndex]) {
|
|
305
|
+
previousEndIndex -= 1;
|
|
306
|
+
nextEndIndex -= 1;
|
|
307
|
+
}
|
|
308
|
+
let previousStartVnode = previousChildren[previousStartIndex];
|
|
309
|
+
let previousEndVnode = previousChildren[previousEndIndex];
|
|
310
|
+
let nextStartVnode = nextChildren[nextStartIndex];
|
|
311
|
+
let nextEndVnode = nextChildren[nextEndIndex];
|
|
312
|
+
let previousKeyToIndex;
|
|
313
|
+
let indexInPreviousChildren;
|
|
314
|
+
let vnodeToMove;
|
|
315
|
+
let before;
|
|
316
|
+
while (previousStartIndex <= previousEndIndex &&
|
|
317
|
+
nextStartIndex <= nextEndIndex) {
|
|
318
|
+
if (previousStartVnode == null) {
|
|
319
|
+
previousStartVnode = previousChildren[++previousStartIndex];
|
|
320
|
+
}
|
|
321
|
+
else if (previousEndVnode == null) {
|
|
322
|
+
previousEndVnode = previousChildren[--previousEndIndex];
|
|
323
|
+
}
|
|
324
|
+
else if (nextStartVnode == null) {
|
|
325
|
+
nextStartVnode = nextChildren[++nextStartIndex];
|
|
326
|
+
}
|
|
327
|
+
else if (nextEndVnode == null) {
|
|
328
|
+
nextEndVnode = nextChildren[--nextEndIndex];
|
|
329
|
+
}
|
|
330
|
+
else if (sameVnode(previousStartVnode, nextStartVnode)) {
|
|
331
|
+
patchVnode(previousStartVnode, nextStartVnode, insertedVnodeQueue);
|
|
332
|
+
previousStartVnode = previousChildren[++previousStartIndex];
|
|
333
|
+
nextStartVnode = nextChildren[++nextStartIndex];
|
|
334
|
+
}
|
|
335
|
+
else if (sameVnode(previousEndVnode, nextEndVnode)) {
|
|
336
|
+
patchVnode(previousEndVnode, nextEndVnode, insertedVnodeQueue);
|
|
337
|
+
previousEndVnode = previousChildren[--previousEndIndex];
|
|
338
|
+
nextEndVnode = nextChildren[--nextEndIndex];
|
|
339
|
+
}
|
|
340
|
+
else if (sameVnode(previousStartVnode, nextEndVnode)) {
|
|
341
|
+
// Vnode moved right
|
|
342
|
+
patchVnode(previousStartVnode, nextEndVnode, insertedVnodeQueue);
|
|
343
|
+
api.insertBefore(parentElement, previousStartVnode.elm, api.nextSibling(previousEndVnode.elm));
|
|
344
|
+
previousStartVnode = previousChildren[++previousStartIndex];
|
|
345
|
+
nextEndVnode = nextChildren[--nextEndIndex];
|
|
346
|
+
}
|
|
347
|
+
else if (sameVnode(previousEndVnode, nextStartVnode)) {
|
|
348
|
+
// Vnode moved left
|
|
349
|
+
patchVnode(previousEndVnode, nextStartVnode, insertedVnodeQueue);
|
|
350
|
+
api.insertBefore(parentElement, previousEndVnode.elm, previousStartVnode.elm);
|
|
351
|
+
previousEndVnode = previousChildren[--previousEndIndex];
|
|
352
|
+
nextStartVnode = nextChildren[++nextStartIndex];
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
if (previousKeyToIndex === undefined) {
|
|
356
|
+
previousKeyToIndex = createKeyToPreviousIndex(previousChildren, previousStartIndex, previousEndIndex);
|
|
357
|
+
warnOnDuplicateKeys(previousChildren, previousStartIndex, previousEndIndex, parentElement);
|
|
358
|
+
}
|
|
359
|
+
const nextStartKey = nextStartVnode.key;
|
|
360
|
+
indexInPreviousChildren =
|
|
361
|
+
nextStartKey === undefined
|
|
362
|
+
? undefined
|
|
363
|
+
: previousKeyToIndex.get(nextStartKey);
|
|
364
|
+
if (indexInPreviousChildren === undefined) {
|
|
365
|
+
// `nextStartVnode` is new, create and insert it in beginning
|
|
366
|
+
api.insertBefore(parentElement, createElm(nextStartVnode, insertedVnodeQueue), previousStartVnode.elm);
|
|
367
|
+
nextStartVnode = nextChildren[++nextStartIndex];
|
|
368
|
+
}
|
|
369
|
+
else if (nextEndVnode.key === undefined ||
|
|
370
|
+
previousKeyToIndex.get(nextEndVnode.key) === undefined) {
|
|
371
|
+
// `nextEndVnode` is new, create and insert it in the end
|
|
372
|
+
api.insertBefore(parentElement, createElm(nextEndVnode, insertedVnodeQueue), api.nextSibling(previousEndVnode.elm));
|
|
373
|
+
nextEndVnode = nextChildren[--nextEndIndex];
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
// Neither of the new endpoints are new vnodes, so we make progress by
|
|
377
|
+
// moving `nextStartVnode` into position
|
|
378
|
+
vnodeToMove = previousChildren[indexInPreviousChildren];
|
|
379
|
+
if (!sameVnode(vnodeToMove, nextStartVnode)) {
|
|
380
|
+
api.insertBefore(parentElement, createElm(nextStartVnode, insertedVnodeQueue), previousStartVnode.elm);
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
patchVnode(vnodeToMove, nextStartVnode, insertedVnodeQueue);
|
|
384
|
+
previousChildren[indexInPreviousChildren] = undefined;
|
|
385
|
+
api.insertBefore(parentElement, vnodeToMove.elm, previousStartVnode.elm);
|
|
386
|
+
}
|
|
387
|
+
nextStartVnode = nextChildren[++nextStartIndex];
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
if (nextStartIndex <= nextEndIndex) {
|
|
392
|
+
before =
|
|
393
|
+
nextChildren[nextEndIndex + 1] == null
|
|
394
|
+
? null
|
|
395
|
+
: nextChildren[nextEndIndex + 1].elm;
|
|
396
|
+
addVnodes(parentElement, before, nextChildren, nextStartIndex, nextEndIndex, insertedVnodeQueue);
|
|
397
|
+
}
|
|
398
|
+
if (previousStartIndex <= previousEndIndex) {
|
|
399
|
+
removeVnodes(parentElement, previousChildren, previousStartIndex, previousEndIndex);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
function patchVnode(oldVnode, vnode, insertedVnodeQueue) {
|
|
403
|
+
if (oldVnode === vnode) {
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
const hook = vnode.data?.hook;
|
|
407
|
+
hook?.prepatch?.(oldVnode, vnode);
|
|
408
|
+
const element = (vnode.elm = oldVnode.elm);
|
|
409
|
+
if (vnode.data !== undefined ||
|
|
410
|
+
(vnode.text !== undefined && vnode.text !== oldVnode.text)) {
|
|
411
|
+
vnode.data ??= {};
|
|
412
|
+
oldVnode.data ??= {};
|
|
413
|
+
const oldDataMask = oldVnode.data[vnodeDataMaskKey];
|
|
414
|
+
const dataMask = vnode.data[vnodeDataMaskKey];
|
|
415
|
+
for (let moduleIndex = 0; moduleIndex < moduleHooks.update.length; ++moduleIndex) {
|
|
416
|
+
const moduleDataMask = moduleDataMasks.update[moduleIndex];
|
|
417
|
+
if (moduleDataMask === undefined ||
|
|
418
|
+
oldDataMask === undefined ||
|
|
419
|
+
dataMask === undefined ||
|
|
420
|
+
((oldDataMask | dataMask) & moduleDataMask) !== 0) {
|
|
421
|
+
moduleHooks.update[moduleIndex](oldVnode, vnode);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
vnode.data?.hook?.update?.(oldVnode, vnode);
|
|
425
|
+
}
|
|
426
|
+
const previousChildren = oldVnode.children;
|
|
427
|
+
const nextChildren = vnode.children;
|
|
428
|
+
if (vnode.text === undefined) {
|
|
429
|
+
if (previousChildren !== undefined && nextChildren !== undefined) {
|
|
430
|
+
if (previousChildren !== nextChildren) {
|
|
431
|
+
updateChildren(element, previousChildren, nextChildren, insertedVnodeQueue);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
else if (nextChildren !== undefined) {
|
|
435
|
+
if (oldVnode.text !== undefined)
|
|
436
|
+
api.setTextContent(element, '');
|
|
437
|
+
addVnodes(element, null, nextChildren, 0, nextChildren.length - 1, insertedVnodeQueue);
|
|
438
|
+
}
|
|
439
|
+
else if (previousChildren !== undefined) {
|
|
440
|
+
removeVnodes(element, previousChildren, 0, previousChildren.length - 1);
|
|
441
|
+
}
|
|
442
|
+
else if (oldVnode.text !== undefined) {
|
|
443
|
+
api.setTextContent(element, '');
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
else if (oldVnode.text !== vnode.text) {
|
|
447
|
+
if (previousChildren !== undefined) {
|
|
448
|
+
removeVnodes(element, previousChildren, 0, previousChildren.length - 1);
|
|
449
|
+
}
|
|
450
|
+
api.setTextContent(element, vnode.text);
|
|
451
|
+
}
|
|
452
|
+
hook?.postpatch?.(oldVnode, vnode);
|
|
453
|
+
}
|
|
454
|
+
return function patch(oldVnode, vnode) {
|
|
455
|
+
const insertedVnodeQueue = [];
|
|
456
|
+
isDuplicateKeyWarningIssued = false;
|
|
457
|
+
for (let moduleIndex = 0; moduleIndex < moduleHooks.pre.length; ++moduleIndex) {
|
|
458
|
+
moduleHooks.pre[moduleIndex]();
|
|
459
|
+
}
|
|
460
|
+
if (isElement(api, oldVnode)) {
|
|
461
|
+
oldVnode = emptyNodeAt(oldVnode);
|
|
462
|
+
}
|
|
463
|
+
else if (isDocumentFragment(api, oldVnode)) {
|
|
464
|
+
oldVnode = emptyDocumentFragmentAt(oldVnode);
|
|
465
|
+
}
|
|
466
|
+
if (sameVnode(oldVnode, vnode)) {
|
|
467
|
+
patchVnode(oldVnode, vnode, insertedVnodeQueue);
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
const element = oldVnode.elm;
|
|
471
|
+
const parent = api.parentNode(element);
|
|
472
|
+
createElm(vnode, insertedVnodeQueue);
|
|
473
|
+
if (parent !== null) {
|
|
474
|
+
api.insertBefore(parent, vnode.elm, api.nextSibling(element));
|
|
475
|
+
removeVnodes(parent, [oldVnode], 0, 0);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
for (let insertedVnodeIndex = 0; insertedVnodeIndex < insertedVnodeQueue.length; ++insertedVnodeIndex) {
|
|
479
|
+
insertedVnodeQueue[insertedVnodeIndex].data.hook.insert(insertedVnodeQueue[insertedVnodeIndex]);
|
|
480
|
+
}
|
|
481
|
+
for (let moduleIndex = 0; moduleIndex < moduleHooks.post.length; ++moduleIndex) {
|
|
482
|
+
moduleHooks.post[moduleIndex]();
|
|
483
|
+
}
|
|
484
|
+
return vnode;
|
|
485
|
+
};
|
|
486
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is.d.ts","sourceRoot":"","sources":["../../src/snabbdom/is.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,4BAAgB,CAAA;AAClC,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI,MAAM,GAAG,MAAM,CAOtD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CreateHook, DestroyHook, PostHook, PreHook, RemoveHook, UpdateHook } from './hooks.js';
|
|
2
|
+
export type Module = Partial<{
|
|
3
|
+
dataMask: number;
|
|
4
|
+
pre: PreHook;
|
|
5
|
+
create: CreateHook;
|
|
6
|
+
update: UpdateHook;
|
|
7
|
+
destroy: DestroyHook;
|
|
8
|
+
remove: RemoveHook;
|
|
9
|
+
post: PostHook;
|
|
10
|
+
}>;
|
|
11
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/snabbdom/module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,QAAQ,EACR,OAAO,EACP,UAAU,EACV,UAAU,EACX,MAAM,YAAY,CAAA;AAEnB,MAAM,MAAM,MAAM,GAAG,OAAO,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,OAAO,CAAA;IACZ,MAAM,EAAE,UAAU,CAAA;IAClB,MAAM,EAAE,UAAU,CAAA;IAClB,OAAO,EAAE,WAAW,CAAA;IACpB,MAAM,EAAE,UAAU,CAAA;IAClB,IAAI,EAAE,QAAQ,CAAA;CACf,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../src/snabbdom/props.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Module } from './module.js';
|
|
2
|
+
export type ElementStyle = Partial<CSSStyleDeclaration>;
|
|
3
|
+
export type VNodeStyle = ElementStyle & Record<string, string> & {
|
|
4
|
+
delayed?: ElementStyle & Record<string, string>;
|
|
5
|
+
remove?: ElementStyle & Record<string, string>;
|
|
6
|
+
destroy?: ElementStyle & Record<string, string>;
|
|
7
|
+
};
|
|
8
|
+
export declare const styleModule: Module;
|
|
9
|
+
//# sourceMappingURL=style.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/snabbdom/style.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;AAEvD,MAAM,MAAM,UAAU,GAAG,YAAY,GACnC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG;IACvB,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9C,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChD,CAAA;AAgHH,eAAO,MAAM,WAAW,EAAE,MAOzB,CAAA"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { VNodeDataMask } from './vnode.js';
|
|
2
|
+
// Binding `requestAnimationFrame` like this fixes a bug in IE/Edge. See #360 and #409.
|
|
3
|
+
const raf = typeof window !== 'undefined' &&
|
|
4
|
+
typeof window.requestAnimationFrame === 'function'
|
|
5
|
+
? window.requestAnimationFrame.bind(window)
|
|
6
|
+
: setTimeout;
|
|
7
|
+
const nextFrame = function (fn) {
|
|
8
|
+
raf(function () {
|
|
9
|
+
raf(fn);
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
let reflowForced = false;
|
|
13
|
+
function setNextFrame(obj, prop, val) {
|
|
14
|
+
nextFrame(function () {
|
|
15
|
+
obj[prop] = val;
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function updateStyle(oldVnode, vnode) {
|
|
19
|
+
let cur;
|
|
20
|
+
let name;
|
|
21
|
+
const elm = vnode.elm;
|
|
22
|
+
let oldStyle = oldVnode.data.style;
|
|
23
|
+
let style = vnode.data.style;
|
|
24
|
+
if (!oldStyle && !style)
|
|
25
|
+
return;
|
|
26
|
+
if (oldStyle === style)
|
|
27
|
+
return;
|
|
28
|
+
oldStyle = oldStyle || {};
|
|
29
|
+
style = style || {};
|
|
30
|
+
const oldHasDel = 'delayed' in oldStyle;
|
|
31
|
+
for (name in oldStyle) {
|
|
32
|
+
if (!(name in style)) {
|
|
33
|
+
if (name[0] === '-' && name[1] === '-') {
|
|
34
|
+
;
|
|
35
|
+
elm.style.removeProperty(name);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
;
|
|
39
|
+
elm.style[name] = '';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
for (name in style) {
|
|
44
|
+
cur = style[name];
|
|
45
|
+
if (name === 'delayed' && style.delayed) {
|
|
46
|
+
for (const name2 in style.delayed) {
|
|
47
|
+
cur = style.delayed[name2];
|
|
48
|
+
if (!oldHasDel || cur !== oldStyle.delayed[name2]) {
|
|
49
|
+
setNextFrame(elm.style, name2, cur);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else if (name !== 'remove' && cur !== oldStyle[name]) {
|
|
54
|
+
if (name[0] === '-' && name[1] === '-') {
|
|
55
|
+
;
|
|
56
|
+
elm.style.setProperty(name, cur);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
;
|
|
60
|
+
elm.style[name] = cur;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function applyDestroyStyle(vnode) {
|
|
66
|
+
let style;
|
|
67
|
+
let name;
|
|
68
|
+
const elm = vnode.elm;
|
|
69
|
+
const s = vnode.data.style;
|
|
70
|
+
if (!s || !(style = s['destroy']))
|
|
71
|
+
return;
|
|
72
|
+
for (name in style) {
|
|
73
|
+
;
|
|
74
|
+
elm.style[name] = style[name];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function applyRemoveStyle(vnode, rm) {
|
|
78
|
+
const s = vnode.data.style;
|
|
79
|
+
if (!s || !s.remove) {
|
|
80
|
+
rm();
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (!reflowForced) {
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
85
|
+
;
|
|
86
|
+
vnode.elm.offsetLeft;
|
|
87
|
+
reflowForced = true;
|
|
88
|
+
}
|
|
89
|
+
let name;
|
|
90
|
+
const elm = vnode.elm;
|
|
91
|
+
let i = 0;
|
|
92
|
+
const style = s.remove;
|
|
93
|
+
let amount = 0;
|
|
94
|
+
const applied = [];
|
|
95
|
+
for (name in style) {
|
|
96
|
+
applied.push(name);
|
|
97
|
+
elm.style[name] = style[name];
|
|
98
|
+
}
|
|
99
|
+
const compStyle = getComputedStyle(elm);
|
|
100
|
+
const props = compStyle['transition-property'].split(', ');
|
|
101
|
+
for (; i < props.length; ++i) {
|
|
102
|
+
if (applied.indexOf(props[i]) !== -1)
|
|
103
|
+
amount++;
|
|
104
|
+
}
|
|
105
|
+
;
|
|
106
|
+
elm.addEventListener('transitionend', function (ev) {
|
|
107
|
+
if (ev.target === elm)
|
|
108
|
+
--amount;
|
|
109
|
+
if (amount === 0)
|
|
110
|
+
rm();
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function forceReflow() {
|
|
114
|
+
reflowForced = false;
|
|
115
|
+
}
|
|
116
|
+
export const styleModule = {
|
|
117
|
+
dataMask: VNodeDataMask.Style,
|
|
118
|
+
pre: forceReflow,
|
|
119
|
+
create: updateStyle,
|
|
120
|
+
update: updateStyle,
|
|
121
|
+
destroy: applyDestroyStyle,
|
|
122
|
+
remove: applyRemoveStyle,
|
|
123
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tovnode.d.ts","sourceRoot":"","sources":["../../src/snabbdom/tovnode.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAc,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,KAAK,KAAK,EAAS,MAAM,YAAY,CAAA;AAc9C,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAiD1D"}
|