Skip to content

Commit

Permalink
morph: fixes attribute removal
Browse files Browse the repository at this point in the history
Before, when syncing attributes, "for ... of" could skip an attribute if a
previous one was removed. Looping backward prevents this.

Change copied from idiomorph.
  • Loading branch information
piranha committed Dec 16, 2023
1 parent 34ee1cf commit 17008d5
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 12 deletions.
5 changes: 3 additions & 2 deletions twinspark.js
Original file line number Diff line number Diff line change
Expand Up @@ -917,8 +917,9 @@
for (var attr of reply.attributes) {
syncattr(target, reply, attr.name);
}
for (var attr of target.attributes) {
syncattr(target, reply, attr.name);
// iterate backwards to avoid skipping over items when a delete occurs
for (let i = target.attributes.length - 1; i >= 0; i--) {
syncattr(target, reply, target.attributes[i].name);
}

// sync inputs
Expand Down
35 changes: 25 additions & 10 deletions www/test/morph/fidelity.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@ describe("Tests to ensure that idiomorph merges properly", function(){
clearWorkArea();
});

function compare(node, end) {
if (node.outerHTML !== end) {
console.log("HTML after morph: " + node.outerHTML);
console.log("Expected: " + end);
}
node.outerHTML.should.equal(end);
}

function testFidelity(start, end, done) {
let initial = make(start);
let final = make(end);
Idiomorph.morph(initial, final);

function compare() {
if (initial.outerHTML !== end) {
console.log("HTML after morph: " + initial.outerHTML);
console.log("Expected: " + end);
}
initial.outerHTML.should.equal(end);
}

if (done) {
setTimeout(() => {
compare();
compare(initial, end);
done();
}, 2);
return;
} else {
compare();
compare(initial, end);
}
}

Expand All @@ -43,6 +43,21 @@ describe("Tests to ensure that idiomorph merges properly", function(){
testFidelity("<button class=\"foo\">Foo</button>", "<button class=\"bar\">Foo</button>")
});

it('morphs multiple attributes correctly twice', function ()
{
const a = `<section class="child">A</section>`;
const b = `<section class="thing" data-one="1" data-two="2" data-three="3" data-four="4" id="foo" fizz="buzz" foo="bar">B</section>`;
const expectedA = make(a);
const expectedB = make(b);
const initial = make(a);

Idiomorph.morph(initial, expectedB);
compare(initial, b);

Idiomorph.morph(initial, expectedA);
compare(initial, a);
});

it('morphs children', function()
{
testFidelity("<div><p>A</p><p>B</p></div>", "<div><p>C</p><p>D</p></div>")
Expand Down

0 comments on commit 17008d5

Please sign in to comment.