Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Release v0.10.0

  • Loading branch information...
commit f1ef64d7cee8f174151db42447dedd3c4ece91c2 1 parent 8930035
@stubbornella stubbornella authored
View
47 CHANGELOG
@@ -1,3 +1,50 @@
+August 15, 2013 - v0.10.0
+
+* Update README.md (Nicole Sullivan)
+* Merge pull request #379 from nschonni/remove-old-node-compat (Nicole Sullivan)
+* Bump minimum Node version to 0.8 and add CI tests (Nick Schonning)
+* Adding contributors to the README.md (Nicole Sullivan)
+* Merge pull request #368 from nschonni/add-grunt-build (Nicole Sullivan)
+* Bump devDependencies (Nick Schonning)
+* Add bug URL to package.json (Nick Schonning)
+* Merge pull request #376 from dmethvin/optional-rc (Nicole Sullivan)
+* Add Full license block banner (Nick Schonning)
+* Alias build directory (Nick Schonning)
+* Minor fixes from code review by @jaredwy (Nick Schonning)
+* Inline YUITest CLI to standardize output (Nick Schonning)
+* Add Rhino test task (Nick Schonning)
+* Fix concat targets (Nick Schonning)
+* Add release task (Nick Schonning)
+* Add clean task (Nick Schonning)
+* Add back testrunner.html test javascript file (Nick Schonning)
+* Update Travis and NPM building (Nick Schonning)
+* Remove Uglify task (Nick Schonning)
+* Add YUITest custom task (Nick Schonning)
+* Add .gitattibutes for line endings (Nick Schonning)
+* Add parser-lib concatination (Nick Schonning)
+* Fix package.json path for Ant (Nick Schonning)
+* Fix linting errors in tests (Nick Schonning)
+* Add concat tasks (Nick Schonning)
+* Suppress new errors caused by latest JSHint (Nick Schonning)
+* Fix indenting and add .editorconfig (Nick Schonning)
+* Scaffold Gruntfile and add node dependencies (Nick Schonning)
+* Ensure node modules won't get checked in (Nick Schonning)
+* Move package.json to project root (Nick Schonning)
+* Fix #364. In WSH, return empty string for files not found. (Dave Methvin)
+* Merge pull request #353 from jklein/master (Nicholas C. Zakas)
+* Merge remote-tracking branch 'upstream/master' (Jonathan Klein)
+* Removing an unneeded line which was causing the CLI option validation to fail (jklein)
+* Merge pull request #352 from vomitcuddle/patch-1 (Nicholas C. Zakas)
+* drop os property from package.json (vomitcuddle)
+* Merge pull request #351 from jklein/master (Nicholas C. Zakas)
+* Adding a validateOptions function and warning/exiting on invalid options (jklein)
+* Merge pull request #347 from jklein/issue345 (Nicholas C. Zakas)
+* Fixes #345 - Using absolute paths for the excluded files and the files to lint so the comparison is clean (jklein)
+* Merge pull request #340 from nschonni/patch-1 (Nicholas C. Zakas)
+* Update CONTRIBUTING.md (Nick Schonning)
+* Updated contributors (Nicholas C. Zakas)
+* Fix Travis build (Nicholas C. Zakas)
+
January 17, 2013 - v0.9.10
* Switch to using Node.js version of YUI Test (Nicholas C. Zakas)
View
6 package.json
@@ -1,13 +1,13 @@
{
"name": "csslint",
- "version": "0.9.10",
+ "version": "0.10.0",
"description": "CSSLint",
"author": {
- "name": "Nicholas C. Zakas"
+ "name": "Nicole Sullivan"
},
"contributors": [
{
- "name": "Nicole Sullivan"
+ "name": "Nicholas C. Zakas"
}
],
"engines": {
View
12,187 release/csslint-node-tests.js
0 additions, 12,187 deletions not shown
View
6,368 release/csslint-node.js
8 additions, 6,360 deletions not shown
View
1,258 release/csslint-rhino.js
@@ -1,6 +1,6 @@
/*!
CSSLint
-Copyright (c) 2011 Nicole Sullivan and Nicholas C. Zakas. All rights reserved.
+Copyright (c) 2013 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,7 +21,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
-/* Build time: 17-January-2013 10:55:01 */
+/* Build: v0.10.0 15-August-2013 01:07:22 */
+var exports = exports || {};
var CSSLint = (function(){
/*!
Parser-Lib
@@ -46,7 +47,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
-/* Version v0.2.2, Build time: 17-January-2013 10:26:34 */
+/* Version v0.2.3, Build time: 19-June-2013 11:16:15 */
var parserlib = {};
(function(){
@@ -956,7 +957,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
-/* Version v0.2.2, Build time: 17-January-2013 10:26:34 */
+/* Version v0.2.3, Build time: 19-June-2013 11:16:15 */
(function(){
var EventTarget = parserlib.util.EventTarget,
TokenStreamBase = parserlib.util.TokenStreamBase,
@@ -1296,10 +1297,10 @@ Parser.prototype = function(){
var proto = new EventTarget(), //new prototype
prop,
additions = {
-
+
//restore constructor
constructor: Parser,
-
+
//instance constants - yuck
DEFAULT_TYPE : 0,
COMBINATOR_TYPE : 1,
@@ -1310,14 +1311,14 @@ Parser.prototype = function(){
PROPERTY_VALUE_PART_TYPE : 6,
SELECTOR_TYPE : 7,
SELECTOR_PART_TYPE : 8,
- SELECTOR_SUB_PART_TYPE : 9,
-
+ SELECTOR_SUB_PART_TYPE : 9,
+
//-----------------------------------------------------------------
// Grammar
//-----------------------------------------------------------------
-
+
_stylesheet: function(){
-
+
/*
* stylesheet
* : [ CHARSET_SYM S* STRING S* ';' ]?
@@ -1325,19 +1326,19 @@ Parser.prototype = function(){
* [ namespace [S|CDO|CDC]* ]*
* [ [ ruleset | media | page | font_face | keyframes ] [S|CDO|CDC]* ]*
* ;
- */
-
+ */
+
var tokenStream = this._tokenStream,
charset = null,
count,
token,
tt;
-
+
this.fire("startstylesheet");
-
+
//try to read character set
this._charset();
-
+
this._skipCruft();
//try to read imports - may be more than one
@@ -1345,42 +1346,46 @@ Parser.prototype = function(){
this._import();
this._skipCruft();
}
-
+
//try to read namespaces - may be more than one
while (tokenStream.peek() == Tokens.NAMESPACE_SYM){
this._namespace();
this._skipCruft();
}
-
+
//get the next token
tt = tokenStream.peek();
-
+
//try to read the rest
while(tt > Tokens.EOF){
-
+
try {
-
+
switch(tt){
case Tokens.MEDIA_SYM:
this._media();
this._skipCruft();
break;
case Tokens.PAGE_SYM:
- this._page();
+ this._page();
this._skipCruft();
- break;
+ break;
case Tokens.FONT_FACE_SYM:
- this._font_face();
+ this._font_face();
this._skipCruft();
- break;
+ break;
case Tokens.KEYFRAMES_SYM:
- this._keyframes();
+ this._keyframes();
+ this._skipCruft();
+ break;
+ case Tokens.VIEWPORT_SYM:
+ this._viewport();
this._skipCruft();
- break;
+ break;
case Tokens.UNKNOWN_SYM: //unknown @ rule
tokenStream.get();
if (!this.options.strict){
-
+
//fire error event
this.fire({
type: "error",
@@ -1388,30 +1393,30 @@ Parser.prototype = function(){
message: "Unknown @ rule: " + tokenStream.LT(0).value + ".",
line: tokenStream.LT(0).startLine,
col: tokenStream.LT(0).startCol
- });
-
+ });
+
//skip braces
count=0;
while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) == Tokens.LBRACE){
count++; //keep track of nesting depth
}
-
+
while(count){
tokenStream.advance([Tokens.RBRACE]);
count--;
}
-
+
} else {
//not a syntax error, rethrow it
throw new SyntaxError("Unknown @ rule.", tokenStream.LT(0).startLine, tokenStream.LT(0).startCol);
- }
+ }
break;
case Tokens.S:
this._readWhitespace();
break;
- default:
+ default:
if(!this._ruleset()){
-
+
//error handling for known issues
switch(tt){
case Tokens.CHARSET_SYM:
@@ -1430,7 +1435,7 @@ Parser.prototype = function(){
tokenStream.get(); //get the last token
this._unexpectedToken(tokenStream.token());
}
-
+
}
}
} catch(ex) {
@@ -1441,84 +1446,84 @@ Parser.prototype = function(){
message: ex.message,
line: ex.line,
col: ex.col
- });
+ });
} else {
throw ex;
}
}
-
+
tt = tokenStream.peek();
}
-
+
if (tt != Tokens.EOF){
this._unexpectedToken(tokenStream.token());
}
-
+
this.fire("endstylesheet");
},
-
+
_charset: function(emit){
var tokenStream = this._tokenStream,
charset,
token,
line,
col;
-
+
if (tokenStream.match(Tokens.CHARSET_SYM)){
line = tokenStream.token().startLine;
col = tokenStream.token().startCol;
-
+
this._readWhitespace();
tokenStream.mustMatch(Tokens.STRING);
-
+
token = tokenStream.token();
charset = token.value;
-
+
this._readWhitespace();
tokenStream.mustMatch(Tokens.SEMICOLON);
-
+
if (emit !== false){
- this.fire({
+ this.fire({
type: "charset",
charset:charset,
line: line,
col: col
});
}
- }
+ }
},
-
+
_import: function(emit){
/*
* import
* : IMPORT_SYM S*
* [STRING|URI] S* media_query_list? ';' S*
- */
-
+ */
+
var tokenStream = this._tokenStream,
tt,
uri,
importToken,
mediaList = [];
-
+
//read import symbol
tokenStream.mustMatch(Tokens.IMPORT_SYM);
importToken = tokenStream.token();
this._readWhitespace();
-
+
tokenStream.mustMatch([Tokens.STRING, Tokens.URI]);
-
+
//grab the URI value
- uri = tokenStream.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/, "$1");
+ uri = tokenStream.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/, "$1");
this._readWhitespace();
-
+
mediaList = this._media_query_list();
-
+
//must end with a semicolon
tokenStream.mustMatch(Tokens.SEMICOLON);
this._readWhitespace();
-
+
if (emit !== false){
this.fire({
type: "import",
@@ -1528,47 +1533,47 @@ Parser.prototype = function(){
col: importToken.startCol
});
}
-
+
},
-
+
_namespace: function(emit){
/*
* namespace
* : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*
- */
-
+ */
+
var tokenStream = this._tokenStream,
line,
col,
prefix,
uri;
-
+
//read import symbol
tokenStream.mustMatch(Tokens.NAMESPACE_SYM);
line = tokenStream.token().startLine;
col = tokenStream.token().startCol;
this._readWhitespace();
-
+
//it's a namespace prefix - no _namespace_prefix() method because it's just an IDENT
if (tokenStream.match(Tokens.IDENT)){
prefix = tokenStream.token().value;
this._readWhitespace();
}
-
+
tokenStream.mustMatch([Tokens.STRING, Tokens.URI]);
/*if (!tokenStream.match(Tokens.STRING)){
tokenStream.mustMatch(Tokens.URI);
}*/
-
+
//grab the URI value
- uri = tokenStream.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/, "$1");
+ uri = tokenStream.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/, "$1");
this._readWhitespace();
//must end with a semicolon
tokenStream.mustMatch(Tokens.SEMICOLON);
this._readWhitespace();
-
+
if (emit !== false){
this.fire({
type: "namespace",
@@ -1578,9 +1583,9 @@ Parser.prototype = function(){
col: col
});
}
-
- },
-
+
+ },
+
_media: function(){
/*
* media
@@ -1591,45 +1596,47 @@ Parser.prototype = function(){
line,
col,
mediaList;// = [];
-
+
//look for @media
tokenStream.mustMatch(Tokens.MEDIA_SYM);
line = tokenStream.token().startLine;
col = tokenStream.token().startCol;
-
- this._readWhitespace();
+
+ this._readWhitespace();
mediaList = this._media_query_list();
tokenStream.mustMatch(Tokens.LBRACE);
this._readWhitespace();
-
+
this.fire({
type: "startmedia",
media: mediaList,
line: line,
col: col
});
-
+
while(true) {
if (tokenStream.peek() == Tokens.PAGE_SYM){
this._page();
+ } else if (tokenStream.peek() == Tokens.FONT_FACE_SYM){
+ this._font_face();
} else if (!this._ruleset()){
break;
- }
+ }
}
-
+
tokenStream.mustMatch(Tokens.RBRACE);
this._readWhitespace();
-
+
this.fire({
type: "endmedia",
media: mediaList,
line: line,
col: col
});
- },
-
+ },
+
//CSS3 Media Queries
_media_query_list: function(){
@@ -1640,26 +1647,26 @@ Parser.prototype = function(){
*/
var tokenStream = this._tokenStream,
mediaList = [];
-
-
+
+
this._readWhitespace();
-
+
if (tokenStream.peek() == Tokens.IDENT || tokenStream.peek() == Tokens.LPAREN){
mediaList.push(this._media_query());
}
-
+
while(tokenStream.match(Tokens.COMMA)){
this._readWhitespace();
mediaList.push(this._media_query());
}
-
+
return mediaList;
},
-
+
/*
* Note: "expression" in the grammar maps to the _media_expression
* method.
-
+
*/
_media_query: function(){
/*
@@ -1673,10 +1680,10 @@ Parser.prototype = function(){
ident = null,
token = null,
expressions = [];
-
+
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"){
tokenStream.unget();
@@ -1685,9 +1692,9 @@ Parser.prototype = function(){
token = tokenStream.token();
}
}
-
+
this._readWhitespace();
-
+
if (tokenStream.peek() == Tokens.IDENT){
type = this._media_type();
if (token === null){
@@ -1698,17 +1705,17 @@ Parser.prototype = function(){
token = tokenStream.LT(1);
}
expressions.push(this._media_expression());
- }
-
+ }
+
if (type === null && expressions.length === 0){
return null;
- } else {
+ } else {
this._readWhitespace();
while (tokenStream.match(Tokens.IDENT)){
if (tokenStream.token().value.toLowerCase() != "and"){
this._unexpectedToken(tokenStream.token());
}
-
+
this._readWhitespace();
expressions.push(this._media_expression());
}
@@ -1724,7 +1731,7 @@ Parser.prototype = function(){
* : IDENT
* ;
*/
- return this._media_feature();
+ return this._media_feature();
},
/**
@@ -1745,22 +1752,22 @@ Parser.prototype = function(){
feature = null,
token,
expression = null;
-
+
tokenStream.mustMatch(Tokens.LPAREN);
-
+
feature = this._media_feature();
this._readWhitespace();
-
+
if (tokenStream.match(Tokens.COLON)){
this._readWhitespace();
token = tokenStream.LT(1);
expression = this._expression();
}
-
+
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
@@ -1771,33 +1778,33 @@ Parser.prototype = function(){
* ;
*/
var tokenStream = this._tokenStream;
-
+
tokenStream.mustMatch(Tokens.IDENT);
-
- return SyntaxUnit.fromToken(tokenStream.token());
+
+ return SyntaxUnit.fromToken(tokenStream.token());
},
-
+
//CSS3 Paged Media
_page: function(){
/*
* page:
- * PAGE_SYM S* IDENT? pseudo_page? S*
+ * PAGE_SYM S* IDENT? pseudo_page? S*
* '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S*
* ;
- */
+ */
var tokenStream = this._tokenStream,
line,
col,
identifier = null,
pseudoPage = null;
-
+
//look for @page
tokenStream.mustMatch(Tokens.PAGE_SYM);
line = tokenStream.token().startLine;
col = tokenStream.token().startCol;
-
+
this._readWhitespace();
-
+
if (tokenStream.match(Tokens.IDENT)){
identifier = tokenStream.token().value;
@@ -1805,35 +1812,35 @@ Parser.prototype = function(){
if (identifier.toLowerCase() === "auto"){
this._unexpectedToken(tokenStream.token());
}
- }
-
+ }
+
//see if there's a colon upcoming
if (tokenStream.peek() == Tokens.COLON){
pseudoPage = this._pseudo_page();
}
-
+
this._readWhitespace();
-
+
this.fire({
type: "startpage",
id: identifier,
pseudo: pseudoPage,
line: line,
col: col
- });
+ });
+
+ this._readDeclarations(true, true);
- this._readDeclarations(true, true);
-
this.fire({
type: "endpage",
id: identifier,
pseudo: pseudoPage,
line: line,
col: col
- });
-
+ });
+
},
-
+
//CSS3 Paged Media
_margin: function(){
/*
@@ -1849,14 +1856,14 @@ Parser.prototype = function(){
if (marginSym){
line = tokenStream.token().startLine;
col = tokenStream.token().startCol;
-
+
this.fire({
type: "startpagemargin",
margin: marginSym,
line: line,
col: col
- });
-
+ });
+
this._readDeclarations(true);
this.fire({
@@ -1864,7 +1871,7 @@ Parser.prototype = function(){
margin: marginSym,
line: line,
col: col
- });
+ });
return true;
} else {
return false;
@@ -1873,17 +1880,17 @@ Parser.prototype = function(){
//CSS3 Paged Media
_margin_sym: function(){
-
+
/*
* margin_sym :
- * TOPLEFTCORNER_SYM |
- * TOPLEFT_SYM |
- * TOPCENTER_SYM |
- * TOPRIGHT_SYM |
+ * TOPLEFTCORNER_SYM |
+ * TOPLEFT_SYM |
+ * TOPCENTER_SYM |
+ * TOPRIGHT_SYM |
* TOPRIGHTCORNER_SYM |
- * BOTTOMLEFTCORNER_SYM |
- * BOTTOMLEFT_SYM |
- * BOTTOMCENTER_SYM |
+ * BOTTOMLEFTCORNER_SYM |
+ * BOTTOMLEFT_SYM |
+ * BOTTOMCENTER_SYM |
* BOTTOMRIGHT_SYM |
* BOTTOMRIGHTCORNER_SYM |
* LEFTTOP_SYM |
@@ -1891,145 +1898,178 @@ Parser.prototype = function(){
* LEFTBOTTOM_SYM |
* RIGHTTOP_SYM |
* RIGHTMIDDLE_SYM |
- * RIGHTBOTTOM_SYM
+ * RIGHTBOTTOM_SYM
* ;
*/
-
+
var tokenStream = this._tokenStream;
-
+
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.BOTTOMLEFTCORNER_SYM, Tokens.BOTTOMLEFT_SYM,
Tokens.BOTTOMCENTER_SYM, Tokens.BOTTOMRIGHT_SYM,
- Tokens.BOTTOMRIGHTCORNER_SYM, Tokens.LEFTTOP_SYM,
+ Tokens.BOTTOMRIGHTCORNER_SYM, Tokens.LEFTTOP_SYM,
Tokens.LEFTMIDDLE_SYM, Tokens.LEFTBOTTOM_SYM, Tokens.RIGHTTOP_SYM,
Tokens.RIGHTMIDDLE_SYM, Tokens.RIGHTBOTTOM_SYM]))
{
- return SyntaxUnit.fromToken(tokenStream.token());
+ return SyntaxUnit.fromToken(tokenStream.token());
} else {
return null;
}
-
+
},
-
+
_pseudo_page: function(){
/*
* pseudo_page
* : ':' IDENT
- * ;
+ * ;
*/
-
+
var tokenStream = this._tokenStream;
-
+
tokenStream.mustMatch(Tokens.COLON);
tokenStream.mustMatch(Tokens.IDENT);
-
+
//TODO: CSS3 Paged Media says only "left", "center", and "right" are allowed
-
+
return tokenStream.token().value;
},
-
+
_font_face: function(){
/*
* font_face
- * : FONT_FACE_SYM S*
+ * : FONT_FACE_SYM S*
* '{' S* declaration [ ';' S* declaration ]* '}' S*
* ;
- */
+ */
var tokenStream = this._tokenStream,
line,
col;
-
+
//look for @page
tokenStream.mustMatch(Tokens.FONT_FACE_SYM);
line = tokenStream.token().startLine;
col = tokenStream.token().startCol;
-
+
this._readWhitespace();
this.fire({
type: "startfontface",
line: line,
col: col
- });
-
+ });
+
this._readDeclarations(true);
-
+
this.fire({
type: "endfontface",
line: line,
col: col
- });
+ });
+ },
+
+ _viewport: function(){
+ /*
+ * viewport
+ * : VIEWPORT_SYM S*
+ * '{' S* declaration? [ ';' S* declaration? ]* '}' S*
+ * ;
+ */
+ var tokenStream = this._tokenStream,
+ line,
+ col;
+
+ tokenStream.mustMatch(Tokens.VIEWPORT_SYM);
+ line = tokenStream.token().startLine;
+ col = tokenStream.token().startCol;
+
+ this._readWhitespace();
+
+ this.fire({
+ type: "startviewport",
+ line: line,
+ col: col
+ });
+
+ this._readDeclarations(true);
+
+ this.fire({
+ type: "endviewport",
+ line: line,
+ col: col
+ });
+
},
_operator: function(inFunction){
-
+
/*
* operator (outside function)
* : '/' S* | ',' S* | /( empty )/
* operator (inside function)
* : '/' S* | '+' S* | '*' S* | '-' S* /( empty )/
* ;
- */
-
+ */
+
var tokenStream = this._tokenStream,
token = null;
-
+
if (tokenStream.match([Tokens.SLASH, Tokens.COMMA]) ||
(inFunction && tokenStream.match([Tokens.PLUS, Tokens.STAR, Tokens.MINUS]))){
token = tokenStream.token();
this._readWhitespace();
- }
+ }
return token ? PropertyValuePart.fromToken(token) : null;
-
+
},
-
+
_combinator: function(){
-
+
/*
* combinator
* : PLUS S* | GREATER S* | TILDE S* | S+
* ;
- */
-
+ */
+
var tokenStream = this._tokenStream,
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();
}
-
+
return value;
},
-
+
_unary_operator: function(){
-
+
/*
* unary_operator
* : '-' | '+'
* ;
*/
-
+
var tokenStream = this._tokenStream;
-
+
if (tokenStream.match([Tokens.MINUS, Tokens.PLUS])){
return tokenStream.token().value;
} else {
return null;
- }
+ }
},
-
+
_property: function(){
-
+
/*
* property
* : IDENT S*
- * ;
+ * ;
*/
-
+
var tokenStream = this._tokenStream,
value = null,
hack = null,
@@ -2037,7 +2077,7 @@ Parser.prototype = function(){
token,
line,
col;
-
+
//check for star hack - throws error if not allowed
if (tokenStream.peek() == Tokens.STAR && this.options.starHack){
tokenStream.get();
@@ -2046,33 +2086,33 @@ Parser.prototype = function(){
line = token.startLine;
col = token.startCol;
}
-
+
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){
hack = "_";
tokenValue = tokenValue.substring(1);
}
-
+
value = new PropertyName(tokenValue, hack, (line||token.startLine), (col||token.startCol));
this._readWhitespace();
}
-
+
return value;
},
-
+
//Augmented with CSS3 Selectors
_ruleset: function(){
/*
* ruleset
* : selectors_group
* '{' S* declaration? [ ';' S* declaration? ]* '}' S*
- * ;
- */
-
+ * ;
+ */
+
var tokenStream = this._tokenStream,
tt,
selectors;
@@ -2086,7 +2126,7 @@ Parser.prototype = function(){
selectors = this._selectors_group();
} catch (ex){
if (ex instanceof SyntaxError && !this.options.strict){
-
+
//fire error event
this.fire({
type: "error",
@@ -2094,8 +2134,8 @@ Parser.prototype = function(){
message: ex.message,
line: ex.line,
col: ex.col
- });
-
+ });
+
//skip over everything until closing brace
tt = tokenStream.advance([Tokens.RBRACE]);
if (tt == Tokens.RBRACE){
@@ -2103,57 +2143,57 @@ Parser.prototype = function(){
} else {
//otherwise, rethrow the error because it wasn't handled properly
throw ex;
- }
-
+ }
+
} else {
//not a syntax error, rethrow it
throw ex;
- }
-
+ }
+
//trigger parser to continue
return true;
}
-
+
//if it got here, all selectors parsed
- if (selectors){
-
+ if (selectors){
+
this.fire({
type: "startrule",
selectors: selectors,
line: selectors[0].line,
col: selectors[0].col
- });
-
- this._readDeclarations(true);
-
+ });
+
+ this._readDeclarations(true);
+
this.fire({
type: "endrule",
selectors: selectors,
line: selectors[0].line,
col: selectors[0].col
- });
-
+ });
+
}
-
+
return selectors;
-
+
},
//CSS3 Selectors
_selectors_group: function(){
-
- /*
+
+ /*
* selectors_group
* : selector [ COMMA S* selector ]*
* ;
- */
+ */
var tokenStream = this._tokenStream,
selectors = [],
selector;
-
+
selector = this._selector();
if (selector !== null){
-
+
selectors.push(selector);
while(tokenStream.match(Tokens.COMMA)){
this._readWhitespace();
@@ -2168,83 +2208,83 @@ Parser.prototype = function(){
return selectors.length ? selectors : null;
},
-
+
//CSS3 Selectors
_selector: function(){
/*
* selector
* : simple_selector_sequence [ combinator simple_selector_sequence ]*
- * ;
+ * ;
*/
-
+
var tokenStream = this._tokenStream,
selector = [],
nextSelector = null,
combinator = null,
ws = null;
-
+
//if there's no simple selector, then there's no selector
nextSelector = this._simple_selector_sequence();
if (nextSelector === null){
return null;
}
-
+
selector.push(nextSelector);
-
+
do {
-
+
//look for a combinator
combinator = this._combinator();
-
+
if (combinator !== null){
selector.push(combinator);
nextSelector = this._simple_selector_sequence();
-
+
//there must be a next selector
if (nextSelector === null){
this._unexpectedToken(tokenStream.LT(1));
} else {
-
+
//nextSelector is an instance of SelectorPart
selector.push(nextSelector);
}
} 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);
-
+
//combinator is not required
combinator = this._combinator();
-
+
//selector is required if there's a combinator
nextSelector = this._simple_selector_sequence();
- if (nextSelector === null){
+ if (nextSelector === null){
if (combinator !== null){
this._unexpectedToken(tokenStream.LT(1));
}
} else {
-
+
if (combinator !== null){
selector.push(combinator);
} else {
selector.push(ws);
}
-
+
selector.push(nextSelector);
- }
+ }
} else {
break;
- }
-
+ }
+
}
} while(true);
-
+
return new Selector(selector, selector[0].line, selector[0].col);
},
-
+
//CSS3 Selectors
_simple_selector_sequence: function(){
/*
@@ -2254,13 +2294,13 @@ Parser.prototype = function(){
* | [ HASH | class | attrib | pseudo | negation ]+
* ;
*/
-
+
var tokenStream = this._tokenStream,
-
+
//parts of a simple selector
elementName = null,
modifiers = [],
-
+
//complete selector text
selectorText= "",
@@ -2283,35 +2323,35 @@ Parser.prototype = function(){
found = false,
line,
col;
-
-
+
+
//get starting line and column for the selector
line = tokenStream.LT(1).startLine;
col = tokenStream.LT(1).startCol;
-
+
elementName = this._type_selector();
if (!elementName){
elementName = this._universal();
}
-
+
if (elementName !== null){
selectorText += elementName;
- }
-
+ }
+
while(true){
//whitespace means we're done
if (tokenStream.peek() === Tokens.S){
break;
}
-
+
//check for each component
while(i < len && component === null){
component = components[i++].call(this);
}
-
+
if (component === null){
-
+
//we don't have a selector
if (selectorText === ""){
return null;
@@ -2321,17 +2361,17 @@ Parser.prototype = function(){
} else {
i = 0;
modifiers.push(component);
- selectorText += component.toString();
+ selectorText += component.toString();
component = null;
}
}
-
+
return selectorText !== "" ?
new SelectorPart(elementName, modifiers, selectorText, line, col) :
null;
- },
-
+ },
+
//CSS3 Selectors
_type_selector: function(){
/*
@@ -2339,12 +2379,12 @@ Parser.prototype = function(){
* : [ namespace_prefix ]? element_name
* ;
*/
-
+
var tokenStream = this._tokenStream,
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
@@ -2357,9 +2397,9 @@ Parser.prototype = function(){
tokenStream.unget();
}
}
-
+
return null;
- } else {
+ } else {
if (ns){
elementName.text = ns + elementName.text;
elementName.col -= ns.length;
@@ -2367,97 +2407,97 @@ Parser.prototype = function(){
return elementName;
}
},
-
+
//CSS3 Selectors
_class: function(){
/*
* class
* : '.' IDENT
* ;
- */
-
+ */
+
var tokenStream = this._tokenStream,
token;
-
+
if (tokenStream.match(Tokens.DOT)){
- tokenStream.mustMatch(Tokens.IDENT);
+ tokenStream.mustMatch(Tokens.IDENT);
token = tokenStream.token();
- return new SelectorSubPart("." + token.value, "class", token.startLine, token.startCol - 1);
+ return new SelectorSubPart("." + token.value, "class", token.startLine, token.startCol - 1);
} else {
return null;
}
-
+
},
-
+
//CSS3 Selectors
_element_name: function(){
/*
* element_name
* : IDENT
* ;
- */
-
+ */
+
var tokenStream = this._tokenStream,
token;
-
+
if (tokenStream.match(Tokens.IDENT)){
token = tokenStream.token();
- return new SelectorSubPart(token.value, "elementName", token.startLine, token.startCol);
-
+ return new SelectorSubPart(token.value, "elementName", token.startLine, token.startCol);
+
} else {
return null;
}
},
-
+
//CSS3 Selectors
_namespace_prefix: function(){
- /*
+ /*
* namespace_prefix
* : [ IDENT | '*' ]? '|'
* ;
*/
var tokenStream = this._tokenStream,
value = "";
-
+
//verify that this is a namespace prefix
if (tokenStream.LA(1) === Tokens.PIPE || tokenStream.LA(2) === Tokens.PIPE){
-
+
if(tokenStream.match([Tokens.IDENT, Tokens.STAR])){
value += tokenStream.token().value;
}
-
+
tokenStream.mustMatch(Tokens.PIPE);
value += "|";
-
+
}
-
- return value.length ? value : null;
+
+ return value.length ? value : null;
},
-
+
//CSS3 Selectors
_universal: function(){
/*
* universal
* : [ namespace_prefix ]? '*'
- * ;
+ * ;
*/
var tokenStream = this._tokenStream,
value = "",
ns;
-
+
ns = this._namespace_prefix();
if(ns){
value += ns;
}
-
+
if(tokenStream.match(Tokens.STAR)){
value += "*";
}
-
+
return value.length ? value : null;
-
+
},
-
+
//CSS3 Selectors
_attrib: function(){
/*
@@ -2470,69 +2510,69 @@ Parser.prototype = function(){
* INCLUDES |
* DASHMATCH ] S* [ IDENT | STRING ] S*
* ]? ']'
- * ;
+ * ;
*/
-
+
var tokenStream = this._tokenStream,
value = null,
ns,
token;
-
+
if (tokenStream.match(Tokens.LBRACKET)){
token = tokenStream.token();
value = token.value;
value += this._readWhitespace();
-
+
ns = this._namespace_prefix();
-
+
if (ns){
value += ns;
}
-
+
tokenStream.mustMatch(Tokens.IDENT);
- value += tokenStream.token().value;
+ value += tokenStream.token().value;
value += this._readWhitespace();
-
+
if(tokenStream.match([Tokens.PREFIXMATCH, Tokens.SUFFIXMATCH, Tokens.SUBSTRINGMATCH,
Tokens.EQUALS, Tokens.INCLUDES, Tokens.DASHMATCH])){
-
- value += tokenStream.token().value;
+
+ value += tokenStream.token().value;
value += this._readWhitespace();
-
+
tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]);
- value += tokenStream.token().value;
+ value += tokenStream.token().value;
value += this._readWhitespace();
}
-
+
tokenStream.mustMatch(Tokens.RBRACKET);
-
+
return new SelectorSubPart(value + "]", "attribute", token.startLine, token.startCol);
} else {
return null;
}
},
-
+
//CSS3 Selectors
_pseudo: function(){
-
+
/*
* pseudo
* : ':' ':'? [ IDENT | functional_pseudo ]
- * ;
- */
-
+ * ;
+ */
+
var tokenStream = this._tokenStream,
pseudo = null,
colons = ":",
line,
col;
-
+
if (tokenStream.match(Tokens.COLON)){
-
+
if (tokenStream.match(Tokens.COLON)){
colons += ":";
}
-
+
if (tokenStream.match(Tokens.IDENT)){
pseudo = tokenStream.token().value;
line = tokenStream.token().startLine;
@@ -2542,26 +2582,26 @@ Parser.prototype = function(){
col = tokenStream.LT(1).startCol - colons.length;
pseudo = this._functional_pseudo();
}
-
+
if (pseudo){
pseudo = new SelectorSubPart(colons + pseudo, "pseudo", line, col);
}
}
-
+
return pseudo;
},
-
+
//CSS3 Selectors
_functional_pseudo: function(){
/*
* functional_pseudo
* : FUNCTION S* expression ')'
* ;
- */
-
+ */
+
var tokenStream = this._tokenStream,
value = null;
-
+
if(tokenStream.match(Tokens.FUNCTION)){
value = tokenStream.token().value;
value += this._readWhitespace();
@@ -2569,10 +2609,10 @@ Parser.prototype = function(){
tokenStream.mustMatch(Tokens.RPAREN);
value += ")";
}
-
+
return value;
},
-
+
//CSS3 Selectors
_expression: function(){
/*
@@ -2580,26 +2620,26 @@ Parser.prototype = function(){
* : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
* ;
*/
-
+
var tokenStream = this._tokenStream,
value = "";
-
+
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])){
-
+
value += tokenStream.token().value;
- value += this._readWhitespace();
+ value += this._readWhitespace();
}
-
+
return value.length ? value : null;
-
+
},
//CSS3 Selectors
_negation: function(){
- /*
+ /*
* negation
* : NOT S* negation_arg S* ')'
* ;
@@ -2611,7 +2651,7 @@ Parser.prototype = function(){
value = "",
arg,
subpart = null;
-
+
if (tokenStream.match(Tokens.NOT)){
value = tokenStream.token().value;
line = tokenStream.token().startLine;
@@ -2622,22 +2662,22 @@ Parser.prototype = function(){
value += this._readWhitespace();
tokenStream.match(Tokens.RPAREN);
value += tokenStream.token().value;
-
+
subpart = new SelectorSubPart(value, "not", line, col);
subpart.args.push(arg);
}
-
+
return subpart;
},
-
+
//CSS3 Selectors
- _negation_arg: function(){
+ _negation_arg: function(){
/*
* negation_arg
* : type_selector | universal | HASH | class | attrib | pseudo
- * ;
- */
-
+ * ;
+ */
+
var tokenStream = this._tokenStream,
args = [
this._type_selector,
@@ -2645,11 +2685,11 @@ Parser.prototype = function(){
function(){
return tokenStream.match(Tokens.HASH) ?
new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) :
- null;
+ null;
},
this._class,
this._attrib,
- this._pseudo
+ this._pseudo
],
arg = null,
i = 0,
@@ -2658,40 +2698,40 @@ Parser.prototype = function(){
line,
col,
part;
-
+
line = tokenStream.LT(1).startLine;
col = tokenStream.LT(1).startCol;
-
+
while(i < len && arg === null){
-
+
arg = args[i].call(this);
i++;
}
-
+
//must be a negation arg
if (arg === null){
this._unexpectedToken(tokenStream.LT(1));
}
-
+
//it's an element name
if (arg.type == "elementName"){
part = new SelectorPart(arg, [], arg.toString(), line, col);
} else {
part = new SelectorPart(null, [arg], arg.toString(), line, col);
}
-
- return part;
+
+ return part;
},
-
+
_declaration: function(){
-
+
/*
* declaration
* : property ':' S* expr prio?
* | /( empty )/
- * ;
- */
-
+ * ;
+ */
+
var tokenStream = this._tokenStream,
property = null,
expr = null,
@@ -2699,22 +2739,22 @@ Parser.prototype = function(){
error = null,
invalid = null,
propertyName= "";
-
+
property = this._property();
if (property !== null){
tokenStream.mustMatch(Tokens.COLON);
this._readWhitespace();
-
+
expr = this._expr();
-
+
//if there's no parts for the value, it's an error
if (!expr || expr.length === 0){
this._unexpectedToken(tokenStream.LT(1));
}
-
+
prio = this._prio();
-
+
/*
* If hacks should be allowed, then only check the root
* property. If hacks should not be allowed, treat
@@ -2723,16 +2763,16 @@ Parser.prototype = function(){
propertyName = property.toString();
if (this.options.starHack && property.hack == "*" ||
this.options.underscoreHack && property.hack == "_") {
-
+
propertyName = property.text;
}
-
+
try {
this._validateProperty(propertyName, expr);
} catch (ex) {
invalid = ex;
}
-
+
this.fire({
type: "property",
property: property,
@@ -2741,46 +2781,46 @@ Parser.prototype = function(){
line: property.line,
col: property.col,
invalid: invalid
- });
-
+ });
+
return true;
} else {
return false;
}
},
-
+
_prio: function(){
/*
* prio
* : IMPORTANT_SYM S*
- * ;
+ * ;
*/
-
+
var tokenStream = this._tokenStream,
result = tokenStream.match(Tokens.IMPORTANT_SYM);
-
+
this._readWhitespace();
return result;
},
-
+
_expr: function(inFunction){
/*
* expr
* : term [ operator term ]*
* ;
*/
-
+
var tokenStream = this._tokenStream,
values = [],
//valueParts = [],
value = null,
operator = null;
-
+
value = this._term();
if (value !== null){
-
+
values.push(value);
-
+
do {
operator = this._operator(inFunction);
@@ -2792,9 +2832,9 @@ Parser.prototype = function(){
values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col));
valueParts = [];
}*/
-
+
value = this._term();
-
+
if (value === null){
break;
} else {
@@ -2802,17 +2842,17 @@ Parser.prototype = function(){
}
} while(true);
}
-
+
//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(){
-
+
+ _term: function(){
+
/*
* term
* : unary_operator?
@@ -2820,36 +2860,36 @@ Parser.prototype = function(){
* TIME S* | FREQ S* | function | ie_function ]
* | STRING S* | IDENT S* | URI S* | UNICODERANGE S* | hexcolor
* ;
- */
-
+ */
+
var tokenStream = this._tokenStream,
unary = null,
value = null,
token,
line,
col;
-
+
//returns the operator or null
unary = this._unary_operator();
if (unary !== null){
line = tokenStream.token().startLine;
col = tokenStream.token().startCol;
- }
-
+ }
+
//exception for IE filters
if (tokenStream.peek() == Tokens.IE_FUNCTION && this.options.ieFilters){
-
+
value = this._ie_function();
if (unary === null){
line = tokenStream.token().startLine;
col = tokenStream.token().startCol;
}
-
+
//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])){
-
+
value = tokenStream.token().value;
if (unary === null){
line = tokenStream.token().startLine;
@@ -2857,20 +2897,20 @@ Parser.prototype = function(){
}
this._readWhitespace();
} else {
-
+
//see if it's a color
token = this._hexcolor();
if (token === null){
-
+
//if there's no unary, get the start of the next token for line/col info
if (unary === null){
line = tokenStream.LT(1).startLine;
col = tokenStream.LT(1).startCol;
- }
-
+ }
+
//has to be a function
if (value === null){
-
+
/*
* This checks for alpha(opacity=0) style of IE
* functions. IE_FUNCTION only presents progid: style.
@@ -2886,61 +2926,61 @@ Parser.prototype = function(){
return null;
//throw new Error("Expected identifier at line " + tokenStream.token().startLine + ", character " + tokenStream.token().startCol + ".");
}*/
-
+
} else {
value = token.value;
if (unary === null){
line = token.startLine;
col = token.startCol;
- }
+ }
}
-
- }
-
+
+ }
+
return value !== null ?
new PropertyValuePart(unary !== null ? unary + value : value, line, col) :
null;
-
+
},
-
+
_function: function(){
-
+
/*
* function
* : FUNCTION S* expr ')' S*
* ;
*/
-
+
var tokenStream = this._tokenStream,
functionText = null,
expr = null,
lt;
-
+
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){
do {
-
+
if (this._readWhitespace()){
functionText += tokenStream.token().value;
}
-
+
//might be second time in the loop
if (tokenStream.LA(0) == Tokens.COMMA){
functionText += tokenStream.token().value;
}
-
+
tokenStream.match(Tokens.IDENT);
functionText += tokenStream.token().value;
-
+
tokenStream.match(Tokens.EQUALS);
functionText += tokenStream.token().value;
-
+
//functionText += this._term();
lt = tokenStream.peek();
while(lt != Tokens.COMMA && lt != Tokens.S && lt != Tokens.RPAREN){
@@ -2952,49 +2992,49 @@ Parser.prototype = function(){
}
//END: Horrible Hack
-
- tokenStream.match(Tokens.RPAREN);
+
+ tokenStream.match(Tokens.RPAREN);
functionText += ")";
this._readWhitespace();
- }
-
+ }
+
return functionText;
- },
-
+ },
+
_ie_function: function(){
-
+
/* (My own extension)
* ie_function
* : IE_FUNCTION S* IDENT '=' term [S* ','? IDENT '=' term]+ ')' S*
* ;
*/
-
+
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])){
functionText = tokenStream.token().value;
-
+
do {
-
+
if (this._readWhitespace()){
functionText += tokenStream.token().value;
}
-
+
//might be second time in the loop
if (tokenStream.LA(0) == Tokens.COMMA){
functionText += tokenStream.token().value;
}
-
+
tokenStream.match(Tokens.IDENT);
functionText += tokenStream.token().value;
-
+
tokenStream.match(Tokens.EQUALS);
functionText += tokenStream.token().value;
-
+
//functionText += this._term();
lt = tokenStream.peek();
while(lt != Tokens.COMMA && lt != Tokens.S && lt != Tokens.RPAREN){
@@ -3002,16 +3042,16 @@ Parser.prototype = function(){
functionText += tokenStream.token().value;
lt = tokenStream.peek();
}
- } while(tokenStream.match([Tokens.COMMA, Tokens.S]));
-
- tokenStream.match(Tokens.RPAREN);
+ } while(tokenStream.match([Tokens.COMMA, Tokens.S]));
+
+ tokenStream.match(Tokens.RPAREN);
functionText += ")";
this._readWhitespace();
- }
-
+ }
+
return functionText;
- },
-
+ },
+
_hexcolor: function(){
/*
* There is a constraint on the color that it must
@@ -3022,15 +3062,15 @@ Parser.prototype = function(){
* : HASH S*
* ;
*/
-
+
var tokenStream = this._tokenStream,
token = null,
color;
-
+
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)){
@@ -3038,16 +3078,16 @@ Parser.prototype = function(){
}
this._readWhitespace();
}
-
+
return token;
},
-
+
//-----------------------------------------------------------------
// Animations methods
//-----------------------------------------------------------------
-
+
_keyframes: function(){
-
+
/*
* keyframes:
* : KEYFRAMES_SYM S* keyframe_name S* '{' S* keyframe_rule* '}' {
@@ -3057,53 +3097,53 @@ Parser.prototype = function(){
token,
tt,
name,
- prefix = "";
-
+ prefix = "";
+
tokenStream.mustMatch(Tokens.KEYFRAMES_SYM);
token = tokenStream.token();
if (/^@\-([^\-]+)\-/.test(token.value)) {
prefix = RegExp.$1;
}
-
+
this._readWhitespace();
name = this._keyframe_name();
-
+
this._readWhitespace();
tokenStream.mustMatch(Tokens.LBRACE);
-
+
this.fire({
type: "startkeyframes",
name: name,
prefix: prefix,
line: token.startLine,
col: token.startCol
- });