Fix scoped CSS selector when class contains a colon (#383)
* fix scoped selector when using escaped colon * update scoped styles test * add changeset * update `scopeRule` test * update `scopeRule` test * update css minifier to account for windows-style line breaks
This commit is contained in:
parent
2d854092a4
commit
e0989c696a
5 changed files with 17 additions and 2 deletions
5
.changeset/twenty-numbers-complain.md
Normal file
5
.changeset/twenty-numbers-complain.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fix scoped CSS selector when class contains a colon
|
|
@ -82,7 +82,7 @@ export function scopeRule(selector: string, className: string) {
|
|||
|
||||
// scope everything else
|
||||
let newSelector = value;
|
||||
const pseudoIndex = newSelector.indexOf(':');
|
||||
const pseudoIndex = newSelector.search(/(?<!\\):/);
|
||||
if (pseudoIndex > 0) {
|
||||
// if there’s a pseudoclass (:focus or ::before)
|
||||
ss = head + newSelector.substring(0, pseudoIndex) + c + newSelector.substr(pseudoIndex) + tail;
|
||||
|
|
|
@ -27,6 +27,8 @@ ScopedStyles('Scopes rules correctly', () => {
|
|||
from: 'from', // ignore keyframe keywords (below)
|
||||
to: 'to',
|
||||
'55%': '55%',
|
||||
'.class\\:class': `.class\\:class.${className}`, // classes can contain special characters if escaped
|
||||
'.class\\:class:focus': `.class\\:class.${className}:focus`,
|
||||
};
|
||||
|
||||
for (const [given, expected] of Object.entries(tests)) {
|
||||
|
|
|
@ -9,7 +9,7 @@ const StylesSSR = suite('Styles SSR');
|
|||
function cssMinify(css) {
|
||||
return css
|
||||
.trim() // remove whitespace
|
||||
.replace(/\n\s*/g, '') // collapse lines
|
||||
.replace(/\r?\n\s*/g, '') // collapse lines
|
||||
.replace(/\s*\{/g, '{') // collapse selectors
|
||||
.replace(/:\s*/g, ':') // collapse attributes
|
||||
.replace(/;}/g, '}'); // collapse block
|
||||
|
@ -121,6 +121,9 @@ StylesSSR('Astro scoped styles', async ({ runtime }) => {
|
|||
|
||||
assert.match(el1.attr('class'), `blue ${scopedClass}`);
|
||||
assert.match(el2.attr('class'), `visible ${scopedClass}`);
|
||||
|
||||
const { contents: css } = await runtime.load('/_astro/src/components/Astro.astro.css');
|
||||
assert.match(cssMinify(css.toString()), `.blue.${scopedClass}{color:powderblue}.color\\:blue.${scopedClass}{color:powderblue}.visible.${scopedClass}{display:block}`);
|
||||
});
|
||||
|
||||
StylesSSR.run();
|
||||
|
|
|
@ -8,6 +8,10 @@ let visible = true;
|
|||
color: powderblue;
|
||||
}
|
||||
|
||||
.color\:blue {
|
||||
color: powderblue;
|
||||
}
|
||||
|
||||
.visible {
|
||||
display: block;
|
||||
}
|
||||
|
@ -16,3 +20,4 @@ let visible = true;
|
|||
<div id="class">I’m just used to get the Scoped class</div>
|
||||
<div id="dynamic-class" class={blue ? 'blue' : 'notblue'}>I change colors</div>
|
||||
{visible && <div id="dynamic-vis" class="visible">I disappear</div>}
|
||||
<div id="colon-class" class="color:blue">I am blue</div>
|
||||
|
|
Loading…
Reference in a new issue