@bpmn-io/properties-panel 3.13.0 → 3.14.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/dist/assets/properties-panel.css +0 -4
- package/dist/index.esm.js +31 -22
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +66 -63
- package/dist/index.js.map +1 -1
- package/package.json +27 -30
- package/preact/README.md +2 -2
- package/preact/compat/LICENSE +21 -0
- package/preact/compat/dist/compat.js +1 -1
- package/preact/compat/dist/compat.js.map +1 -1
- package/preact/compat/dist/compat.mjs +1 -1
- package/preact/compat/dist/compat.module.js +1 -1
- package/preact/compat/dist/compat.module.js.map +1 -1
- package/preact/compat/dist/compat.umd.js +1 -1
- package/preact/compat/dist/compat.umd.js.map +1 -1
- package/preact/compat/server.browser.js +7 -0
- package/preact/compat/server.mjs +7 -0
- package/preact/compat/src/index.d.ts +22 -8
- package/preact/compat/src/index.js +35 -3
- package/preact/compat/src/portals.js +26 -35
- package/preact/compat/src/suspense.js +9 -6
- package/preact/compat/src/util.js +0 -5
- package/preact/debug/LICENSE +21 -0
- package/preact/debug/dist/debug.js +1 -1
- package/preact/debug/dist/debug.js.map +1 -1
- package/preact/debug/dist/debug.mjs +1 -1
- package/preact/debug/dist/debug.module.js +1 -1
- package/preact/debug/dist/debug.module.js.map +1 -1
- package/preact/debug/dist/debug.umd.js +1 -1
- package/preact/debug/dist/debug.umd.js.map +1 -1
- package/preact/debug/src/debug.js +124 -42
- package/preact/devtools/LICENSE +21 -0
- package/preact/devtools/dist/devtools.js +1 -1
- package/preact/devtools/dist/devtools.js.map +1 -1
- package/preact/devtools/dist/devtools.mjs +1 -1
- package/preact/devtools/dist/devtools.module.js +1 -1
- package/preact/devtools/dist/devtools.module.js.map +1 -1
- package/preact/devtools/dist/devtools.umd.js +1 -1
- package/preact/devtools/dist/devtools.umd.js.map +1 -1
- package/preact/devtools/src/devtools.js +1 -1
- package/preact/dist/preact.js +1 -1
- package/preact/dist/preact.js.map +1 -1
- package/preact/dist/preact.min.js +1 -1
- package/preact/dist/preact.min.js.map +1 -1
- package/preact/dist/preact.min.module.js +1 -1
- package/preact/dist/preact.min.module.js.map +1 -1
- package/preact/dist/preact.min.umd.js +1 -1
- package/preact/dist/preact.min.umd.js.map +1 -1
- package/preact/dist/preact.mjs +1 -1
- package/preact/dist/preact.module.js +1 -1
- package/preact/dist/preact.module.js.map +1 -1
- package/preact/dist/preact.umd.js +1 -1
- package/preact/dist/preact.umd.js.map +1 -1
- package/preact/hooks/LICENSE +21 -0
- package/preact/jsx-runtime/LICENSE +21 -0
- package/preact/jsx-runtime/dist/jsxRuntime.js +1 -1
- package/preact/jsx-runtime/dist/jsxRuntime.js.map +1 -1
- package/preact/jsx-runtime/dist/jsxRuntime.mjs +1 -1
- package/preact/jsx-runtime/dist/jsxRuntime.module.js +1 -1
- package/preact/jsx-runtime/dist/jsxRuntime.module.js.map +1 -1
- package/preact/jsx-runtime/dist/jsxRuntime.umd.js +1 -1
- package/preact/jsx-runtime/dist/jsxRuntime.umd.js.map +1 -1
- package/preact/jsx-runtime/src/index.d.ts +10 -0
- package/preact/jsx-runtime/src/index.js +113 -4
- package/preact/jsx-runtime/src/utils.js +36 -0
- package/preact/package.json +4 -3
- package/preact/src/clone-element.js +6 -4
- package/preact/src/component.js +34 -28
- package/preact/src/constants.js +13 -1
- package/preact/src/create-context.js +3 -3
- package/preact/src/create-element.js +14 -11
- package/preact/src/diff/catch-error.js +11 -7
- package/preact/src/diff/children.js +321 -218
- package/preact/src/diff/index.js +188 -142
- package/preact/src/diff/props.js +31 -38
- package/preact/src/index.d.ts +38 -19
- package/preact/src/index.js +1 -1
- package/preact/src/internal.d.ts +183 -153
- package/preact/src/jsx.d.ts +883 -19
- package/preact/src/options.js +1 -1
- package/preact/src/render.js +11 -11
- package/preact/src/util.js +2 -2
- package/preact/test-utils/dist/testUtils.js +1 -1
- package/preact/test-utils/dist/testUtils.js.map +1 -1
- package/preact/test-utils/dist/testUtils.mjs +1 -1
- package/preact/test-utils/dist/testUtils.module.js +1 -1
- package/preact/test-utils/dist/testUtils.module.js.map +1 -1
- package/preact/test-utils/dist/testUtils.umd.js +1 -1
- package/preact/test-utils/dist/testUtils.umd.js.map +1 -1
- package/preact/test-utils/src/index.js +13 -5
package/preact/src/diff/index.js
CHANGED
|
@@ -1,26 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
EMPTY_OBJ,
|
|
3
|
+
MODE_HYDRATE,
|
|
4
|
+
MODE_SUSPENDED,
|
|
5
|
+
RESET_MODE
|
|
6
|
+
} from '../constants';
|
|
7
|
+
import { BaseComponent, getDomSibling } from '../component';
|
|
3
8
|
import { Fragment } from '../create-element';
|
|
4
9
|
import { diffChildren } from './children';
|
|
5
|
-
import {
|
|
10
|
+
import { setProperty } from './props';
|
|
6
11
|
import { assign, isArray, removeNode, slice } from '../util';
|
|
7
12
|
import options from '../options';
|
|
8
13
|
|
|
9
14
|
/**
|
|
10
15
|
* Diff two virtual nodes and apply proper changes to the DOM
|
|
11
|
-
* @param {
|
|
12
|
-
* @param {
|
|
13
|
-
* @param {
|
|
14
|
-
* @param {object} globalContext The current context object. Modified by
|
|
16
|
+
* @param {PreactElement} parentDom The parent of the DOM element
|
|
17
|
+
* @param {VNode} newVNode The new virtual node
|
|
18
|
+
* @param {VNode} oldVNode The old virtual node
|
|
19
|
+
* @param {object} globalContext The current context object. Modified by
|
|
20
|
+
* getChildContext
|
|
15
21
|
* @param {boolean} isSvg Whether or not this element is an SVG node
|
|
16
|
-
* @param {Array<
|
|
17
|
-
* @param {Array<
|
|
18
|
-
*
|
|
19
|
-
* @param {
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* @param {boolean}
|
|
22
|
+
* @param {Array<PreactElement>} excessDomChildren
|
|
23
|
+
* @param {Array<Component>} commitQueue List of components which have callbacks
|
|
24
|
+
* to invoke in commitRoot
|
|
25
|
+
* @param {PreactElement} oldDom The current attached DOM element any new dom
|
|
26
|
+
* elements should be placed around. Likely `null` on first render (except when
|
|
27
|
+
* hydrating). Can be a sibling DOM element when diffing Fragments that have
|
|
28
|
+
* siblings. In most cases, it starts out as `oldChildren[0]._dom`.
|
|
29
|
+
* @param {boolean} isHydrating Whether or not we are in hydration
|
|
30
|
+
* @param {any[]} refQueue an array of elements needed to invoke refs
|
|
24
31
|
*/
|
|
25
32
|
export function diff(
|
|
26
33
|
parentDom,
|
|
@@ -31,8 +38,10 @@ export function diff(
|
|
|
31
38
|
excessDomChildren,
|
|
32
39
|
commitQueue,
|
|
33
40
|
oldDom,
|
|
34
|
-
isHydrating
|
|
41
|
+
isHydrating,
|
|
42
|
+
refQueue
|
|
35
43
|
) {
|
|
44
|
+
/** @type {any} */
|
|
36
45
|
let tmp,
|
|
37
46
|
newType = newVNode.type;
|
|
38
47
|
|
|
@@ -41,18 +50,16 @@ export function diff(
|
|
|
41
50
|
if (newVNode.constructor !== undefined) return null;
|
|
42
51
|
|
|
43
52
|
// If the previous diff bailed out, resume creating/hydrating.
|
|
44
|
-
if (oldVNode.
|
|
45
|
-
isHydrating = oldVNode.
|
|
53
|
+
if (oldVNode._flags & MODE_SUSPENDED) {
|
|
54
|
+
isHydrating = !!(oldVNode._flags & MODE_HYDRATE);
|
|
46
55
|
oldDom = newVNode._dom = oldVNode._dom;
|
|
47
|
-
// if we resume, we want the tree to be "unlocked"
|
|
48
|
-
newVNode._hydrating = null;
|
|
49
56
|
excessDomChildren = [oldDom];
|
|
50
57
|
}
|
|
51
58
|
|
|
52
59
|
if ((tmp = options._diff)) tmp(newVNode);
|
|
53
60
|
|
|
54
|
-
|
|
55
|
-
|
|
61
|
+
outer: if (typeof newType == 'function') {
|
|
62
|
+
try {
|
|
56
63
|
let c, isNew, oldProps, oldState, snapshot, clearProcessingException;
|
|
57
64
|
let newProps = newVNode.props;
|
|
58
65
|
|
|
@@ -73,11 +80,14 @@ export function diff(
|
|
|
73
80
|
} else {
|
|
74
81
|
// Instantiate the new component
|
|
75
82
|
if ('prototype' in newType && newType.prototype.render) {
|
|
76
|
-
// @ts-
|
|
83
|
+
// @ts-expect-error The check above verifies that newType is suppose to be constructed
|
|
77
84
|
newVNode._component = c = new newType(newProps, componentContext); // eslint-disable-line new-cap
|
|
78
85
|
} else {
|
|
79
|
-
// @ts-
|
|
80
|
-
newVNode._component = c = new
|
|
86
|
+
// @ts-expect-error Trust me, Component implements the interface we want
|
|
87
|
+
newVNode._component = c = new BaseComponent(
|
|
88
|
+
newProps,
|
|
89
|
+
componentContext
|
|
90
|
+
);
|
|
81
91
|
c.constructor = newType;
|
|
82
92
|
c.render = doRender;
|
|
83
93
|
}
|
|
@@ -134,14 +144,14 @@ export function diff(
|
|
|
134
144
|
}
|
|
135
145
|
|
|
136
146
|
if (
|
|
137
|
-
|
|
138
|
-
|
|
147
|
+
!c._force &&
|
|
148
|
+
((c.shouldComponentUpdate != null &&
|
|
139
149
|
c.shouldComponentUpdate(
|
|
140
150
|
newProps,
|
|
141
151
|
c._nextState,
|
|
142
152
|
componentContext
|
|
143
153
|
) === false) ||
|
|
144
|
-
|
|
154
|
+
newVNode._original === oldVNode._original)
|
|
145
155
|
) {
|
|
146
156
|
// More info about this here: https://gist.github.com/JoviDeCroock/bec5f2ce93544d2e6070ef8e0036e4e8
|
|
147
157
|
if (newVNode._original !== oldVNode._original) {
|
|
@@ -154,8 +164,6 @@ export function diff(
|
|
|
154
164
|
c._dirty = false;
|
|
155
165
|
}
|
|
156
166
|
|
|
157
|
-
// In cases of bailing due to strict-equality we have to reset force as well
|
|
158
|
-
c._force = false;
|
|
159
167
|
newVNode._dom = oldVNode._dom;
|
|
160
168
|
newVNode._children = oldVNode._children;
|
|
161
169
|
newVNode._children.forEach(vnode => {
|
|
@@ -188,6 +196,7 @@ export function diff(
|
|
|
188
196
|
c.context = componentContext;
|
|
189
197
|
c.props = newProps;
|
|
190
198
|
c._parentDom = parentDom;
|
|
199
|
+
c._force = false;
|
|
191
200
|
|
|
192
201
|
let renderHook = options._render,
|
|
193
202
|
count = 0;
|
|
@@ -240,13 +249,14 @@ export function diff(
|
|
|
240
249
|
excessDomChildren,
|
|
241
250
|
commitQueue,
|
|
242
251
|
oldDom,
|
|
243
|
-
isHydrating
|
|
252
|
+
isHydrating,
|
|
253
|
+
refQueue
|
|
244
254
|
);
|
|
245
255
|
|
|
246
256
|
c.base = newVNode._dom;
|
|
247
257
|
|
|
248
258
|
// We successfully rendered this VNode, unset any stored hydration/bailout state:
|
|
249
|
-
newVNode.
|
|
259
|
+
newVNode._flags &= RESET_MODE;
|
|
250
260
|
|
|
251
261
|
if (c._renderCallbacks.length) {
|
|
252
262
|
commitQueue.push(c);
|
|
@@ -255,57 +265,67 @@ export function diff(
|
|
|
255
265
|
if (clearProcessingException) {
|
|
256
266
|
c._pendingError = c._processingException = null;
|
|
257
267
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
excessDomChildren
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
oldVNode
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
commitQueue,
|
|
275
|
-
isHydrating
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if ((tmp = options.diffed)) tmp(newVNode);
|
|
280
|
-
} catch (e) {
|
|
281
|
-
newVNode._original = null;
|
|
282
|
-
// if hydrating or creating initial tree, bailout preserves DOM:
|
|
283
|
-
if (isHydrating || excessDomChildren != null) {
|
|
284
|
-
newVNode._dom = oldDom;
|
|
285
|
-
newVNode._hydrating = !!isHydrating;
|
|
286
|
-
excessDomChildren[excessDomChildren.indexOf(oldDom)] = null;
|
|
287
|
-
// ^ could possibly be simplified to:
|
|
288
|
-
// excessDomChildren.length = 0;
|
|
268
|
+
} catch (e) {
|
|
269
|
+
newVNode._original = null;
|
|
270
|
+
// if hydrating or creating initial tree, bailout preserves DOM:
|
|
271
|
+
if (isHydrating || excessDomChildren != null) {
|
|
272
|
+
newVNode._dom = oldDom;
|
|
273
|
+
newVNode._flags |= isHydrating
|
|
274
|
+
? MODE_HYDRATE | MODE_SUSPENDED
|
|
275
|
+
: MODE_HYDRATE;
|
|
276
|
+
excessDomChildren[excessDomChildren.indexOf(oldDom)] = null;
|
|
277
|
+
// ^ could possibly be simplified to:
|
|
278
|
+
// excessDomChildren.length = 0;
|
|
279
|
+
} else {
|
|
280
|
+
newVNode._dom = oldVNode._dom;
|
|
281
|
+
newVNode._children = oldVNode._children;
|
|
282
|
+
}
|
|
283
|
+
options._catchError(e, newVNode, oldVNode);
|
|
289
284
|
}
|
|
290
|
-
|
|
285
|
+
} else if (
|
|
286
|
+
excessDomChildren == null &&
|
|
287
|
+
newVNode._original === oldVNode._original
|
|
288
|
+
) {
|
|
289
|
+
newVNode._children = oldVNode._children;
|
|
290
|
+
newVNode._dom = oldVNode._dom;
|
|
291
|
+
} else {
|
|
292
|
+
newVNode._dom = diffElementNodes(
|
|
293
|
+
oldVNode._dom,
|
|
294
|
+
newVNode,
|
|
295
|
+
oldVNode,
|
|
296
|
+
globalContext,
|
|
297
|
+
isSvg,
|
|
298
|
+
excessDomChildren,
|
|
299
|
+
commitQueue,
|
|
300
|
+
isHydrating,
|
|
301
|
+
refQueue
|
|
302
|
+
);
|
|
291
303
|
}
|
|
304
|
+
|
|
305
|
+
if ((tmp = options.diffed)) tmp(newVNode);
|
|
292
306
|
}
|
|
293
307
|
|
|
294
308
|
/**
|
|
295
|
-
* @param {Array<
|
|
309
|
+
* @param {Array<Component>} commitQueue List of components
|
|
296
310
|
* which have callbacks to invoke in commitRoot
|
|
297
|
-
* @param {
|
|
311
|
+
* @param {VNode} root
|
|
298
312
|
*/
|
|
299
|
-
export function commitRoot(commitQueue, root) {
|
|
313
|
+
export function commitRoot(commitQueue, root, refQueue) {
|
|
314
|
+
root._nextDom = undefined;
|
|
315
|
+
|
|
316
|
+
for (let i = 0; i < refQueue.length; i++) {
|
|
317
|
+
applyRef(refQueue[i], refQueue[++i], refQueue[++i]);
|
|
318
|
+
}
|
|
319
|
+
|
|
300
320
|
if (options._commit) options._commit(root, commitQueue);
|
|
301
321
|
|
|
302
322
|
commitQueue.some(c => {
|
|
303
323
|
try {
|
|
304
|
-
// @ts-
|
|
324
|
+
// @ts-expect-error Reuse the commitQueue variable here so the type changes
|
|
305
325
|
commitQueue = c._renderCallbacks;
|
|
306
326
|
c._renderCallbacks = [];
|
|
307
327
|
commitQueue.some(cb => {
|
|
308
|
-
// @ts-
|
|
328
|
+
// @ts-expect-error See above comment on commitQueue
|
|
309
329
|
cb.call(c);
|
|
310
330
|
});
|
|
311
331
|
} catch (e) {
|
|
@@ -316,17 +336,18 @@ export function commitRoot(commitQueue, root) {
|
|
|
316
336
|
|
|
317
337
|
/**
|
|
318
338
|
* Diff two virtual nodes representing DOM element
|
|
319
|
-
* @param {
|
|
320
|
-
*
|
|
321
|
-
* @param {
|
|
322
|
-
* @param {
|
|
339
|
+
* @param {PreactElement} dom The DOM element representing the virtual nodes
|
|
340
|
+
* being diffed
|
|
341
|
+
* @param {VNode} newVNode The new virtual node
|
|
342
|
+
* @param {VNode} oldVNode The old virtual node
|
|
323
343
|
* @param {object} globalContext The current context object
|
|
324
344
|
* @param {boolean} isSvg Whether or not this DOM node is an SVG node
|
|
325
|
-
* @param {
|
|
326
|
-
* @param {Array<
|
|
327
|
-
*
|
|
345
|
+
* @param {Array<PreactElement>} excessDomChildren
|
|
346
|
+
* @param {Array<Component>} commitQueue List of components which have callbacks
|
|
347
|
+
* to invoke in commitRoot
|
|
328
348
|
* @param {boolean} isHydrating Whether or not we are in hydration
|
|
329
|
-
* @
|
|
349
|
+
* @param {any[]} refQueue an array of elements needed to invoke refs
|
|
350
|
+
* @returns {PreactElement}
|
|
330
351
|
*/
|
|
331
352
|
function diffElementNodes(
|
|
332
353
|
dom,
|
|
@@ -336,29 +357,40 @@ function diffElementNodes(
|
|
|
336
357
|
isSvg,
|
|
337
358
|
excessDomChildren,
|
|
338
359
|
commitQueue,
|
|
339
|
-
isHydrating
|
|
360
|
+
isHydrating,
|
|
361
|
+
refQueue
|
|
340
362
|
) {
|
|
341
363
|
let oldProps = oldVNode.props;
|
|
342
364
|
let newProps = newVNode.props;
|
|
343
|
-
let nodeType = newVNode.type;
|
|
344
|
-
|
|
365
|
+
let nodeType = /** @type {string} */ (newVNode.type);
|
|
366
|
+
/** @type {any} */
|
|
367
|
+
let i;
|
|
368
|
+
/** @type {{ __html?: string }} */
|
|
369
|
+
let newHtml;
|
|
370
|
+
/** @type {{ __html?: string }} */
|
|
371
|
+
let oldHtml;
|
|
372
|
+
/** @type {ComponentChildren} */
|
|
373
|
+
let newChildren;
|
|
374
|
+
let value;
|
|
375
|
+
let inputValue;
|
|
376
|
+
let checked;
|
|
345
377
|
|
|
346
378
|
// Tracks entering and exiting SVG namespace when descending through the tree.
|
|
347
379
|
if (nodeType === 'svg') isSvg = true;
|
|
348
380
|
|
|
349
381
|
if (excessDomChildren != null) {
|
|
350
|
-
for (; i < excessDomChildren.length; i++) {
|
|
351
|
-
|
|
382
|
+
for (i = 0; i < excessDomChildren.length; i++) {
|
|
383
|
+
value = excessDomChildren[i];
|
|
352
384
|
|
|
353
385
|
// if newVNode matches an element in excessDomChildren or the `dom`
|
|
354
386
|
// argument matches an element in excessDomChildren, remove it from
|
|
355
387
|
// excessDomChildren so it isn't later removed in diffChildren
|
|
356
388
|
if (
|
|
357
|
-
|
|
358
|
-
'setAttribute' in
|
|
359
|
-
(nodeType ?
|
|
389
|
+
value &&
|
|
390
|
+
'setAttribute' in value === !!nodeType &&
|
|
391
|
+
(nodeType ? value.localName === nodeType : value.nodeType === 3)
|
|
360
392
|
) {
|
|
361
|
-
dom =
|
|
393
|
+
dom = value;
|
|
362
394
|
excessDomChildren[i] = null;
|
|
363
395
|
break;
|
|
364
396
|
}
|
|
@@ -367,27 +399,19 @@ function diffElementNodes(
|
|
|
367
399
|
|
|
368
400
|
if (dom == null) {
|
|
369
401
|
if (nodeType === null) {
|
|
370
|
-
// @ts-ignore createTextNode returns Text, we expect PreactElement
|
|
371
402
|
return document.createTextNode(newProps);
|
|
372
403
|
}
|
|
373
404
|
|
|
374
405
|
if (isSvg) {
|
|
375
|
-
dom = document.createElementNS(
|
|
376
|
-
'http://www.w3.org/2000/svg',
|
|
377
|
-
// @ts-ignore We know `newVNode.type` is a string
|
|
378
|
-
nodeType
|
|
379
|
-
);
|
|
406
|
+
dom = document.createElementNS('http://www.w3.org/2000/svg', nodeType);
|
|
380
407
|
} else {
|
|
381
|
-
dom = document.createElement(
|
|
382
|
-
// @ts-ignore We know `newVNode.type` is a string
|
|
383
|
-
nodeType,
|
|
384
|
-
newProps.is && newProps
|
|
385
|
-
);
|
|
408
|
+
dom = document.createElement(nodeType, newProps.is && newProps);
|
|
386
409
|
}
|
|
387
410
|
|
|
388
411
|
// we created a new parent, so none of the previously attached children can be reused:
|
|
389
412
|
excessDomChildren = null;
|
|
390
|
-
// we are creating a new node, so we can assume this is a new subtree (in
|
|
413
|
+
// we are creating a new node, so we can assume this is a new subtree (in
|
|
414
|
+
// case we are hydrating), this deopts the hydrate
|
|
391
415
|
isHydrating = false;
|
|
392
416
|
}
|
|
393
417
|
|
|
@@ -402,43 +426,67 @@ function diffElementNodes(
|
|
|
402
426
|
|
|
403
427
|
oldProps = oldVNode.props || EMPTY_OBJ;
|
|
404
428
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
if (excessDomChildren != null) {
|
|
414
|
-
oldProps = {};
|
|
415
|
-
for (i = 0; i < dom.attributes.length; i++) {
|
|
416
|
-
oldProps[dom.attributes[i].name] = dom.attributes[i].value;
|
|
417
|
-
}
|
|
429
|
+
// If we are in a situation where we are not hydrating but are using
|
|
430
|
+
// existing DOM (e.g. replaceNode) we should read the existing DOM
|
|
431
|
+
// attributes to diff them
|
|
432
|
+
if (!isHydrating && excessDomChildren != null) {
|
|
433
|
+
oldProps = {};
|
|
434
|
+
for (i = 0; i < dom.attributes.length; i++) {
|
|
435
|
+
value = dom.attributes[i];
|
|
436
|
+
oldProps[value.name] = value.value;
|
|
418
437
|
}
|
|
438
|
+
}
|
|
419
439
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
)
|
|
427
|
-
dom.innerHTML = (newHtml && newHtml.__html) || '';
|
|
428
|
-
}
|
|
440
|
+
for (i in oldProps) {
|
|
441
|
+
value = oldProps[i];
|
|
442
|
+
if (i == 'children') {
|
|
443
|
+
} else if (i == 'dangerouslySetInnerHTML') {
|
|
444
|
+
oldHtml = value;
|
|
445
|
+
} else if (i !== 'key' && !(i in newProps)) {
|
|
446
|
+
setProperty(dom, i, null, value, isSvg);
|
|
429
447
|
}
|
|
430
448
|
}
|
|
431
449
|
|
|
432
|
-
|
|
450
|
+
// During hydration, props are not diffed at all (including dangerouslySetInnerHTML)
|
|
451
|
+
// @TODO we should warn in debug mode when props don't match here.
|
|
452
|
+
for (i in newProps) {
|
|
453
|
+
value = newProps[i];
|
|
454
|
+
if (i == 'children') {
|
|
455
|
+
newChildren = value;
|
|
456
|
+
} else if (i == 'dangerouslySetInnerHTML') {
|
|
457
|
+
newHtml = value;
|
|
458
|
+
} else if (i == 'value') {
|
|
459
|
+
inputValue = value;
|
|
460
|
+
} else if (i == 'checked') {
|
|
461
|
+
checked = value;
|
|
462
|
+
} else if (
|
|
463
|
+
i !== 'key' &&
|
|
464
|
+
(!isHydrating || typeof value == 'function') &&
|
|
465
|
+
oldProps[i] !== value
|
|
466
|
+
) {
|
|
467
|
+
setProperty(dom, i, value, oldProps[i], isSvg);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
433
470
|
|
|
434
471
|
// If the new vnode didn't have dangerouslySetInnerHTML, diff its children
|
|
435
472
|
if (newHtml) {
|
|
473
|
+
// Avoid re-applying the same '__html' if it did not changed between re-render
|
|
474
|
+
if (
|
|
475
|
+
!isHydrating &&
|
|
476
|
+
(!oldHtml ||
|
|
477
|
+
(newHtml.__html !== oldHtml.__html &&
|
|
478
|
+
newHtml.__html !== dom.innerHTML))
|
|
479
|
+
) {
|
|
480
|
+
dom.innerHTML = newHtml.__html;
|
|
481
|
+
}
|
|
482
|
+
|
|
436
483
|
newVNode._children = [];
|
|
437
484
|
} else {
|
|
438
|
-
|
|
485
|
+
if (oldHtml) dom.innerHTML = '';
|
|
486
|
+
|
|
439
487
|
diffChildren(
|
|
440
488
|
dom,
|
|
441
|
-
isArray(
|
|
489
|
+
isArray(newChildren) ? newChildren : [newChildren],
|
|
442
490
|
newVNode,
|
|
443
491
|
oldVNode,
|
|
444
492
|
globalContext,
|
|
@@ -448,7 +496,8 @@ function diffElementNodes(
|
|
|
448
496
|
excessDomChildren
|
|
449
497
|
? excessDomChildren[0]
|
|
450
498
|
: oldVNode._children && getDomSibling(oldVNode, 0),
|
|
451
|
-
isHydrating
|
|
499
|
+
isHydrating,
|
|
500
|
+
refQueue
|
|
452
501
|
);
|
|
453
502
|
|
|
454
503
|
// Remove children that are not part of any vnode.
|
|
@@ -459,30 +508,28 @@ function diffElementNodes(
|
|
|
459
508
|
}
|
|
460
509
|
}
|
|
461
510
|
|
|
462
|
-
//
|
|
511
|
+
// As above, don't diff props during hydration
|
|
463
512
|
if (!isHydrating) {
|
|
513
|
+
i = 'value';
|
|
464
514
|
if (
|
|
465
|
-
|
|
466
|
-
(i = newProps.value) !== undefined &&
|
|
515
|
+
inputValue !== undefined &&
|
|
467
516
|
// #2756 For the <progress>-element the initial value is 0,
|
|
468
517
|
// despite the attribute not being present. When the attribute
|
|
469
518
|
// is missing the progress bar is treated as indeterminate.
|
|
470
519
|
// To fix that we'll always update it when it is 0 for progress elements
|
|
471
|
-
(
|
|
472
|
-
(nodeType === 'progress' && !
|
|
520
|
+
(inputValue !== dom[i] ||
|
|
521
|
+
(nodeType === 'progress' && !inputValue) ||
|
|
473
522
|
// This is only for IE 11 to fix <select> value not being updated.
|
|
474
523
|
// To avoid a stale select value we need to set the option.value
|
|
475
524
|
// again, which triggers IE11 to re-evaluate the select value
|
|
476
|
-
(nodeType === 'option' &&
|
|
525
|
+
(nodeType === 'option' && inputValue !== oldProps[i]))
|
|
477
526
|
) {
|
|
478
|
-
setProperty(dom,
|
|
527
|
+
setProperty(dom, i, inputValue, oldProps[i], false);
|
|
479
528
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
i
|
|
484
|
-
) {
|
|
485
|
-
setProperty(dom, 'checked', i, oldProps.checked, false);
|
|
529
|
+
|
|
530
|
+
i = 'checked';
|
|
531
|
+
if (checked !== undefined && checked !== dom[i]) {
|
|
532
|
+
setProperty(dom, i, checked, oldProps[i], false);
|
|
486
533
|
}
|
|
487
534
|
}
|
|
488
535
|
}
|
|
@@ -492,9 +539,9 @@ function diffElementNodes(
|
|
|
492
539
|
|
|
493
540
|
/**
|
|
494
541
|
* Invoke or update a ref, depending on whether it is a function or object ref.
|
|
495
|
-
* @param {
|
|
542
|
+
* @param {Ref<any>} ref
|
|
496
543
|
* @param {any} value
|
|
497
|
-
* @param {
|
|
544
|
+
* @param {VNode} vnode
|
|
498
545
|
*/
|
|
499
546
|
export function applyRef(ref, value, vnode) {
|
|
500
547
|
try {
|
|
@@ -507,9 +554,8 @@ export function applyRef(ref, value, vnode) {
|
|
|
507
554
|
|
|
508
555
|
/**
|
|
509
556
|
* Unmount a virtual node from the tree and apply DOM changes
|
|
510
|
-
* @param {
|
|
511
|
-
* @param {
|
|
512
|
-
* initiated the unmount
|
|
557
|
+
* @param {VNode} vnode The virtual node to unmount
|
|
558
|
+
* @param {VNode} parentVNode The parent of the VNode that initiated the unmount
|
|
513
559
|
* @param {boolean} [skipRemove] Flag that indicates that a parent node of the
|
|
514
560
|
* current element is already detached from the DOM.
|
|
515
561
|
*/
|
package/preact/src/diff/props.js
CHANGED
|
@@ -1,38 +1,6 @@
|
|
|
1
1
|
import { IS_NON_DIMENSIONAL } from '../constants';
|
|
2
2
|
import options from '../options';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Diff the old and new properties of a VNode and apply changes to the DOM node
|
|
6
|
-
* @param {import('../internal').PreactElement} dom The DOM node to apply
|
|
7
|
-
* changes to
|
|
8
|
-
* @param {object} newProps The new props
|
|
9
|
-
* @param {object} oldProps The old props
|
|
10
|
-
* @param {boolean} isSvg Whether or not this node is an SVG node
|
|
11
|
-
* @param {boolean} hydrate Whether or not we are in hydration mode
|
|
12
|
-
*/
|
|
13
|
-
export function diffProps(dom, newProps, oldProps, isSvg, hydrate) {
|
|
14
|
-
let i;
|
|
15
|
-
|
|
16
|
-
for (i in oldProps) {
|
|
17
|
-
if (i !== 'children' && i !== 'key' && !(i in newProps)) {
|
|
18
|
-
setProperty(dom, i, null, oldProps[i], isSvg);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
for (i in newProps) {
|
|
23
|
-
if (
|
|
24
|
-
(!hydrate || typeof newProps[i] == 'function') &&
|
|
25
|
-
i !== 'children' &&
|
|
26
|
-
i !== 'key' &&
|
|
27
|
-
i !== 'value' &&
|
|
28
|
-
i !== 'checked' &&
|
|
29
|
-
oldProps[i] !== newProps[i]
|
|
30
|
-
) {
|
|
31
|
-
setProperty(dom, i, newProps[i], oldProps[i], isSvg);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
4
|
function setStyle(style, key, value) {
|
|
37
5
|
if (key[0] === '-') {
|
|
38
6
|
style.setProperty(key, value == null ? '' : value);
|
|
@@ -47,7 +15,7 @@ function setStyle(style, key, value) {
|
|
|
47
15
|
|
|
48
16
|
/**
|
|
49
17
|
* Set a property value on a DOM node
|
|
50
|
-
* @param {
|
|
18
|
+
* @param {PreactElement} dom The DOM node to modify
|
|
51
19
|
* @param {string} name The name of the property to set
|
|
52
20
|
* @param {*} value The value to set the property to
|
|
53
21
|
* @param {*} oldValue The old value the property had
|
|
@@ -83,7 +51,8 @@ export function setProperty(dom, name, value, oldValue, isSvg) {
|
|
|
83
51
|
}
|
|
84
52
|
// Benchmark for comparison: https://esbench.com/bench/574c954bdb965b9a00965ac6
|
|
85
53
|
else if (name[0] === 'o' && name[1] === 'n') {
|
|
86
|
-
useCapture =
|
|
54
|
+
useCapture =
|
|
55
|
+
name !== (name = name.replace(/(PointerCapture)$|Capture$/, '$1'));
|
|
87
56
|
|
|
88
57
|
// Infer correct casing for DOM built-in events:
|
|
89
58
|
if (name.toLowerCase() in dom) name = name.toLowerCase().slice(2);
|
|
@@ -94,14 +63,17 @@ export function setProperty(dom, name, value, oldValue, isSvg) {
|
|
|
94
63
|
|
|
95
64
|
if (value) {
|
|
96
65
|
if (!oldValue) {
|
|
66
|
+
value._attached = Date.now();
|
|
97
67
|
const handler = useCapture ? eventProxyCapture : eventProxy;
|
|
98
68
|
dom.addEventListener(name, handler, useCapture);
|
|
69
|
+
} else {
|
|
70
|
+
value._attached = oldValue._attached;
|
|
99
71
|
}
|
|
100
72
|
} else {
|
|
101
73
|
const handler = useCapture ? eventProxyCapture : eventProxy;
|
|
102
74
|
dom.removeEventListener(name, handler, useCapture);
|
|
103
75
|
}
|
|
104
|
-
} else
|
|
76
|
+
} else {
|
|
105
77
|
if (isSvg) {
|
|
106
78
|
// Normalize incorrect prop usage for SVG:
|
|
107
79
|
// - xlink:href / xlinkHref --> href (xlink:href was removed from SVG and isn't needed)
|
|
@@ -119,6 +91,7 @@ export function setProperty(dom, name, value, oldValue, isSvg) {
|
|
|
119
91
|
name !== 'download' &&
|
|
120
92
|
name !== 'rowSpan' &&
|
|
121
93
|
name !== 'colSpan' &&
|
|
94
|
+
name !== 'role' &&
|
|
122
95
|
name in dom
|
|
123
96
|
) {
|
|
124
97
|
try {
|
|
@@ -135,7 +108,7 @@ export function setProperty(dom, name, value, oldValue, isSvg) {
|
|
|
135
108
|
// amount of exceptions would cost too many bytes. On top of
|
|
136
109
|
// that other frameworks generally stringify `false`.
|
|
137
110
|
|
|
138
|
-
if (typeof value
|
|
111
|
+
if (typeof value == 'function') {
|
|
139
112
|
// never serialize functions as attribute values
|
|
140
113
|
} else if (value != null && (value !== false || name[4] === '-')) {
|
|
141
114
|
dom.setAttribute(name, value);
|
|
@@ -147,13 +120,33 @@ export function setProperty(dom, name, value, oldValue, isSvg) {
|
|
|
147
120
|
|
|
148
121
|
/**
|
|
149
122
|
* Proxy an event to hooked event handlers
|
|
150
|
-
* @param {
|
|
123
|
+
* @param {PreactEvent} e The event object from the browser
|
|
151
124
|
* @private
|
|
152
125
|
*/
|
|
153
126
|
function eventProxy(e) {
|
|
154
|
-
|
|
127
|
+
const eventHandler = this._listeners[e.type + false];
|
|
128
|
+
/**
|
|
129
|
+
* This trick is inspired by Vue https://github.com/vuejs/core/blob/main/packages/runtime-dom/src/modules/events.ts#L90-L101
|
|
130
|
+
* when the dom performs an event it leaves micro-ticks in between bubbling up which means that an event can trigger on a newly
|
|
131
|
+
* created DOM-node while the event bubbles up, this can cause quirky behavior as seen in https://github.com/preactjs/preact/issues/3927
|
|
132
|
+
*/
|
|
133
|
+
if (!e._dispatched) {
|
|
134
|
+
// When an event has no _dispatched we know this is the first event-target in the chain
|
|
135
|
+
// so we set the initial dispatched time.
|
|
136
|
+
e._dispatched = Date.now();
|
|
137
|
+
// When the _dispatched is smaller than the time when the targetted event handler was attached
|
|
138
|
+
// we know we have bubbled up to an element that was added during patching the dom.
|
|
139
|
+
} else if (e._dispatched <= eventHandler._attached) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
return eventHandler(options.event ? options.event(e) : e);
|
|
155
143
|
}
|
|
156
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Proxy an event to hooked event handlers
|
|
147
|
+
* @param {PreactEvent} e The event object from the browser
|
|
148
|
+
* @private
|
|
149
|
+
*/
|
|
157
150
|
function eventProxyCapture(e) {
|
|
158
151
|
return this._listeners[e.type + true](options.event ? options.event(e) : e);
|
|
159
152
|
}
|