Skip to content

Commit

Permalink
Also avoid double-prefix of root selectors
Browse files Browse the repository at this point in the history
  • Loading branch information
talldan committed Jul 31, 2024
1 parent f7690e3 commit 4cb7592
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 15 deletions.
17 changes: 17 additions & 0 deletions packages/block-editor/src/utils/test/transform-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,23 @@ describe( 'transformStyles', () => {
expect( output ).toEqual( [ input ] );
} );

it( 'should not double prefix a root selector', () => {
const input = 'body .my-namespace h1 { color: goldenrod; }';

const output = transformStyles(
[
{
css: input,
},
],
'.my-namespace'
);

expect( output ).toEqual( [
'.my-namespace h1 { color: goldenrod; }',
] );
} );

it( 'should not try to wrap items within `:where` selectors', () => {
const input = `:where(.wp-element-button:active, .wp-block-button__link:active) { color: blue; }`;
const prefix = '.my-namespace';
Expand Down
35 changes: 20 additions & 15 deletions packages/block-editor/src/utils/transform-styles/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ const cacheByWrapperSelector = new Map();
const ROOT_SELECTOR_REGEX =
/^(:root :where\(body\)|:where\(body\)|:root|html|body)/;

function replaceDoublePrefix( selector, prefix ) {
// Avoid prefixing an already prefixed selector.
const doublePrefix = `${ prefix } ${ prefix }`;
if ( selector.startsWith( doublePrefix ) ) {
return selector.replace( doublePrefix, prefix );
}
return selector;
}

function transformStyle(
{ css, ignoredSelectors = [], baseURL },
wrapperSelector = ''
Expand All @@ -30,29 +39,25 @@ function transformStyle(
prefix: wrapperSelector,
exclude: [ ...ignoredSelectors, wrapperSelector ],
transform( prefix, selector, prefixedSelector ) {
// Avoid prefixing an already prefixed selector.
if (
prefixedSelector.startsWith(
`${ prefix } ${ prefix }`
)
) {
prefixedSelector = prefixedSelector.replace(
`${ prefix } ${ prefix }`,
prefix
);
}

// `html`, `body` and `:root` need some special handling since they
// generally cannot be prefixed with a classname and produce a valid
// generally cannot be prefixed with a class name and produce a valid
// selector. Instead we replace the whole root part of the selector.
if ( ROOT_SELECTOR_REGEX.test( selector ) ) {
return selector.replace(
const updatedRootSelector = selector.replace(
ROOT_SELECTOR_REGEX,
prefix
);

return replaceDoublePrefix(
updatedRootSelector,
prefix
);
}

return prefixedSelector;
return replaceDoublePrefix(
prefixedSelector,
prefix
);
},
} ),
baseURL && rebaseUrl( { rootUrl: baseURL } ),
Expand Down

0 comments on commit 4cb7592

Please sign in to comment.