Skip to content

Commit 2ec2ebb

Browse files
author
Nicholas C. Zakas
committed
Updated parser to fix a few small parsing bugs
1 parent 312f54b commit 2ec2ebb

1 file changed

Lines changed: 57 additions & 29 deletions

File tree

lib/parserlib.js

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2121
THE SOFTWARE.
2222
2323
*/
24-
/* Build time: 16-November-2011 01:11:51 */
24+
/* Version v@VERSION@, Build time: 17-November-2011 10:55:53 */
2525
var parserlib = {};
2626
(function(){
2727

@@ -493,6 +493,8 @@ SyntaxUnit.prototype = {
493493
}
494494

495495
};
496+
/*global StringReader, SyntaxError*/
497+
496498
/**
497499
* Generic TokenStream providing base functionality.
498500
* @class TokenStreamBase
@@ -509,7 +511,6 @@ function TokenStreamBase(input, tokenData){
509511
* @property _reader
510512
* @private
511513
*/
512-
//this._reader = (typeof input == "string") ? new StringReader(input) : input;
513514
this._reader = input ? new StringReader(input.toString()) : null;
514515

515516
/**
@@ -675,7 +676,7 @@ TokenStreamBase.prototype = {
675676
*/
676677
advance: function(tokenTypes, channel){
677678

678-
while(this.LA(0) != 0 && !this.match(tokenTypes, channel)){
679+
while(this.LA(0) !== 0 && !this.match(tokenTypes, channel)){
679680
this.get();
680681
}
681682

@@ -925,7 +926,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
925926
THE SOFTWARE.
926927
927928
*/
928-
/* Build time: 16-November-2011 01:11:51 */
929+
/* Version v@VERSION@, Build time: 17-November-2011 10:55:53 */
929930
(function(){
930931
var EventTarget = parserlib.util.EventTarget,
931932
TokenStreamBase = parserlib.util.TokenStreamBase,
@@ -1075,6 +1076,7 @@ var Colors = {
10751076
yellow :"#ffff00",
10761077
yellowgreen :"#9acd32"
10771078
};
1079+
/*global SyntaxUnit, Parser*/
10781080
/**
10791081
* Represents a selector combinator (whitespace, +, >).
10801082
* @namespace parserlib.css
@@ -1112,6 +1114,7 @@ function Combinator(text, line, col){
11121114
Combinator.prototype = new SyntaxUnit();
11131115
Combinator.prototype.constructor = Combinator;
11141116

1117+
/*global SyntaxUnit, Parser*/
11151118
/**
11161119
* Represents a media feature, such as max-width:500.
11171120
* @namespace parserlib.css
@@ -1143,6 +1146,7 @@ function MediaFeature(name, value){
11431146
MediaFeature.prototype = new SyntaxUnit();
11441147
MediaFeature.prototype.constructor = MediaFeature;
11451148

1149+
/*global SyntaxUnit, Parser*/
11461150
/**
11471151
* Represents an individual media query.
11481152
* @namespace parserlib.css
@@ -1185,6 +1189,10 @@ function MediaQuery(modifier, mediaType, features, line, col){
11851189
MediaQuery.prototype = new SyntaxUnit();
11861190
MediaQuery.prototype.constructor = MediaQuery;
11871191

1192+
/*global Tokens, TokenStream, SyntaxError, Properties, ValidationError, SyntaxUnit,
1193+
PropertyValue, PropertyValuePart, SelectorPart, SelectorSubPart, Selector,
1194+
PropertyName, Combinator, MediaFeature, MediaQuery, EventTarget */
1195+
11881196
/**
11891197
* A CSS3 parser.
11901198
* @namespace parserlib.css
@@ -1332,7 +1340,7 @@ Parser.prototype = function(){
13321340

13331341
} else {
13341342
//not a syntax error, rethrow it
1335-
throw new SyntaxError("Unknown @ rule.", tokenStream.LT(0).startLine, tokenStream.LT(0).startCol);;
1343+
throw new SyntaxError("Unknown @ rule.", tokenStream.LT(0).startLine, tokenStream.LT(0).startCol);
13361344
}
13371345
break;
13381346
case Tokens.S:
@@ -3195,10 +3203,9 @@ Parser.prototype = function(){
31953203
tt = tokenStream.advance([Tokens.SEMICOLON, Tokens.RBRACE]);
31963204
if (tt == Tokens.SEMICOLON){
31973205
//if there's a semicolon, then there might be another declaration
3198-
this._readDeclarations(false, readMargins);
3199-
} else if (tt == Tokens.RBRACE){
3206+
this._readDeclarations(false, readMargins);
3207+
} else if (tt != Tokens.RBRACE){
32003208
//if there's a right brace, the rule is finished so don't do anything
3201-
} else {
32023209
//otherwise, rethrow the error because it wasn't handled properly
32033210
throw ex;
32043211
}
@@ -3373,13 +3380,27 @@ Parser.prototype = function(){
33733380

33743381
//otherwise return result
33753382
return result;
3383+
},
3384+
3385+
/**
3386+
* Parses an HTML style attribute: a set of CSS declarations
3387+
* separated by semicolons.
3388+
* @param {String} input The text to parse as a style attribute
3389+
* @return {void}
3390+
* @method parseStyleAttribute
3391+
*/
3392+
parseStyleAttribute: function(input){
3393+
input += "}"; // for error recovery in _readDeclarations()
3394+
this._tokenStream = new TokenStream(input, Tokens);
3395+
this._readDeclarations();
33763396
}
3377-
33783397
};
33793398

33803399
//copy over onto prototype
33813400
for (prop in additions){
3382-
proto[prop] = additions[prop];
3401+
if (additions.hasOwnProperty(prop)){
3402+
proto[prop] = additions[prop];
3403+
}
33833404
}
33843405

33853406
return proto;
@@ -3393,6 +3414,7 @@ nth
33933414
;
33943415
*/
33953416
//This file will likely change a lot! Very experimental!
3417+
/*global ValidationError*/
33963418

33973419
var ValidationType = {
33983420

@@ -3927,6 +3949,7 @@ var Properties = {
39273949
}
39283950
}
39293951
})();
3952+
/*global SyntaxUnit, Parser*/
39303953
/**
39313954
* Represents a selector combinator (whitespace, +, >).
39323955
* @namespace parserlib.css
@@ -3956,6 +3979,7 @@ PropertyName.prototype.constructor = PropertyName;
39563979
PropertyName.prototype.toString = function(){
39573980
return (this.hack ? this.hack : "") + this.text;
39583981
};
3982+
/*global SyntaxUnit, Parser*/
39593983
/**
39603984
* Represents a single part of a CSS property value, meaning that it represents
39613985
* just everything single part between ":" and ";". If there are multiple values
@@ -3984,6 +4008,7 @@ function PropertyValue(parts, line, col){
39844008
PropertyValue.prototype = new SyntaxUnit();
39854009
PropertyValue.prototype.constructor = PropertyValue;
39864010

4011+
/*global SyntaxUnit, Parser, Colors*/
39874012
/**
39884013
* Represents a single part of a CSS property value, meaning that it represents
39894014
* just one part of the data between ":" and ";".
@@ -4137,7 +4162,7 @@ function PropertyValuePart(text, line, col){
41374162
}
41384163

41394164
PropertyValuePart.prototype = new SyntaxUnit();
4140-
PropertyValuePart.prototype.constructor = PropertyValue;
4165+
PropertyValuePart.prototype.constructor = PropertyValuePart;
41414166

41424167
/**
41434168
* Create a new syntax unit based solely on the given token.
@@ -4164,6 +4189,7 @@ Pseudos.CLASS = 2;
41644189
Pseudos.isElement = function(pseudo){
41654190
return pseudo.indexOf("::") === 0 || Pseudos[pseudo.toLowerCase()] == Pseudos.ELEMENT;
41664191
};
4192+
/*global SyntaxUnit, Parser, Specificity*/
41674193
/**
41684194
* Represents an entire single selector, including all parts but not
41694195
* including multiple selectors (those separated by commas).
@@ -4198,6 +4224,7 @@ function Selector(parts, line, col){
41984224
Selector.prototype = new SyntaxUnit();
41994225
Selector.prototype.constructor = Selector;
42004226

4227+
/*global SyntaxUnit, Parser*/
42014228
/**
42024229
* Represents a single part of a selector string, meaning a single set of
42034230
* element name and modifiers. This does not include combinators such as
@@ -4239,6 +4266,7 @@ function SelectorPart(elementName, modifiers, text, line, col){
42394266
SelectorPart.prototype = new SyntaxUnit();
42404267
SelectorPart.prototype.constructor = SelectorPart;
42414268

4269+
/*global SyntaxUnit, Parser*/
42424270
/**
42434271
* Represents a selector modifier string, meaning a class name, element name,
42444272
* element ID, pseudo rule, etc.
@@ -4274,6 +4302,7 @@ function SelectorSubPart(text, type, line, col){
42744302
SelectorSubPart.prototype = new SyntaxUnit();
42754303
SelectorSubPart.prototype.constructor = SelectorSubPart;
42764304

4305+
/*global Pseudos, SelectorPart*/
42774306
/**
42784307
* Represents a selector's specificity.
42794308
* @namespace parserlib.css
@@ -4345,14 +4374,16 @@ Specificity.prototype = {
43454374
Specificity.calculate = function(selector){
43464375

43474376
var i, len,
4377+
part,
43484378
b=0, c=0, d=0;
43494379

43504380
function updateValues(part){
43514381

43524382
var i, j, len, num,
4383+
elementName = part.elementName ? part.elementName.text : "",
43534384
modifier;
43544385

4355-
if (part.elementName && part.text.charAt(part.text.length-1) != "*") {
4386+
if (elementName && elementName.charAt(elementName.length-1) != "*") {
43564387
d++;
43574388
}
43584389

@@ -4394,7 +4425,7 @@ Specificity.calculate = function(selector){
43944425

43954426
return new Specificity(0, b, c, d);
43964427
};
4397-
4428+
/*global Tokens, TokenStreamBase*/
43984429

43994430
var h = /^[0-9a-fA-F]$/,
44004431
nonascii = /^[\u0080-\uFFFF]$/,
@@ -4406,31 +4437,31 @@ var h = /^[0-9a-fA-F]$/,
44064437

44074438

44084439
function isHexDigit(c){
4409-
return c != null && h.test(c);
4440+
return c !== null && h.test(c);
44104441
}
44114442

44124443
function isDigit(c){
4413-
return c != null && /\d/.test(c);
4444+
return c !== null && /\d/.test(c);
44144445
}
44154446

44164447
function isWhitespace(c){
4417-
return c != null && /\s/.test(c);
4448+
return c !== null && /\s/.test(c);
44184449
}
44194450

44204451
function isNewLine(c){
4421-
return c != null && nl.test(c);
4452+
return c !== null && nl.test(c);
44224453
}
44234454

44244455
function isNameStart(c){
4425-
return c != null && (/[a-z_\u0080-\uFFFF\\]/i.test(c));
4456+
return c !== null && (/[a-z_\u0080-\uFFFF\\]/i.test(c));
44264457
}
44274458

44284459
function isNameChar(c){
4429-
return c != null && (isNameStart(c) || /[0-9\-\\]/.test(c));
4460+
return c !== null && (isNameStart(c) || /[0-9\-\\]/.test(c));
44304461
}
44314462

44324463
function isIdentStart(c){
4433-
return c != null && (isNameStart(c) || /\-\\/.test(c));
4464+
return c !== null && (isNameStart(c) || /\-\\/.test(c));
44344465
}
44354466

44364467
function mix(receiver, supplier){
@@ -4621,8 +4652,7 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
46214652
token = this.unicodeRangeToken(c, startLine, startCol);
46224653
break;
46234654
}
4624-
/*falls through*/
4625-
4655+
/* falls through */
46264656
default:
46274657

46284658
/*
@@ -4675,11 +4705,9 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
46754705
//make sure this token is wanted
46764706
//TODO: check channel
46774707
break;
4678-
4679-
c = reader.read();
46804708
}
46814709

4682-
if (!token && c == null){
4710+
if (!token && c === null){
46834711
token = this.createToken(Tokens.EOF,null,startLine,startCol);
46844712
}
46854713

@@ -4963,7 +4991,7 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
49634991
break;
49644992
} else {
49654993
temp = this.readComment(c);
4966-
if (temp == ""){ //broken!
4994+
if (temp === ""){ //broken!
49674995
break;
49684996
}
49694997
}
@@ -5104,7 +5132,7 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
51045132
}
51055133

51065134
//if c is null, that means we're out of input and the string was never closed
5107-
if (c == null){
5135+
if (c === null){
51085136
tt = Tokens.INVALID;
51095137
}
51105138

@@ -5269,7 +5297,7 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
52695297
}
52705298

52715299
//if c is null, that means we're out of input and the string was never closed
5272-
if (c == null){
5300+
if (c === null){
52735301
string = "";
52745302
}
52755303

@@ -5305,7 +5333,7 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
53055333
}
53065334

53075335
//if there was no inner value or the next character isn't closing paren, it's not a URI
5308-
if (inner == "" || c != ")"){
5336+
if (inner === "" || c != ")"){
53095337
uri = first;
53105338
reader.reset();
53115339
} else {

0 commit comments

Comments
 (0)