Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add twoPass option for additional state retention#72

Merged
1cg merged 3 commits into
bigskysoftware:mainfrom
botandrose:two-pass
Dec 23, 2024
Merged

Add twoPass option for additional state retention#72
1cg merged 3 commits into
bigskysoftware:mainfrom
botandrose:two-pass

Conversation

@botandrose
Copy link
Copy Markdown
Collaborator

Add Two-Pass option for retaining additional element state

Superseeds #61. Read that for more context, but the gist of it is that this is a stop-gap solution for retaining more element state within morphs until moveBefore lands in browsers.

This draft PR is just an initial spike, so there are some missing pieces that I'd like to resolve before considering this ready for merge:

  1. Only works with morphStyle: innerHTML
  2. moveBefore support is still missing
  3. Only tested in a super basic scenario where it successfully maintains checkbox indeterminate state

What else? Any other thoughts about this direction?

Comment thread src/idiomorph.js
}

function createPantry() {
const pantry = document.createElement("div");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add style='display:none' to hide?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also maybe throw an id on it? idiomorph-pantry?

Copy link
Copy Markdown
Collaborator Author

@botandrose botandrose Dec 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add style='display:none' to hide?

IDK, el.hidden = true on the next line seems to be a higher level way to express the same thing as style="display: none", and is just as good in terms of browser support https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/hidden#browser_compatibility

I'm not married to it, though. If you prefer the latter that's fine.

Copy link
Copy Markdown
Collaborator Author

@botandrose botandrose Dec 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also maybe throw an id on it? idiomorph-pantry?

I actually had this at first, but ultimately decided to remove it, thinking that it could get weird with id collision if we have more than one instance of Idiomorph running on a page simultaneously, which seems plausible when used in the context of Turbo or htmx. I'm not imagining it buying us much, either, aside from perhaps someone being able to pick it out more easily in the dev tools html inspector while debugging. What do you think?

Comment thread src/idiomorph.js Outdated
}

function moveToPantry(node, ctx) {
if (!node) return;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than a recursive algo, do a query selector on [id] to grab all elements that have ids?

might be better for perf

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, except is it possible to do bottom-up in that way? Maybe that's where the idSets can come into the picture?

Comment thread src/idiomorph.js Outdated
Array.from(ctx.pantry.children).forEach(element => {
const matchElement = root.findElementById(element.id);
if (matchElement) {
matchElement.before(element);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks reasonable, want to also have a moveBefore() branch

maybe we empty the children out of the old node when it is stuck in the pantry?

Comment thread src/idiomorph.js Outdated
Comment thread src/idiomorph.js
Comment thread src/idiomorph.js Outdated
@botandrose
Copy link
Copy Markdown
Collaborator Author

Okay, got something working with testing moveBefore. Ideally it'd just be a separate browser run in the main CI job, but it was surprisingly difficult to get a browser with the chrome://flags/#atomic-move experiment enabled. You can't enable it at runtime, the browser needs to boot up with that flag already enabled for it work. But there's no command-line flag to do so! The only way I could figure out how to do this was to dig into the on-disk Chrome profile and manually munge in the setting. So its currently a separate npm script: npm run test-move-before, and this is run as a separate job in the GitHub Actions CI.

Anyways, I've just pushed with it failing so that the next commit will correct a trivial error, so that we can see it passing, thus demonstrating that it is indeed testing what we think it is testing.

@botandrose
Copy link
Copy Markdown
Collaborator Author

Just pushed a commit that makes isSoftMatch more strict, in that it no longer considers two elements with differing ids to be a soft match. This was a source of lost or incorrect hidden state during morphs.

@botandrose botandrose changed the title [DRAFT] Add twoPass option for additional state retention Add twoPass option for additional state retention Dec 23, 2024
@botandrose
Copy link
Copy Markdown
Collaborator Author

@1cg Okay, this is ready for review! Notes since the last push:

  1. I've added docs. Not my strongest suit, but they're something.
  2. I added the beforeNodePantried hook, so Turbo can use it for nested handling.
  3. I've added an env var FORCE_TWO_PASS to the test suite to run the entire thing with twoPass enabled to make sure it has the same behavior.
  4. I've added two new runs to the CI matrix to test this with and without moveBefore added.
  5. Turbo's test suite passes without changes when this version of Idiomorph is dropped in, both with twoPass on and off.

So I think we're looking good!

@1cg 1cg merged commit a42245d into bigskysoftware:main Dec 23, 2024
@1cg
Copy link
Copy Markdown
Contributor

1cg commented Dec 23, 2024

💥

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants