Skip to content

Commit

Permalink
Bug - morph lookahead and keys (#2544)
Browse files Browse the repository at this point in the history
* Add failing tests

* Set lookahead default value to false and fix bugs

Co-authored-by: Caleb Porzio <calebporzio@gmail.com>
  • Loading branch information
SimoTod and calebporzio committed Jan 21, 2022
1 parent 977c76e commit ef6511e
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 7 deletions.
20 changes: 14 additions & 6 deletions packages/morph/src/morph.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function assignOptions(options = {}) {
adding = options.adding || noop
added = options.added || noop
key = options.key || defaultGetKey
lookahead = options.lookahead || true
lookahead = options.lookahead || false
debug = options.debug || false
}

Expand Down Expand Up @@ -190,7 +190,7 @@ async function patchChildren(from, to) {
if (toKey && domKeyHoldovers[toKey]) {
let holdover = domKeyHoldovers[toKey]

dom.append(from, holdover)
dom(from).append(holdover)
currentFrom = holdover

await breakpoint('Add element (from key)')
Expand All @@ -208,12 +208,20 @@ async function patchChildren(from, to) {
if (lookahead) {
let nextToElementSibling = dom(currentTo).next()

if (nextToElementSibling && currentFrom.isEqualNode(nextToElementSibling)) {
currentFrom = addNodeBefore(currentTo, currentFrom)
let found = false

while (!found && nextToElementSibling) {
if (currentFrom.isEqualNode(nextToElementSibling)) {
found = true

currentFrom = addNodeBefore(currentTo, currentFrom)

domKey = getKey(currentFrom)

domKey = getKey(currentFrom)
await breakpoint('Move element (lookahead)')
}

await breakpoint('Move element (lookahead)')
nextToElementSibling = dom(nextToElementSibling).next()
}
}

Expand Down
115 changes: 114 additions & 1 deletion tests/cypress/integration/plugins/morph.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { haveText, haveHtml, html, test } from '../../utils'
import { haveLength, haveText, haveValue, haveHtml, html, test } from '../../utils'

test('can morph components and preserve Alpine state',
[html`
Expand Down Expand Up @@ -134,6 +134,119 @@ test('can morph teleports',
},
)

test('can morph',
[html`
<ul>
<li>foo<input></li>
</ul>
`],
({ get }, reload, window, document) => {
let toHtml = html`
<ul>
<li>bar<input></li>
<li>foo<input></li>
</ul>
`

get('input').type('foo')

get('ul').then(([el]) => window.Alpine.morph(el, toHtml))

get('li').should(haveLength(2))
get('li:nth-of-type(1)').should(haveText('bar'))
get('li:nth-of-type(2)').should(haveText('foo'))
get('li:nth-of-type(1) input').should(haveValue('foo'))
get('li:nth-of-type(2) input').should(haveValue(''))
},
)

test('can morph using lookahead',
[html`
<ul>
<li>foo<input></li>
</ul>
`],
({ get }, reload, window, document) => {
let toHtml = html`
<ul>
<li>bar<input></li>
<li>baz<input></li>
<li>foo<input></li>
</ul>
`

get('input').type('foo')

get('ul').then(([el]) => window.Alpine.morph(el, toHtml, {lookahead: true}))

get('li').should(haveLength(3))
get('li:nth-of-type(1)').should(haveText('bar'))
get('li:nth-of-type(2)').should(haveText('baz'))
get('li:nth-of-type(3)').should(haveText('foo'))
get('li:nth-of-type(1) input').should(haveValue(''))
get('li:nth-of-type(2) input').should(haveValue(''))
get('li:nth-of-type(3) input').should(haveValue('foo'))
},
)

test('can morph using keys',
[html`
<ul>
<li key="1">foo<input></li>
</ul>
`],
({ get }, reload, window, document) => {
let toHtml = html`
<ul>
<li key="2">bar<input></li>
<li key="3">baz<input></li>
<li key="1">foo<input></li>
</ul>
`

get('input').type('foo')

get('ul').then(([el]) => window.Alpine.morph(el, toHtml))

get('li').should(haveLength(3))
get('li:nth-of-type(1)').should(haveText('bar'))
get('li:nth-of-type(2)').should(haveText('baz'))
get('li:nth-of-type(3)').should(haveText('foo'))
get('li:nth-of-type(1) input').should(haveValue(''))
get('li:nth-of-type(2) input').should(haveValue(''))
get('li:nth-of-type(3) input').should(haveValue('foo'))
},
)

test('can morph using a custom key function',
[html`
<ul>
<li data-key="1">foo<input></li>
</ul>
`],
({ get }, reload, window, document) => {
let toHtml = html`
<ul>
<li data-key="2">bar<input></li>
<li data-key="3">baz<input></li>
<li data-key="1">foo<input></li>
</ul>
`

get('input').type('foo')

get('ul').then(([el]) => window.Alpine.morph(el, toHtml, {key(el) {return el.dataset.key}}))

get('li').should(haveLength(3))
get('li:nth-of-type(1)').should(haveText('bar'))
get('li:nth-of-type(2)').should(haveText('baz'))
get('li:nth-of-type(3)').should(haveText('foo'))
get('li:nth-of-type(1) input').should(haveValue(''))
get('li:nth-of-type(2) input').should(haveValue(''))
get('li:nth-of-type(3) input').should(haveValue('foo'))
},
)

test('can morph text nodes',
[html`<h2>Foo <br> Bar</h2>`],
({ get }, reload, window, document) => {
Expand Down

0 comments on commit ef6511e

Please sign in to comment.