Repository navigation
MD-3032 Fix replaceRange when range components share elements, and cut nested containers by their own ranges - #48
Draft
benney wants to merge 4 commits into
Conversation
… elements
Only the last end tag callback registered on an element runs. When the
containers or markers of two range components overlapped, one component's
callback replaced the other's, so a container's depth never went back to 0
and every later container of that component was skipped by the marker pass
while the replacement pass still counted it. The two passes then disagreed
on which markers belonged to which range.
One handler on every range container and descendant now starts each element,
visits it for each range whose container it is in (in place of a
`${container} *` handler per component), and lets the range handlers share
one end tag callback for it. It is registered with the first range
component, so components ahead of the ranges keep seeing elements before a
range removes them. A component registered between two range components
now sees the later range's cut first, as it does when the wrapper cuts the
page.
🦋 Changeset detectedLatest commit: caf3838 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
A container nested in another container of the same range is now cut by its own range. The outer container's cut goes around it, keeps what holds it, and ignores the markers inside it, which belong to the innermost container. The Cloudflare proxy's nested `.c2` truncation case is back to its original output. Element by element, both passes keep a stack of open containers in place of the depth counter, each element goes to the innermost container's range, and a range records where its nested containers start so its cut keeps them and the elements holding them. A void container has nothing to cut, so the container it is in still cuts it. The wrapper keeps the same stack per range. A nested container that is a direct child of the outer container's cut closes the cut before it and reopens it after, without a second replacement. A marker is the innermost container's, so a marker directly in a nested container no longer sends the page element by element; a marker on a nested container is the next container out's. A nested container deeper in the cut, in raw text or MathML, on a page with a nested start marker, or closed by another element's end tag still goes element by element. The last needs the end tag's name, so `onEndTag` callbacks now receive it as `RewriterEndTag`; native rewriters already pass it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two replaceRange changes, plus whole-page tests for range truncation and component content.
Range components sharing elements (bug, since 1.8.1):
onEndTagcallback registered on an element runs, so one range component's callback replaced another's. The marker pass then lost count of open containers and skipped every later container of that component, while the replacement pass still counted them. Later containers were cut from the wrong markers.${container} *handler. It visits each element for the ranges whose container holds it, and the range handlers share one end tag callback per element.Nested containers cut by their own ranges (replaces "outermost wins" from 1.8.1):
onEndTagcallbacks now receive it asRewriterEndTag. Native rewriters already pass it.Tests:
test/stages/truncation.spec.tscovers range truncation on whole pages, running each case on both the wrapper and the element-by-element path.test/stages/componentContent.spec.tscovers component content transforms (before, after, prepend, append, remove, MOS elements, ignored selectors)..celements unclosed too.Performance (workerd, 1 MB and 5 MB pages):
Patch and minor changesets.