mirror of https://github.com/sveltejs/svelte
Merge pull request #294 from sveltejs/css-parser
Use css-tree to generate a proper CSS AST and use it for transformationspull/295/head
commit
47cd1d4df3
@ -1,5 +0,0 @@
|
|||||||
import transform from './transform.js';
|
|
||||||
|
|
||||||
export default function process ( parsed ) {
|
|
||||||
return transform( parsed.css.content.styles, parsed.hash );
|
|
||||||
}
|
|
@ -0,0 +1,51 @@
|
|||||||
|
import parse from 'css-tree/lib/parser/index.js';
|
||||||
|
import walk from 'css-tree/lib/utils/walk.js';
|
||||||
|
|
||||||
|
const commentsPattern = /\/\*[\s\S]*?\*\//g;
|
||||||
|
|
||||||
|
export default function processCss ( parsed, code ) {
|
||||||
|
const css = parsed.css.content.styles;
|
||||||
|
const offset = parsed.css.content.start;
|
||||||
|
|
||||||
|
const ast = parse( css, {
|
||||||
|
positions: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const attr = `[svelte-${parsed.hash}]`;
|
||||||
|
|
||||||
|
walk.rules( ast, rule => {
|
||||||
|
rule.selector.children.each( selector => {
|
||||||
|
const start = selector.loc.start.offset;
|
||||||
|
const end = selector.loc.end.offset;
|
||||||
|
|
||||||
|
const selectorString = css.slice( start, end );
|
||||||
|
|
||||||
|
const firstToken = selector.children.head;
|
||||||
|
|
||||||
|
let transformed;
|
||||||
|
|
||||||
|
if ( firstToken.data.type === 'TypeSelector' ) {
|
||||||
|
const insert = firstToken.data.loc.end.offset;
|
||||||
|
const head = css.slice( start, insert );
|
||||||
|
const tail = css.slice( insert, end );
|
||||||
|
|
||||||
|
transformed = `${head}${attr}${tail}, ${attr} ${selectorString}`;
|
||||||
|
} else {
|
||||||
|
transformed = `${attr}${selectorString}, ${attr} ${selectorString}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
code.overwrite( start + offset, end + offset, transformed );
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// remove comments. TODO would be nice if this was exposed in css-tree
|
||||||
|
let match;
|
||||||
|
while ( match = commentsPattern.exec( css ) ) {
|
||||||
|
const start = match.index + offset;
|
||||||
|
const end = start + match[0].length;
|
||||||
|
|
||||||
|
code.remove( start, end );
|
||||||
|
}
|
||||||
|
|
||||||
|
return code.slice( parsed.css.content.start, parsed.css.content.end );
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
<p class='foo bar'>red on black</p>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.foo {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*=" bar"] {
|
||||||
|
background: black;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,11 @@
|
|||||||
|
export default {
|
||||||
|
test ( assert, component, target, window ) {
|
||||||
|
const [ control, test ] = target.querySelectorAll( 'p' );
|
||||||
|
|
||||||
|
assert.equal( window.getComputedStyle( control ).color, '' );
|
||||||
|
assert.equal( window.getComputedStyle( control ).backgroundColor, '' );
|
||||||
|
|
||||||
|
assert.equal( window.getComputedStyle( test ).color, 'red' );
|
||||||
|
assert.equal( window.getComputedStyle( test ).backgroundColor, 'black' );
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,10 @@
|
|||||||
|
<p class='foo bar'>control</p>
|
||||||
|
<Widget/>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Widget from './Widget.html';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { Widget }
|
||||||
|
};
|
||||||
|
</script>
|
Loading…
Reference in new issue