0
0
mirror of https://github.com/sveltejs/svelte.git synced 2024-12-01 17:30:59 +01:00

include CSS AST in svelte.parse output

This commit is contained in:
Rich Harris 2017-02-27 15:30:37 -05:00
parent 8740cfe6f4
commit 27579cd668
4 changed files with 83 additions and 11 deletions

View File

@ -1,4 +1,3 @@
import parse from 'css-tree/lib/parser/index.js';
import walk from 'css-tree/lib/utils/walk.js';
const commentsPattern = /\/\*[\s\S]*?\*\//g;
@ -7,16 +6,12 @@ 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 => {
walk.rules( parsed.css.ast, rule => {
rule.selector.children.each( selector => {
const start = selector.loc.start.offset;
const end = selector.loc.end.offset;
const start = selector.start - offset;
const end = selector.end - offset;
const selectorString = css.slice( start, end );
@ -25,7 +20,7 @@ export default function processCss ( parsed, code ) {
let transformed;
if ( firstToken.data.type === 'TypeSelector' ) {
const insert = firstToken.data.loc.end.offset;
const insert = firstToken.data.end - offset;
const head = css.slice( start, insert );
const tail = css.slice( insert, end );
@ -41,7 +36,7 @@ export default function processCss ( parsed, code ) {
// 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 start = match.index;
const end = start + match[0].length;
code.remove( start, end );

View File

@ -1,8 +1,25 @@
import parse from 'css-tree/lib/parser/index.js';
import walk from 'css-tree/lib/utils/walk.js';
export default function readStyle ( parser, start, attributes ) {
const contentStart = parser.index;
const styles = parser.readUntil( /<\/style>/ );
const contentEnd = parser.index;
const ast = parse( styles, {
positions: true,
offset: contentStart
});
// tidy up AST
walk.all( ast, node => {
if ( node.loc ) {
node.start = node.loc.start.offset;
node.end = node.loc.end.offset;
delete node.loc;
}
});
parser.eat( '</style>', true );
const end = parser.index;
@ -10,6 +27,7 @@ export default function readStyle ( parser, start, attributes ) {
start,
end,
attributes,
ast,
content: {
start: contentStart,
end: contentEnd,

View File

@ -16,7 +16,7 @@ describe( 'parse', () => {
const input = fs.readFileSync( `test/parser/${dir}/input.html`, 'utf-8' ).replace( /\s+$/, '' );
try {
const actual = svelte.parse( input );
const actual = JSON.parse( JSON.stringify( svelte.parse( input ) ) );
const expected = require( `./parser/${dir}/output.json` );
assert.deepEqual( actual.html, expected.html );

View File

@ -29,6 +29,65 @@
"start": 23,
"end": 48,
"styles": "\n\tdiv {\n\t\tcolor: red;\n\t}\n"
},
"ast": {
"type": "StyleSheet",
"start": 23,
"end": 48,
"children": [
{
"type": "Rule",
"start": 25,
"end": 47,
"selector": {
"type": "SelectorList",
"start": 25,
"end": 28,
"children": [
{
"type": "Selector",
"start": 25,
"end": 28,
"children": [
{
"type": "TypeSelector",
"start": 25,
"end": 28,
"name": "div"
}
]
}
]
},
"block": {
"type": "Block",
"start": 29,
"end": 47,
"children": [
{
"type": "Declaration",
"start": 33,
"end": 43,
"important": false,
"property": "color",
"value": {
"type": "Value",
"start": 39,
"end": 43,
"children": [
{
"type": "Identifier",
"start": 40,
"end": 43,
"name": "red"
}
]
}
}
]
}
}
]
}
},
"js": null