-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
toStyles: don't mutate the tree argument #49806
Conversation
Size Change: -21 B (0%) Total Size: 1.37 MB
ℹ️ View Unchanged
|
duotoneStyles.filter = styles.filter; | ||
delete styles.filter; | ||
} | ||
|
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.
@ajlende This behavior, where the duotone style is always extracted, and then used only conditionally, when the duotone selector exists, I think it was a bug originally introduced in #37727. It means that if there is a filter.duotone
style specified, and no feature selector for it, then the style will be ignored. Instead of being applied to the root selector just like any other style. Not sure if this was ever intended.
The duotone selector was a first ever example of a "feature selector". And the generic feature selector feature was introduced only later. Today, it might be possible to remove the duotone-specific code completely and just use a generic feature selector for it. The only thing that needs to be done is to convert the legacy __experimentalDuotone
option into a featured selectors.filter.duotone
selector.
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.
Should we go ahead and actually do that?
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.
By "that" you mean eliminating the duotoneSelector
variable and integrate it into featureSelectors
? Yes, I could push a commit like this 👍
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.
yes, that's the idea.
Potentially we could add a "shim" within registerBlockType
+ a deprecated function call.
const duotoneStyles = {}; | ||
if ( styles?.filter ) { | ||
duotoneStyles.filter = styles.filter; | ||
delete styles.filter; |
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.
Isn't there another fix where we avoid "delete" (avoid mutations at all)? It feels to me like if we keep it around, it can regress again at anytime with some small unintended changes.
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.
That would be very desirable and I spent some time thinking about how to do it. It wouldn't be a "fix" but rather a major rewrite of the toStyles
function.
Currently it processes feature selectors and the root selector in separate loops. Pseudocode:
for ( featSelector of featureSelectors ) {
declarations = [];
for ( style of styles ) {
if ( styleUsesSelector( style, featSelector ) ) {
declarations.push( style );
delete styles[ style ];
}
}
write( `${ featSelector } { ${ declarations.join() } }`;
}
declarations = [];
for ( style of styles ) {
declarations.push( style );
}
write( `${ rootSelector } { ${ declarations.join() } }`;
The second loop processes only styles that haven't been deleted by the first loop.
Rewritten version would have one loop, assigning each style to the right selector:
declarations = new Map<string, string[]>();
for ( style of styles ) {
selector = findFeatureSelector( style ) || rootSelector;
declarations.get( selector ).push( style );
}
for ( [ selector, decls ] of declarations ) {
write( `${ selector } { ${ decls.join() } }` );
}
No delete
needed.
Consider this PR a first step towards that goal. It's adding many new unit tests, which will be needed to perform the rewrite safely.
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.
I'm happy to land this to fix the issue, considering we have two todo lists to consider:
- Removing the specific way to define selector for duotone
- Potentially refactor the code to avoid the mutation
4110706
to
412e004
Compare
Yes I can commit to that 🙂 |
Alternative to #49623 which doesn't clone the entire
tree
object, but only the style objects that are created bypickStyleKeys
. Consumed styles are removed only when the "node" (returned bygetNodesWithStyles
) has afeatureSelectors
orduotoneSelector
property, and for these nodes thestyles
are always created withpickStyleKeys
.I'm adding also several new unit tests, to cover various cases: feature selectors, block variation styles, duotone filters...