Skip to content

Commit

Permalink
Merge pull request #302 from sveltejs/css-errors
Browse files Browse the repository at this point in the history
Normalise CSS parse errors
  • Loading branch information
Rich-Harris authored Feb 27, 2017
2 parents 8740cfe + 3f93b1d commit ce1916f
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 17 deletions.
35 changes: 20 additions & 15 deletions src/generators/shared/processCss.js
Original file line number Diff line number Diff line change
@@ -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 );

Expand All @@ -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;
Expand Down
28 changes: 28 additions & 0 deletions src/parse/read/style.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,43 @@
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;

return {
start,
end,
attributes,
children: JSON.parse( JSON.stringify( ast.children ) ),
content: {
start: contentStart,
end: contentEnd,
Expand Down
2 changes: 1 addition & 1 deletion test/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down
56 changes: 55 additions & 1 deletion test/parser/css/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
8 changes: 8 additions & 0 deletions test/parser/error-css/error.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"message": "LeftCurlyBracket is expected",
"loc": {
"line": 2,
"column": 16
},
"pos": 24
}
3 changes: 3 additions & 0 deletions test/parser/error-css/input.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<style>
this is not css
</style>

0 comments on commit ce1916f

Please sign in to comment.