Skip to content

Commit

Permalink
Merge pull request #240 from jeromecornet/remove_and_append
Browse files Browse the repository at this point in the history
Remove target children with duplicate ID before append/prepend
  • Loading branch information
dhh authored Jun 8, 2021
2 parents aae03ad + 9b83894 commit 34ee694
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/core/streams/stream_actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { StreamElement } from "../../elements/stream_element"

export const StreamActions: { [action: string]: (this: StreamElement) => void } = {
append() {
this.removeDuplicateTargetChildren()
this.targetElement?.append(this.templateContent)
},

prepend() {
this.removeDuplicateTargetChildren()
this.targetElement?.prepend(this.templateContent)
},

Expand Down
13 changes: 13 additions & 0 deletions src/elements/stream_element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,20 @@ export class StreamElement extends HTMLElement {
disconnect() {
try { this.remove() } catch {}
}

removeDuplicateTargetChildren() {
this.duplicateChildren.forEach(({targetChild}) => {
targetChild.remove();
})
}

get duplicateChildren() {
return [...this.templateContent?.children].map(templateChild => {
let targetChild = [...this.targetElement!.children].filter(c => c.id === templateChild.id)[0]
return { targetChild , templateChild }
}).filter(({targetChild}) => targetChild);
}

get performAction() {
if (this.action) {
const actionFunction = StreamActions[this.action]
Expand Down
34 changes: 34 additions & 0 deletions src/tests/unit/stream_element_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,23 @@ export class StreamElementTests extends DOMTestCase {
this.assert.isNull(element.parentElement)
}

async "test action=append with children ID already present in target"() {
const element = createStreamElement("append", "hello", createTemplateElement(' <div id="child_1">First</div> tail1 '))
const element2 = createStreamElement("append", "hello", createTemplateElement('<div id="child_1">New First</div> <div id="child_2">Second</div> tail2 '))
this.assert.equal(this.find("#hello")?.textContent, "Hello Turbo")

this.append(element)
await nextAnimationFrame()

this.assert.equal(this.find("#hello")?.textContent, 'Hello Turbo First tail1 ')
this.assert.isNull(element.parentElement)

this.append(element2)
await nextAnimationFrame()

this.assert.equal(this.find("#hello")?.textContent, 'Hello Turbo tail1 New First Second tail2 ')
}

async "test action=prepend"() {
const element = createStreamElement("prepend", "hello", createTemplateElement("Streams "))
this.assert.equal(this.find("#hello")?.textContent, "Hello Turbo")
Expand All @@ -29,6 +46,23 @@ export class StreamElementTests extends DOMTestCase {
this.assert.isNull(element.parentElement)
}

async "test action=prepend with children ID already present in target"() {
const element = createStreamElement("prepend", "hello", createTemplateElement('<div id="child_1">First</div> tail1 '))
const element2 = createStreamElement("prepend", "hello", createTemplateElement('<div id="child_1">New First</div> <div id="child_2">Second</div> tail2 '))
this.assert.equal(this.find("#hello")?.textContent, "Hello Turbo")

this.append(element)
await nextAnimationFrame()

this.assert.equal(this.find("#hello")?.textContent, 'First tail1 Hello Turbo')
this.assert.isNull(element.parentElement)

this.append(element2)
await nextAnimationFrame()

this.assert.equal(this.find("#hello")?.textContent, 'New First Second tail2 tail1 Hello Turbo')
}

async "test action=remove"() {
const element = createStreamElement("remove", "hello")
this.assert.ok(this.find("#hello"))
Expand Down

0 comments on commit 34ee694

Please sign in to comment.