Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: remove fragment delimiters and update tests #3845

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

jye-sf
Copy link
Contributor

@jye-sf jye-sf commented Nov 6, 2023

Details

Since the initial implementation of VFragments, we've changed the way we reference elements from the vnode (leading, trailing) and implemented VFragment-specific logic for handling slots and diffing. As a result, I'm not sure we still need the empty text nodes.

This PR explores whether it's possible to remove the text delimiters and keep everything working. Although our integration tests all pass, I'm unfortunately not 100% confident they cover all possible use cases.

Can anyone else think of any use cases we may want to verify this against? If there are, I'd like to add them to our test suite. Otherwise, our current test suite seems to be telling us we're able to remove the text nodes with no regression.

Does this pull request introduce a breaking change?

  • ✅ No, it does not introduce a breaking change.

Does this pull request introduce an observable change?

  • ⚠️ Yes, it does include an observable change.

Extra text nodes from VFragments (used for slots and if-elseif-else) are removed and no longer in the DOM.

GUS work item

@jodarove
Copy link
Contributor

jodarove commented Nov 6, 2023

Since the initial implementation of VFragments, we've changed the way we reference elements from the vnode (leading, trailing) and implemented VFragment-specific logic for handling slots and diffing.

Makes sense. @jye-sf can you point me to those mentioned changes so I can catch up?

@jye-sf
Copy link
Contributor Author

jye-sf commented Nov 6, 2023

@jodarove Here are the main changes I had in mind:
#3405 is the main one I think addresses our diffing concerns.
#3140 dealt with an issue with native slotting

@jye-sf
Copy link
Contributor Author

jye-sf commented Nov 7, 2023

Potential issues to verify against:
#3827
#3843

Copy link
Contributor

@jodarove jodarove left a comment

Choose a reason for hiding this comment

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

first pass. Note: this change greatly depends on how/when we generate things (especially fragments) on the compiler (which tbh, i don't remember well)


// Reorder
elm.beforeItems = [];
elm.afterItems = ['bar'];
Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't matter much, but this is changing the test. Since beforeItems was previously assigned to foo, we don't know for sure if the foo rendered is a new or the one from beforeItems.

@@ -238,7 +238,7 @@ function patchFragment(n1: VFragment, n2: VFragment, parent: ParentNode, rendere
}

// Note: not reusing n1.elm, because during patching, it may be patched with another text node.
n2.elm = n2.leading.elm;
n2.elm = n2.leading?.elm;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a way that the fragment can be empty?

If it could empty, then "leading" might be empty and there might be issues when computing the "anchor" (insert before/after) the fragment in update(Static/Dynamic)Children.

@@ -99,21 +99,34 @@ function st(fragment: Element, key: Key, parts?: VStaticPart[]): VStatic {

// [fr]agment node
function fr(key: Key, children: VNodes, stable: 0 | 1): VFragment {
const leading = t('');
Copy link
Contributor

Choose a reason for hiding this comment

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

iirc, these served as a delimiter to updateDynamicChildren (as they will always match), and all insertions/deletions happen within that boundary. Can you think of a case in which you are (dynamically) updating (to add) the children of a fragment, which is in the middle of the elements of the parent? (ex: [div, FragmentWithChildren, div])

@@ -6,18 +6,14 @@
<x-child-with-for-each>
<ul>
<li>
‍‍
Copy link
Contributor

Choose a reason for hiding this comment

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

iirc, there is a special handling on SSR and hydration logic to handle these. should we remove that?

@jye-sf jye-sf added the work-in-progress Work in progress label Jan 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
work-in-progress Work in progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants