-
Notifications
You must be signed in to change notification settings - Fork 5.1k
css: do not add transition entries the declaration already lists #38692
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
Open
robobun
wants to merge
1
commit into
main
Choose a base branch
from
farm/e66ba5e1/css-transition-prefix-dedupe
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟣 Pre-existing (not introduced by this PR, and strictly mitigated by it): when the
-webkit-mask-box-image*entry is inserted here,durations/delays/timing_functionsinflushare not grown to match, soget_transitionscycles and shifts every subsequent entry — safari 15 +transition: mask-border .5s, opacity .1scomes out as-webkit-mask-box-image .5s, mask-border .1s, opacity .5s. TheLogicalPropertyId::Block/Inlinereplace()arms (e.g.inset-block→ two entries) have the same shape. Noting only because the refactored block is where a fix would land and the new tests all use single-entry or equal-duration lists that hide the cycling; not blocking.Extended reasoning...
What the bug is
expand_propertiesreceives only thepropertieslist (flush()calls it asexpand_properties(&mut p.0, arena, context)) and grows it in place viaproperties.insert(index, property_id)when amask-border*entry needs a-webkit-mask-box-image*counterpart. Thedurations,delays, andtiming_functionslists thatflushholds alongside it are never touched, so after the insert the property list is one entry longer than the value lists it is paired with.get_transitionsthen walksproperties.slice()and pairs each entry withdurations.at(durations_idx), bumping the index once per property viacycle_bump(&mut durations_idx, durations.len()). Whenproperties.len() > durations.len(), that cycling shifts every entry after the insertion point onto its neighbor's value and wraps the last entry back to the first slot.Step-by-step repro
Input (targets: safari 15, which needs the
-webkit-mask-box-imageinsert):handle_propertysplits the shorthand intoproperties = [MaskBorder, Opacity],durations = [.5s, .1s](delays/timing similarly length-2).flushcallsexpand_properties.webkit_mask_property_to_insertreturnsWebKitMaskBoxImage(as_writtendoes not contain it), soproperties.insert(0, WebKitMaskBoxImage)runs. Nowproperties = [WebKitMaskBoxImage, MaskBorder, Opacity]— length 3.durationsis still[.5s, .1s]— length 2;flushnever grew it.get_transitionsiterates:WebKitMaskBoxImage→durations[0] = .5s, bump → idx 1MaskBorder→durations[1] = .1s, bump → idx 0 (cycle)Opacity→durations[0] = .5stransition: -webkit-mask-box-image .5s, mask-border .1s, opacity .5s—mask-borderlost its.5sandopacitywas rewritten from.1sto.5s.The prefix-expansion path (
expand_prefixes) is not affected: a multi-bitVendorPrefixstays a singleproperties[]entry andget_transitionsfans it out with onedurations_idxincrement. Only the mask insert (and theLogicalPropertyId::Block/Inlinearms whosereplace()callsinsert_slicefor multi-entry expansions likeInsetBlock→[Top, Bottom]) add real list entries.Why this is pre-existing and why the new tests don't catch it
The removed code did the identical
properties.insert(index, property_id)without growing the value lists; this PR only wraps the condition inwebkit_mask_property_to_insertand adds theas_writtendedup. So this is not a regression — and the PR strictly reduces how often it fires, since the second-pass insert (merged rules,:lang()rules) is now skipped when the entry is already listed. The upstream lightningcss code the file was ported from has the same behavior.The 13 new
prefix_tests all use either a singlemask-borderentry (durations.len() == 1, so cycling is a no-op) or equal durations across every entry (.2s, .2s), both of which are invariant under the shift. A two-entry list with distinct durations, e.g.transition: mask-border .5s, opacity .1sat safari 15, would exercise it.What a fix would look like
The value lists need the entry duplicated at the same index the property was inserted at (so the inserted
-webkit-mask-box-imagereusesmask-border's duration and everything after it stays paired). That means either passing the value lists intoexpand_propertiesand inserting alongside the property, or havingexpand_propertiesreturn the insertion indices forflushto apply to all four lists. The same treatment would cover the multi-entryBlock/Inlinereplace()expansions. Not asking for it here — it's a separate change from the fixed-point fix this PR makes, and it exists upstream too — but flagging it since the PR description's "no entry is removed or reordered, so each entry keeps its own duration" holds forexpand_prefixesbut not for this insert.