@kunpeng-js/properties-panel 2026.0.0-alpha2 → 2026.10.2
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/LICENSE +9 -2
- package/dist/index.esm.js +3760 -3762
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +3724 -3804
- package/dist/index.js.map +1 -1
- package/package.json +22 -48
- package/preact/README.md +5 -5
- package/preact/compat/client.d.ts +1 -3
- package/preact/compat/dist/compat.mjs +2 -2
- package/preact/compat/dist/compat.mjs.map +1 -0
- package/preact/compat/package.json +2 -41
- package/preact/compat/scheduler.d.ts +12 -0
- package/preact/compat/server.d.ts +17 -0
- package/preact/compat/src/Children.js +3 -3
- package/preact/compat/src/PureComponent.js +20 -12
- package/preact/compat/src/forwardRef.js +4 -17
- package/preact/compat/src/hooks.js +17 -51
- package/preact/compat/src/index.d.ts +249 -164
- package/preact/compat/src/index.js +52 -43
- package/preact/compat/src/internal.d.ts +1 -2
- package/preact/compat/src/memo.js +2 -2
- package/preact/compat/src/portals.js +2 -68
- package/preact/compat/src/render.js +182 -73
- package/preact/compat/src/suspense.d.ts +1 -3
- package/preact/compat/src/suspense.js +169 -179
- package/preact/compat/src/util.js +5 -22
- package/preact/debug/dist/debug.mjs +2 -2
- package/preact/debug/dist/debug.mjs.map +1 -0
- package/preact/debug/package.json +3 -14
- package/preact/debug/src/check-props.js +2 -6
- package/preact/debug/src/component-stack.js +67 -16
- package/preact/debug/src/debug.js +80 -35
- package/preact/debug/src/index.d.ts +11 -1
- package/preact/debug/src/index.js +3 -1
- package/preact/debug/src/util.js +1 -11
- package/preact/devtools/dist/devtools.mjs +2 -2
- package/preact/devtools/dist/devtools.mjs.map +1 -0
- package/preact/devtools/package.json +3 -15
- package/preact/devtools/src/devtools.js +1 -1
- package/preact/dist/preact.mjs +2 -2
- package/preact/dist/preact.mjs.map +1 -0
- package/preact/hooks/dist/hooks.mjs +2 -2
- package/preact/hooks/dist/hooks.mjs.map +1 -0
- package/preact/hooks/package.json +5 -24
- package/preact/hooks/src/index.d.ts +6 -13
- package/preact/hooks/src/index.js +95 -73
- package/preact/hooks/src/internal.d.ts +8 -3
- package/preact/jsx-runtime/dist/jsxRuntime.mjs +2 -2
- package/preact/jsx-runtime/dist/jsxRuntime.mjs.map +1 -0
- package/preact/jsx-runtime/package.json +4 -16
- package/preact/jsx-runtime/src/index.d.ts +11 -11
- package/preact/jsx-runtime/src/index.js +25 -40
- package/preact/jsx-runtime/src/utils.js +3 -3
- package/preact/package.json +59 -115
- package/preact/src/component.js +54 -47
- package/preact/src/constants.js +17 -2
- package/preact/src/create-context.js +4 -14
- package/preact/src/create-element.js +42 -17
- package/preact/src/create-portal.js +20 -0
- package/preact/src/diff/catch-error.js +26 -8
- package/preact/src/diff/children.js +158 -96
- package/preact/src/diff/index.js +265 -146
- package/preact/src/diff/props.js +39 -50
- package/preact/src/dom.d.ts +796 -147
- package/preact/src/index.d.ts +7 -18
- package/preact/src/index.js +2 -1
- package/preact/src/internal.d.ts +16 -24
- package/preact/src/jsx.d.ts +222 -2910
- package/preact/src/render.js +30 -34
- package/preact/src/util.js +5 -20
- package/preact/test-utils/dist/testUtils.mjs +1 -1
- package/preact/test-utils/dist/testUtils.mjs.map +1 -0
- package/preact/test-utils/package.json +5 -17
- package/README.md +0 -35
- package/preact/compat/dist/compat.js +0 -2
- package/preact/compat/dist/compat.js.map +0 -1
- package/preact/compat/dist/compat.module.js +0 -2
- package/preact/compat/dist/compat.module.js.map +0 -1
- package/preact/compat/dist/compat.umd.js +0 -2
- package/preact/compat/dist/compat.umd.js.map +0 -1
- package/preact/compat/src/suspense-list.d.ts +0 -16
- package/preact/compat/src/suspense-list.js +0 -127
- package/preact/debug/dist/debug.js +0 -2
- package/preact/debug/dist/debug.js.map +0 -1
- package/preact/debug/dist/debug.module.js +0 -2
- package/preact/debug/dist/debug.module.js.map +0 -1
- package/preact/debug/dist/debug.umd.js +0 -2
- package/preact/debug/dist/debug.umd.js.map +0 -1
- package/preact/devtools/dist/devtools.js +0 -2
- package/preact/devtools/dist/devtools.js.map +0 -1
- package/preact/devtools/dist/devtools.module.js +0 -2
- package/preact/devtools/dist/devtools.module.js.map +0 -1
- package/preact/devtools/dist/devtools.umd.js +0 -2
- package/preact/devtools/dist/devtools.umd.js.map +0 -1
- package/preact/dist/preact.js +0 -2
- package/preact/dist/preact.js.map +0 -1
- package/preact/dist/preact.min.js +0 -2
- package/preact/dist/preact.min.js.map +0 -1
- package/preact/dist/preact.min.module.js +0 -2
- package/preact/dist/preact.min.module.js.map +0 -1
- package/preact/dist/preact.min.umd.js +0 -2
- package/preact/dist/preact.min.umd.js.map +0 -1
- package/preact/dist/preact.module.js +0 -2
- package/preact/dist/preact.module.js.map +0 -1
- package/preact/dist/preact.umd.js +0 -2
- package/preact/dist/preact.umd.js.map +0 -1
- package/preact/hooks/dist/hooks.js +0 -2
- package/preact/hooks/dist/hooks.js.map +0 -1
- package/preact/hooks/dist/hooks.module.js +0 -2
- package/preact/hooks/dist/hooks.module.js.map +0 -1
- package/preact/hooks/dist/hooks.umd.js +0 -2
- package/preact/hooks/dist/hooks.umd.js.map +0 -1
- package/preact/jsx-runtime/dist/jsxRuntime.js +0 -2
- package/preact/jsx-runtime/dist/jsxRuntime.js.map +0 -1
- package/preact/jsx-runtime/dist/jsxRuntime.module.js +0 -2
- package/preact/jsx-runtime/dist/jsxRuntime.module.js.map +0 -1
- package/preact/jsx-runtime/dist/jsxRuntime.umd.js +0 -2
- package/preact/jsx-runtime/dist/jsxRuntime.umd.js.map +0 -1
- package/preact/src/cjs.js +0 -3
- package/preact/src/clone-element.js +0 -48
- package/preact/src/index-5.d.ts +0 -399
- package/preact/test-utils/dist/testUtils.js +0 -2
- package/preact/test-utils/dist/testUtils.js.map +0 -1
- package/preact/test-utils/dist/testUtils.module.js +0 -2
- package/preact/test-utils/dist/testUtils.module.js.map +0 -1
- package/preact/test-utils/dist/testUtils.umd.js +0 -2
- package/preact/test-utils/dist/testUtils.umd.js.map +0 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createVNode } from './create-element';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Portal component. A unique type is used instead of Fragment so that a
|
|
5
|
+
* portal returned directly from a component isn't collapsed into the
|
|
6
|
+
* component's children array by the Fragment unwrapping in `diff()`.
|
|
7
|
+
* @param {object} props
|
|
8
|
+
*/
|
|
9
|
+
function Portal(props) {
|
|
10
|
+
return props.children;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Create a `Portal` to continue rendering the vnode tree at a different DOM node
|
|
15
|
+
* @param {import('./internal').ComponentChildren} vnode The vnode to render
|
|
16
|
+
* @param {import('./internal').PreactElement} container The DOM node to continue rendering in to
|
|
17
|
+
*/
|
|
18
|
+
export function createPortal(vnode, container) {
|
|
19
|
+
return createVNode(Portal, { _parentDom: container, children: vnode });
|
|
20
|
+
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resetRenderCount } from '../component';
|
|
2
|
+
import {
|
|
3
|
+
COMPONENT_DIRTY,
|
|
4
|
+
COMPONENT_PENDING_ERROR,
|
|
5
|
+
COMPONENT_PROCESSING_EXCEPTION,
|
|
6
|
+
COMPONENT_FORCE
|
|
7
|
+
} from '../constants';
|
|
2
8
|
|
|
3
9
|
/**
|
|
4
10
|
* Find the closest error boundary to a thrown error and call it
|
|
@@ -14,33 +20,45 @@ export function _catchError(error, vnode, oldVNode, errorInfo) {
|
|
|
14
20
|
let component,
|
|
15
21
|
/** @type {import('../internal').ComponentType} */
|
|
16
22
|
ctor,
|
|
17
|
-
/** @type {
|
|
23
|
+
/** @type {number} */
|
|
18
24
|
handled;
|
|
19
25
|
|
|
20
26
|
for (; (vnode = vnode._parent); ) {
|
|
21
|
-
if (
|
|
27
|
+
if (
|
|
28
|
+
(component = vnode._component) &&
|
|
29
|
+
!(component._bits & COMPONENT_PROCESSING_EXCEPTION)
|
|
30
|
+
) {
|
|
31
|
+
component._bits |= COMPONENT_FORCE;
|
|
22
32
|
try {
|
|
23
33
|
ctor = component.constructor;
|
|
24
34
|
|
|
25
|
-
if (ctor && ctor.getDerivedStateFromError
|
|
35
|
+
if (ctor && ctor.getDerivedStateFromError) {
|
|
26
36
|
component.setState(ctor.getDerivedStateFromError(error));
|
|
27
|
-
handled = component.
|
|
37
|
+
handled = component._bits & COMPONENT_DIRTY;
|
|
28
38
|
}
|
|
29
39
|
|
|
30
|
-
if (component.componentDidCatch
|
|
40
|
+
if (component.componentDidCatch) {
|
|
31
41
|
component.componentDidCatch(error, errorInfo || {});
|
|
32
|
-
handled = component.
|
|
42
|
+
handled = component._bits & COMPONENT_DIRTY;
|
|
33
43
|
}
|
|
34
44
|
|
|
35
45
|
// This is an error boundary. Mark it as having bailed out, and whether it was mid-hydration.
|
|
36
46
|
if (handled) {
|
|
37
|
-
|
|
47
|
+
component._bits |= COMPONENT_PENDING_ERROR;
|
|
48
|
+
return;
|
|
38
49
|
}
|
|
39
50
|
} catch (e) {
|
|
40
51
|
error = e;
|
|
52
|
+
// This component failed to handle the error, so what its
|
|
53
|
+
// getDerivedStateFromError did must not make the next ancestor a
|
|
54
|
+
// boundary.
|
|
55
|
+
handled = 0;
|
|
41
56
|
}
|
|
42
57
|
}
|
|
43
58
|
}
|
|
44
59
|
|
|
60
|
+
// Reset rerender count to 0, so that the next render will not be skipped
|
|
61
|
+
// when we leverage prefresh
|
|
62
|
+
resetRenderCount();
|
|
45
63
|
throw error;
|
|
46
64
|
}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
EMPTY_ARR,
|
|
6
6
|
INSERT_VNODE,
|
|
7
7
|
MATCHED,
|
|
8
|
+
REF_DETACHED,
|
|
8
9
|
UNDEFINED,
|
|
9
10
|
NULL
|
|
10
11
|
} from '../constants';
|
|
@@ -39,6 +40,7 @@ import { getDomSibling } from '../component';
|
|
|
39
40
|
* siblings. In most cases, it starts out as `oldChildren[0]._dom`.
|
|
40
41
|
* @param {boolean} isHydrating Whether or not we are in hydration
|
|
41
42
|
* @param {any[]} refQueue an array of elements needed to invoke refs
|
|
43
|
+
* @returns {PreactElement} The next sibling DOM element to insert new elements
|
|
42
44
|
*/
|
|
43
45
|
export function diffChildren(
|
|
44
46
|
parentDom,
|
|
@@ -63,10 +65,11 @@ export function diffChildren(
|
|
|
63
65
|
/** @type {PreactElement} */
|
|
64
66
|
firstChildDom;
|
|
65
67
|
|
|
66
|
-
// This is a compression of oldParentVNode
|
|
67
|
-
// as EMPTY_OBJ._children should be `undefined`.
|
|
68
|
+
// This is a compression of oldParentVNode != EMPTY_OBJ && oldParentVNode._children || EMPTY_ARR
|
|
69
|
+
// as EMPTY_OBJ._children should be `undefined`. Callers always pass at
|
|
70
|
+
// least EMPTY_OBJ, so a null check isn't needed.
|
|
68
71
|
/** @type {VNode[]} */
|
|
69
|
-
let oldChildren =
|
|
72
|
+
let oldChildren = oldParentVNode._children || EMPTY_ARR;
|
|
70
73
|
|
|
71
74
|
let newChildrenLength = renderResult.length;
|
|
72
75
|
|
|
@@ -84,8 +87,10 @@ export function diffChildren(
|
|
|
84
87
|
|
|
85
88
|
// At this point, constructNewChildrenArray has assigned _index to be the
|
|
86
89
|
// matchingIndex for this VNode's oldVNode (or -1 if there is no oldVNode).
|
|
90
|
+
// ~_index guards the -1 case: a negative array index is a named property
|
|
91
|
+
// access which V8 can't serve from the fast elements path.
|
|
87
92
|
oldVNode =
|
|
88
|
-
(childVNode._index
|
|
93
|
+
(~childVNode._index && oldChildren[childVNode._index]) || EMPTY_OBJ;
|
|
89
94
|
|
|
90
95
|
// Update childVNode._index to its final index
|
|
91
96
|
childVNode._index = i;
|
|
@@ -106,23 +111,23 @@ export function diffChildren(
|
|
|
106
111
|
|
|
107
112
|
// Adjust DOM nodes
|
|
108
113
|
newDom = childVNode._dom;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
114
|
+
// A ref detached while its subtree was parked by Suspense is attached
|
|
115
|
+
// again on reveal.
|
|
116
|
+
if (oldVNode.ref != childVNode.ref || oldVNode._flags & REF_DETACHED) {
|
|
117
|
+
if (oldVNode.ref) applyRef(oldVNode.ref, NULL, childVNode, oldVNode);
|
|
118
|
+
if (childVNode.ref) {
|
|
119
|
+
refQueue.push(
|
|
120
|
+
childVNode.ref,
|
|
121
|
+
childVNode._component || newDom,
|
|
122
|
+
childVNode
|
|
123
|
+
);
|
|
112
124
|
}
|
|
113
|
-
refQueue.push(
|
|
114
|
-
childVNode.ref,
|
|
115
|
-
childVNode._component || newDom,
|
|
116
|
-
childVNode
|
|
117
|
-
);
|
|
118
125
|
}
|
|
119
126
|
|
|
120
|
-
|
|
121
|
-
firstChildDom = newDom;
|
|
122
|
-
}
|
|
127
|
+
firstChildDom = firstChildDom || newDom;
|
|
123
128
|
|
|
124
129
|
if (childVNode._flags & INSERT_VNODE) {
|
|
125
|
-
oldDom = insert(childVNode, oldDom, parentDom);
|
|
130
|
+
oldDom = insert(childVNode, oldDom, parentDom, !oldVNode._original);
|
|
126
131
|
|
|
127
132
|
// When a matched VNode is physically moved via INSERT_VNODE, its old
|
|
128
133
|
// _dom pointer becomes a stale positional reference. Clear it so that
|
|
@@ -170,7 +175,14 @@ function constructNewChildrenArray(
|
|
|
170
175
|
|
|
171
176
|
let skew = 0;
|
|
172
177
|
|
|
173
|
-
|
|
178
|
+
/** Whether any matched child was found far from its skewed index, i.e. a
|
|
179
|
+
* real reorder happened and we need to compute the minimal set of moves. */
|
|
180
|
+
let moved = false;
|
|
181
|
+
|
|
182
|
+
// Hoisted: every normalization branch below writes through this array, so
|
|
183
|
+
// reading `_children` off the vnode each time is a wasted property load.
|
|
184
|
+
/** @type {VNode[]} */
|
|
185
|
+
let newChildren = (newParentVNode._children = Array(newChildrenLength));
|
|
174
186
|
for (i = 0; i < newChildrenLength; i++) {
|
|
175
187
|
// @ts-expect-error We are reusing the childVNode variable to hold both the
|
|
176
188
|
// pre and post normalized childVNode
|
|
@@ -181,48 +193,38 @@ function constructNewChildrenArray(
|
|
|
181
193
|
typeof childVNode == 'boolean' ||
|
|
182
194
|
typeof childVNode == 'function'
|
|
183
195
|
) {
|
|
184
|
-
|
|
196
|
+
newChildren[i] = NULL;
|
|
185
197
|
continue;
|
|
186
198
|
}
|
|
187
199
|
// If this newVNode is being reused (e.g. <div>{reuse}{reuse}</div>) in the same diff,
|
|
188
200
|
// or we are rendering a component (e.g. setState) copy the oldVNodes so it can have
|
|
189
201
|
// it's own DOM & etc. pointers
|
|
202
|
+
// Anything that isn't an object at this point is a string, number or
|
|
203
|
+
// bigint (null, booleans and functions are handled above), String
|
|
204
|
+
// objects are the lone object type rendered as text.
|
|
190
205
|
else if (
|
|
191
|
-
typeof childVNode
|
|
192
|
-
typeof childVNode == 'number' ||
|
|
193
|
-
// eslint-disable-next-line valid-typeof
|
|
194
|
-
typeof childVNode == 'bigint' ||
|
|
206
|
+
typeof childVNode != 'object' ||
|
|
195
207
|
childVNode.constructor == String
|
|
196
208
|
) {
|
|
197
|
-
childVNode =
|
|
198
|
-
NULL,
|
|
199
|
-
childVNode,
|
|
200
|
-
NULL,
|
|
201
|
-
NULL,
|
|
202
|
-
NULL
|
|
203
|
-
);
|
|
209
|
+
childVNode = newChildren[i] = createVNode(NULL, childVNode);
|
|
204
210
|
} else if (isArray(childVNode)) {
|
|
205
|
-
childVNode =
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
NULL,
|
|
210
|
-
NULL
|
|
211
|
-
);
|
|
212
|
-
} else if (childVNode.constructor === UNDEFINED && childVNode._depth > 0) {
|
|
211
|
+
childVNode = newChildren[i] = createVNode(Fragment, {
|
|
212
|
+
children: childVNode
|
|
213
|
+
});
|
|
214
|
+
} else if (childVNode.constructor === UNDEFINED && childVNode._depth) {
|
|
213
215
|
// VNode is already in use, clone it. This can happen in the following
|
|
214
216
|
// scenario:
|
|
215
217
|
// const reuse = <div />
|
|
216
218
|
// <div>{reuse}<span />{reuse}</div>
|
|
217
|
-
childVNode =
|
|
219
|
+
childVNode = newChildren[i] = createVNode(
|
|
218
220
|
childVNode.type,
|
|
219
221
|
childVNode.props,
|
|
220
222
|
childVNode.key,
|
|
221
|
-
childVNode.ref
|
|
223
|
+
childVNode.ref,
|
|
222
224
|
childVNode._original
|
|
223
225
|
);
|
|
224
226
|
} else {
|
|
225
|
-
|
|
227
|
+
newChildren[i] = childVNode;
|
|
226
228
|
}
|
|
227
229
|
|
|
228
230
|
const skewedIndex = i + skew;
|
|
@@ -240,7 +242,8 @@ function constructNewChildrenArray(
|
|
|
240
242
|
));
|
|
241
243
|
|
|
242
244
|
oldVNode = NULL;
|
|
243
|
-
|
|
245
|
+
// ~matchingIndex is only falsy for -1, i.e. when no match was found
|
|
246
|
+
if (~matchingIndex) {
|
|
244
247
|
oldVNode = oldChildren[matchingIndex];
|
|
245
248
|
remainingOldChildren--;
|
|
246
249
|
if (oldVNode) {
|
|
@@ -251,10 +254,8 @@ function constructNewChildrenArray(
|
|
|
251
254
|
// Here, we define isMounting for the purposes of the skew diffing
|
|
252
255
|
// algorithm. Nodes that are unsuspending are considered mounting and we detect
|
|
253
256
|
// this by checking if oldVNode._original == null
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
if (isMounting) {
|
|
257
|
-
if (matchingIndex == -1) {
|
|
257
|
+
if (!oldVNode || !oldVNode._original) {
|
|
258
|
+
if (!~matchingIndex) {
|
|
258
259
|
// When the array of children is growing we need to decrease the skew
|
|
259
260
|
// as we are adding a new element to the array.
|
|
260
261
|
// Example:
|
|
@@ -280,38 +281,74 @@ function constructNewChildrenArray(
|
|
|
280
281
|
if (typeof childVNode.type != 'function') {
|
|
281
282
|
childVNode._flags |= INSERT_VNODE;
|
|
282
283
|
}
|
|
283
|
-
} else
|
|
284
|
-
//
|
|
285
|
-
//
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
//
|
|
289
|
-
//
|
|
290
|
-
//
|
|
291
|
-
//
|
|
292
|
-
//
|
|
293
|
-
//
|
|
294
|
-
// We could probably build heuristics for having an optimized course of action here as well, but
|
|
295
|
-
// might go at the cost of some bytes.
|
|
296
|
-
//
|
|
297
|
-
// If we wanted to optimize for i.e. only swaps we'd just do the last two code-branches and have
|
|
298
|
-
// only the first item be a re-scouting and all the others fall in their skewed counter-part.
|
|
299
|
-
// We could also further optimize for swaps
|
|
284
|
+
} else {
|
|
285
|
+
// Matched children are candidates for the minimal-move pass below;
|
|
286
|
+
// MATCHED on a _new_ vnode is cleared in diffChildren's placement loop.
|
|
287
|
+
childVNode._flags |= MATCHED;
|
|
288
|
+
|
|
289
|
+
// The skew adjustments keep findMatchingIndex's search centered for
|
|
290
|
+
// shift patterns (insertions/removals at the front). A match further
|
|
291
|
+
// than one position away means children were genuinely reordered:
|
|
292
|
+
// flag it so the minimal set of moves is computed below. Off-by-one
|
|
293
|
+
// matches provably keep matched old indices in increasing order, so
|
|
294
|
+
// no moves are needed for them.
|
|
300
295
|
if (matchingIndex == skewedIndex - 1) {
|
|
301
296
|
skew--;
|
|
302
297
|
} else if (matchingIndex == skewedIndex + 1) {
|
|
303
298
|
skew++;
|
|
304
|
-
} else {
|
|
299
|
+
} else if (matchingIndex != skewedIndex) {
|
|
305
300
|
if (matchingIndex > skewedIndex) {
|
|
306
301
|
skew--;
|
|
307
302
|
} else {
|
|
308
303
|
skew++;
|
|
309
304
|
}
|
|
310
305
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
306
|
+
moved = true;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (moved) {
|
|
312
|
+
// Children were reordered: mark the minimal set of matched (MATCHED flag)
|
|
313
|
+
// children for insertion by finding the longest increasing subsequence of
|
|
314
|
+
// old indices (patience sorting). Children on the subsequence stay in
|
|
315
|
+
// place, all others get INSERT_VNODE. `_index` still holds the
|
|
316
|
+
// matchingIndex here.
|
|
317
|
+
/** @type {number[]} tails[x] is the smallest old index ending an increasing subsequence of length x+1 */
|
|
318
|
+
let tails = [];
|
|
319
|
+
/** @type {number[]} length of the longest increasing subsequence ending at child i */
|
|
320
|
+
let lisLengths = [];
|
|
321
|
+
for (i = 0; i < newChildrenLength; i++) {
|
|
322
|
+
childVNode = newChildren[i];
|
|
323
|
+
if (childVNode && childVNode._flags & MATCHED) {
|
|
324
|
+
// Binary search for the insertion point, keeping the pass at
|
|
325
|
+
// O(n log n) even for pathological reorders.
|
|
326
|
+
let lo = 0,
|
|
327
|
+
hi = tails.length;
|
|
328
|
+
while (lo < hi) {
|
|
329
|
+
const mid = (lo + hi) >> 1;
|
|
330
|
+
if (tails[mid] < childVNode._index) {
|
|
331
|
+
lo = mid + 1;
|
|
332
|
+
} else {
|
|
333
|
+
hi = mid;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
tails[lo] = childVNode._index;
|
|
337
|
+
lisLengths[i] = lo + 1;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// `skew` is dead after the main loop; reuse it as the remaining
|
|
342
|
+
// subsequence length while walking backwards. Likewise `i` is left at
|
|
343
|
+
// newChildrenLength by the loop above.
|
|
344
|
+
skew = tails.length;
|
|
345
|
+
while (i--) {
|
|
346
|
+
if (lisLengths[i]) {
|
|
347
|
+
if (lisLengths[i] == skew) {
|
|
348
|
+
skew--;
|
|
349
|
+
} else {
|
|
350
|
+
newChildren[i]._flags |= INSERT_VNODE;
|
|
351
|
+
}
|
|
315
352
|
}
|
|
316
353
|
}
|
|
317
354
|
}
|
|
@@ -319,11 +356,12 @@ function constructNewChildrenArray(
|
|
|
319
356
|
// Remove remaining oldChildren if there are any. Loop forwards so that as we
|
|
320
357
|
// unmount DOM from the beginning of the oldChildren, we can adjust oldDom to
|
|
321
358
|
// point to the next child, which needs to be the first DOM node that won't be
|
|
322
|
-
// unmounted.
|
|
359
|
+
// unmounted. Keep this a plain loop: an arrow function here would capture
|
|
360
|
+
// `oldDom`, forcing V8 to context-allocate it on every call to this function.
|
|
323
361
|
if (remainingOldChildren) {
|
|
324
362
|
for (i = 0; i < oldChildrenLength; i++) {
|
|
325
363
|
oldVNode = oldChildren[i];
|
|
326
|
-
if (oldVNode
|
|
364
|
+
if (oldVNode && !(oldVNode._flags & MATCHED)) {
|
|
327
365
|
if (oldVNode._dom == oldDom) {
|
|
328
366
|
oldDom = getDomSibling(oldVNode);
|
|
329
367
|
}
|
|
@@ -340,35 +378,56 @@ function constructNewChildrenArray(
|
|
|
340
378
|
* @param {VNode} parentVNode
|
|
341
379
|
* @param {PreactElement} oldDom
|
|
342
380
|
* @param {PreactElement} parentDom
|
|
381
|
+
* @param {boolean} isMounting
|
|
343
382
|
* @returns {PreactElement}
|
|
344
383
|
*/
|
|
345
|
-
function insert(parentVNode, oldDom, parentDom) {
|
|
384
|
+
function insert(parentVNode, oldDom, parentDom, isMounting) {
|
|
346
385
|
// Note: VNodes in nested suspended trees may be missing _children.
|
|
347
|
-
|
|
348
386
|
if (typeof parentVNode.type == 'function') {
|
|
387
|
+
// Root children live in another container, they never move with the
|
|
388
|
+
// host tree and contribute nothing to the host insertion cursor.
|
|
389
|
+
if (parentVNode.props._parentDom) return oldDom;
|
|
349
390
|
let children = parentVNode._children;
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
391
|
+
if (children) {
|
|
392
|
+
for (let i = 0; i < children.length; i++) {
|
|
393
|
+
if (children[i]) {
|
|
394
|
+
// If we enter this code path on sCU bailout, where we copy
|
|
395
|
+
// oldVNode._children to newVNode._children, we need to update the old
|
|
396
|
+
// children's _parent pointer to point to the newVNode (parentVNode
|
|
397
|
+
// here).
|
|
398
|
+
children[i]._parent = parentVNode;
|
|
399
|
+
oldDom = insert(children[i], oldDom, parentDom, false);
|
|
400
|
+
}
|
|
358
401
|
}
|
|
359
402
|
}
|
|
360
403
|
|
|
361
404
|
return oldDom;
|
|
362
|
-
} else
|
|
363
|
-
|
|
405
|
+
} else {
|
|
406
|
+
// A cursor a parked Suspense subtree detached can't be a reference node:
|
|
407
|
+
// retry from the vnode tree, then give up and append.
|
|
408
|
+
if (oldDom && !oldDom.parentNode) {
|
|
364
409
|
oldDom = getDomSibling(parentVNode);
|
|
410
|
+
if (oldDom && !oldDom.parentNode) oldDom = NULL;
|
|
365
411
|
}
|
|
366
|
-
|
|
412
|
+
|
|
413
|
+
// Comments (e.g. server `$s` markers) are never ours: a node right after
|
|
414
|
+
// them is already in place.
|
|
415
|
+
let next = oldDom;
|
|
416
|
+
while (next && next.nodeType == 8) next = next.nextSibling;
|
|
417
|
+
|
|
418
|
+
if (parentVNode._dom != next) {
|
|
419
|
+
// Containers that aren't DOM nodes may not implement moveBefore()
|
|
420
|
+
if (!isMounting && parentDom.moveBefore && parentVNode._dom.parentNode) {
|
|
421
|
+
// @ts-expect-error This isn't added to TypeScript lib.d.ts yet
|
|
422
|
+
parentDom.moveBefore(parentVNode._dom, oldDom);
|
|
423
|
+
} else {
|
|
424
|
+
parentDom.insertBefore(parentVNode._dom, oldDom || NULL);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
oldDom = parentVNode._dom;
|
|
367
428
|
}
|
|
368
429
|
|
|
369
|
-
|
|
370
|
-
oldDom = oldDom && oldDom.nextSibling;
|
|
371
|
-
} while (oldDom != NULL && oldDom.nodeType == 8);
|
|
430
|
+
while ((oldDom = oldDom && oldDom.nextSibling) && oldDom.nodeType == 8);
|
|
372
431
|
|
|
373
432
|
return oldDom;
|
|
374
433
|
}
|
|
@@ -381,13 +440,14 @@ function insert(parentVNode, oldDom, parentDom) {
|
|
|
381
440
|
*/
|
|
382
441
|
export function toChildArray(children, out) {
|
|
383
442
|
out = out || [];
|
|
384
|
-
if (children
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
443
|
+
if (children != NULL && typeof children != 'boolean') {
|
|
444
|
+
if (isArray(children)) {
|
|
445
|
+
children.some(child => {
|
|
446
|
+
toChildArray(child, out);
|
|
447
|
+
});
|
|
448
|
+
} else {
|
|
449
|
+
out.push(children);
|
|
450
|
+
}
|
|
391
451
|
}
|
|
392
452
|
return out;
|
|
393
453
|
}
|
|
@@ -408,7 +468,7 @@ function findMatchingIndex(
|
|
|
408
468
|
const key = childVNode.key;
|
|
409
469
|
const type = childVNode.type;
|
|
410
470
|
let oldVNode = oldChildren[skewedIndex];
|
|
411
|
-
const matched = oldVNode
|
|
471
|
+
const matched = oldVNode && !(oldVNode._flags & MATCHED);
|
|
412
472
|
|
|
413
473
|
// We only need to perform a search if there are more children
|
|
414
474
|
// (remainingOldChildren) to search. However, if the oldVNode we just looked
|
|
@@ -423,10 +483,12 @@ function findMatchingIndex(
|
|
|
423
483
|
// we should not search as we risk re-using state of an unrelated VNode. (reverted for now)
|
|
424
484
|
let shouldSearch =
|
|
425
485
|
// (typeof type != 'function' || type === Fragment || key) &&
|
|
486
|
+
// The ternary keeps this a Smi comparison; `> matched` would compare
|
|
487
|
+
// number to boolean which V8 can't serve from the fast path.
|
|
426
488
|
remainingOldChildren > (matched ? 1 : 0);
|
|
427
489
|
|
|
428
490
|
if (
|
|
429
|
-
(oldVNode === NULL && key ==
|
|
491
|
+
(oldVNode === NULL && key == NULL) ||
|
|
430
492
|
(matched && key == oldVNode.key && type == oldVNode.type)
|
|
431
493
|
) {
|
|
432
494
|
return skewedIndex;
|
|
@@ -437,8 +499,8 @@ function findMatchingIndex(
|
|
|
437
499
|
const childIndex = x >= 0 ? x-- : y++;
|
|
438
500
|
oldVNode = oldChildren[childIndex];
|
|
439
501
|
if (
|
|
440
|
-
oldVNode
|
|
441
|
-
(oldVNode._flags & MATCHED)
|
|
502
|
+
oldVNode &&
|
|
503
|
+
!(oldVNode._flags & MATCHED) &&
|
|
442
504
|
key == oldVNode.key &&
|
|
443
505
|
type == oldVNode.type
|
|
444
506
|
) {
|