From 03f4900506f838038f8721a933f77bfa477f2c0f Mon Sep 17 00:00:00 2001 From: Jeremy Schomery Date: Wed, 8 Feb 2017 17:17:52 +0330 Subject: [PATCH] updating CSSLint to v1.0.4 --- csslint/{csslint.js => csslint-worker.js} | 6478 ++++++++++++--------- edit.html | 2 +- 2 files changed, 3712 insertions(+), 2768 deletions(-) rename csslint/{csslint.js => csslint-worker.js} (67%) diff --git a/csslint/csslint.js b/csslint/csslint-worker.js similarity index 67% rename from csslint/csslint.js rename to csslint/csslint-worker.js index 0a31bb19..52602c80 100644 --- a/csslint/csslint.js +++ b/csslint/csslint-worker.js @@ -1,6 +1,6 @@ /*! -CSSLint -Copyright (c) 2015 Nicole Sullivan and Nicholas C. Zakas. All rights reserved. +CSSLint v1.0.4 +Copyright (c) 2016 Nicole Sullivan and Nicholas C. Zakas. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal @@ -21,12 +21,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* Build: v0.10.0 07-May-2015 02:11:31 */ var exports = exports || {}; -var CSSLint = (function(){ /*! Parser-Lib -Copyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved. +Copyright (c) 2009-2016 Nicholas C. Zakas. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -45,929 +43,17 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -/* Version v0.2.5dev+PR, Build time: 6-May-2015 08:03:14 */ -var parserlib = {}; -(function(){ +/* Version v1.1.0, Build time: 6-December-2016 10:31:29 */ +var parserlib = (function () { +var require; +require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 0 && this._ltIndex < this._lt.length){ - - i++; - this._token = this._lt[this._ltIndex++]; - info = tokenInfo[this._token.type]; - - //obey channels logic - while((info.channel !== undefined && channel !== info.channel) && - this._ltIndex < this._lt.length){ - this._token = this._lt[this._ltIndex++]; - info = tokenInfo[this._token.type]; - i++; - } - - //here be dragons - if ((info.channel === undefined || channel === info.channel) && - this._ltIndex <= this._lt.length){ - this._ltIndexCache.push(i); - return this._token.type; - } - } - - //call token retriever method - token = this._getToken(); - - //if it should be hidden, don't save a token - if (token.type > -1 && !tokenInfo[token.type].hide){ - - //apply token channel - token.channel = tokenInfo[token.type].channel; - - //save for later - this._token = token; - this._lt.push(token); - - //save space that will be moved (must be done before array is truncated) - this._ltIndexCache.push(this._lt.length - this._ltIndex + i); - - //keep the buffer under 5 items - if (this._lt.length > 5){ - this._lt.shift(); - } - - //also keep the shift buffer under 5 items - if (this._ltIndexCache.length > 5){ - this._ltIndexCache.shift(); - } - - //update lookahead index - this._ltIndex = this._lt.length; - } - - /* - * Skip to the next token if: - * 1. The token type is marked as hidden. - * 2. The token type has a channel specified and it isn't the current channel. - */ - info = tokenInfo[token.type]; - if (info && - (info.hide || - (info.channel !== undefined && channel !== info.channel))){ - return this.get(channel); - } else { - //return just the type - return token.type; - } - }, - - /** - * Looks ahead a certain number of tokens and returns the token type at - * that position. This will throw an error if you lookahead past the - * end of input, past the size of the lookahead buffer, or back past - * the first token in the lookahead buffer. - * @param {int} The index of the token type to retrieve. 0 for the - * current token, 1 for the next, -1 for the previous, etc. - * @return {int} The token type of the token in the given position. - * @method LA - */ - LA: function(index){ - var total = index, - tt; - if (index > 0){ - //TODO: Store 5 somewhere - if (index > 5){ - throw new Error("Too much lookahead."); - } - - //get all those tokens - while(total){ - tt = this.get(); - total--; - } - - //unget all those tokens - while(total < index){ - this.unget(); - total++; - } - } else if (index < 0){ - - if(this._lt[this._ltIndex+index]){ - tt = this._lt[this._ltIndex+index].type; - } else { - throw new Error("Too much lookbehind."); - } - - } else { - tt = this._token.type; - } - - return tt; - - }, - - /** - * Looks ahead a certain number of tokens and returns the token at - * that position. This will throw an error if you lookahead past the - * end of input, past the size of the lookahead buffer, or back past - * the first token in the lookahead buffer. - * @param {int} The index of the token type to retrieve. 0 for the - * current token, 1 for the next, -1 for the previous, etc. - * @return {Object} The token of the token in the given position. - * @method LA - */ - LT: function(index){ - - //lookahead first to prime the token buffer - this.LA(index); - - //now find the token, subtract one because _ltIndex is already at the next index - return this._lt[this._ltIndex+index-1]; - }, - - /** - * Returns the token type for the next token in the stream without - * consuming it. - * @return {int} The token type of the next token in the stream. - * @method peek - */ - peek: function(){ - return this.LA(1); - }, - - /** - * Returns the actual token object for the last consumed token. - * @return {Token} The token object for the last consumed token. - * @method token - */ - token: function(){ - return this._token; - }, - - /** - * Returns the name of the token for the given token type. - * @param {int} tokenType The type of token to get the name of. - * @return {String} The name of the token or "UNKNOWN_TOKEN" for any - * invalid token type. - * @method tokenName - */ - tokenName: function(tokenType){ - if (tokenType < 0 || tokenType > this._tokenData.length){ - return "UNKNOWN_TOKEN"; - } else { - return this._tokenData[tokenType].name; - } - }, - - /** - * Returns the token type value for the given token name. - * @param {String} tokenName The name of the token whose value should be returned. - * @return {int} The token type value for the given token name or -1 - * for an unknown token. - * @method tokenName - */ - tokenType: function(tokenName){ - return this._tokenData[tokenName] || -1; - }, - - /** - * Returns the last consumed token to the token stream. - * @method unget - */ - unget: function(){ - //if (this._ltIndex > -1){ - if (this._ltIndexCache.length){ - this._ltIndex -= this._ltIndexCache.pop();//--; - this._token = this._lt[this._ltIndex - 1]; - } else { - throw new Error("Too much lookahead."); - } - } - -}; - - - - -parserlib.util = { -StringReader: StringReader, -SyntaxError : SyntaxError, -SyntaxUnit : SyntaxUnit, -EventTarget : EventTarget, -TokenStreamBase : TokenStreamBase -}; -})(); - - -/* -Parser-Lib -Copyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ -/* Version v0.2.5dev+PR, Build time: 6-May-2015 08:03:14 */ -(function(){ -var EventTarget = parserlib.util.EventTarget, -TokenStreamBase = parserlib.util.TokenStreamBase, -StringReader = parserlib.util.StringReader, -SyntaxError = parserlib.util.SyntaxError, -SyntaxUnit = parserlib.util.SyntaxUnit; - - -var Colors = { +var Colors = module.exports = { + __proto__ :null, aliceblue :"#f0f8ff", antiquewhite :"#faebd7", aqua :"#00ffff", @@ -1115,7 +201,9 @@ var Colors = { whitesmoke :"#f5f5f5", yellow :"#ffff00", yellowgreen :"#9acd32", - //CSS2 system colors http://www.w3.org/TR/css3-color/#css2-system + //'currentColor' color keyword https://www.w3.org/TR/css3-color/#currentcolor + currentColor :"The value of the 'color' property.", + //CSS2 system colors https://www.w3.org/TR/css3-color/#css2-system activeBorder :"Active window border.", activecaption :"Active window caption.", appworkspace :"Background color of multiple document interface.", @@ -1146,7 +234,16 @@ var Colors = { windowframe :"Window frame.", windowtext :"Text in windows." }; -/*global SyntaxUnit, Parser*/ + +},{}],2:[function(require,module,exports){ +"use strict"; + +module.exports = Combinator; + +var SyntaxUnit = require("../util/SyntaxUnit"); + +var Parser = require("./Parser"); + /** * Represents a selector combinator (whitespace, +, >). * @namespace parserlib.css @@ -1157,7 +254,7 @@ var Colors = { * @param {int} line The line of text on which the unit resides. * @param {int} col The column of text on which the unit resides. */ -function Combinator(text, line, col){ +function Combinator(text, line, col) { SyntaxUnit.call(this, text, line, col, Parser.COMBINATOR_TYPE); @@ -1169,13 +266,13 @@ function Combinator(text, line, col){ this.type = "unknown"; //pretty simple - if (/^\s+$/.test(text)){ + if (/^\s+$/.test(text)) { this.type = "descendant"; - } else if (text == ">"){ + } else if (text === ">") { this.type = "child"; - } else if (text == "+"){ + } else if (text === "+") { this.type = "adjacent-sibling"; - } else if (text == "~"){ + } else if (text === "~") { this.type = "sibling"; } @@ -1185,7 +282,372 @@ Combinator.prototype = new SyntaxUnit(); Combinator.prototype.constructor = Combinator; -/*global SyntaxUnit, Parser*/ +},{"../util/SyntaxUnit":26,"./Parser":6}],3:[function(require,module,exports){ +"use strict"; + +module.exports = Matcher; + +var StringReader = require("../util/StringReader"); +var SyntaxError = require("../util/SyntaxError"); + +/** + * This class implements a combinator library for matcher functions. + * The combinators are described at: + * https://developer.mozilla.org/en-US/docs/Web/CSS/Value_definition_syntax#Component_value_combinators + */ +function Matcher(matchFunc, toString) { + this.match = function(expression) { + // Save/restore marks to ensure that failed matches always restore + // the original location in the expression. + var result; + expression.mark(); + result = matchFunc(expression); + if (result) { + expression.drop(); + } else { + expression.restore(); + } + return result; + }; + this.toString = typeof toString === "function" ? toString : function() { + return toString; + }; +} + +/** Precedence table of combinators. */ +Matcher.prec = { + MOD: 5, + SEQ: 4, + ANDAND: 3, + OROR: 2, + ALT: 1 +}; + +/** Simple recursive-descent grammar to build matchers from strings. */ +Matcher.parse = function(str) { + var reader, eat, expr, oror, andand, seq, mod, term, result; + reader = new StringReader(str); + eat = function(matcher) { + var result = reader.readMatch(matcher); + if (result === null) { + throw new SyntaxError( + "Expected "+matcher, reader.getLine(), reader.getCol()); + } + return result; + }; + expr = function() { + // expr = oror (" | " oror)* + var m = [ oror() ]; + while (reader.readMatch(" | ") !== null) { + m.push(oror()); + } + return m.length === 1 ? m[0] : Matcher.alt.apply(Matcher, m); + }; + oror = function() { + // oror = andand ( " || " andand)* + var m = [ andand() ]; + while (reader.readMatch(" || ") !== null) { + m.push(andand()); + } + return m.length === 1 ? m[0] : Matcher.oror.apply(Matcher, m); + }; + andand = function() { + // andand = seq ( " && " seq)* + var m = [ seq() ]; + while (reader.readMatch(" && ") !== null) { + m.push(seq()); + } + return m.length === 1 ? m[0] : Matcher.andand.apply(Matcher, m); + }; + seq = function() { + // seq = mod ( " " mod)* + var m = [ mod() ]; + while (reader.readMatch(/^ (?![&|\]])/) !== null) { + m.push(mod()); + } + return m.length === 1 ? m[0] : Matcher.seq.apply(Matcher, m); + }; + mod = function() { + // mod = term ( "?" | "*" | "+" | "#" | "{,}" )? + var m = term(); + if (reader.readMatch("?") !== null) { + return m.question(); + } else if (reader.readMatch("*") !== null) { + return m.star(); + } else if (reader.readMatch("+") !== null) { + return m.plus(); + } else if (reader.readMatch("#") !== null) { + return m.hash(); + } else if (reader.readMatch(/^\{\s*/) !== null) { + var min = eat(/^\d+/); + eat(/^\s*,\s*/); + var max = eat(/^\d+/); + eat(/^\s*\}/); + return m.braces(+min, +max); + } + return m; + }; + term = function() { + // term = | literal | "[ " expression " ]" + if (reader.readMatch("[ ") !== null) { + var m = expr(); + eat(" ]"); + return m; + } + return Matcher.fromType(eat(/^[^ ?*+#{]+/)); + }; + result = expr(); + if (!reader.eof()) { + throw new SyntaxError( + "Expected end of string", reader.getLine(), reader.getCol()); + } + return result; +}; + +/** + * Convert a string to a matcher (parsing simple alternations), + * or do nothing if the argument is already a matcher. + */ +Matcher.cast = function(m) { + if (m instanceof Matcher) { + return m; + } + return Matcher.parse(m); +}; + +/** + * Create a matcher for a single type. + */ +Matcher.fromType = function(type) { + // Late require of ValidationTypes to break a dependency cycle. + var ValidationTypes = require("./ValidationTypes"); + return new Matcher(function(expression) { + return expression.hasNext() && ValidationTypes.isType(expression, type); + }, type); +}; + +/** + * Create a matcher for one or more juxtaposed words, which all must + * occur, in the given order. + */ +Matcher.seq = function() { + var ms = Array.prototype.slice.call(arguments).map(Matcher.cast); + if (ms.length === 1) { + return ms[0]; + } + return new Matcher(function(expression) { + var i, result = true; + for (i = 0; result && i < ms.length; i++) { + result = ms[i].match(expression); + } + return result; + }, function(prec) { + var p = Matcher.prec.SEQ; + var s = ms.map(function(m) { + return m.toString(p); + }).join(" "); + if (prec > p) { + s = "[ " + s + " ]"; + } + return s; + }); +}; + +/** + * Create a matcher for one or more alternatives, where exactly one + * must occur. + */ +Matcher.alt = function() { + var ms = Array.prototype.slice.call(arguments).map(Matcher.cast); + if (ms.length === 1) { + return ms[0]; + } + return new Matcher(function(expression) { + var i, result = false; + for (i = 0; !result && i < ms.length; i++) { + result = ms[i].match(expression); + } + return result; + }, function(prec) { + var p = Matcher.prec.ALT; + var s = ms.map(function(m) { + return m.toString(p); + }).join(" | "); + if (prec > p) { + s = "[ " + s + " ]"; + } + return s; + }); +}; + +/** + * Create a matcher for two or more options. This implements the + * double bar (||) and double ampersand (&&) operators, as well as + * variants of && where some of the alternatives are optional. + * This will backtrack through even successful matches to try to + * maximize the number of items matched. + */ +Matcher.many = function(required) { + var ms = Array.prototype.slice.call(arguments, 1).reduce(function(acc, v) { + if (v.expand) { + // Insert all of the options for the given complex rule as + // individual options. + var ValidationTypes = require("./ValidationTypes"); + acc.push.apply(acc, ValidationTypes.complex[v.expand].options); + } else { + acc.push(Matcher.cast(v)); + } + return acc; + }, []); + + if (required === true) { + required = ms.map(function() { + return true; + }); + } + + var result = new Matcher(function(expression) { + var seen = [], max = 0, pass = 0; + var success = function(matchCount) { + if (pass === 0) { + max = Math.max(matchCount, max); + return matchCount === ms.length; + } else { + return matchCount === max; + } + }; + var tryMatch = function(matchCount) { + for (var i = 0; i < ms.length; i++) { + if (seen[i]) { + continue; + } + expression.mark(); + if (ms[i].match(expression)) { + seen[i] = true; + // Increase matchCount iff this was a required element + // (or if all the elements are optional) + if (tryMatch(matchCount + ((required === false || required[i]) ? 1 : 0))) { + expression.drop(); + return true; + } + // Backtrack: try *not* matching using this rule, and + // let's see if it leads to a better overall match. + expression.restore(); + seen[i] = false; + } else { + expression.drop(); + } + } + return success(matchCount); + }; + if (!tryMatch(0)) { + // Couldn't get a complete match, retrace our steps to make the + // match with the maximum # of required elements. + pass++; + tryMatch(0); + } + + if (required === false) { + return max > 0; + } + // Use finer-grained specification of which matchers are required. + for (var i = 0; i < ms.length; i++) { + if (required[i] && !seen[i]) { + return false; + } + } + return true; + }, function(prec) { + var p = required === false ? Matcher.prec.OROR : Matcher.prec.ANDAND; + var s = ms.map(function(m, i) { + if (required !== false && !required[i]) { + return m.toString(Matcher.prec.MOD) + "?"; + } + return m.toString(p); + }).join(required === false ? " || " : " && "); + if (prec > p) { + s = "[ " + s + " ]"; + } + return s; + }); + result.options = ms; + return result; +}; + +/** + * Create a matcher for two or more options, where all options are + * mandatory but they may appear in any order. + */ +Matcher.andand = function() { + var args = Array.prototype.slice.call(arguments); + args.unshift(true); + return Matcher.many.apply(Matcher, args); +}; + +/** + * Create a matcher for two or more options, where options are + * optional and may appear in any order, but at least one must be + * present. + */ +Matcher.oror = function() { + var args = Array.prototype.slice.call(arguments); + args.unshift(false); + return Matcher.many.apply(Matcher, args); +}; + +/** Instance methods on Matchers. */ +Matcher.prototype = { + constructor: Matcher, + // These are expected to be overridden in every instance. + match: function() { throw new Error("unimplemented"); }, + toString: function() { throw new Error("unimplemented"); }, + // This returns a standalone function to do the matching. + func: function() { return this.match.bind(this); }, + // Basic combinators + then: function(m) { return Matcher.seq(this, m); }, + or: function(m) { return Matcher.alt(this, m); }, + andand: function(m) { return Matcher.many(true, this, m); }, + oror: function(m) { return Matcher.many(false, this, m); }, + // Component value multipliers + star: function() { return this.braces(0, Infinity, "*"); }, + plus: function() { return this.braces(1, Infinity, "+"); }, + question: function() { return this.braces(0, 1, "?"); }, + hash: function() { + return this.braces(1, Infinity, "#", Matcher.cast(",")); + }, + braces: function(min, max, marker, optSep) { + var m1 = this, m2 = optSep ? optSep.then(this) : this; + if (!marker) { + marker = "{" + min + "," + max + "}"; + } + return new Matcher(function(expression) { + var result = true, i; + for (i = 0; i < max; i++) { + if (i > 0 && optSep) { + result = m2.match(expression); + } else { + result = m1.match(expression); + } + if (!result) { + break; + } + } + return i >= min; + }, function() { + return m1.toString(Matcher.prec.MOD) + marker; + }); + } +}; + +},{"../util/StringReader":24,"../util/SyntaxError":25,"./ValidationTypes":21}],4:[function(require,module,exports){ +"use strict"; + +module.exports = MediaFeature; + +var SyntaxUnit = require("../util/SyntaxUnit"); + +var Parser = require("./Parser"); + /** * Represents a media feature, such as max-width:500. * @namespace parserlib.css @@ -1195,7 +657,7 @@ Combinator.prototype.constructor = Combinator; * @param {SyntaxUnit} name The name of the feature. * @param {SyntaxUnit} value The value of the feature or null if none. */ -function MediaFeature(name, value){ +function MediaFeature(name, value) { SyntaxUnit.call(this, "(" + name + (value !== null ? ":" + value : "") + ")", name.startLine, name.startCol, Parser.MEDIA_FEATURE_TYPE); @@ -1218,7 +680,15 @@ MediaFeature.prototype = new SyntaxUnit(); MediaFeature.prototype.constructor = MediaFeature; -/*global SyntaxUnit, Parser*/ +},{"../util/SyntaxUnit":26,"./Parser":6}],5:[function(require,module,exports){ +"use strict"; + +module.exports = MediaQuery; + +var SyntaxUnit = require("../util/SyntaxUnit"); + +var Parser = require("./Parser"); + /** * Represents an individual media query. * @namespace parserlib.css @@ -1231,7 +701,7 @@ MediaFeature.prototype.constructor = MediaFeature; * @param {int} line The line of text on which the unit resides. * @param {int} col The column of text on which the unit resides. */ -function MediaQuery(modifier, mediaType, features, line, col){ +function MediaQuery(modifier, mediaType, features, line, col) { SyntaxUnit.call(this, (modifier ? modifier + " ": "") + (mediaType ? mediaType : "") + (mediaType && features.length > 0 ? " and " : "") + features.join(" and "), line, col, Parser.MEDIA_QUERY_TYPE); @@ -1262,9 +732,27 @@ MediaQuery.prototype = new SyntaxUnit(); MediaQuery.prototype.constructor = MediaQuery; -/*global Tokens, TokenStream, SyntaxError, Properties, Validation, ValidationError, SyntaxUnit, - PropertyValue, PropertyValuePart, SelectorPart, SelectorSubPart, Selector, - PropertyName, Combinator, MediaFeature, MediaQuery, EventTarget */ +},{"../util/SyntaxUnit":26,"./Parser":6}],6:[function(require,module,exports){ +"use strict"; + +module.exports = Parser; + +var EventTarget = require("../util/EventTarget"); +var SyntaxError = require("../util/SyntaxError"); +var SyntaxUnit = require("../util/SyntaxUnit"); + +var Combinator = require("./Combinator"); +var MediaFeature = require("./MediaFeature"); +var MediaQuery = require("./MediaQuery"); +var PropertyName = require("./PropertyName"); +var PropertyValue = require("./PropertyValue"); +var PropertyValuePart = require("./PropertyValuePart"); +var Selector = require("./Selector"); +var SelectorPart = require("./SelectorPart"); +var SelectorSubPart = require("./SelectorSubPart"); +var TokenStream = require("./TokenStream"); +var Tokens = require("./Tokens"); +var Validation = require("./Validation"); /** * A CSS3 parser. @@ -1278,7 +766,7 @@ MediaQuery.prototype.constructor = MediaQuery; * to indicate that IE < 8 filters should be accepted and not throw * syntax errors. */ -function Parser(options){ +function Parser(options) { //inherit event functionality EventTarget.call(this); @@ -1301,11 +789,12 @@ Parser.SELECTOR_TYPE = 7; Parser.SELECTOR_PART_TYPE = 8; Parser.SELECTOR_SUB_PART_TYPE = 9; -Parser.prototype = function(){ +Parser.prototype = function() { var proto = new EventTarget(), //new prototype prop, additions = { + __proto__: null, //restore constructor constructor: Parser, @@ -1326,19 +815,18 @@ Parser.prototype = function(){ // Grammar //----------------------------------------------------------------- - _stylesheet: function(){ + _stylesheet: function() { /* * stylesheet * : [ CHARSET_SYM S* STRING S* ';' ]? * [S|CDO|CDC]* [ import [S|CDO|CDC]* ]* * [ namespace [S|CDO|CDC]* ]* - * [ [ ruleset | media | page | font_face | keyframes ] [S|CDO|CDC]* ]* + * [ [ ruleset | media | page | font_face | keyframes_rule | supports_rule ] [S|CDO|CDC]* ]* * ; */ var tokenStream = this._tokenStream, - charset = null, count, token, tt; @@ -1351,13 +839,13 @@ Parser.prototype = function(){ this._skipCruft(); //try to read imports - may be more than one - while (tokenStream.peek() == Tokens.IMPORT_SYM){ + while (tokenStream.peek() === Tokens.IMPORT_SYM) { this._import(); this._skipCruft(); } //try to read namespaces - may be more than one - while (tokenStream.peek() == Tokens.NAMESPACE_SYM){ + while (tokenStream.peek() === Tokens.NAMESPACE_SYM) { this._namespace(); this._skipCruft(); } @@ -1366,11 +854,11 @@ Parser.prototype = function(){ tt = tokenStream.peek(); //try to read the rest - while(tt > Tokens.EOF){ + while (tt > Tokens.EOF) { try { - switch(tt){ + switch (tt) { case Tokens.MEDIA_SYM: this._media(); this._skipCruft(); @@ -1395,9 +883,13 @@ Parser.prototype = function(){ this._document(); this._skipCruft(); break; + case Tokens.SUPPORTS_SYM: + this._supports(); + this._skipCruft(); + break; case Tokens.UNKNOWN_SYM: //unknown @ rule tokenStream.get(); - if (!this.options.strict){ + if (!this.options.strict) { //fire error event this.fire({ @@ -1410,11 +902,11 @@ Parser.prototype = function(){ //skip braces count=0; - while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) == Tokens.LBRACE){ + while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) === Tokens.LBRACE) { count++; //keep track of nesting depth } - while(count){ + while (count) { tokenStream.advance([Tokens.RBRACE]); count--; } @@ -1428,10 +920,10 @@ Parser.prototype = function(){ this._readWhitespace(); break; default: - if(!this._ruleset()){ + if (!this._ruleset()) { //error handling for known issues - switch(tt){ + switch (tt) { case Tokens.CHARSET_SYM: token = tokenStream.LT(1); this._charset(false); @@ -1451,8 +943,8 @@ Parser.prototype = function(){ } } - } catch(ex) { - if (ex instanceof SyntaxError && !this.options.strict){ + } catch (ex) { + if (ex instanceof SyntaxError && !this.options.strict) { this.fire({ type: "error", error: ex, @@ -1468,21 +960,21 @@ Parser.prototype = function(){ tt = tokenStream.peek(); } - if (tt != Tokens.EOF){ + if (tt !== Tokens.EOF) { this._unexpectedToken(tokenStream.token()); } this.fire("endstylesheet"); }, - _charset: function(emit){ + _charset: function(emit) { var tokenStream = this._tokenStream, charset, token, line, col; - if (tokenStream.match(Tokens.CHARSET_SYM)){ + if (tokenStream.match(Tokens.CHARSET_SYM)) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; @@ -1495,7 +987,7 @@ Parser.prototype = function(){ this._readWhitespace(); tokenStream.mustMatch(Tokens.SEMICOLON); - if (emit !== false){ + if (emit !== false) { this.fire({ type: "charset", charset:charset, @@ -1506,7 +998,7 @@ Parser.prototype = function(){ } }, - _import: function(emit){ + _import: function(emit) { /* * import * : IMPORT_SYM S* @@ -1514,7 +1006,6 @@ Parser.prototype = function(){ */ var tokenStream = this._tokenStream, - tt, uri, importToken, mediaList = []; @@ -1537,7 +1028,7 @@ Parser.prototype = function(){ tokenStream.mustMatch(Tokens.SEMICOLON); this._readWhitespace(); - if (emit !== false){ + if (emit !== false) { this.fire({ type: "import", uri: uri, @@ -1549,7 +1040,7 @@ Parser.prototype = function(){ }, - _namespace: function(emit){ + _namespace: function(emit) { /* * namespace * : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S* @@ -1568,7 +1059,7 @@ Parser.prototype = function(){ this._readWhitespace(); //it's a namespace prefix - no _namespace_prefix() method because it's just an IDENT - if (tokenStream.match(Tokens.IDENT)){ + if (tokenStream.match(Tokens.IDENT)) { prefix = tokenStream.token().value; this._readWhitespace(); } @@ -1587,7 +1078,7 @@ Parser.prototype = function(){ tokenStream.mustMatch(Tokens.SEMICOLON); this._readWhitespace(); - if (emit !== false){ + if (emit !== false) { this.fire({ type: "namespace", prefix: prefix, @@ -1599,7 +1090,138 @@ Parser.prototype = function(){ }, - _media: function(){ + _supports: function(emit) { + /* + * supports_rule + * : SUPPORTS_SYM S* supports_condition S* group_rule_body + * ; + */ + var tokenStream = this._tokenStream, + line, + col; + + if (tokenStream.match(Tokens.SUPPORTS_SYM)) { + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + + this._readWhitespace(); + this._supports_condition(); + this._readWhitespace(); + + tokenStream.mustMatch(Tokens.LBRACE); + this._readWhitespace(); + + if (emit !== false) { + this.fire({ + type: "startsupports", + line: line, + col: col + }); + } + + while (true) { + if (!this._ruleset()) { + break; + } + } + + tokenStream.mustMatch(Tokens.RBRACE); + this._readWhitespace(); + + this.fire({ + type: "endsupports", + line: line, + col: col + }); + } + }, + + _supports_condition: function() { + /* + * supports_condition + * : supports_negation | supports_conjunction | supports_disjunction | + * supports_condition_in_parens + * ; + */ + var tokenStream = this._tokenStream, + ident; + + if (tokenStream.match(Tokens.IDENT)) { + ident = tokenStream.token().value.toLowerCase(); + + if (ident === "not") { + tokenStream.mustMatch(Tokens.S); + this._supports_condition_in_parens(); + } else { + tokenStream.unget(); + } + } else { + this._supports_condition_in_parens(); + this._readWhitespace(); + + while (tokenStream.peek() === Tokens.IDENT) { + ident = tokenStream.LT(1).value.toLowerCase(); + if (ident === "and" || ident === "or") { + tokenStream.mustMatch(Tokens.IDENT); + this._readWhitespace(); + this._supports_condition_in_parens(); + this._readWhitespace(); + } + } + } + }, + + _supports_condition_in_parens: function() { + /* + * supports_condition_in_parens + * : ( '(' S* supports_condition S* ')' ) | supports_declaration_condition | + * general_enclosed + * ; + */ + var tokenStream = this._tokenStream, + ident; + + if (tokenStream.match(Tokens.LPAREN)) { + this._readWhitespace(); + if (tokenStream.match(Tokens.IDENT)) { + // look ahead for not keyword, if not given, continue with declaration condition. + ident = tokenStream.token().value.toLowerCase(); + if (ident === "not") { + this._readWhitespace(); + this._supports_condition(); + this._readWhitespace(); + tokenStream.mustMatch(Tokens.RPAREN); + } else { + tokenStream.unget(); + this._supports_declaration_condition(false); + } + } else { + this._supports_condition(); + this._readWhitespace(); + tokenStream.mustMatch(Tokens.RPAREN); + } + } else { + this._supports_declaration_condition(); + } + }, + + _supports_declaration_condition: function(requireStartParen) { + /* + * supports_declaration_condition + * : '(' S* declaration ')' + * ; + */ + var tokenStream = this._tokenStream; + + if (requireStartParen !== false) { + tokenStream.mustMatch(Tokens.LPAREN); + } + this._readWhitespace(); + this._declaration(); + tokenStream.mustMatch(Tokens.RPAREN); + }, + + _media: function() { /* * media * : MEDIA_SYM S* media_query_list S* '{' S* ruleset* '}' S* @@ -1629,16 +1251,20 @@ Parser.prototype = function(){ col: col }); - while(true) { - if (tokenStream.peek() == Tokens.PAGE_SYM){ + while (true) { + if (tokenStream.peek() === Tokens.PAGE_SYM) { this._page(); - } else if (tokenStream.peek() == Tokens.FONT_FACE_SYM){ + } else if (tokenStream.peek() === Tokens.FONT_FACE_SYM) { this._font_face(); - } else if (tokenStream.peek() == Tokens.VIEWPORT_SYM){ + } else if (tokenStream.peek() === Tokens.VIEWPORT_SYM) { this._viewport(); - } else if (tokenStream.peek() == Tokens.DOCUMENT_SYM){ + } else if (tokenStream.peek() === Tokens.DOCUMENT_SYM) { this._document(); - } else if (!this._ruleset()){ + } else if (tokenStream.peek() === Tokens.SUPPORTS_SYM) { + this._supports(); + } else if (tokenStream.peek() === Tokens.MEDIA_SYM) { + this._media(); + } else if (!this._ruleset()) { break; } } @@ -1656,7 +1282,7 @@ Parser.prototype = function(){ //CSS3 Media Queries - _media_query_list: function(){ + _media_query_list: function() { /* * media_query_list * : S* [media_query [ ',' S* media_query ]* ]? @@ -1668,11 +1294,11 @@ Parser.prototype = function(){ this._readWhitespace(); - if (tokenStream.peek() == Tokens.IDENT || tokenStream.peek() == Tokens.LPAREN){ + if (tokenStream.peek() === Tokens.IDENT || tokenStream.peek() === Tokens.LPAREN) { mediaList.push(this._media_query()); } - while(tokenStream.match(Tokens.COMMA)){ + while (tokenStream.match(Tokens.COMMA)) { this._readWhitespace(); mediaList.push(this._media_query()); } @@ -1685,7 +1311,7 @@ Parser.prototype = function(){ * method. */ - _media_query: function(){ + _media_query: function() { /* * media_query * : [ONLY | NOT]? S* media_type S* [ AND S* expression ]* @@ -1698,11 +1324,11 @@ Parser.prototype = function(){ token = null, expressions = []; - if (tokenStream.match(Tokens.IDENT)){ + if (tokenStream.match(Tokens.IDENT)) { ident = tokenStream.token().value.toLowerCase(); //since there's no custom tokens for these, need to manually check - if (ident != "only" && ident != "not"){ + if (ident !== "only" && ident !== "not") { tokenStream.unget(); ident = null; } else { @@ -1712,24 +1338,24 @@ Parser.prototype = function(){ this._readWhitespace(); - if (tokenStream.peek() == Tokens.IDENT){ + if (tokenStream.peek() === Tokens.IDENT) { type = this._media_type(); - if (token === null){ + if (token === null) { token = tokenStream.token(); } - } else if (tokenStream.peek() == Tokens.LPAREN){ - if (token === null){ + } else if (tokenStream.peek() === Tokens.LPAREN) { + if (token === null) { token = tokenStream.LT(1); } expressions.push(this._media_expression()); } - if (type === null && expressions.length === 0){ + if (type === null && expressions.length === 0) { return null; } else { this._readWhitespace(); - while (tokenStream.match(Tokens.IDENT)){ - if (tokenStream.token().value.toLowerCase() != "and"){ + while (tokenStream.match(Tokens.IDENT)) { + if (tokenStream.token().value.toLowerCase() !== "and") { this._unexpectedToken(tokenStream.token()); } @@ -1742,7 +1368,7 @@ Parser.prototype = function(){ }, //CSS3 Media Queries - _media_type: function(){ + _media_type: function() { /* * media_type * : IDENT @@ -1759,7 +1385,7 @@ Parser.prototype = function(){ * @method _media_expression * @private */ - _media_expression: function(){ + _media_expression: function() { /* * expression * : '(' S* media_feature S* [ ':' S* expr ]? ')' S* @@ -1775,7 +1401,7 @@ Parser.prototype = function(){ feature = this._media_feature(); this._readWhitespace(); - if (tokenStream.match(Tokens.COLON)){ + if (tokenStream.match(Tokens.COLON)) { this._readWhitespace(); token = tokenStream.LT(1); expression = this._expression(); @@ -1784,11 +1410,11 @@ Parser.prototype = function(){ tokenStream.mustMatch(Tokens.RPAREN); this._readWhitespace(); - return new MediaFeature(feature, (expression ? new SyntaxUnit(expression, token.startLine, token.startCol) : null)); + return new MediaFeature(feature, expression ? new SyntaxUnit(expression, token.startLine, token.startCol) : null); }, //CSS3 Media Queries - _media_feature: function(){ + _media_feature: function() { /* * media_feature * : IDENT @@ -1804,7 +1430,7 @@ Parser.prototype = function(){ }, //CSS3 Paged Media - _page: function(){ + _page: function() { /* * page: * PAGE_SYM S* IDENT? pseudo_page? S* @@ -1824,17 +1450,17 @@ Parser.prototype = function(){ this._readWhitespace(); - if (tokenStream.match(Tokens.IDENT)){ + if (tokenStream.match(Tokens.IDENT)) { identifier = tokenStream.token().value; //The value 'auto' may not be used as a page name and MUST be treated as a syntax error. - if (identifier.toLowerCase() === "auto"){ + if (identifier.toLowerCase() === "auto") { this._unexpectedToken(tokenStream.token()); } } //see if there's a colon upcoming - if (tokenStream.peek() == Tokens.COLON){ + if (tokenStream.peek() === Tokens.COLON) { pseudoPage = this._pseudo_page(); } @@ -1861,7 +1487,7 @@ Parser.prototype = function(){ }, //CSS3 Paged Media - _margin: function(){ + _margin: function() { /* * margin : * margin_sym S* '{' declaration [ ';' S* declaration? ]* '}' S* @@ -1872,7 +1498,7 @@ Parser.prototype = function(){ col, marginSym = this._margin_sym(); - if (marginSym){ + if (marginSym) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; @@ -1898,7 +1524,7 @@ Parser.prototype = function(){ }, //CSS3 Paged Media - _margin_sym: function(){ + _margin_sym: function() { /* * margin_sym : @@ -1923,14 +1549,13 @@ Parser.prototype = function(){ var tokenStream = this._tokenStream; - if(tokenStream.match([Tokens.TOPLEFTCORNER_SYM, Tokens.TOPLEFT_SYM, + if (tokenStream.match([Tokens.TOPLEFTCORNER_SYM, Tokens.TOPLEFT_SYM, Tokens.TOPCENTER_SYM, Tokens.TOPRIGHT_SYM, Tokens.TOPRIGHTCORNER_SYM, Tokens.BOTTOMLEFTCORNER_SYM, Tokens.BOTTOMLEFT_SYM, Tokens.BOTTOMCENTER_SYM, Tokens.BOTTOMRIGHT_SYM, Tokens.BOTTOMRIGHTCORNER_SYM, Tokens.LEFTTOP_SYM, Tokens.LEFTMIDDLE_SYM, Tokens.LEFTBOTTOM_SYM, Tokens.RIGHTTOP_SYM, - Tokens.RIGHTMIDDLE_SYM, Tokens.RIGHTBOTTOM_SYM])) - { + Tokens.RIGHTMIDDLE_SYM, Tokens.RIGHTBOTTOM_SYM])) { return SyntaxUnit.fromToken(tokenStream.token()); } else { return null; @@ -1938,7 +1563,7 @@ Parser.prototype = function(){ }, - _pseudo_page: function(){ + _pseudo_page: function() { /* * pseudo_page * : ':' IDENT @@ -1955,7 +1580,7 @@ Parser.prototype = function(){ return tokenStream.token().value; }, - _font_face: function(){ + _font_face: function() { /* * font_face * : FONT_FACE_SYM S* @@ -1988,40 +1613,40 @@ Parser.prototype = function(){ }); }, - _viewport: function(){ + _viewport: function() { /* * viewport * : VIEWPORT_SYM S* * '{' S* declaration? [ ';' S* declaration? ]* '}' S* * ; */ - var tokenStream = this._tokenStream, + var tokenStream = this._tokenStream, line, col; - tokenStream.mustMatch(Tokens.VIEWPORT_SYM); - line = tokenStream.token().startLine; - col = tokenStream.token().startCol; + tokenStream.mustMatch(Tokens.VIEWPORT_SYM); + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; - this._readWhitespace(); + this._readWhitespace(); - this.fire({ - type: "startviewport", - line: line, - col: col - }); + this.fire({ + type: "startviewport", + line: line, + col: col + }); - this._readDeclarations(true); + this._readDeclarations(true); - this.fire({ - type: "endviewport", - line: line, - col: col - }); + this.fire({ + type: "endviewport", + line: line, + col: col + }); }, - _document: function(){ + _document: function() { /* * document * : DOCUMENT_SYM S* @@ -2032,7 +1657,6 @@ Parser.prototype = function(){ var tokenStream = this._tokenStream, token, - tt, functions = [], prefix = ""; @@ -2045,7 +1669,7 @@ Parser.prototype = function(){ this._readWhitespace(); functions.push(this._document_function()); - while(tokenStream.match(Tokens.COMMA)) { + while (tokenStream.match(Tokens.COMMA)) { this._readWhitespace(); functions.push(this._document_function()); } @@ -2062,18 +1686,28 @@ Parser.prototype = function(){ }); var ok = true; - while(ok) { + while (ok) { switch (tokenStream.peek()) { - case Tokens.PAGE_SYM: this._page(); break; - case Tokens.FONT_FACE_SYM: this._font_face(); break; - case Tokens.VIEWPORT_SYM: this._viewport(); break; - case Tokens.MEDIA_SYM: this._media(); break; - case Tokens.KEYFRAMES_SYM: this._keyframes(); break; - case Tokens.DOCUMENT_SYM: this._document(); break; + case Tokens.PAGE_SYM: + this._page(); + break; + case Tokens.FONT_FACE_SYM: + this._font_face(); + break; + case Tokens.VIEWPORT_SYM: + this._viewport(); + break; + case Tokens.MEDIA_SYM: + this._media(); + break; + case Tokens.KEYFRAMES_SYM: + this._keyframes(); + break; + case Tokens.DOCUMENT_SYM: + this._document(); + break; default: - if (!this._ruleset()) { - ok = false; - } + ok = Boolean(this._ruleset()); } } @@ -2090,7 +1724,7 @@ Parser.prototype = function(){ }); }, - _document_function: function(){ + _document_function: function() { /* * document_function * : function | URI S* @@ -2110,7 +1744,7 @@ Parser.prototype = function(){ return value; }, - _operator: function(inFunction){ + _operator: function(inFunction) { /* * operator (outside function) @@ -2124,7 +1758,7 @@ Parser.prototype = function(){ token = null; if (tokenStream.match([Tokens.SLASH, Tokens.COMMA]) || - (inFunction && tokenStream.match([Tokens.PLUS, Tokens.STAR, Tokens.MINUS]))){ + (inFunction && tokenStream.match([Tokens.PLUS, Tokens.STAR, Tokens.MINUS]))) { token = tokenStream.token(); this._readWhitespace(); } @@ -2132,7 +1766,7 @@ Parser.prototype = function(){ }, - _combinator: function(){ + _combinator: function() { /* * combinator @@ -2144,7 +1778,7 @@ Parser.prototype = function(){ value = null, token; - if(tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE])){ + if (tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE])) { token = tokenStream.token(); value = new Combinator(token.value, token.startLine, token.startCol); this._readWhitespace(); @@ -2153,7 +1787,7 @@ Parser.prototype = function(){ return value; }, - _unary_operator: function(){ + _unary_operator: function() { /* * unary_operator @@ -2163,14 +1797,14 @@ Parser.prototype = function(){ var tokenStream = this._tokenStream; - if (tokenStream.match([Tokens.MINUS, Tokens.PLUS])){ + if (tokenStream.match([Tokens.MINUS, Tokens.PLUS])) { return tokenStream.token().value; } else { return null; } }, - _property: function(){ + _property: function() { /* * property @@ -2187,7 +1821,7 @@ Parser.prototype = function(){ col; //check for star hack - throws error if not allowed - if (tokenStream.peek() == Tokens.STAR && this.options.starHack){ + if (tokenStream.peek() === Tokens.STAR && this.options.starHack) { tokenStream.get(); token = tokenStream.token(); hack = token.value; @@ -2195,12 +1829,12 @@ Parser.prototype = function(){ col = token.startCol; } - if(tokenStream.match(Tokens.IDENT)){ + if (tokenStream.match(Tokens.IDENT)) { token = tokenStream.token(); tokenValue = token.value; //check for underscore hack - no error if not allowed because it's valid CSS syntax - if (tokenValue.charAt(0) == "_" && this.options.underscoreHack){ + if (tokenValue.charAt(0) === "_" && this.options.underscoreHack) { hack = "_"; tokenValue = tokenValue.substring(1); } @@ -2213,7 +1847,7 @@ Parser.prototype = function(){ }, //Augmented with CSS3 Selectors - _ruleset: function(){ + _ruleset: function() { /* * ruleset * : selectors_group @@ -2232,8 +1866,8 @@ Parser.prototype = function(){ */ try { selectors = this._selectors_group(); - } catch (ex){ - if (ex instanceof SyntaxError && !this.options.strict){ + } catch (ex) { + if (ex instanceof SyntaxError && !this.options.strict) { //fire error event this.fire({ @@ -2246,7 +1880,7 @@ Parser.prototype = function(){ //skip over everything until closing brace tt = tokenStream.advance([Tokens.RBRACE]); - if (tt == Tokens.RBRACE){ + if (tt === Tokens.RBRACE) { //if there's a right brace, the rule is finished so don't do anything } else { //otherwise, rethrow the error because it wasn't handled properly @@ -2263,7 +1897,7 @@ Parser.prototype = function(){ } //if it got here, all selectors parsed - if (selectors){ + if (selectors) { this.fire({ type: "startrule", @@ -2288,7 +1922,7 @@ Parser.prototype = function(){ }, //CSS3 Selectors - _selectors_group: function(){ + _selectors_group: function() { /* * selectors_group @@ -2300,13 +1934,13 @@ Parser.prototype = function(){ selector; selector = this._selector(); - if (selector !== null){ + if (selector !== null) { selectors.push(selector); - while(tokenStream.match(Tokens.COMMA)){ + while (tokenStream.match(Tokens.COMMA)) { this._readWhitespace(); selector = this._selector(); - if (selector !== null){ + if (selector !== null) { selectors.push(selector); } else { this._unexpectedToken(tokenStream.LT(1)); @@ -2318,7 +1952,7 @@ Parser.prototype = function(){ }, //CSS3 Selectors - _selector: function(){ + _selector: function() { /* * selector * : simple_selector_sequence [ combinator simple_selector_sequence ]* @@ -2333,7 +1967,7 @@ Parser.prototype = function(){ //if there's no simple selector, then there's no selector nextSelector = this._simple_selector_sequence(); - if (nextSelector === null){ + if (nextSelector === null) { return null; } @@ -2344,12 +1978,12 @@ Parser.prototype = function(){ //look for a combinator combinator = this._combinator(); - if (combinator !== null){ + if (combinator !== null) { selector.push(combinator); nextSelector = this._simple_selector_sequence(); //there must be a next selector - if (nextSelector === null){ + if (nextSelector === null) { this._unexpectedToken(tokenStream.LT(1)); } else { @@ -2359,7 +1993,7 @@ Parser.prototype = function(){ } else { //if there's not whitespace, we're done - if (this._readWhitespace()){ + if (this._readWhitespace()) { //add whitespace separator ws = new Combinator(tokenStream.token().value, tokenStream.token().startLine, tokenStream.token().startCol); @@ -2369,13 +2003,13 @@ Parser.prototype = function(){ //selector is required if there's a combinator nextSelector = this._simple_selector_sequence(); - if (nextSelector === null){ - if (combinator !== null){ + if (nextSelector === null) { + if (combinator !== null) { this._unexpectedToken(tokenStream.LT(1)); } } else { - if (combinator !== null){ + if (combinator !== null) { selector.push(combinator); } else { selector.push(ws); @@ -2388,13 +2022,13 @@ Parser.prototype = function(){ } } - } while(true); + } while (true); return new Selector(selector, selector[0].line, selector[0].col); }, //CSS3 Selectors - _simple_selector_sequence: function(){ + _simple_selector_sequence: function() { /* * simple_selector_sequence * : [ type_selector | universal ] @@ -2415,7 +2049,7 @@ Parser.prototype = function(){ //the different parts after the element name to search for components = [ //HASH - function(){ + function() { return tokenStream.match(Tokens.HASH) ? new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) : null; @@ -2428,7 +2062,6 @@ Parser.prototype = function(){ i = 0, len = components.length, component = null, - found = false, line, col; @@ -2438,30 +2071,30 @@ Parser.prototype = function(){ col = tokenStream.LT(1).startCol; elementName = this._type_selector(); - if (!elementName){ + if (!elementName) { elementName = this._universal(); } - if (elementName !== null){ + if (elementName !== null) { selectorText += elementName; } - while(true){ + while (true) { //whitespace means we're done - if (tokenStream.peek() === Tokens.S){ + if (tokenStream.peek() === Tokens.S) { break; } //check for each component - while(i < len && component === null){ + while (i < len && component === null) { component = components[i++].call(this); } - if (component === null){ + if (component === null) { //we don't have a selector - if (selectorText === ""){ + if (selectorText === "") { return null; } else { break; @@ -2481,7 +2114,7 @@ Parser.prototype = function(){ }, //CSS3 Selectors - _type_selector: function(){ + _type_selector: function() { /* * type_selector * : [ namespace_prefix ]? element_name @@ -2492,23 +2125,23 @@ Parser.prototype = function(){ ns = this._namespace_prefix(), elementName = this._element_name(); - if (!elementName){ + if (!elementName) { /* * Need to back out the namespace that was read due to both * type_selector and universal reading namespace_prefix * first. Kind of hacky, but only way I can figure out * right now how to not change the grammar. */ - if (ns){ + if (ns) { tokenStream.unget(); - if (ns.length > 1){ + if (ns.length > 1) { tokenStream.unget(); } } return null; } else { - if (ns){ + if (ns) { elementName.text = ns + elementName.text; elementName.col -= ns.length; } @@ -2517,7 +2150,7 @@ Parser.prototype = function(){ }, //CSS3 Selectors - _class: function(){ + _class: function() { /* * class * : '.' IDENT @@ -2527,7 +2160,7 @@ Parser.prototype = function(){ var tokenStream = this._tokenStream, token; - if (tokenStream.match(Tokens.DOT)){ + if (tokenStream.match(Tokens.DOT)) { tokenStream.mustMatch(Tokens.IDENT); token = tokenStream.token(); return new SelectorSubPart("." + token.value, "class", token.startLine, token.startCol - 1); @@ -2538,7 +2171,7 @@ Parser.prototype = function(){ }, //CSS3 Selectors - _element_name: function(){ + _element_name: function() { /* * element_name * : IDENT @@ -2548,7 +2181,7 @@ Parser.prototype = function(){ var tokenStream = this._tokenStream, token; - if (tokenStream.match(Tokens.IDENT)){ + if (tokenStream.match(Tokens.IDENT)) { token = tokenStream.token(); return new SelectorSubPart(token.value, "elementName", token.startLine, token.startCol); @@ -2558,7 +2191,7 @@ Parser.prototype = function(){ }, //CSS3 Selectors - _namespace_prefix: function(){ + _namespace_prefix: function() { /* * namespace_prefix * : [ IDENT | '*' ]? '|' @@ -2568,9 +2201,9 @@ Parser.prototype = function(){ value = ""; //verify that this is a namespace prefix - if (tokenStream.LA(1) === Tokens.PIPE || tokenStream.LA(2) === Tokens.PIPE){ + if (tokenStream.LA(1) === Tokens.PIPE || tokenStream.LA(2) === Tokens.PIPE) { - if(tokenStream.match([Tokens.IDENT, Tokens.STAR])){ + if (tokenStream.match([Tokens.IDENT, Tokens.STAR])) { value += tokenStream.token().value; } @@ -2583,7 +2216,7 @@ Parser.prototype = function(){ }, //CSS3 Selectors - _universal: function(){ + _universal: function() { /* * universal * : [ namespace_prefix ]? '*' @@ -2594,20 +2227,20 @@ Parser.prototype = function(){ ns; ns = this._namespace_prefix(); - if(ns){ + if (ns) { value += ns; } - if(tokenStream.match(Tokens.STAR)){ + if (tokenStream.match(Tokens.STAR)) { value += "*"; } return value.length ? value : null; - }, + }, //CSS3 Selectors - _attrib: function(){ + _attrib: function() { /* * attrib * : '[' S* [ namespace_prefix ]? IDENT S* @@ -2626,14 +2259,14 @@ Parser.prototype = function(){ ns, token; - if (tokenStream.match(Tokens.LBRACKET)){ + if (tokenStream.match(Tokens.LBRACKET)) { token = tokenStream.token(); value = token.value; value += this._readWhitespace(); ns = this._namespace_prefix(); - if (ns){ + if (ns) { value += ns; } @@ -2641,8 +2274,8 @@ Parser.prototype = function(){ value += tokenStream.token().value; value += this._readWhitespace(); - if(tokenStream.match([Tokens.PREFIXMATCH, Tokens.SUFFIXMATCH, Tokens.SUBSTRINGMATCH, - Tokens.EQUALS, Tokens.INCLUDES, Tokens.DASHMATCH])){ + if (tokenStream.match([Tokens.PREFIXMATCH, Tokens.SUFFIXMATCH, Tokens.SUBSTRINGMATCH, + Tokens.EQUALS, Tokens.INCLUDES, Tokens.DASHMATCH])) { value += tokenStream.token().value; value += this._readWhitespace(); @@ -2661,7 +2294,7 @@ Parser.prototype = function(){ }, //CSS3 Selectors - _pseudo: function(){ + _pseudo: function() { /* * pseudo @@ -2675,24 +2308,28 @@ Parser.prototype = function(){ line, col; - if (tokenStream.match(Tokens.COLON)){ + if (tokenStream.match(Tokens.COLON)) { - if (tokenStream.match(Tokens.COLON)){ + if (tokenStream.match(Tokens.COLON)) { colons += ":"; } - if (tokenStream.match(Tokens.IDENT)){ + if (tokenStream.match(Tokens.IDENT)) { pseudo = tokenStream.token().value; line = tokenStream.token().startLine; col = tokenStream.token().startCol - colons.length; - } else if (tokenStream.peek() == Tokens.FUNCTION){ + } else if (tokenStream.peek() === Tokens.FUNCTION) { line = tokenStream.LT(1).startLine; col = tokenStream.LT(1).startCol - colons.length; pseudo = this._functional_pseudo(); } - if (pseudo){ + if (pseudo) { pseudo = new SelectorSubPart(colons + pseudo, "pseudo", line, col); + } else { + var startLine = tokenStream.LT(1).startLine, + startCol = tokenStream.LT(0).startCol; + throw new SyntaxError("Expected a `FUNCTION` or `IDENT` after colon at line " + startLine + ", col " + startCol + ".", startLine, startCol); } } @@ -2700,7 +2337,7 @@ Parser.prototype = function(){ }, //CSS3 Selectors - _functional_pseudo: function(){ + _functional_pseudo: function() { /* * functional_pseudo * : FUNCTION S* expression ')' @@ -2710,7 +2347,7 @@ Parser.prototype = function(){ var tokenStream = this._tokenStream, value = null; - if(tokenStream.match(Tokens.FUNCTION)){ + if (tokenStream.match(Tokens.FUNCTION)) { value = tokenStream.token().value; value += this._readWhitespace(); value += this._expression(); @@ -2722,7 +2359,7 @@ Parser.prototype = function(){ }, //CSS3 Selectors - _expression: function(){ + _expression: function() { /* * expression * : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+ @@ -2732,10 +2369,10 @@ Parser.prototype = function(){ var tokenStream = this._tokenStream, value = ""; - while(tokenStream.match([Tokens.PLUS, Tokens.MINUS, Tokens.DIMENSION, + while (tokenStream.match([Tokens.PLUS, Tokens.MINUS, Tokens.DIMENSION, Tokens.NUMBER, Tokens.STRING, Tokens.IDENT, Tokens.LENGTH, Tokens.FREQ, Tokens.ANGLE, Tokens.TIME, - Tokens.RESOLUTION, Tokens.SLASH])){ + Tokens.RESOLUTION, Tokens.SLASH])) { value += tokenStream.token().value; value += this._readWhitespace(); @@ -2746,7 +2383,7 @@ Parser.prototype = function(){ }, //CSS3 Selectors - _negation: function(){ + _negation: function() { /* * negation * : NOT S* negation_arg S* ')' @@ -2760,7 +2397,7 @@ Parser.prototype = function(){ arg, subpart = null; - if (tokenStream.match(Tokens.NOT)){ + if (tokenStream.match(Tokens.NOT)) { value = tokenStream.token().value; line = tokenStream.token().startLine; col = tokenStream.token().startCol; @@ -2779,7 +2416,7 @@ Parser.prototype = function(){ }, //CSS3 Selectors - _negation_arg: function(){ + _negation_arg: function() { /* * negation_arg * : type_selector | universal | HASH | class | attrib | pseudo @@ -2790,7 +2427,7 @@ Parser.prototype = function(){ args = [ this._type_selector, this._universal, - function(){ + function() { return tokenStream.match(Tokens.HASH) ? new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) : null; @@ -2802,7 +2439,6 @@ Parser.prototype = function(){ arg = null, i = 0, len = args.length, - elementName, line, col, part; @@ -2810,19 +2446,19 @@ Parser.prototype = function(){ line = tokenStream.LT(1).startLine; col = tokenStream.LT(1).startCol; - while(i < len && arg === null){ + while (i < len && arg === null) { arg = args[i].call(this); i++; } //must be a negation arg - if (arg === null){ + if (arg === null) { this._unexpectedToken(tokenStream.LT(1)); } //it's an element name - if (arg.type == "elementName"){ + if (arg.type === "elementName") { part = new SelectorPart(arg, [], arg.toString(), line, col); } else { part = new SelectorPart(null, [arg], arg.toString(), line, col); @@ -2831,7 +2467,7 @@ Parser.prototype = function(){ return part; }, - _declaration: function(){ + _declaration: function() { /* * declaration @@ -2844,12 +2480,11 @@ Parser.prototype = function(){ property = null, expr = null, prio = null, - error = null, invalid = null, propertyName= ""; property = this._property(); - if (property !== null){ + if (property !== null) { tokenStream.mustMatch(Tokens.COLON); this._readWhitespace(); @@ -2857,7 +2492,7 @@ Parser.prototype = function(){ expr = this._expr(); //if there's no parts for the value, it's an error - if (!expr || expr.length === 0){ + if (!expr || expr.length === 0) { this._unexpectedToken(tokenStream.LT(1)); } @@ -2869,8 +2504,8 @@ Parser.prototype = function(){ * _property or *property as invalid properties. */ propertyName = property.toString(); - if (this.options.starHack && property.hack == "*" || - this.options.underscoreHack && property.hack == "_") { + if (this.options.starHack && property.hack === "*" || + this.options.underscoreHack && property.hack === "_") { propertyName = property.text; } @@ -2897,7 +2532,7 @@ Parser.prototype = function(){ } }, - _prio: function(){ + _prio: function() { /* * prio * : IMPORTANT_SYM S* @@ -2911,21 +2546,20 @@ Parser.prototype = function(){ return result; }, - _expr: function(inFunction){ + _expr: function(inFunction) { /* * expr * : term [ operator term ]* * ; */ - var tokenStream = this._tokenStream, - values = [], - //valueParts = [], + var values = [], + //valueParts = [], value = null, operator = null; value = this._term(inFunction); - if (value !== null){ + if (value !== null) { values.push(value); @@ -2933,33 +2567,33 @@ Parser.prototype = function(){ operator = this._operator(inFunction); //if there's an operator, keep building up the value parts - if (operator){ + if (operator) { values.push(operator); } /*else { //if there's not an operator, you have a full value - values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col)); - valueParts = []; - }*/ + values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col)); + valueParts = []; + }*/ value = this._term(inFunction); - if (value === null){ + if (value === null) { break; } else { values.push(value); } - } while(true); + } while (true); } - //cleanup - /*if (valueParts.length){ + //cleanup + /*if (valueParts.length) { values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col)); }*/ return values.length > 0 ? new PropertyValue(values, values[0].line, values[0].col) : null; }, - _term: function(inFunction){ + _term: function(inFunction) { /* * term @@ -2974,33 +2608,34 @@ Parser.prototype = function(){ unary = null, value = null, endChar = null, + part = null, token, line, col; //returns the operator or null unary = this._unary_operator(); - if (unary !== null){ + if (unary !== null) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; } //exception for IE filters - if (tokenStream.peek() == Tokens.IE_FUNCTION && this.options.ieFilters){ + if (tokenStream.peek() === Tokens.IE_FUNCTION && this.options.ieFilters) { value = this._ie_function(); - if (unary === null){ + if (unary === null) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; } //see if it's a simple block - } else if (inFunction && tokenStream.match([Tokens.LPAREN, Tokens.LBRACE, Tokens.LBRACKET])){ + } else if (inFunction && tokenStream.match([Tokens.LPAREN, Tokens.LBRACE, Tokens.LBRACKET])) { token = tokenStream.token(); endChar = token.endChar; value = token.value + this._expr(inFunction).text; - if (unary === null){ + if (unary === null) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; } @@ -3011,48 +2646,51 @@ Parser.prototype = function(){ //see if there's a simple match } else if (tokenStream.match([Tokens.NUMBER, Tokens.PERCENTAGE, Tokens.LENGTH, Tokens.ANGLE, Tokens.TIME, - Tokens.FREQ, Tokens.STRING, Tokens.IDENT, Tokens.URI, Tokens.UNICODE_RANGE])){ + Tokens.FREQ, Tokens.STRING, Tokens.IDENT, Tokens.URI, Tokens.UNICODE_RANGE])) { value = tokenStream.token().value; - if (unary === null){ + if (unary === null) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; + // Correct potentially-inaccurate IDENT parsing in + // PropertyValuePart constructor. + part = PropertyValuePart.fromToken(tokenStream.token()); } this._readWhitespace(); } else { //see if it's a color token = this._hexcolor(); - if (token === null){ + if (token === null) { //if there's no unary, get the start of the next token for line/col info - if (unary === null){ + if (unary === null) { line = tokenStream.LT(1).startLine; col = tokenStream.LT(1).startCol; } //has to be a function - if (value === null){ + if (value === null) { /* * This checks for alpha(opacity=0) style of IE * functions. IE_FUNCTION only presents progid: style. */ - if (tokenStream.LA(3) == Tokens.EQUALS && this.options.ieFilters){ + if (tokenStream.LA(3) === Tokens.EQUALS && this.options.ieFilters) { value = this._ie_function(); } else { value = this._function(); } } - /*if (value === null){ + /*if (value === null) { return null; //throw new Error("Expected identifier at line " + tokenStream.token().startLine + ", character " + tokenStream.token().startCol + "."); }*/ } else { value = token.value; - if (unary === null){ + if (unary === null) { line = token.startLine; col = token.startCol; } @@ -3060,13 +2698,13 @@ Parser.prototype = function(){ } - return value !== null ? + return part !== null ? part : value !== null ? new PropertyValuePart(unary !== null ? unary + value : value, line, col) : null; }, - _function: function(){ + _function: function() { /* * function @@ -3079,22 +2717,22 @@ Parser.prototype = function(){ expr = null, lt; - if (tokenStream.match(Tokens.FUNCTION)){ + if (tokenStream.match(Tokens.FUNCTION)) { functionText = tokenStream.token().value; this._readWhitespace(); expr = this._expr(true); functionText += expr; //START: Horrible hack in case it's an IE filter - if (this.options.ieFilters && tokenStream.peek() == Tokens.EQUALS){ + if (this.options.ieFilters && tokenStream.peek() === Tokens.EQUALS) { do { - if (this._readWhitespace()){ + if (this._readWhitespace()) { functionText += tokenStream.token().value; } //might be second time in the loop - if (tokenStream.LA(0) == Tokens.COMMA){ + if (tokenStream.LA(0) === Tokens.COMMA) { functionText += tokenStream.token().value; } @@ -3106,12 +2744,12 @@ Parser.prototype = function(){ //functionText += this._term(); lt = tokenStream.peek(); - while(lt != Tokens.COMMA && lt != Tokens.S && lt != Tokens.RPAREN){ + while (lt !== Tokens.COMMA && lt !== Tokens.S && lt !== Tokens.RPAREN) { tokenStream.get(); functionText += tokenStream.token().value; lt = tokenStream.peek(); } - } while(tokenStream.match([Tokens.COMMA, Tokens.S])); + } while (tokenStream.match([Tokens.COMMA, Tokens.S])); } //END: Horrible Hack @@ -3124,7 +2762,7 @@ Parser.prototype = function(){ return functionText; }, - _ie_function: function(){ + _ie_function: function() { /* (My own extension) * ie_function @@ -3134,21 +2772,20 @@ Parser.prototype = function(){ var tokenStream = this._tokenStream, functionText = null, - expr = null, lt; //IE function can begin like a regular function, too - if (tokenStream.match([Tokens.IE_FUNCTION, Tokens.FUNCTION])){ + if (tokenStream.match([Tokens.IE_FUNCTION, Tokens.FUNCTION])) { functionText = tokenStream.token().value; do { - if (this._readWhitespace()){ + if (this._readWhitespace()) { functionText += tokenStream.token().value; } //might be second time in the loop - if (tokenStream.LA(0) == Tokens.COMMA){ + if (tokenStream.LA(0) === Tokens.COMMA) { functionText += tokenStream.token().value; } @@ -3160,12 +2797,12 @@ Parser.prototype = function(){ //functionText += this._term(); lt = tokenStream.peek(); - while(lt != Tokens.COMMA && lt != Tokens.S && lt != Tokens.RPAREN){ + while (lt !== Tokens.COMMA && lt !== Tokens.S && lt !== Tokens.RPAREN) { tokenStream.get(); functionText += tokenStream.token().value; lt = tokenStream.peek(); } - } while(tokenStream.match([Tokens.COMMA, Tokens.S])); + } while (tokenStream.match([Tokens.COMMA, Tokens.S])); tokenStream.match(Tokens.RPAREN); functionText += ")"; @@ -3175,7 +2812,7 @@ Parser.prototype = function(){ return functionText; }, - _hexcolor: function(){ + _hexcolor: function() { /* * There is a constraint on the color that it must * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F]) @@ -3190,13 +2827,13 @@ Parser.prototype = function(){ token = null, color; - if(tokenStream.match(Tokens.HASH)){ + if (tokenStream.match(Tokens.HASH)) { //need to do some validation here token = tokenStream.token(); color = token.value; - if (!/#[a-f0-9]{3,6}/i.test(color)){ + if (!/#[a-f0-9]{3,6}/i.test(color)) { throw new SyntaxError("Expected a hex color but found '" + color + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); } this._readWhitespace(); @@ -3209,7 +2846,7 @@ Parser.prototype = function(){ // Animations methods //----------------------------------------------------------------- - _keyframes: function(){ + _keyframes: function() { /* * keyframes: @@ -3246,7 +2883,7 @@ Parser.prototype = function(){ tt = tokenStream.peek(); //check for key - while(tt == Tokens.IDENT || tt == Tokens.PERCENTAGE) { + while (tt === Tokens.IDENT || tt === Tokens.PERCENTAGE) { this._keyframe_rule(); this._readWhitespace(); tt = tokenStream.peek(); @@ -3266,7 +2903,7 @@ Parser.prototype = function(){ }, - _keyframe_name: function(){ + _keyframe_name: function() { /* * keyframe_name: @@ -3274,14 +2911,13 @@ Parser.prototype = function(){ * | STRING * ; */ - var tokenStream = this._tokenStream, - token; + var tokenStream = this._tokenStream; tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]); return SyntaxUnit.fromToken(tokenStream.token()); }, - _keyframe_rule: function(){ + _keyframe_rule: function() { /* * keyframe_rule: @@ -3289,9 +2925,7 @@ Parser.prototype = function(){ * '{' S* declaration [ ';' S* declaration ]* '}' S* * ; */ - var tokenStream = this._tokenStream, - token, - keyList = this._key_list(); + var keyList = this._key_list(); this.fire({ type: "startkeyframerule", @@ -3311,7 +2945,7 @@ Parser.prototype = function(){ }, - _key_list: function(){ + _key_list: function() { /* * key_list: @@ -3319,8 +2953,6 @@ Parser.prototype = function(){ * ; */ var tokenStream = this._tokenStream, - token, - key, keyList = []; //must be least one key @@ -3328,7 +2960,7 @@ Parser.prototype = function(){ this._readWhitespace(); - while(tokenStream.match(Tokens.COMMA)){ + while (tokenStream.match(Tokens.COMMA)) { this._readWhitespace(); keyList.push(this._key()); this._readWhitespace(); @@ -3337,7 +2969,7 @@ Parser.prototype = function(){ return keyList; }, - _key: function(){ + _key: function() { /* * There is a restriction that IDENT can be only "from" or "to". * @@ -3350,12 +2982,12 @@ Parser.prototype = function(){ var tokenStream = this._tokenStream, token; - if (tokenStream.match(Tokens.PERCENTAGE)){ + if (tokenStream.match(Tokens.PERCENTAGE)) { return SyntaxUnit.fromToken(tokenStream.token()); - } else if (tokenStream.match(Tokens.IDENT)){ + } else if (tokenStream.match(Tokens.IDENT)) { token = tokenStream.token(); - if (/from|to/i.test(token.value)){ + if (/from|to/i.test(token.value)) { return SyntaxUnit.fromToken(token); } @@ -3377,8 +3009,8 @@ Parser.prototype = function(){ * @method _skipCruft * @private */ - _skipCruft: function(){ - while(this._tokenStream.match([Tokens.S, Tokens.CDO, Tokens.CDC])){ + _skipCruft: function() { + while (this._tokenStream.match([Tokens.S, Tokens.CDO, Tokens.CDC])) { //noop } }, @@ -3395,14 +3027,14 @@ Parser.prototype = function(){ * @method _readDeclarations * @private */ - _readDeclarations: function(checkStart, readMargins){ + _readDeclarations: function(checkStart, readMargins) { /* * Reads the pattern * S* '{' S* declaration [ ';' S* declaration ]* '}' S* * or * S* '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S* * Note that this is how it is described in CSS3 Paged Media, but is actually incorrect. - * A semicolon is only necessary following a declaration is there's another declaration + * A semicolon is only necessary following a declaration if there's another declaration * or margin afterwards. */ var tokenStream = this._tokenStream, @@ -3411,7 +3043,7 @@ Parser.prototype = function(){ this._readWhitespace(); - if (checkStart){ + if (checkStart) { tokenStream.mustMatch(Tokens.LBRACE); } @@ -3419,12 +3051,12 @@ Parser.prototype = function(){ try { - while(true){ + while (true) { - if (tokenStream.match(Tokens.SEMICOLON) || (readMargins && this._margin())){ + if (tokenStream.match(Tokens.SEMICOLON) || (readMargins && this._margin())) { //noop - } else if (this._declaration()){ - if (!tokenStream.match(Tokens.SEMICOLON)){ + } else if (this._declaration()) { + if (!tokenStream.match(Tokens.SEMICOLON)) { break; } } else { @@ -3441,7 +3073,7 @@ Parser.prototype = function(){ this._readWhitespace(); } catch (ex) { - if (ex instanceof SyntaxError && !this.options.strict){ + if (ex instanceof SyntaxError && !this.options.strict) { //fire error event this.fire({ @@ -3454,10 +3086,10 @@ Parser.prototype = function(){ //see if there's another declaration tt = tokenStream.advance([Tokens.SEMICOLON, Tokens.RBRACE]); - if (tt == Tokens.SEMICOLON){ + if (tt === Tokens.SEMICOLON) { //if there's a semicolon, then there might be another declaration this._readDeclarations(false, readMargins); - } else if (tt != Tokens.RBRACE){ + } else if (tt !== Tokens.RBRACE) { //if there's a right brace, the rule is finished so don't do anything //otherwise, rethrow the error because it wasn't handled properly throw ex; @@ -3480,12 +3112,12 @@ Parser.prototype = function(){ * @return {String} The white space if found, empty string if not. * @private */ - _readWhitespace: function(){ + _readWhitespace: function() { var tokenStream = this._tokenStream, ws = ""; - while(tokenStream.match(Tokens.S)){ + while (tokenStream.match(Tokens.S)) { ws += tokenStream.token().value; } @@ -3500,7 +3132,7 @@ Parser.prototype = function(){ * @return {void} * @private */ - _unexpectedToken: function(token){ + _unexpectedToken: function(token) { throw new SyntaxError("Unexpected token '" + token.value + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); }, @@ -3510,8 +3142,8 @@ Parser.prototype = function(){ * @method _verifyEnd * @private */ - _verifyEnd: function(){ - if (this._tokenStream.LA(1) != Tokens.EOF){ + _verifyEnd: function() { + if (this._tokenStream.LA(1) !== Tokens.EOF) { this._unexpectedToken(this._tokenStream.LT(1)); } }, @@ -3519,7 +3151,7 @@ Parser.prototype = function(){ //----------------------------------------------------------------- // Validation methods //----------------------------------------------------------------- - _validateProperty: function(property, value){ + _validateProperty: function(property, value) { Validation.validate(property, value); }, @@ -3527,17 +3159,17 @@ Parser.prototype = function(){ // Parsing methods //----------------------------------------------------------------- - parse: function(input){ + parse: function(input) { this._tokenStream = new TokenStream(input, Tokens); this._stylesheet(); }, - parseStyleSheet: function(input){ + parseStyleSheet: function(input) { //just passthrough return this.parse(input); }, - parseMediaQuery: function(input){ + parseMediaQuery: function(input) { this._tokenStream = new TokenStream(input, Tokens); var result = this._media_query(); @@ -3554,7 +3186,7 @@ Parser.prototype = function(){ * @throws parserlib.util.SyntaxError If an unexpected token is found. * @method parserPropertyValue */ - parsePropertyValue: function(input){ + parsePropertyValue: function(input) { this._tokenStream = new TokenStream(input, Tokens); this._readWhitespace(); @@ -3578,7 +3210,7 @@ Parser.prototype = function(){ * @return {Boolean} True if the parse completed successfully, false if not. * @method parseRule */ - parseRule: function(input){ + parseRule: function(input) { this._tokenStream = new TokenStream(input, Tokens); //skip any leading white space @@ -3603,7 +3235,7 @@ Parser.prototype = function(){ * @throws parserlib.util.SyntaxError If an unexpected token is found. * @method parseSelector */ - parseSelector: function(input){ + parseSelector: function(input) { this._tokenStream = new TokenStream(input, Tokens); @@ -3629,7 +3261,7 @@ Parser.prototype = function(){ * @return {void} * @method parseStyleAttribute */ - parseStyleAttribute: function(input){ + parseStyleAttribute: function(input) { input += "}"; // for error recovery in _readDeclarations() this._tokenStream = new TokenStream(input, Tokens); this._readDeclarations(); @@ -3637,8 +3269,8 @@ Parser.prototype = function(){ }; //copy over onto prototype - for (prop in additions){ - if (additions.hasOwnProperty(prop)){ + for (prop in additions) { + if (Object.prototype.hasOwnProperty.call(additions, prop)) { proto[prop] = additions[prop]; } } @@ -3654,102 +3286,84 @@ nth ; */ -/*global Validation, ValidationTypes, ValidationError*/ -var Properties = { +},{"../util/EventTarget":23,"../util/SyntaxError":25,"../util/SyntaxUnit":26,"./Combinator":2,"./MediaFeature":4,"./MediaQuery":5,"./PropertyName":8,"./PropertyValue":9,"./PropertyValuePart":11,"./Selector":13,"./SelectorPart":14,"./SelectorSubPart":15,"./TokenStream":17,"./Tokens":18,"./Validation":19}],7:[function(require,module,exports){ +"use strict"; + +/* exported Properties */ + +var Properties = module.exports = { + __proto__: null, //A "align-items" : "flex-start | flex-end | center | baseline | stretch", "align-content" : "flex-start | flex-end | center | space-between | space-around | stretch", "align-self" : "auto | flex-start | flex-end | center | baseline | stretch", + "all" : "initial | inherit | unset", "-webkit-align-items" : "flex-start | flex-end | center | baseline | stretch", "-webkit-align-content" : "flex-start | flex-end | center | space-between | space-around | stretch", "-webkit-align-self" : "auto | flex-start | flex-end | center | baseline | stretch", "alignment-adjust" : "auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | | ", - "alignment-baseline" : "auto | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical | inherit", + "alignment-baseline" : "auto | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical", "animation" : 1, - "animation-delay" : { multi: "