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:
Brad Cornes 2021-06-14 17:36:33 +01:00 committed by GitHub
parent 2d854092a4
commit e0989c696a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 17 additions and 2 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fix scoped CSS selector when class contains a colon

View file

@ -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 theres a pseudoclass (:focus or ::before)
ss = head + newSelector.substring(0, pseudoIndex) + c + newSelector.substr(pseudoIndex) + tail;

View file

@ -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)) {

View file

@ -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();

View file

@ -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">Im 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>