Skip to content

Commit

Permalink
bring back old findidset matching behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelWest22 committed Jan 17, 2025
1 parent dc50ef1 commit a1f27da
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 67 deletions.
16 changes: 15 additions & 1 deletion src/idiomorph.js
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,10 @@ var Idiomorph = (function () {
let softMatch = null;
let nextSibling = node.nextSibling;
let siblingSoftMatchCount = 0;
let discardMatchCount = 0;

// max id matches we are willing to discard in our search
const nodeMatchCount = ctx.idMap.get(node)?.size || 0;

let cursor = startPoint;
while (cursor && cursor != endPoint) {
Expand All @@ -415,6 +419,16 @@ var Idiomorph = (function () {
}
}
}
// check for ids we may be discarding when matching nodes with ids
if (nodeMatchCount) {
discardMatchCount += ctx.idMap.get(cursor)?.size || 0;
if (discardMatchCount > nodeMatchCount) {
// if we are going to discard more ids than the node contains then
// we do not have a good candidate for an id match, so return
break;
}
}

if (nextSibling && isSoftMatch(cursor, nextSibling)) {
// the next new node has a soft match with this node, so
// increment the count of future soft matches
Expand All @@ -428,7 +442,7 @@ var Idiomorph = (function () {
softMatch = undefined;
}
}

cursor = cursor.nextSibling;
}

Expand Down
58 changes: 0 additions & 58 deletions test/mw-temp.js
Original file line number Diff line number Diff line change
@@ -1,64 +1,6 @@
describe("Michael West temp tests", function () {
setup();

it("Show findSoftMatch aborting on two future soft matches", function () {
// when nodes can't be softMatched because they have different types it will scan ahead
// but it aborts the scan ahead if it finds two nodes ahead in both the new and old content
// that softmatch so it can just insert the mis matched node it is on and get to the matching.
assertOps(
"<section><h1></h1><h2></h2><div></div></section>",
"<section><div>Alert</div><h1></h1><h2></h2><div></div></section>",
[
[
"Morphed",
"<section><h1></h1><h2></h2><div></div></section>",
"<section><div>Alert</div><h1></h1><h2></h2><div></div></section>",
],
["Added", "<div>Alert</div>"],
["Morphed", "<h1></h1>", "<h1></h1>"],
["Morphed", "<h2></h2>", "<h2></h2>"],
["Morphed", "<div></div>", "<div></div>"],
],
);
});

it.skip("findIdSetMatch rejects morphing node that would lose more IDs", function () {
// here the findIdSetMatch function when it finds a node with id's it will track how many
// id matches in this node and then as it searches for a matching node it will track
// how many id's in the content it would have to remove before it finds a match
// if it finds more ids are going to match in-between nodes it aborts matching to
// allow better matching with less dom updates.
assertOps(
`<div>` +
`<label>1</label><input id="first">` +
`<label>2</label><input id="second">` +
`<label>3</label><input id="third">` +
`</div>`,

`<div>` +
`<label>3</label><input id="third">` +
`<label>1</label><input id="first">` +
`<label>2</label><input id="second">` +
`</div>`,
[
[
"Morphed",
'<div><label>1</label><input id="first"><label>2</label><input id="second"><label>3</label><input id="third"></div>',
'<div><label>3</label><input id="third"><label>1</label><input id="first"><label>2</label><input id="second"></div>',
],
["Morphed", "<label>1</label>", "<label>3</label>"],
["Morphed", "1", "3"],
["Morphed", '<input id="third">', '<input id="third">'],
["Added", "<label>1</label>"],
["Morphed", '<input id="first">', '<input id="first">'],
["Morphed", "<label>2</label>", "<label>2</label>"],
["Morphed", "2", "2"],
["Morphed", '<input id="second">', '<input id="second">'],
["Removed", "<label>3</label>"],
],
);
});

// five tests that show it is possible with the right activeElement preservation tricks you could preserve focus both ways
it.skip("preserves focus state and outerHTML morphStyle first", function () {
const div = make(`
Expand Down
56 changes: 56 additions & 0 deletions test/ops.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,60 @@ describe("morphing operations", function () {
],
);
});

it("Show findSoftMatch aborting on two future soft matches", function () {
// when nodes can't be softMatched because they have different types it will scan ahead
// but it aborts the scan ahead if it finds two nodes ahead in both the new and old content
// that softmatch so it can just insert the mis matched node it is on and get to the matching.
assertOps(
"<section><h1></h1><h2></h2><div></div></section>",
"<section><div>Alert</div><h1></h1><h2></h2><div></div></section>",
[
[
"Morphed",
"<section><h1></h1><h2></h2><div></div></section>",
"<section><div>Alert</div><h1></h1><h2></h2><div></div></section>",
],
["Added", "<div>Alert</div>"],
["Morphed", "<h1></h1>", "<h1></h1>"],
["Morphed", "<h2></h2>", "<h2></h2>"],
["Morphed", "<div></div>", "<div></div>"],
],
);
});

it("findIdSetMatch rejects morphing node that would lose more IDs", function () {
// here the findIdSetMatch function when it finds a node with id's it will track how many
// id matches in this node and then as it searches for a matching node it will track
// how many id's in the content it would have to remove before it finds a match
// if it finds more ids are going to match in-between nodes it aborts matching to
// allow better matching with less dom updates.
assertOps(
`<div>` +
`<label>1</label><input id="first">` +
`<label>2</label><input id="second">` +
`<label>3</label><input id="third">` +
`</div>`,

`<div>` +
`<label>3</label><input id="third">` +
`<label>1</label><input id="first">` +
`<label>2</label><input id="second">` +
`</div>`,
[
[
"Morphed",
'<div><label>1</label><input id="first"><label>2</label><input id="second"><label>3</label><input id="third"></div>',
'<div><label>3</label><input id="third"><label>1</label><input id="first"><label>2</label><input id="second"></div>',
],
["Morphed", "<label>1</label>", "<label>3</label>"],
["Morphed", '<input id="third">', '<input id="third">'],
["Added", "<label>1</label>"],
["Morphed", '<input id="first">', '<input id="first">'],
["Morphed", "<label>2</label>", "<label>2</label>"],
["Morphed", '<input id="second">', '<input id="second">'],
["Removed", "<label>3</label>"],
],
);
});
});
9 changes: 1 addition & 8 deletions test/preserve-focus.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,6 @@ describe("Preserves focus where possible", function () {
"b",
false,
);
if (hasMoveBefore()) {
assertFocus("focused");
// TODO moveBefore loses selection on Chrome 131.0.6778.264
// expect will be fixed in future release
// assertFocusAndSelection("focused", "b");
} else {
assertNoFocus();
}
assertFocus("focused");
});
});

0 comments on commit a1f27da

Please sign in to comment.