From a0503c7e8016b38eb130eb121c0978a459dd17b1 Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 22 May 2014 12:20:27 +1000 Subject: [PATCH 1/6] add silent option --- index.js | 3 +++ test/css-parse.js | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/index.js b/index.js index 9c43241..5dcd71b 100644 --- a/index.js +++ b/index.js @@ -69,6 +69,9 @@ module.exports = function(css, options){ */ function error(msg) { + if(options.silent === true){ + return false; + } var err = new Error(msg + ' near line ' + lineno + ':' + column); err.filename = options.source; err.line = lineno; diff --git a/test/css-parse.js b/test/css-parse.js index d166c53..ff63a2b 100644 --- a/test/css-parse.js +++ b/test/css-parse.js @@ -66,4 +66,18 @@ describe('parse(str)', function(){ parse('p { color:; }'); }); }); + + it('should not throw with silent option', function () { + assert.doesNotThrow(function(){ + parse('thing { color: red; } /* b { color: blue; }',{ silent: true }); + }); + + /* Nested comments should be fine */ + assert.doesNotThrow(function(){ + parse('/* /* */'); + }); + }); + + + }); From fe4e83cedcb956ab804d12f158cdb840c8143dae Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 22 May 2014 12:25:21 +1000 Subject: [PATCH 2/6] better ignore rules that fail --- index.js | 12 +- index.js.orig | 555 ++++++++++++++++++++++++++++++++++++++++++++++ test/css-parse.js | 5 - 3 files changed, 563 insertions(+), 9 deletions(-) create mode 100644 index.js.orig diff --git a/index.js b/index.js index 5dcd71b..384ec5c 100644 --- a/index.js +++ b/index.js @@ -119,8 +119,10 @@ module.exports = function(css, options){ whitespace(); comments(rules); while (css.length && css.charAt(0) != '}' && (node = atrule() || rule())) { - rules.push(node); - comments(rules); + if(node !== false){ + rules.push(node); + comments(rules); + } } return rules; } @@ -248,8 +250,10 @@ module.exports = function(css, options){ // declarations var decl; while (decl = declaration()) { - decls.push(decl); - comments(decls); + if(decl !== false){ + decls.push(decl); + comments(decls); + } } if (!close()) return error("missing '}'"); diff --git a/index.js.orig b/index.js.orig new file mode 100644 index 0000000..384ec5c --- /dev/null +++ b/index.js.orig @@ -0,0 +1,555 @@ +// http://www.w3.org/TR/CSS21/grammar.html +// https://github.com/visionmedia/css-parse/pull/49#issuecomment-30088027 +var commentre = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g + +module.exports = function(css, options){ + options = options || {}; + options.position = options.position === false ? false : true; + + /** + * Positional. + */ + + var lineno = 1; + var column = 1; + + /** + * Update lineno and column based on `str`. + */ + + function updatePosition(str) { + var lines = str.match(/\n/g); + if (lines) lineno += lines.length; + var i = str.lastIndexOf('\n'); + column = ~i ? str.length - i : column + str.length; + } + + /** + * Mark position and patch `node.position`. + */ + + function position() { + var start = { line: lineno, column: column }; + if (!options.position) return positionNoop; + + return function(node){ + node.position = new Position(start); + whitespace(); + return node; + }; + } + + /** + * Store position information for a node + */ + + function Position(start) { + this.start = start; + this.end = { line: lineno, column: column }; + this.source = options.source; + } + + /** + * Non-enumerable source string + */ + + Position.prototype.content = css; + + /** + * Return `node`. + */ + + function positionNoop(node) { + whitespace(); + return node; + } + + /** + * Error `msg`. + */ + + function error(msg) { + if(options.silent === true){ + return false; + } + var err = new Error(msg + ' near line ' + lineno + ':' + column); + err.filename = options.source; + err.line = lineno; + err.column = column; + err.source = css; + throw err; + } + + /** + * Parse stylesheet. + */ + + function stylesheet() { + return { + type: 'stylesheet', + stylesheet: { + rules: rules() + } + }; + } + + /** + * Opening brace. + */ + + function open() { + return match(/^{\s*/); + } + + /** + * Closing brace. + */ + + function close() { + return match(/^}/); + } + + /** + * Parse ruleset. + */ + + function rules() { + var node; + var rules = []; + whitespace(); + comments(rules); + while (css.length && css.charAt(0) != '}' && (node = atrule() || rule())) { + if(node !== false){ + rules.push(node); + comments(rules); + } + } + return rules; + } + + /** + * Match `re` and return captures. + */ + + function match(re) { + var m = re.exec(css); + if (!m) return; + var str = m[0]; + updatePosition(str); + css = css.slice(str.length); + return m; + } + + /** + * Parse whitespace. + */ + + function whitespace() { + match(/^\s*/); + } + + /** + * Parse comments; + */ + + function comments(rules) { + var c; + rules = rules || []; + while (c = comment()) rules.push(c); + return rules; + } + + /** + * Parse comment. + */ + + function comment() { + var pos = position(); + if ('/' != css.charAt(0) || '*' != css.charAt(1)) return; + + var i = 2; + while ("" != css.charAt(i) && ('*' != css.charAt(i) || '/' != css.charAt(i + 1))) ++i; + i += 2; + + if ("" === css.charAt(i-1)) { + return error('End of comment missing'); + } + + var str = css.slice(2, i - 2); + column += 2; + updatePosition(str); + css = css.slice(i); + column += 2; + + return pos({ + type: 'comment', + comment: str + }); + } + + /** + * Parse selector. + */ + + function selector() { + var m = match(/^([^{]+)/); + if (!m) return; + /* @fix Remove all comments from selectors + * http://ostermiller.org/findcomment.html */ + return trim(m[0]) + .replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, '') + .replace(/(?:"[^"]*"|'[^']*')/g, function(m) { + return m.replace(/,/g, '\u200C'); + }) + .split(/\s*,\s*/) + .map(function(s) { + return s.replace(/\u200C/g, ','); + }); + } + + /** + * Parse declaration. + */ + + function declaration() { + var pos = position(); + + // prop + var prop = match(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/); + if (!prop) return; + prop = trim(prop[0]); + + // : + if (!match(/^:\s*/)) return error("property missing ':'"); + + // val + var val = match(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/); + + var ret = pos({ + type: 'declaration', + property: prop.replace(commentre, ''), + value: val ? trim(val[0]).replace(commentre, '') : '' + }); + + // ; + match(/^[;\s]*/); + + return ret; + } + + /** + * Parse declarations. + */ + + function declarations() { + var decls = []; + + if (!open()) return error("missing '{'"); + comments(decls); + + // declarations + var decl; + while (decl = declaration()) { + if(decl !== false){ + decls.push(decl); + comments(decls); + } + } + + if (!close()) return error("missing '}'"); + return decls; + } + + /** + * Parse keyframe. + */ + + function keyframe() { + var m; + var vals = []; + var pos = position(); + + while (m = match(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/)) { + vals.push(m[1]); + match(/^,\s*/); + } + + if (!vals.length) return; + + return pos({ + type: 'keyframe', + values: vals, + declarations: declarations() + }); + } + + /** + * Parse keyframes. + */ + + function atkeyframes() { + var pos = position(); + var m = match(/^@([-\w]+)?keyframes */); + + if (!m) return; + var vendor = m[1]; + + // identifier + var m = match(/^([-\w]+)\s*/); + if (!m) return error("@keyframes missing name"); + var name = m[1]; + + if (!open()) return error("@keyframes missing '{'"); + + var frame; + var frames = comments(); + while (frame = keyframe()) { + frames.push(frame); + frames = frames.concat(comments()); + } + + if (!close()) return error("@keyframes missing '}'"); + + return pos({ + type: 'keyframes', + name: name, + vendor: vendor, + keyframes: frames + }); + } + + /** + * Parse supports. + */ + + function atsupports() { + var pos = position(); + var m = match(/^@supports *([^{]+)/); + + if (!m) return; + var supports = trim(m[1]); + + if (!open()) return error("@supports missing '{'"); + + var style = comments().concat(rules()); + + if (!close()) return error("@supports missing '}'"); + + return pos({ + type: 'supports', + supports: supports, + rules: style + }); + } + + /** + * Parse host. + */ + + function athost() { + var pos = position(); + var m = match(/^@host */); + + if (!m) return; + + if (!open()) return error("@host missing '{'"); + + var style = comments().concat(rules()); + + if (!close()) return error("@host missing '}'"); + + return pos({ + type: 'host', + rules: style + }); + } + + /** + * Parse media. + */ + + function atmedia() { + var pos = position(); + var m = match(/^@media *([^{]+)/); + + if (!m) return; + var media = trim(m[1]); + + if (!open()) return error("@media missing '{'"); + + var style = comments().concat(rules()); + + if (!close()) return error("@media missing '}'"); + + return pos({ + type: 'media', + media: media, + rules: style + }); + } + + /** + * Parse paged media. + */ + + function atpage() { + var pos = position(); + var m = match(/^@page */); + if (!m) return; + + var sel = selector() || []; + + if (!open()) return error("@page missing '{'"); + var decls = comments(); + + // declarations + var decl; + while (decl = declaration()) { + decls.push(decl); + decls = decls.concat(comments()); + } + + if (!close()) return error("@page missing '}'"); + + return pos({ + type: 'page', + selectors: sel, + declarations: decls + }); + } + + /** + * Parse document. + */ + + function atdocument() { + var pos = position(); + var m = match(/^@([-\w]+)?document *([^{]+)/); + if (!m) return; + + var vendor = trim(m[1]); + var doc = trim(m[2]); + + if (!open()) return error("@document missing '{'"); + + var style = comments().concat(rules()); + + if (!close()) return error("@document missing '}'"); + + return pos({ + type: 'document', + document: doc, + vendor: vendor, + rules: style + }); + } + + /** + * Parse font-face. + */ + + function atfontface() { + var pos = position(); + var m = match(/^@font-face */); + if (!m) return; + + if (!open()) return error("@font-face missing '{'"); + var decls = comments(); + + // declarations + var decl; + while (decl = declaration()) { + decls.push(decl); + decls = decls.concat(comments()); + } + + if (!close()) return error("@font-face missing '}'"); + + return pos({ + type: 'font-face', + declarations: decls + }); + } + + /** + * Parse import + */ + + var atimport = _compileAtrule('import'); + + /** + * Parse charset + */ + + var atcharset = _compileAtrule('charset'); + + /** + * Parse namespace + */ + + var atnamespace = _compileAtrule('namespace'); + + /** + * Parse non-block at-rules + */ + + + function _compileAtrule(name) { + var re = new RegExp('^@' + name + ' *([^;\\n]+);'); + return function() { + var pos = position(); + var m = match(re); + if (!m) return; + var ret = { type: name }; + ret[name] = m[1].trim(); + return pos(ret); + } + } + + /** + * Parse at rule. + */ + + function atrule() { + if (css[0] != '@') return; + + return atkeyframes() + || atmedia() + || atsupports() + || atimport() + || atcharset() + || atnamespace() + || atdocument() + || atpage() + || athost() + || atfontface(); + } + + /** + * Parse rule. + */ + + function rule() { + var pos = position(); + var sel = selector(); + + if (!sel) return error('selector missing'); + comments(); + + return pos({ + type: 'rule', + selectors: sel, + declarations: declarations() + }); + } + + return stylesheet(); +}; + +/** + * Trim `str`. + */ + +function trim(str) { + return str ? str.replace(/^\s+|\s+$/g, '') : ''; +} diff --git a/test/css-parse.js b/test/css-parse.js index ff63a2b..562886f 100644 --- a/test/css-parse.js +++ b/test/css-parse.js @@ -71,11 +71,6 @@ describe('parse(str)', function(){ assert.doesNotThrow(function(){ parse('thing { color: red; } /* b { color: blue; }',{ silent: true }); }); - - /* Nested comments should be fine */ - assert.doesNotThrow(function(){ - parse('/* /* */'); - }); }); From 3a7cb54d52bdcb53f86fd24690a49a1c528461da Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 22 May 2014 12:27:10 +1000 Subject: [PATCH 3/6] delete tmp file --- index.js.orig | 555 -------------------------------------------------- 1 file changed, 555 deletions(-) delete mode 100644 index.js.orig diff --git a/index.js.orig b/index.js.orig deleted file mode 100644 index 384ec5c..0000000 --- a/index.js.orig +++ /dev/null @@ -1,555 +0,0 @@ -// http://www.w3.org/TR/CSS21/grammar.html -// https://github.com/visionmedia/css-parse/pull/49#issuecomment-30088027 -var commentre = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g - -module.exports = function(css, options){ - options = options || {}; - options.position = options.position === false ? false : true; - - /** - * Positional. - */ - - var lineno = 1; - var column = 1; - - /** - * Update lineno and column based on `str`. - */ - - function updatePosition(str) { - var lines = str.match(/\n/g); - if (lines) lineno += lines.length; - var i = str.lastIndexOf('\n'); - column = ~i ? str.length - i : column + str.length; - } - - /** - * Mark position and patch `node.position`. - */ - - function position() { - var start = { line: lineno, column: column }; - if (!options.position) return positionNoop; - - return function(node){ - node.position = new Position(start); - whitespace(); - return node; - }; - } - - /** - * Store position information for a node - */ - - function Position(start) { - this.start = start; - this.end = { line: lineno, column: column }; - this.source = options.source; - } - - /** - * Non-enumerable source string - */ - - Position.prototype.content = css; - - /** - * Return `node`. - */ - - function positionNoop(node) { - whitespace(); - return node; - } - - /** - * Error `msg`. - */ - - function error(msg) { - if(options.silent === true){ - return false; - } - var err = new Error(msg + ' near line ' + lineno + ':' + column); - err.filename = options.source; - err.line = lineno; - err.column = column; - err.source = css; - throw err; - } - - /** - * Parse stylesheet. - */ - - function stylesheet() { - return { - type: 'stylesheet', - stylesheet: { - rules: rules() - } - }; - } - - /** - * Opening brace. - */ - - function open() { - return match(/^{\s*/); - } - - /** - * Closing brace. - */ - - function close() { - return match(/^}/); - } - - /** - * Parse ruleset. - */ - - function rules() { - var node; - var rules = []; - whitespace(); - comments(rules); - while (css.length && css.charAt(0) != '}' && (node = atrule() || rule())) { - if(node !== false){ - rules.push(node); - comments(rules); - } - } - return rules; - } - - /** - * Match `re` and return captures. - */ - - function match(re) { - var m = re.exec(css); - if (!m) return; - var str = m[0]; - updatePosition(str); - css = css.slice(str.length); - return m; - } - - /** - * Parse whitespace. - */ - - function whitespace() { - match(/^\s*/); - } - - /** - * Parse comments; - */ - - function comments(rules) { - var c; - rules = rules || []; - while (c = comment()) rules.push(c); - return rules; - } - - /** - * Parse comment. - */ - - function comment() { - var pos = position(); - if ('/' != css.charAt(0) || '*' != css.charAt(1)) return; - - var i = 2; - while ("" != css.charAt(i) && ('*' != css.charAt(i) || '/' != css.charAt(i + 1))) ++i; - i += 2; - - if ("" === css.charAt(i-1)) { - return error('End of comment missing'); - } - - var str = css.slice(2, i - 2); - column += 2; - updatePosition(str); - css = css.slice(i); - column += 2; - - return pos({ - type: 'comment', - comment: str - }); - } - - /** - * Parse selector. - */ - - function selector() { - var m = match(/^([^{]+)/); - if (!m) return; - /* @fix Remove all comments from selectors - * http://ostermiller.org/findcomment.html */ - return trim(m[0]) - .replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, '') - .replace(/(?:"[^"]*"|'[^']*')/g, function(m) { - return m.replace(/,/g, '\u200C'); - }) - .split(/\s*,\s*/) - .map(function(s) { - return s.replace(/\u200C/g, ','); - }); - } - - /** - * Parse declaration. - */ - - function declaration() { - var pos = position(); - - // prop - var prop = match(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/); - if (!prop) return; - prop = trim(prop[0]); - - // : - if (!match(/^:\s*/)) return error("property missing ':'"); - - // val - var val = match(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/); - - var ret = pos({ - type: 'declaration', - property: prop.replace(commentre, ''), - value: val ? trim(val[0]).replace(commentre, '') : '' - }); - - // ; - match(/^[;\s]*/); - - return ret; - } - - /** - * Parse declarations. - */ - - function declarations() { - var decls = []; - - if (!open()) return error("missing '{'"); - comments(decls); - - // declarations - var decl; - while (decl = declaration()) { - if(decl !== false){ - decls.push(decl); - comments(decls); - } - } - - if (!close()) return error("missing '}'"); - return decls; - } - - /** - * Parse keyframe. - */ - - function keyframe() { - var m; - var vals = []; - var pos = position(); - - while (m = match(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/)) { - vals.push(m[1]); - match(/^,\s*/); - } - - if (!vals.length) return; - - return pos({ - type: 'keyframe', - values: vals, - declarations: declarations() - }); - } - - /** - * Parse keyframes. - */ - - function atkeyframes() { - var pos = position(); - var m = match(/^@([-\w]+)?keyframes */); - - if (!m) return; - var vendor = m[1]; - - // identifier - var m = match(/^([-\w]+)\s*/); - if (!m) return error("@keyframes missing name"); - var name = m[1]; - - if (!open()) return error("@keyframes missing '{'"); - - var frame; - var frames = comments(); - while (frame = keyframe()) { - frames.push(frame); - frames = frames.concat(comments()); - } - - if (!close()) return error("@keyframes missing '}'"); - - return pos({ - type: 'keyframes', - name: name, - vendor: vendor, - keyframes: frames - }); - } - - /** - * Parse supports. - */ - - function atsupports() { - var pos = position(); - var m = match(/^@supports *([^{]+)/); - - if (!m) return; - var supports = trim(m[1]); - - if (!open()) return error("@supports missing '{'"); - - var style = comments().concat(rules()); - - if (!close()) return error("@supports missing '}'"); - - return pos({ - type: 'supports', - supports: supports, - rules: style - }); - } - - /** - * Parse host. - */ - - function athost() { - var pos = position(); - var m = match(/^@host */); - - if (!m) return; - - if (!open()) return error("@host missing '{'"); - - var style = comments().concat(rules()); - - if (!close()) return error("@host missing '}'"); - - return pos({ - type: 'host', - rules: style - }); - } - - /** - * Parse media. - */ - - function atmedia() { - var pos = position(); - var m = match(/^@media *([^{]+)/); - - if (!m) return; - var media = trim(m[1]); - - if (!open()) return error("@media missing '{'"); - - var style = comments().concat(rules()); - - if (!close()) return error("@media missing '}'"); - - return pos({ - type: 'media', - media: media, - rules: style - }); - } - - /** - * Parse paged media. - */ - - function atpage() { - var pos = position(); - var m = match(/^@page */); - if (!m) return; - - var sel = selector() || []; - - if (!open()) return error("@page missing '{'"); - var decls = comments(); - - // declarations - var decl; - while (decl = declaration()) { - decls.push(decl); - decls = decls.concat(comments()); - } - - if (!close()) return error("@page missing '}'"); - - return pos({ - type: 'page', - selectors: sel, - declarations: decls - }); - } - - /** - * Parse document. - */ - - function atdocument() { - var pos = position(); - var m = match(/^@([-\w]+)?document *([^{]+)/); - if (!m) return; - - var vendor = trim(m[1]); - var doc = trim(m[2]); - - if (!open()) return error("@document missing '{'"); - - var style = comments().concat(rules()); - - if (!close()) return error("@document missing '}'"); - - return pos({ - type: 'document', - document: doc, - vendor: vendor, - rules: style - }); - } - - /** - * Parse font-face. - */ - - function atfontface() { - var pos = position(); - var m = match(/^@font-face */); - if (!m) return; - - if (!open()) return error("@font-face missing '{'"); - var decls = comments(); - - // declarations - var decl; - while (decl = declaration()) { - decls.push(decl); - decls = decls.concat(comments()); - } - - if (!close()) return error("@font-face missing '}'"); - - return pos({ - type: 'font-face', - declarations: decls - }); - } - - /** - * Parse import - */ - - var atimport = _compileAtrule('import'); - - /** - * Parse charset - */ - - var atcharset = _compileAtrule('charset'); - - /** - * Parse namespace - */ - - var atnamespace = _compileAtrule('namespace'); - - /** - * Parse non-block at-rules - */ - - - function _compileAtrule(name) { - var re = new RegExp('^@' + name + ' *([^;\\n]+);'); - return function() { - var pos = position(); - var m = match(re); - if (!m) return; - var ret = { type: name }; - ret[name] = m[1].trim(); - return pos(ret); - } - } - - /** - * Parse at rule. - */ - - function atrule() { - if (css[0] != '@') return; - - return atkeyframes() - || atmedia() - || atsupports() - || atimport() - || atcharset() - || atnamespace() - || atdocument() - || atpage() - || athost() - || atfontface(); - } - - /** - * Parse rule. - */ - - function rule() { - var pos = position(); - var sel = selector(); - - if (!sel) return error('selector missing'); - comments(); - - return pos({ - type: 'rule', - selectors: sel, - declarations: declarations() - }); - } - - return stylesheet(); -}; - -/** - * Trim `str`. - */ - -function trim(str) { - return str ? str.replace(/^\s+|\s+$/g, '') : ''; -} From 8fbb7a09afa842216c6999e35f8829cae1a2a901 Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 22 May 2014 12:36:49 +1000 Subject: [PATCH 4/6] more better ignore errors --- index.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 384ec5c..5b1628b 100644 --- a/index.js +++ b/index.js @@ -155,7 +155,11 @@ module.exports = function(css, options){ function comments(rules) { var c; rules = rules || []; - while (c = comment()) rules.push(c); + while (c = comment()){ + if (c !== false) { + rules.push(c); + } + } return rules; } @@ -253,7 +257,7 @@ module.exports = function(css, options){ if(decl !== false){ decls.push(decl); comments(decls); - } + } } if (!close()) return error("missing '}'"); From 4962d20fb973aeebabbc137024a8cc9dcc04397e Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 22 May 2014 14:48:00 +1000 Subject: [PATCH 5/6] code formatting my opinionated IDE and lack of attention to detail have upset Nicolas Gallagher and that upsets me :). I hope I found them all! --- index.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index 5b1628b..3a65a11 100644 --- a/index.js +++ b/index.js @@ -69,9 +69,10 @@ module.exports = function(css, options){ */ function error(msg) { - if(options.silent === true){ + if (options.silent === true) { return false; } + var err = new Error(msg + ' near line ' + lineno + ':' + column); err.filename = options.source; err.line = lineno; @@ -119,7 +120,7 @@ module.exports = function(css, options){ whitespace(); comments(rules); while (css.length && css.charAt(0) != '}' && (node = atrule() || rule())) { - if(node !== false){ + if (node !== false) { rules.push(node); comments(rules); } @@ -155,7 +156,7 @@ module.exports = function(css, options){ function comments(rules) { var c; rules = rules || []; - while (c = comment()){ + while (c = comment()) { if (c !== false) { rules.push(c); } @@ -254,10 +255,10 @@ module.exports = function(css, options){ // declarations var decl; while (decl = declaration()) { - if(decl !== false){ + if (decl !== false) { decls.push(decl); comments(decls); - } + } } if (!close()) return error("missing '}'"); From 46825cf760209724678d500b88a1d27ba66a1762 Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 22 May 2014 14:48:49 +1000 Subject: [PATCH 6/6] code formatting --- test/css-parse.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/css-parse.js b/test/css-parse.js index 562886f..e77c942 100644 --- a/test/css-parse.js +++ b/test/css-parse.js @@ -73,6 +73,4 @@ describe('parse(str)', function(){ }); }); - - });