Merge pull request #302 from sveltejs/css-errors

Normalise CSS parse errors
pull/305/head
Rich Harris 8 years ago committed by GitHub
commit ce1916ff95

@ -1,31 +1,24 @@
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;
function transform ( rule ) {
rule.selector.children.forEach( selector => {
const start = selector.start - offset;
const end = selector.end - offset;
const selectorString = css.slice( start, end );
const firstToken = selector.children.head;
const firstToken = selector.children[0];
let transformed;
if ( firstToken.data.type === 'TypeSelector' ) {
const insert = firstToken.data.loc.end.offset;
if ( firstToken.type === 'TypeSelector' ) {
const insert = firstToken.end - offset;
const head = css.slice( start, insert );
const tail = css.slice( insert, end );
@ -36,7 +29,19 @@ export default function processCss ( parsed, code ) {
code.overwrite( start + offset, end + offset, transformed );
});
});
}
function walk ( node ) {
if ( node.type === 'Rule' ) {
transform( node );
} else if ( node.children ) {
node.children.forEach( walk );
} else if ( node.block ) {
walk( node.block );
}
}
parsed.css.children.forEach( walk );
// remove comments. TODO would be nice if this was exposed in css-tree
let match;

@ -1,8 +1,35 @@
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;
let ast;
try {
ast = parse( styles, {
positions: true,
offset: contentStart
});
} catch ( err ) {
if ( err.name === 'CssSyntaxError' ) {
parser.error( err.message, err.offset );
} else {
throw err;
}
}
// 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 +37,7 @@ export default function readStyle ( parser, start, attributes ) {
start,
end,
attributes,
children: JSON.parse( JSON.stringify( ast.children ) ),
content: {
start: contentStart,
end: contentEnd,

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

@ -29,7 +29,61 @@
"start": 23,
"end": 48,
"styles": "\n\tdiv {\n\t\tcolor: red;\n\t}\n"
}
},
"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
}

@ -0,0 +1,8 @@
{
"message": "LeftCurlyBracket is expected",
"loc": {
"line": 2,
"column": 16
},
"pos": 24
}

@ -0,0 +1,3 @@
<style>
this is not css
</style>
Loading…
Cancel
Save