Skip to content

Commit d9fbb28

Browse files
authored
Add skip children to morph (#4568)
* Add skip children to morph * Use shouldSkipChildren
1 parent 3bb1bad commit d9fbb28

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

packages/morph/src/morph.js

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,17 @@ export function morph(from, toHtml, options) {
3434
}
3535

3636
let updateChildrenOnly = false
37-
38-
if (shouldSkip(updating, from, to, () => updateChildrenOnly = true)) return
37+
let skipChildren = false
38+
39+
// If we used `shouldSkip()` here and append the `skipChildren` function on the end, it will cause the signature of the `updating`
40+
// hook to change. For example, when it was `shouldSkip()` the signature was `updating: (el, toEl, childrenOnly, skip)`. But if
41+
// we append `skipChildren()`, it would make the signature `updating: (el, toEl, childrenOnly, skipChildren, skip)`. This is
42+
// a breaking change due to how the `shouldSkip()` function is structured.
43+
//
44+
// So we're using `shouldSkipChildren()` instead which doesn't have this problem as it allows us to pass in the `skipChildren()`
45+
// function as an earlier parameter and then append it to the `updating` hook signature manually. The signature of `updating`
46+
// hook is now `updating: (el, toEl, childrenOnly, skip, skipChildren)`.
47+
if (shouldSkipChildren(updating, () => skipChildren = true, from, to, () => updateChildrenOnly = true)) return
3948

4049
// Initialize the server-side HTML element with Alpine...
4150
if (from.nodeType === 1 && window.Alpine) {
@@ -60,7 +69,9 @@ export function morph(from, toHtml, options) {
6069

6170
updated(from, to)
6271

63-
patchChildren(from, to)
72+
if (! skipChildren) {
73+
patchChildren(from, to)
74+
}
6475
}
6576

6677
function differentElementNamesTypesOrKeys(from, to) {
@@ -386,6 +397,19 @@ function shouldSkip(hook, ...args) {
386397
return skip
387398
}
388399

400+
// Due to the structure of the `shouldSkip()` function, we can't pass in the `skipChildren`
401+
// function as an argument as it would change the signature of the existing hooks. So we
402+
// are using this function instead which doesn't have this problem as we can pass the
403+
// `skipChildren` function in as an earlier argument and then append it to the end
404+
// of the hook signature manually.
405+
function shouldSkipChildren(hook, skipChildren, ...args) {
406+
let skip = false
407+
408+
hook(...args, () => skip = true, skipChildren)
409+
410+
return skip
411+
}
412+
389413
let patched = false
390414

391415
export function createElement(html) {

0 commit comments

Comments
 (0)