Skip to content

Commit b889909

Browse files
committed
wip
1 parent b6fd7a9 commit b889909

File tree

2 files changed

+65
-5
lines changed

2 files changed

+65
-5
lines changed

packages/morph/src/morph.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,10 @@ function createMorphContext(options = {}) {
9696
// So we're using `shouldSkipChildren()` instead which doesn't have this problem as it allows us to pass in the `skipChildren()`
9797
// function as an earlier parameter and then append it to the `updating` hook signature manually. The signature of `updating`
9898
// hook is now `updating: (el, toEl, childrenOnly, skip, skipChildren)`.
99-
if (shouldSkipChildren(context.updating, () => skipChildren = true, from, to, () => updateChildrenOnly = true)) return
99+
100+
let skipUntil = predicate => context.skipUntilCondition = predicate
101+
102+
if (shouldSkipChildren(context.updating, () => skipChildren = true, skipUntil, from, to, () => updateChildrenOnly = true)) return
100103

101104
// Initialize the server-side HTML element with Alpine...
102105
if (from.nodeType === 1 && window.Alpine) {
@@ -201,6 +204,18 @@ function createMorphContext(options = {}) {
201204
let toKey = context.getKey(currentTo)
202205
let fromKey = context.getKey(currentFrom)
203206

207+
if (context.skipUntilCondition) {
208+
let fromDone = ! currentFrom || context.skipUntilCondition(currentFrom)
209+
let toDone = ! currentTo || context.skipUntilCondition(currentTo)
210+
if (fromDone && toDone) {
211+
context.skipUntilCondition = null
212+
} else {
213+
if (! fromDone) currentFrom = currentFrom && getNextSibling(from, currentFrom)
214+
if (! toDone) currentTo = currentTo && getNextSibling(to, currentTo)
215+
continue
216+
}
217+
}
218+
204219
// Add new elements...
205220
if (! currentFrom) {
206221
if (toKey && fromKeyHoldovers[toKey]) {
@@ -431,11 +446,9 @@ function shouldSkip(hook, ...args) {
431446
// are using this function instead which doesn't have this problem as we can pass the
432447
// `skipChildren` function in as an earlier argument and then append it to the end
433448
// of the hook signature manually.
434-
function shouldSkipChildren(hook, skipChildren, ...args) {
449+
function shouldSkipChildren(hook, skipChildren, skipUntil, ...args) {
435450
let skip = false
436-
437-
hook(...args, () => skip = true, skipChildren)
438-
451+
hook(...args, () => skip = true, skipChildren, skipUntil)
439452
return skip
440453
}
441454

tests/cypress/integration/plugins/morph.spec.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,3 +1014,50 @@ test('morphBetween with conditional blocks',
10141014
get('p input').should(haveValue('p-value'))
10151015
},
10161016
)
1017+
1018+
test('can ignore region between comment markers using skipUntil',
1019+
[html`
1020+
<ul>
1021+
<li>foo</li>
1022+
<!-- [Slot] -->
1023+
<li>bar</li>
1024+
<li>baz</li>
1025+
<!-- [EndSlot] -->
1026+
<!-- bob -->
1027+
</ul>
1028+
`],
1029+
({ get }, reload, window, document) => {
1030+
// Generate "to" html without the items between Slot markers
1031+
let toHtml = html`
1032+
<ul>
1033+
<li>foo</li>
1034+
<!-- [Slot] -->
1035+
<!-- [EndSlot] -->
1036+
<!-- bob -->
1037+
</ul>
1038+
`
1039+
1040+
// The original list should have 3 li's
1041+
get('li').should(haveLength(3))
1042+
get('li:nth-of-type(1)').should(haveText('foo'))
1043+
get('li:nth-of-type(2)').should(haveText('bar'))
1044+
get('li:nth-of-type(3)').should(haveText('baz'))
1045+
1046+
// Run morph with custom updating hook that calls skipUntil
1047+
let isStart = node => node && node.nodeType === 8 && node.textContent.trim() === '[Slot]'
1048+
let isEnd = node => node && node.nodeType === 8 && node.textContent.trim() === '[EndSlot]'
1049+
1050+
get('ul').then(([el]) => window.Alpine.morph(el, toHtml, {
1051+
updating(from, to, childrenOnly, skip, skipChildren, skipUntil) {
1052+
if (isStart(from) && isStart(to)) {
1053+
skipUntil(node => isEnd(node))
1054+
}
1055+
},
1056+
}))
1057+
1058+
// After morph, the list should still contain the items inside the slot
1059+
get('li').should(haveLength(3))
1060+
get('li:nth-of-type(2)').should(haveText('bar'))
1061+
get('li:nth-of-type(3)').should(haveText('baz'))
1062+
},
1063+
)

0 commit comments

Comments
 (0)