Best JavaScript code snippet using playwright-internal
parse-css.js
Source:parse-css.js
...27 this.message = message;28};29InvalidCharacterError.prototype = new Error;30InvalidCharacterError.prototype.name = 'InvalidCharacterError';31function stringFromCode(code) {32 if(code <= 0xffff) return String.fromCharCode(code);33 // Otherwise, encode astral char as surrogate pair.34 code -= Math.pow(2, 20);35 var lead = Math.floor(code/Math.pow(2, 10)) + 0xd800;36 var trail = code % Math.pow(2, 10) + 0xdc00;37 return String.fromCharCode(lead) + String.fromCharCode(trail);38}39function* tokenize(str, options) {40 if (options === undefined) {41 options = {};42 }43 if (options.loc === undefined) {44 options.loc = false;45 }46 if (options.offsets === undefined) {47 options.offsets = false;48 }49 if (options.keepComments === undefined) {50 options.keepComments = false;51 }52 if (options.startOffset === undefined) {53 options.startOffset = 0;54 }55 var i = options.startOffset - 1;56 var code;57 // Line number information.58 var line = 0;59 var column = 0;60 // The only use of lastLineLength is in reconsume().61 var lastLineLength = 0;62 var incrLineno = function() {63 line += 1;64 lastLineLength = column;65 column = 0;66 };67 var locStart = {line:line, column:column};68 var offsetStart = i;69 var codepoint = function(i) {70 if(i >= str.length) {71 return -1;72 }73 return str.charCodeAt(i);74 };75 var next = function(num) {76 if(num === undefined)77 num = 1;78 if(num > 3)79 throw "Spec Error: no more than three codepoints of lookahead.";80 var rcode;81 for (var offset = i + 1; num-- > 0; ++offset) {82 rcode = codepoint(offset);83 if (rcode === 0xd && codepoint(offset+1) === 0xa) {84 ++offset;85 rcode = 0xa;86 } else if (rcode === 0xd || rcode === 0xc) {87 rcode = 0xa;88 } else if (rcode === 0x0) {89 rcode = 0xfffd;90 }91 }92 return rcode;93 };94 var consume = function(num) {95 if(num === undefined)96 num = 1;97 while(num-- > 0) {98 ++i;99 code = codepoint(i);100 if (code === 0xd && codepoint(i+1) === 0xa) {101 ++i;102 code = 0xa;103 } else if (code === 0xd || code === 0xc) {104 code = 0xa;105 } else if (code === 0x0) {106 code = 0xfffd;107 }108 if(newline(code)) incrLineno();109 else column++;110 }111 return true;112 };113 var reconsume = function() {114 i -= 1; // This is ok even in the \r\n case.115 if (newline(code)) {116 line -= 1;117 column = lastLineLength;118 } else {119 column -= 1;120 }121 return true;122 };123 var eof = function(codepoint) {124 if(codepoint === undefined) codepoint = code;125 return codepoint == -1;126 };127 var donothing = function() {};128 var parseerror = function() { console.log("Parse error at index " + i + ", processing codepoint 0x" + code.toString(16) + ".");return true; };129 var consumeAToken = function() {130 consume();131 if (!options.keepComments) {132 while(code == 0x2f && next() == 0x2a) {133 consumeAComment();134 consume();135 }136 }137 locStart.line = line;138 locStart.column = column;139 offsetStart = i;140 if(whitespace(code)) {141 while(whitespace(next())) consume();142 return new WhitespaceToken;143 }144 else if(code == 0x2f && next() == 0x2a) return consumeAComment();145 else if(code == 0x22) return consumeAStringToken();146 else if(code == 0x23) {147 if(namechar(next()) || areAValidEscape(next(1), next(2))) {148 var token = new HashToken();149 if(wouldStartAnIdentifier(next(1), next(2), next(3))) {150 token.type = "id";151 token.tokenType = "id";152 }153 token.value = consumeAName();154 token.text = token.value;155 return token;156 } else {157 return new DelimToken(code);158 }159 }160 else if(code == 0x24) {161 if(next() == 0x3d) {162 consume();163 return new SuffixMatchToken();164 } else {165 return new DelimToken(code);166 }167 }168 else if(code == 0x27) return consumeAStringToken();169 else if(code == 0x28) return new OpenParenToken();170 else if(code == 0x29) return new CloseParenToken();171 else if(code == 0x2a) {172 if(next() == 0x3d) {173 consume();174 return new SubstringMatchToken();175 } else {176 return new DelimToken(code);177 }178 }179 else if(code == 0x2b) {180 if(startsWithANumber()) {181 reconsume();182 return consumeANumericToken();183 } else {184 return new DelimToken(code);185 }186 }187 else if(code == 0x2c) return new CommaToken();188 else if(code == 0x2d) {189 if(startsWithANumber()) {190 reconsume();191 return consumeANumericToken();192 } else if(next(1) == 0x2d && next(2) == 0x3e) {193 consume(2);194 return new CDCToken();195 } else if(startsWithAnIdentifier()) {196 reconsume();197 return consumeAnIdentlikeToken();198 } else {199 return new DelimToken(code);200 }201 }202 else if(code == 0x2e) {203 if(startsWithANumber()) {204 reconsume();205 return consumeANumericToken();206 } else {207 return new DelimToken(code);208 }209 }210 else if(code == 0x3a) return new ColonToken;211 else if(code == 0x3b) return new SemicolonToken;212 else if(code == 0x3c) {213 if(next(1) == 0x21 && next(2) == 0x2d && next(3) == 0x2d) {214 consume(3);215 return new CDOToken();216 } else {217 return new DelimToken(code);218 }219 }220 else if(code == 0x40) {221 if(wouldStartAnIdentifier(next(1), next(2), next(3))) {222 return new AtKeywordToken(consumeAName());223 } else {224 return new DelimToken(code);225 }226 }227 else if(code == 0x5b) return new OpenSquareToken();228 else if(code == 0x5c) {229 if(startsWithAValidEscape()) {230 reconsume();231 return consumeAnIdentlikeToken();232 } else {233 parseerror();234 return new DelimToken(code);235 }236 }237 else if(code == 0x5d) return new CloseSquareToken();238 else if(code == 0x5e) {239 if(next() == 0x3d) {240 consume();241 return new PrefixMatchToken();242 } else {243 return new DelimToken(code);244 }245 }246 else if(code == 0x7b) return new OpenCurlyToken();247 else if(code == 0x7c) {248 if(next() == 0x3d) {249 consume();250 return new DashMatchToken();251 // } else if(next() == 0x7c) {252 // consume();253 // return new ColumnToken();254 } else {255 return new DelimToken(code);256 }257 }258 else if(code == 0x7d) return new CloseCurlyToken();259 else if(code == 0x7e) {260 if(next() == 0x3d) {261 consume();262 return new IncludeMatchToken();263 } else {264 return new DelimToken(code);265 }266 }267 else if(digit(code)) {268 reconsume();269 return consumeANumericToken();270 }271 else if(namestartchar(code)) {272 reconsume();273 return consumeAnIdentlikeToken();274 }275 else if(eof()) return new EOFToken();276 else return new DelimToken(code);277 };278 var consumeAComment = function() {279 consume();280 var comment = "";281 while(true) {282 consume();283 if(code == 0x2a && next() == 0x2f) {284 consume();285 break;286 } else if(eof()) {287 break;288 }289 comment += stringFromCode(code);290 }291 return new CommentToken(comment);292 };293 var consumeANumericToken = function() {294 var num = consumeANumber();295 var token;296 if(wouldStartAnIdentifier(next(1), next(2), next(3))) {297 token = new DimensionToken();298 token.value = num.value;299 token.repr = num.repr;300 token.type = num.type;301 token.unit = consumeAName();302 token.text = token.unit;303 } else if(next() == 0x25) {304 consume();305 token = new PercentageToken();306 token.value = num.value;307 token.repr = num.repr;308 } else {309 var token = new NumberToken();310 token.value = num.value;311 token.repr = num.repr;312 token.type = num.type;313 }314 token.number = token.value;315 token.isInteger = token.type === "integer";316 // FIXME hasSign317 return token;318 };319 var consumeAnIdentlikeToken = function() {320 var str = consumeAName();321 if(str.toLowerCase() == "url" && next() == 0x28) {322 consume();323 while(whitespace(next(1)) && whitespace(next(2)))324 consume();325 if((next() == 0x22 || next() == 0x27) ||326 (whitespace(next()) && (next(2) == 0x22 || next(2) == 0x27))) {327 while(whitespace(next()))328 consume();329 consume();330 let str = consumeAStringToken();331 while(whitespace(next()))332 consume();333 // The closing paren.334 consume();335 return new URLToken(str.text);336 } else {337 return consumeAURLToken();338 }339 } else if(next() == 0x28) {340 consume();341 return new FunctionToken(str);342 } else {343 return new IdentToken(str);344 }345 };346 var consumeAStringToken = function(endingCodePoint) {347 if(endingCodePoint === undefined) endingCodePoint = code;348 var string = "";349 while(consume()) {350 if(code == endingCodePoint || eof()) {351 return new StringToken(string);352 } else if(newline(code)) {353 reconsume();354 return new BadStringToken(string);355 } else if(code == 0x5c) {356 if(eof(next())) {357 donothing();358 } else if(newline(next())) {359 consume();360 } else {361 string += stringFromCode(consumeEscape());362 }363 } else {364 string += stringFromCode(code);365 }366 }367 };368 var consumeAURLToken = function() {369 var token = new URLToken("");370 while(whitespace(next())) consume();371 if(eof(next())) return token;372 while(consume()) {373 if(code == 0x29 || eof()) {374 break;375 } else if(whitespace(code)) {376 while(whitespace(next()))377 consume();378 if(next() == 0x29 || eof(next())) {379 consume();380 break;381 } else {382 consumeTheRemnantsOfABadURL();383 return new BadURLToken();384 }385 } else if(code == 0x22 || code == 0x27 || code == 0x28 || nonprintable(code)) {386 parseerror();387 consumeTheRemnantsOfABadURL();388 return new BadURLToken();389 } else if(code == 0x5c) {390 if(startsWithAValidEscape()) {391 token.value += stringFromCode(consumeEscape());392 } else {393 parseerror();394 consumeTheRemnantsOfABadURL();395 return new BadURLToken();396 }397 } else {398 token.value += stringFromCode(code);399 }400 }401 token.text = token.value;402 return token;403 };404 var consumeEscape = function() {405 // Assume the the current character is the \406 // and the next code point is not a newline.407 consume();408 if(hexdigit(code)) {409 // Consume 1-6 hex digits410 var digits = [code];411 for(var total = 0; total < 5; total++) {412 if(hexdigit(next())) {413 consume();414 digits.push(code);415 } else {416 break;417 }418 }419 if(whitespace(next())) consume();420 var value = parseInt(digits.map(function(x){return String.fromCharCode(x);}).join(''), 16);421 if( value > maximumallowedcodepoint ) value = 0xfffd;422 return value;423 } else if(eof()) {424 return 0xfffd;425 } else {426 return code;427 }428 };429 var areAValidEscape = function(c1, c2) {430 if(c1 != 0x5c) return false;431 if(newline(c2)) return false;432 return true;433 };434 var startsWithAValidEscape = function() {435 return areAValidEscape(code, next());436 };437 var wouldStartAnIdentifier = function(c1, c2, c3) {438 if(c1 == 0x2d) {439 return namestartchar(c2) || c2 == 0x2d || areAValidEscape(c2, c3);440 } else if(namestartchar(c1)) {441 return true;442 } else if(c1 == 0x5c) {443 return areAValidEscape(c1, c2);444 } else {445 return false;446 }447 };448 var startsWithAnIdentifier = function() {449 return wouldStartAnIdentifier(code, next(1), next(2));450 };451 var wouldStartANumber = function(c1, c2, c3) {452 if(c1 == 0x2b || c1 == 0x2d) {453 if(digit(c2)) return true;454 if(c2 == 0x2e && digit(c3)) return true;455 return false;456 } else if(c1 == 0x2e) {457 if(digit(c2)) return true;458 return false;459 } else if(digit(c1)) {460 return true;461 } else {462 return false;463 }464 };465 var startsWithANumber = function() {466 return wouldStartANumber(code, next(1), next(2));467 };468 var consumeAName = function() {469 var result = "";470 while(consume()) {471 if(namechar(code)) {472 result += stringFromCode(code);473 } else if(startsWithAValidEscape()) {474 result += stringFromCode(consumeEscape());475 } else {476 reconsume();477 return result;478 }479 }480 };481 var consumeANumber = function() {482 var repr = [];483 var type = "integer";484 if(next() == 0x2b || next() == 0x2d) {485 consume();486 repr += stringFromCode(code);487 }488 while(digit(next())) {489 consume();490 repr += stringFromCode(code);491 }492 if(next(1) == 0x2e && digit(next(2))) {493 consume();494 repr += stringFromCode(code);495 consume();496 repr += stringFromCode(code);497 type = "number";498 while(digit(next())) {499 consume();500 repr += stringFromCode(code);501 }502 }503 var c1 = next(1), c2 = next(2), c3 = next(3);504 if((c1 == 0x45 || c1 == 0x65) && digit(c2)) {505 consume();506 repr += stringFromCode(code);507 consume();508 repr += stringFromCode(code);509 type = "number";510 while(digit(next())) {511 consume();512 repr += stringFromCode(code);513 }514 } else if((c1 == 0x45 || c1 == 0x65) && (c2 == 0x2b || c2 == 0x2d) && digit(c3)) {515 consume();516 repr += stringFromCode(code);517 consume();518 repr += stringFromCode(code);519 consume();520 repr += stringFromCode(code);521 type = "number";522 while(digit(next())) {523 consume();524 repr += stringFromCode(code);525 }526 }527 var value = convertAStringToANumber(repr);528 return {type:type, value:value, repr:repr};529 };530 var convertAStringToANumber = function(string) {531 // CSS's number rules are identical to JS, afaik.532 return +string;533 };534 var consumeTheRemnantsOfABadURL = function() {535 while(consume()) {536 if(code == 0x2d || eof()) {537 return;538 } else if(startsWithAValidEscape()) {539 consumeEscape();540 donothing();541 } else {542 donothing();543 }544 }545 };546 var iterationCount = 0;547 while(!eof(next())) {548 var token = consumeAToken();549 if (options.loc) {550 token.loc = {};551 token.loc.start = {line:locStart.line, column:locStart.column};552 token.loc.end = {line:line, column:column};553 }554 if (options.offsets) {555 token.startOffset = offsetStart;556 token.endOffset = i + 1;557 }558 yield token;559 iterationCount++;560 if(iterationCount > str.length*2) return "I'm infinite-looping!";561 }562}563function CSSParserToken() { throw "Abstract Base Class"; }564CSSParserToken.prototype.toJSON = function() {565 return {token: this.tokenType};566};567CSSParserToken.prototype.toString = function() { return this.tokenType; };568CSSParserToken.prototype.toSource = function() { return ''+this; };569function BadStringToken(text) {570 this.text = text;571 return this;572}573BadStringToken.prototype = Object.create(CSSParserToken.prototype);574BadStringToken.prototype.tokenType = "bad_string";575function BadURLToken() { return this; }576BadURLToken.prototype = Object.create(CSSParserToken.prototype);577BadURLToken.prototype.tokenType = "bad_url";578function WhitespaceToken() { return this; }579WhitespaceToken.prototype = Object.create(CSSParserToken.prototype);580WhitespaceToken.prototype.tokenType = "whitespace";581WhitespaceToken.prototype.toString = function() { return "WS"; };582WhitespaceToken.prototype.toSource = function() { return " "; };583function CDOToken() { return this; }584CDOToken.prototype = Object.create(CSSParserToken.prototype);585CDOToken.prototype.tokenType = "htmlcomment";586CDOToken.prototype.toSource = function() { return "<!--"; };587function CDCToken() { return this; }588CDCToken.prototype = Object.create(CSSParserToken.prototype);589CDCToken.prototype.tokenType = "htmlcomment";590CDCToken.prototype.toSource = function() { return "-->"; };591function ColonToken() { return this; }592ColonToken.prototype = Object.create(CSSParserToken.prototype);593ColonToken.prototype.tokenType = "symbol";594ColonToken.prototype.text = ":";595function SemicolonToken() { return this; }596SemicolonToken.prototype = Object.create(CSSParserToken.prototype);597SemicolonToken.prototype.tokenType = "symbol";598SemicolonToken.prototype.text = ";";599function CommaToken() { return this; }600CommaToken.prototype = Object.create(CSSParserToken.prototype);601CommaToken.prototype.tokenType = "symbol";602CommaToken.prototype.text = ",";603function GroupingToken() { throw "Abstract Base Class"; }604GroupingToken.prototype = Object.create(CSSParserToken.prototype);605function OpenCurlyToken() { this.value = "{"; this.mirror = "}"; return this; }606OpenCurlyToken.prototype = Object.create(GroupingToken.prototype);607OpenCurlyToken.prototype.tokenType = "symbol";608OpenCurlyToken.prototype.text = "{";609function CloseCurlyToken() { this.value = "}"; this.mirror = "{"; return this; }610CloseCurlyToken.prototype = Object.create(GroupingToken.prototype);611CloseCurlyToken.prototype.tokenType = "symbol";612CloseCurlyToken.prototype.text = "}";613function OpenSquareToken() { this.value = "["; this.mirror = "]"; return this; }614OpenSquareToken.prototype = Object.create(GroupingToken.prototype);615OpenSquareToken.prototype.tokenType = "symbol";616OpenSquareToken.prototype.text = "[";617function CloseSquareToken() { this.value = "]"; this.mirror = "["; return this; }618CloseSquareToken.prototype = Object.create(GroupingToken.prototype);619CloseSquareToken.prototype.tokenType = "symbol";620CloseSquareToken.prototype.text = "]";621function OpenParenToken() { this.value = "("; this.mirror = ")"; return this; }622OpenParenToken.prototype = Object.create(GroupingToken.prototype);623OpenParenToken.prototype.tokenType = "symbol";624OpenParenToken.prototype.text = "(";625function CloseParenToken() { this.value = ")"; this.mirror = "("; return this; }626CloseParenToken.prototype = Object.create(GroupingToken.prototype);627CloseParenToken.prototype.tokenType = "symbol";628CloseParenToken.prototype.text = ")";629function IncludeMatchToken() { return this; }630IncludeMatchToken.prototype = Object.create(CSSParserToken.prototype);631IncludeMatchToken.prototype.tokenType = "includes";632function DashMatchToken() { return this; }633DashMatchToken.prototype = Object.create(CSSParserToken.prototype);634DashMatchToken.prototype.tokenType = "dashmatch";635function PrefixMatchToken() { return this; }636PrefixMatchToken.prototype = Object.create(CSSParserToken.prototype);637PrefixMatchToken.prototype.tokenType = "beginsmatch";638function SuffixMatchToken() { return this; }639SuffixMatchToken.prototype = Object.create(CSSParserToken.prototype);640SuffixMatchToken.prototype.tokenType = "endsmatch";641function SubstringMatchToken() { return this; }642SubstringMatchToken.prototype = Object.create(CSSParserToken.prototype);643SubstringMatchToken.prototype.tokenType = "containsmatch";644function ColumnToken() { return this; }645ColumnToken.prototype = Object.create(CSSParserToken.prototype);646ColumnToken.prototype.tokenType = "||";647function EOFToken() { return this; }648EOFToken.prototype = Object.create(CSSParserToken.prototype);649EOFToken.prototype.tokenType = "EOF";650EOFToken.prototype.toSource = function() { return ""; };651function DelimToken(code) {652 this.value = stringFromCode(code);653 this.text = this.value;654 return this;655}656DelimToken.prototype = Object.create(CSSParserToken.prototype);657DelimToken.prototype.tokenType = "symbol";658DelimToken.prototype.toString = function() { return "DELIM("+this.value+")"; };659DelimToken.prototype.toJSON = function() {660 var json = this.constructor.prototype.constructor.prototype.toJSON.call(this);661 json.value = this.value;662 return json;663};664DelimToken.prototype.toSource = function() {665 if(this.value == "\\")666 return "\\\n";...
tokenize-css.js
Source:tokenize-css.js
...182/**183 * @param {number} code184 * @return {string}185 */186function stringFromCode(code) {187 if (code <= 0xffff) {188 return String.fromCharCode(code);189 }190 // Otherwise, encode astral char as surrogate pair.191 code -= Math.pow(2, 20);192 const lead = Math.floor(code / Math.pow(2, 10)) + 0xd800;193 const trail = code % Math.pow(2, 10) + 0xdc00;194 return String.fromCharCode(lead) + String.fromCharCode(trail);195}196/**197 * Tokenizer class. Used internally by the tokenize function.198 * @private199 */200class Tokenizer {201 /**202 * @param {string} strIn203 * @param {number|undefined} line204 * @param {number|undefined} col205 * @param {!Array<!ErrorToken>} errors output array for the206 * errors.207 */208 constructor(strIn, line, col, errors) {209 this.tokens_ = [];210 /**211 * @private212 * @type {!Array<!ErrorToken>}213 */214 this.errors_ = errors;215 /**216 * @private217 * @type {!Array<number>}218 */219 this.codepoints_ = preprocess(strIn);220 /**221 * @private222 * @type {number}223 */224 this.pos_ = -1;225 /**226 * @private227 * @type {number}228 */229 this.code_;230 // Line number information.231 let eofToken;232 /** @private @type {!Array<number>} */233 this.lineByPos_ = [];234 /** @private @type {!Array<number>} */235 this.colByPos_ = [];236 let currentLine = line || 1;237 let currentCol = col || 0;238 for (let i = 0; i < this.codepoints_.length; ++i) {239 this.lineByPos_[i] = currentLine;240 this.colByPos_[i] = currentCol;241 if (newline(this.codepoints_[i])) {242 ++currentLine;243 currentCol = 0;244 } else {245 ++currentCol;246 }247 }248 eofToken = new EOFToken();249 eofToken.line = currentLine;250 eofToken.col = currentCol;251 let iterationCount = 0;252 while (!this.eof(this.next())) {253 const token = this.consumeAToken();254 if (token.tokenType === TokenType.ERROR) {255 this.errors_.push(/** @type {!ErrorToken} */ (token));256 } else {257 this.tokens_.push(token);258 }259 iterationCount++;260 asserts.assert(261 iterationCount <= this.codepoints_.length * 2,262 'Internal Error: infinite-looping');263 }264 this.tokens_.push(eofToken);265 }266 /**267 * @return {number}268 */269 getLine() {270 const pos = Math.min(this.pos_, this.lineByPos_.length - 1);271 return (pos < 0) ? 1 : this.lineByPos_[this.pos_];272 }273 /**274 * @return {number}275 */276 getCol() {277 const pos = Math.min(this.pos_, this.colByPos_.length - 1);278 return (pos < 0) ? 0 : this.colByPos_[this.pos_];279 }280 /**281 * @return {!Array<!Token>}282 */283 getTokens() {284 return this.tokens_;285 }286 /**287 * Returns the codepoint at the given position.288 * @param {number} num289 * @return {number}290 */291 codepoint(num) {292 if (num >= this.codepoints_.length) {293 return -1;294 }295 return this.codepoints_[num];296 }297 /**298 * Peeks ahead and returns the codepoint opt_num positions ahead.299 * @param {number=} opt_num300 * @return {number}301 */302 next(opt_num) {303 const num = opt_num || 1;304 asserts.assert(305 num <= 3, 'Spec Error: no more than three codepoints of lookahead.');306 return this.codepoint(this.pos_ + num);307 }308 /**309 * Moves ahead opt_num positions in the string. May move past the310 * end of the string.311 * @param {number=} opt_num312 */313 consume(opt_num) {314 const num = opt_num || 1;315 this.pos_ += num;316 this.code_ = this.codepoint(this.pos_);317 }318 /**319 * Backs up exactly one position in the string.320 */321 reconsume() {322 this.pos_ -= 1;323 // TODO(johannes): Oddly, adding the following breaks the test with324 // internal errors. Investigate.325 // this.code_ = this.codepoint(this.pos_);326 }327 /**328 * @param {number=} opt_codepoint329 * @return {boolean}330 */331 eof(opt_codepoint) {332 const codepoint = opt_codepoint || this.code_;333 return codepoint === -1;334 }335 /** @return {!Token} */336 consumeAToken() {337 this.consumeComments();338 this.consume();339 const mark = new Token();340 mark.line = this.getLine();341 mark.col = this.getCol();342 if (whitespace(this.code_)) {343 // Merge consecutive whitespace into one token.344 while (whitespace(this.next())) {345 this.consume();346 }347 return mark.copyPosTo(new WhitespaceToken());348 } else if (this.code_ === /* '"' */ 0x22) {349 return mark.copyPosTo(this.consumeAStringToken());350 } else if (this.code_ === /* '#' */ 0x23) {351 if (nameChar(this.next()) ||352 this.areAValidEscape(this.next(1), this.next(2))) {353 let type = null;354 if (this.wouldStartAnIdentifier(355 this.next(1), this.next(2), this.next(3))) {356 type = 'id';357 }358 const token = new HashToken();359 token.value = this.consumeAName();360 if (type !== null) {361 token.type = type;362 }363 return mark.copyPosTo(token);364 } else {365 return mark.copyPosTo(new DelimToken(this.code_));366 }367 } else if (this.code_ === /* '$' */ 0x24) {368 if (this.next() === /* '=' */ 0x3d) {369 this.consume();370 return mark.copyPosTo(new SuffixMatchToken());371 } else {372 return mark.copyPosTo(new DelimToken(this.code_));373 }374 } else if (this.code_ === /* ''' */ 0x27) {375 return mark.copyPosTo(this.consumeAStringToken());376 } else if (this.code_ === /* '(' */ 0x28) {377 return mark.copyPosTo(new OpenParenToken());378 } else if (this.code_ === /* ')' */ 0x29) {379 return mark.copyPosTo(new CloseParenToken());380 } else if (this.code_ === /* '*' */ 0x2a) {381 if (this.next() === /* '=' */ 0x3d) {382 this.consume();383 return mark.copyPosTo(new SubstringMatchToken());384 } else {385 return mark.copyPosTo(new DelimToken(this.code_));386 }387 } else if (this.code_ === /* '+' */ 0x2b) {388 if (this./*OK*/ startsWithANumber()) {389 this.reconsume();390 return mark.copyPosTo(this.consumeANumericToken());391 } else {392 return mark.copyPosTo(new DelimToken(this.code_));393 }394 } else if (this.code_ === /* ',' */ 0x2c) {395 return mark.copyPosTo(new CommaToken());396 } else if (this.code_ === /* '-' */ 0x2d) {397 if (this./*OK*/ startsWithANumber()) {398 this.reconsume();399 return mark.copyPosTo(this.consumeANumericToken());400 } else if (401 this.next(1) === /* '-' */ 0x2d && this.next(2) === /* '>' */ 0x3e) {402 this.consume(2);403 return mark.copyPosTo(new CDCToken());404 } else if (this./*OK*/ startsWithAnIdentifier()) {405 this.reconsume();406 return mark.copyPosTo(this.consumeAnIdentlikeToken());407 } else {408 return mark.copyPosTo(new DelimToken(this.code_));409 }410 } else if (this.code_ === /* '.' */ 0x2e) {411 if (this./*OK*/ startsWithANumber()) {412 this.reconsume();413 return mark.copyPosTo(this.consumeANumericToken());414 } else {415 return mark.copyPosTo(new DelimToken(this.code_));416 }417 } else if (this.code_ === /* ':' */ 0x3a) {418 return mark.copyPosTo(new ColonToken());419 } else if (this.code_ === /* ';' */ 0x3b) {420 return mark.copyPosTo(new SemicolonToken());421 } else if (this.code_ === /* '<' */ 0x3c) {422 if (this.next(1) === /* '!' */ 0x21 && this.next(2) === /* '-' */ 0x2d &&423 this.next(3) === /* '-' */ 0x2d) {424 this.consume(3);425 return mark.copyPosTo(new CDOToken());426 } else {427 return mark.copyPosTo(new DelimToken(this.code_));428 }429 } else if (this.code_ === /* '@' */ 0x40) {430 if (this.wouldStartAnIdentifier(431 this.next(1), this.next(2), this.next(3))) {432 const token = new AtKeywordToken();433 token.value = this.consumeAName();434 return mark.copyPosTo(token);435 } else {436 return mark.copyPosTo(new DelimToken(this.code_));437 }438 } else if (this.code_ === /* '[' */ 0x5b) {439 return mark.copyPosTo(new OpenSquareToken());440 } else if (this.code_ === /* '\' */ 0x5c) {441 if (this./*OK*/ startsWithAValidEscape()) {442 this.reconsume();443 return mark.copyPosTo(this.consumeAnIdentlikeToken());444 } else {445 // This condition happens if we are in consumeAToken (this method),446 // the current codepoint is 0x5c (\) and the next codepoint is a447 // newline (\n).448 return mark.copyPosTo(new ErrorToken(449 ValidationError.Code.CSS_SYNTAX_STRAY_TRAILING_BACKSLASH,450 ['style']));451 }452 } else if (this.code_ === /* ']' */ 0x5d) {453 return mark.copyPosTo(new CloseSquareToken());454 } else if (this.code_ === /* '^' */ 0x5e) {455 if (this.next() === /* '=' */ 0x3d) {456 this.consume();457 return mark.copyPosTo(new PrefixMatchToken());458 } else {459 return mark.copyPosTo(new DelimToken(this.code_));460 }461 } else if (this.code_ === /* '{' */ 0x7b) {462 return mark.copyPosTo(new OpenCurlyToken());463 } else if (this.code_ === /* '|' */ 0x7c) {464 if (this.next() === /* '=' */ 0x3d) {465 this.consume();466 return mark.copyPosTo(new DashMatchToken());467 } else if (this.next() === /* '|' */ 0x7c) {468 this.consume();469 return mark.copyPosTo(new ColumnToken());470 } else {471 return mark.copyPosTo(new DelimToken(this.code_));472 }473 } else if (this.code_ === /* '}' */ 0x7d) {474 return mark.copyPosTo(new CloseCurlyToken());475 } else if (this.code_ === /* '~' */ 0x7e) {476 if (this.next() === /* '=' */ 0x3d) {477 this.consume();478 return mark.copyPosTo(new IncludeMatchToken());479 } else {480 return mark.copyPosTo(new DelimToken(this.code_));481 }482 } else if (digit(this.code_)) {483 this.reconsume();484 return mark.copyPosTo(this.consumeANumericToken());485 } else if (nameStartChar(this.code_)) {486 this.reconsume();487 return mark.copyPosTo(this.consumeAnIdentlikeToken());488 } else if (this.eof()) {489 return mark.copyPosTo(new EOFToken());490 } else {491 const token = new DelimToken(this.code_);492 return mark.copyPosTo(token);493 }494 }495 /**496 * Consume everything starting with /* and ending at * / (ignore the space),497 * emitting a parse error if we hit the end of the file. Returns nothing.498 */499 consumeComments() {500 const mark = new Token();501 mark.line = this.getLine();502 mark.col = this.getCol();503 while (this.next(1) === /* '/' */ 0x2f && this.next(2) === /* '*' */ 0x2a) {504 this.consume(2);505 while (true) {506 this.consume();507 if (this.code_ === /* '*' */ 0x2a && this.next() === /* '/' */ 0x2f) {508 this.consume();509 break;510 } else if (this.eof()) {511 // For example "h1 { color: red; } \* " would emit this parse error512 // at the end of the string.513 this.errors_.push(mark.copyPosTo(new ErrorToken(514 ValidationError.Code.CSS_SYNTAX_UNTERMINATED_COMMENT,515 ['style'])));516 return;517 }518 }519 }520 }521 /**522 * Consumes a token that starts with a number.523 * The specific type is one of:524 * NumberToken, DimensionToken, PercentageToken525 * @return {!Token}526 */527 consumeANumericToken() {528 asserts.assert(529 this.wouldStartANumber(this.next(1), this.next(2), this.next(3)),530 'Internal Error: consumeANumericToken precondition not met');531 /** @type {!NumberToken} */532 const num = this.consumeANumber();533 if (this.wouldStartAnIdentifier(this.next(1), this.next(2), this.next(3))) {534 const token = new DimensionToken();535 token.value = num.value;536 token.repr = num.repr;537 token.type = num.type;538 token.unit = this.consumeAName();539 return token;540 } else if (this.next() === /* '%' */ 0x25) {541 this.consume();542 const token = new PercentageToken();543 token.value = num.value;544 token.repr = num.repr;545 return token;546 }547 return num;548 }549 /**550 * Consume an identifier-like token.551 * The specific type is one of:552 * FunctionToken, URLToken, ErrorToken, IdentToken553 * @return {!Token}554 */555 consumeAnIdentlikeToken() {556 const name = this.consumeAName();557 if (name.toLowerCase() === 'url' && this.next() === /* '(' */ 0x28) {558 this.consume();559 while (whitespace(this.next(1)) && whitespace(this.next(2))) {560 this.consume();561 }562 if (this.next() === /* '"' */ 0x22 || this.next() === /* ''' */ 0x27) {563 const token = new FunctionToken();564 token.value = name;565 return token;566 } else if (567 whitespace(this.next()) &&568 (this.next(2) === /* '"' */ 0x22 ||569 this.next(2) === /* ''' */ 0x27)) {570 const token = new FunctionToken();571 token.value = name;572 return token;573 } else {574 return this.consumeAURLToken();575 }576 } else if (this.next() === /* '(' */ 0x28) {577 this.consume();578 const token = new FunctionToken();579 token.value = name;580 return token;581 } else {582 const token = new IdentToken();583 token.value = name;584 return token;585 }586 }587 /**588 * Consume a string token.589 * The specific type is one of:590 * StringToken, ErrorToken591 * @return {!Token}592 */593 consumeAStringToken() {594 asserts.assert(595 (this.code_ === /* '"' */ 0x22) || (this.code_ === /* ''' */ 0x27),596 'Internal Error: consumeAStringToken precondition not met');597 const endingCodePoint = this.code_;598 let string = '';599 while (true) {600 this.consume();601 if (this.code_ === endingCodePoint || this.eof()) {602 const token = new StringToken();603 token.value = string;604 return token;605 } else if (newline(this.code_)) {606 this.reconsume();607 return new ErrorToken(608 ValidationError.Code.CSS_SYNTAX_UNTERMINATED_STRING, ['style']);609 } else if (this.code_ === /* '\' */ 0x5c) {610 if (this.eof(this.next())) {611 continue;612 } else if (newline(this.next())) {613 this.consume();614 } else {615 string += stringFromCode(this.consumeEscape());616 }617 } else {618 string += stringFromCode(this.code_);619 }620 }621 }622 /**623 * Consume an URL token.624 * The specific type is one of:625 * URLToken, ErrorToken626 * @return {!Token}627 */628 consumeAURLToken() {629 const token = new URLToken();630 while (whitespace(this.next())) {631 this.consume();632 }633 if (this.eof(this.next())) {634 return token;635 }636 while (true) {637 this.consume();638 if (this.code_ === /* ')' */ 0x29 || this.eof()) {639 return token;640 } else if (whitespace(this.code_)) {641 while (whitespace(this.next())) {642 this.consume();643 }644 if (this.next() === /* ')' */ 0x29 || this.eof(this.next())) {645 this.consume();646 return token;647 } else {648 this.consumeTheRemnantsOfABadURL();649 return new ErrorToken(650 ValidationError.Code.CSS_SYNTAX_BAD_URL, ['style']);651 }652 } else if (653 this.code_ === /* '"' */ 0x22 || this.code_ === /* ''' */ 0x27 ||654 this.code_ === /* '(' */ 0x28 || nonPrintable(this.code_)) {655 this.consumeTheRemnantsOfABadURL();656 return new ErrorToken(657 ValidationError.Code.CSS_SYNTAX_BAD_URL, ['style']);658 } else if (this.code_ === /* '\' */ 0x5c) {659 if (this./*OK*/ startsWithAValidEscape()) {660 token.value += stringFromCode(this.consumeEscape());661 } else {662 this.consumeTheRemnantsOfABadURL();663 return new ErrorToken(664 ValidationError.Code.CSS_SYNTAX_BAD_URL, ['style']);665 }666 } else {667 token.value += stringFromCode(this.code_);668 }669 }670 }671 /**672 * Consume an escaped character, ex: \a212f3, followed by any whitespace.673 * Returns the numerical value of the character. If the codepoint following674 * the '\' character is not a hex code and not EOF, returns that codepoint.675 * @return {number}676 */677 consumeEscape() {678 // Assume the the current character is the \679 // and the next code point is not a newline.680 this.consume(); // '\'681 if (hexDigit(this.code_)) {682 // Consume 1-6 hex digits683 const digits = [this.code_];684 for (let total = 0; total < 5; total++) {685 if (hexDigit(this.next())) {686 this.consume();687 digits.push(this.code_);688 } else {689 break;690 }691 }692 if (whitespace(this.next())) {693 this.consume();694 }695 let value = parseInt(696 digits697 .map(function(x) {698 return String.fromCharCode(x);699 })700 .join(''),701 16);702 if (value > maxAllowedCodepoint) {703 value = 0xfffd;704 }705 return value;706 } else if (this.eof()) {707 return 0xfffd;708 } else {709 return this.code_;710 }711 }712 /**713 * Returns true if the codepoint sequence c1, c2 are the start714 * of an escape token.715 * @param {number} c1 codepoint at pos x716 * @param {number} c2 codepoint at pos x + 1717 * @return {boolean}718 */719 areAValidEscape(c1, c2) {720 if (c1 != /* '\' */ 0x5c) {721 return false;722 }723 if (newline(c2)) {724 return false;725 }726 return true;727 }728 /**729 * Returns true if the next two codepoints are the start of an escape token.730 * @return {boolean}731 */732 /*OK*/ startsWithAValidEscape() {733 return this.areAValidEscape(this.code_, this.next());734 }735 /**736 * Returns true if the codepoint sequence c1, c2, c3 are the737 * start of an identifier.738 * @param {number} c1 codepoint at pos x739 * @param {number} c2 codepoint at pos x + 1740 * @param {number} c3 codepoint at pos x + 2741 * @return {boolean}742 */743 wouldStartAnIdentifier(c1, c2, c3) {744 if (c1 === /* '-' */ 0x2d) {745 return nameStartChar(c2) || c2 === /* '-' */ 0x2d ||746 this.areAValidEscape(c2, c3);747 } else if (nameStartChar(c1)) {748 return true;749 } else if (c1 === /* '\' */ 0x5c) {750 return this.areAValidEscape(c1, c2);751 } else {752 return false;753 }754 }755 /**756 * Returns true if the next three codepoints are the start of an identifier.757 * @return {boolean}758 */759 /*OK*/ startsWithAnIdentifier() {760 return this.wouldStartAnIdentifier(this.code_, this.next(1), this.next(2));761 }762 /**763 * Returns true if the codepoint sequence c1, c2, c3 are the764 * start of a number.765 * @param {number} c1 codepoint at pos x766 * @param {number} c2 codepoint at pos x + 1767 * @param {number} c3 codepoint at pos x + 2768 * @return {boolean}769 */770 wouldStartANumber(c1, c2, c3) {771 if (c1 === /* '+' */ 0x2b || c1 === /* '-' */ 0x2d) {772 if (digit(c2)) {773 return true;774 }775 if (c2 === /* '.' */ 0x2e && digit(c3)) {776 return true;777 }778 return false;779 } else if (c1 === /* '.' */ 0x2e) {780 if (digit(c2)) {781 return true;782 }783 return false;784 } else if (digit(c1)) {785 return true;786 } else {787 return false;788 }789 }790 /**791 * Returns true if the next three codepoints are the start of a number.792 * @return {boolean}793 */794 /*OK*/ startsWithANumber() {795 return this.wouldStartANumber(this.code_, this.next(1), this.next(2));796 }797 /** @return {string} */798 consumeAName() {799 let result = '';800 while (true) {801 this.consume();802 if (nameChar(this.code_)) {803 result += stringFromCode(this.code_);804 } else if (this./*OK*/ startsWithAValidEscape()) {805 result += stringFromCode(this.consumeEscape());806 } else {807 this.reconsume();808 return result;809 }810 }811 }812 /**813 * Consumes a number, returning it as a string representation. Numbers814 * may include +/- prefixes, ./e/E delimiters, etc. The type string will815 * be either 'integer' or 'number'. A number may be an integer.816 * @return {!NumberToken}817 */818 consumeANumber() {819 asserts.assert(820 this.wouldStartANumber(this.next(1), this.next(2), this.next(3)),821 'Internal Error: consumeANumber precondition not met');822 /** @type {string} */823 let repr = '';824 /** @type {string} */825 let type = 'integer';826 if (this.next() === /* '+' */ 0x2b || this.next() === /* '-' */ 0x2d) {827 this.consume();828 repr += stringFromCode(this.code_); // + or -829 }830 while (digit(this.next())) {831 this.consume();832 repr += stringFromCode(this.code_); // 0-9833 }834 if (this.next(1) === /* '.' */ 0x2e && digit(this.next(2))) {835 this.consume();836 repr += stringFromCode(this.code_); // '.'837 type = 'number';838 while (digit(this.next())) {839 this.consume();840 repr += stringFromCode(this.code_); // 0-9841 }842 }843 const c1 = this.next(1);844 const c2 = this.next(2);845 const c3 = this.next(3);846 if ((c1 === /* 'E' */ 0x45 || c1 === /* 'e' */ 0x65) && digit(c2)) {847 this.consume();848 repr += stringFromCode(this.code_); // E or e849 type = 'number';850 while (digit(this.next())) {851 this.consume();852 repr += stringFromCode(this.code_); // 0-9853 }854 } else if (855 (c1 === /* 'E' */ 0x45 || c1 === /* 'e' */ 0x65) &&856 (c2 === /* '+' */ 0x2b || c2 === /* '-' */ 0x2d) && digit(c3)) {857 this.consume();858 repr += stringFromCode(this.code_); // E or e859 this.consume();860 repr += stringFromCode(this.code_); // + or -861 type = 'number';862 while (digit(this.next())) {863 this.consume();864 repr += stringFromCode(this.code_); // 0-9865 }866 }867 const numberToken = new NumberToken();868 numberToken.type = type;869 numberToken.value = this.convertAStringToANumber(repr);870 numberToken.repr = repr;871 return numberToken;872 }873 /**874 * Converts a numerical representation of a string to a number.875 * @param {string} string876 * @return {number}877 */878 convertAStringToANumber(string) {879 // CSS's number rules are identical to JS, afaik.880 return Number(string);881 }882 /**883 * Consumes ?. Returns nothing.884 */885 consumeTheRemnantsOfABadURL() {886 while (true) {887 this.consume();888 if (this.code_ === /* '-' */ 0x2d || this.eof()) {889 return;890 } else if (this./*OK*/ startsWithAValidEscape()) {891 this.consumeEscape();892 }893 }894 }895}896/**897 * NOTE: When adding to this enum, you must update TokenType_NamesById below.898 * @enum {number}899 */900const TokenType = {901 UNKNOWN: 0,902 AT_KEYWORD: 1,903 CDC: 2, // -->904 CDO: 3, // <!--905 CLOSE_CURLY: 4,906 CLOSE_PAREN: 5,907 CLOSE_SQUARE: 6,908 COLON: 7,909 COLUMN: 8, // ||910 COMMA: 9,911 DASH_MATCH: 10, // |=912 DELIM: 11,913 DIMENSION: 12,914 EOF_TOKEN: 13, // Can't call this EOF due to symbol conflict in C.915 ERROR: 14,916 FUNCTION_TOKEN: 15,917 HASH: 16, // #918 IDENT: 17,919 INCLUDE_MATCH: 18, // ~=920 NUMBER: 19,921 OPEN_CURLY: 20,922 OPEN_PAREN: 21,923 OPEN_SQUARE: 22,924 PERCENTAGE: 23,925 PREFIX_MATCH: 24, // ^=926 SEMICOLON: 25,927 STRING: 26,928 SUBSTRING_MATCH: 27, // *=929 SUFFIX_MATCH: 28, // $=930 WHITESPACE: 29,931 URL: 30,932 // AST nodes produced by the parsing routines.933 STYLESHEET: 31,934 AT_RULE: 32,935 QUALIFIED_RULE: 33,936 DECLARATION: 34,937 BLOCK: 35,938 FUNCTION: 36,939 // For ExtractUrls940 PARSED_CSS_URL: 37,941 // For css-selectors.js.942 TYPE_SELECTOR: 38,943 ID_SELECTOR: 39,944 ATTR_SELECTOR: 40,945 PSEUDO_SELECTOR: 41,946 CLASS_SELECTOR: 42,947 SIMPLE_SELECTOR_SEQUENCE: 43,948 COMBINATOR: 44,949 SELECTORS_GROUP: 45,950};951exports.TokenType = TokenType;952/** @type {!Array<string>} */953const TokenType_NamesById = [954 'UNKNOWN',955 'AT_KEYWORD',956 'CDC',957 'CDO',958 'CLOSE_CURLY',959 'CLOSE_PAREN',960 'CLOSE_SQUARE',961 'COLON',962 'COLUMN',963 'COMMA',964 'DASH_MATCH',965 'DELIM',966 'DIMENSION',967 'EOF_TOKEN',968 'ERROR',969 'FUNCTION_TOKEN',970 'HASH',971 'IDENT',972 'INCLUDE_MATCH',973 'NUMBER',974 'OPEN_CURLY',975 'OPEN_PAREN',976 'OPEN_SQUARE',977 'PERCENTAGE',978 'PREFIX_MATCH',979 'SEMICOLON',980 'STRING',981 'SUBSTRING_MATCH',982 'SUFFIX_MATCH',983 'WHITESPACE',984 'URL',985 'STYLESHEET',986 'AT_RULE',987 'QUALIFIED_RULE',988 'DECLARATION',989 'BLOCK',990 'FUNCTION',991 'PARSED_CSS_URL',992 'TYPE_SELECTOR',993 'ID_SELECTOR',994 'ATTR_SELECTOR',995 'PSEUDO_SELECTOR',996 'CLASS_SELECTOR',997 'SIMPLE_SELECTOR_SEQUENCE',998 'COMBINATOR',999 'SELECTORS_GROUP',1000];1001/**1002 * The abstract superclass for all tokens.1003 */1004const Token = class {1005 constructor() {1006 /** @type {number} */1007 this.line = 1;1008 /** @type {number} */1009 this.col = 0;1010 }1011 /**1012 * Copies the line / col values of |this| to |other|.1013 * @param {!T} other1014 * @return {!T}1015 * @template T1016 */1017 copyPosTo(other) {1018 other.line = this.line;1019 other.col = this.col;1020 return other;1021 }1022};1023exports.Token = Token;1024/** @type {!TokenType} */1025Token.prototype.tokenType = TokenType.UNKNOWN;1026/** @return {!Object} */1027Token.prototype.toJSON = function() {1028 return {1029 'tokenType': TokenType_NamesById[this.tokenType],1030 'line': this.line,1031 'col': this.col,1032 };1033};1034/**1035 * Error tokens carry an error code and parameters, which can be1036 * formatted into an error message via the format strings in1037 * validator.protoascii.1038 */1039const ErrorToken = class extends Token {1040 /**1041 * @param {!ValidationError.Code=} opt_code1042 * @param {!Array<string>=} opt_params1043 */1044 constructor(opt_code, opt_params) {1045 super();1046 asserts.assert(opt_code !== undefined);1047 asserts.assert(opt_params !== undefined);1048 /** @type {!ValidationError.Code} */1049 this.code = opt_code;1050 /** @type {!Array<string>} */1051 this.params = opt_params;1052 }1053};1054/** @type {!TokenType} */1055ErrorToken.prototype.tokenType = TokenType.ERROR;1056exports.ErrorToken = ErrorToken;1057/** @inheritDoc */1058ErrorToken.prototype.toJSON = function() {1059 const json = Token.prototype.toJSON.call(this);1060 json['code'] = this.code;1061 json['params'] = this.params;1062 return json;1063};1064const WhitespaceToken = class extends Token {};1065exports.WhitespaceToken = WhitespaceToken;1066/** @type {!TokenType} */1067WhitespaceToken.prototype.tokenType = TokenType.WHITESPACE;1068const CDOToken = class extends Token {};1069exports.CDOToken = CDOToken;1070/** @type {!TokenType} */1071CDOToken.prototype.tokenType = TokenType.CDO;1072const CDCToken = class extends Token {};1073exports.CDCToken = CDCToken;1074/** @type {!TokenType} */1075CDCToken.prototype.tokenType = TokenType.CDC;1076const ColonToken = class extends Token {};1077exports.ColonToken = ColonToken;1078/** @type {!TokenType} */1079ColonToken.prototype.tokenType = TokenType.COLON;1080const SemicolonToken = class extends Token {};1081exports.SemicolonToken = SemicolonToken;1082/** @type {!TokenType} */1083SemicolonToken.prototype.tokenType = TokenType.SEMICOLON;1084const CommaToken = class extends Token {};1085exports.CommaToken = CommaToken;1086/** @type {!TokenType} */1087CommaToken.prototype.tokenType = TokenType.COMMA;1088const GroupingToken = class extends Token {};1089exports.GroupingToken = GroupingToken;1090/** @type {string} */1091GroupingToken.prototype.value = 'abstract';1092/** @type {string} */1093GroupingToken.prototype.mirror = 'abstract';1094const OpenCurlyToken = class extends GroupingToken {};1095exports.OpenCurlyToken = OpenCurlyToken;1096/** @type {!TokenType} */1097OpenCurlyToken.prototype.tokenType = TokenType.OPEN_CURLY;1098/** @type {string} */1099OpenCurlyToken.prototype.value = '{';1100/** @type {string} */1101OpenCurlyToken.prototype.mirror = '}';1102const CloseCurlyToken = class extends GroupingToken {};1103exports.CloseCurlyToken = CloseCurlyToken;1104/** @type {!TokenType} */1105CloseCurlyToken.prototype.tokenType = TokenType.CLOSE_CURLY;1106/** @type {string} */1107CloseCurlyToken.prototype.value = '}';1108/** @type {string} */1109CloseCurlyToken.prototype.mirror = '{';1110const OpenSquareToken = class extends GroupingToken {};1111exports.OpenSquareToken = OpenSquareToken;1112/** @type {!TokenType} */1113OpenSquareToken.prototype.tokenType = TokenType.OPEN_SQUARE;1114/** @type {string} */1115OpenSquareToken.prototype.value = '[';1116/** @type {string} */1117OpenSquareToken.prototype.mirror = ']';1118const CloseSquareToken = class extends GroupingToken {};1119exports.CloseSquareToken = CloseSquareToken;1120/** @type {!TokenType} */1121CloseSquareToken.prototype.tokenType = TokenType.CLOSE_SQUARE;1122/** @type {string} */1123CloseSquareToken.prototype.value = ']';1124/** @type {string} */1125CloseSquareToken.prototype.mirror = '[';1126const OpenParenToken = class extends GroupingToken {};1127exports.OpenParenToken = OpenParenToken;1128/** @type {!TokenType} */1129OpenParenToken.prototype.tokenType = TokenType.OPEN_PAREN;1130/** @type {string} */1131OpenParenToken.prototype.value = '(';1132/** @type {string} */1133OpenParenToken.prototype.mirror = ')';1134const CloseParenToken = class extends GroupingToken {};1135exports.CloseParenToken = CloseParenToken;1136/** @type {!TokenType} */1137CloseParenToken.prototype.tokenType = TokenType.CLOSE_PAREN;1138/** @type {string} */1139CloseParenToken.prototype.value = ')';1140/** @type {string} */1141CloseParenToken.prototype.mirror = '(';1142const IncludeMatchToken = class extends Token {};1143exports.IncludeMatchToken = IncludeMatchToken;1144/** @type {!TokenType} */1145IncludeMatchToken.prototype.tokenType = TokenType.INCLUDE_MATCH;1146const DashMatchToken = class extends Token {};1147exports.DashMatchToken = DashMatchToken;1148/** @type {!TokenType} */1149DashMatchToken.prototype.tokenType = TokenType.DASH_MATCH;1150const PrefixMatchToken = class extends Token {};1151exports.PrefixMatchToken = PrefixMatchToken;1152/** @type {!TokenType} */1153PrefixMatchToken.prototype.tokenType = TokenType.PREFIX_MATCH;1154const SuffixMatchToken = class extends Token {};1155exports.SuffixMatchToken = SuffixMatchToken;1156/** @type {!TokenType} */1157SuffixMatchToken.prototype.tokenType = TokenType.SUFFIX_MATCH;1158const SubstringMatchToken = class extends Token {};1159exports.SubstringMatchToken = SubstringMatchToken;1160/** @type {!TokenType} */1161SubstringMatchToken.prototype.tokenType = TokenType.SUBSTRING_MATCH;1162const ColumnToken = class extends Token {};1163exports.ColumnToken = ColumnToken;1164/** @type {!TokenType} */1165ColumnToken.prototype.tokenType = TokenType.COLUMN;1166const EOFToken = class extends Token {};1167exports.EOFToken = EOFToken;1168/** @type {!TokenType} */1169EOFToken.prototype.tokenType = TokenType.EOF_TOKEN;1170const DelimToken = class extends Token {1171 /**1172 * @param {number} code1173 */1174 constructor(code) {1175 super();1176 /** @type {string} */1177 this.value = stringFromCode(code);1178 }1179};1180exports.DelimToken = DelimToken;1181/** @type {!TokenType} */1182DelimToken.prototype.tokenType = TokenType.DELIM;1183/** @inheritDoc */1184DelimToken.prototype.toJSON = function() {1185 const json = Token.prototype.toJSON.call(this);1186 json['value'] = this.value;1187 return json;1188};1189const StringValuedToken = class extends Token {1190 constructor() {1191 super();...
css-syntax.js
Source:css-syntax.js
...73 codepoints.push(code);74 }75 return codepoints;76}77function stringFromCode(code) {78 if(code <= 0xffff) return String.fromCharCode(code);79 // Otherwise, encode astral char as surrogate pair.80 code -= Math.pow(2, 21);81 var lead = Math.floor(code/Math.pow(2, 10)) + 0xd800;82 var trail = code % Math.pow(2, 10); + 0xdc00;83 return String.fromCharCode(lead) + String.fromCharCode(trail);84}85function tokenize(str) {86 str = preprocess(str);87 var i = -1;88 var tokens = new TokenList();89 var code;90 // Line number information.91 var line = 0;92 var column = 0;93 // The only use of lastLineLength is in reconsume().94 var lastLineLength = 0;95 var incrLineno = function() {96 line += 1;97 lastLineLength = column;98 column = 0;99 };100 var locStart = {line:line, column:column};101 var codepoint = function(i) {102 if(i >= str.length) {103 return -1;104 }105 return str[i];106 }107 var next = function(num) {108 if(num === undefined) { num = 1; }109 if(num > 3) { throw "Spec Error: no more than three codepoints of lookahead."; }110 return codepoint(i+num);111 };112 var consume = function(num) {113 if(num === undefined)114 num = 1;115 i += num;116 code = codepoint(i);117 if(newline(code)) incrLineno();118 else column += num;119 //console.log('Consume '+i+' '+String.fromCharCode(code) + ' 0x' + code.toString(16));120 return true;121 };122 var reconsume = function() {123 i -= 1;124 if (newline(code)) {125 line -= 1;126 column = lastLineLength;127 } else {128 column -= 1;129 }130 locStart.line = line;131 locStart.column = column;132 return true;133 };134 var eof = function(codepoint) {135 if(codepoint === undefined) codepoint = code;136 return codepoint == -1;137 };138 var donothing = function() {};139 var tokenizeerror = function() { console.log("Parse error at index " + i + ", processing codepoint 0x" + code.toString(16) + ".");return true; };140 var consumeAToken = function() {141 consumeComments();142 consume();143 if(whitespace(code)) {144 while(whitespace(next())) consume();145 return new WhitespaceToken;146 }147 else if(code == 0x22) return consumeAStringToken();148 else if(code == 0x23) {149 if(namechar(next()) || areAValidEscape(next(1), next(2))) {150 var token = new HashToken();151 if(wouldStartAnIdentifier(next(1), next(2), next(3))) token.type = "id";152 token.value = consumeAName();153 return token;154 } else {155 return new DelimToken(code);156 }157 }158 else if(code == 0x24) {159 if(next() == 0x3d) {160 consume();161 return new SuffixMatchToken();162 } else {163 return new DelimToken(code);164 }165 }166 else if(code == 0x27) return consumeAStringToken();167 else if(code == 0x28) return new OpenParenToken();168 else if(code == 0x29) return new CloseParenToken();169 else if(code == 0x2a) {170 if(next() == 0x3d) {171 consume();172 return new SubstringMatchToken();173 } else {174 return new DelimToken(code);175 }176 }177 else if(code == 0x2b) {178 if(startsWithANumber()) {179 reconsume();180 return consumeANumericToken();181 } else {182 return new DelimToken(code);183 }184 }185 else if(code == 0x2c) return new CommaToken();186 else if(code == 0x2d) {187 if(startsWithANumber()) {188 reconsume();189 return consumeANumericToken();190 } else if(next(1) == 0x2d && next(2) == 0x3e) {191 consume(2);192 return new CDCToken();193 } else if(startsWithAnIdentifier()) {194 reconsume();195 return consumeAnIdentlikeToken();196 } else {197 return new DelimToken(code);198 }199 }200 else if(code == 0x2e) {201 if(startsWithANumber()) {202 reconsume();203 return consumeANumericToken();204 } else {205 return new DelimToken(code);206 }207 }208 else if(code == 0x3a) return new ColonToken;209 else if(code == 0x3b) return new SemicolonToken;210 else if(code == 0x3c) {211 if(next(1) == 0x21 && next(2) == 0x2d && next(3) == 0x2d) {212 consume(3);213 return new CDOToken();214 } else {215 return new DelimToken(code);216 }217 }218 else if(code == 0x40) {219 if(wouldStartAnIdentifier(next(1), next(2), next(3))) {220 return new AtKeywordToken(consumeAName());221 } else {222 return new DelimToken(code);223 }224 }225 else if(code == 0x5b) return new OpenSquareToken();226 else if(code == 0x5c) {227 if(startsWithAValidEscape()) {228 reconsume();229 return consumeAnIdentlikeToken();230 } else {231 tokenizeerror();232 return new DelimToken(code);233 }234 }235 else if(code == 0x5d) return new CloseSquareToken();236 else if(code == 0x5e) {237 if(next() == 0x3d) {238 consume();239 return new PrefixMatchToken();240 } else {241 return new DelimToken(code);242 }243 }244 else if(code == 0x7b) return new OpenCurlyToken();245 else if(code == 0x7c) {246 if(next() == 0x3d) {247 consume();248 return new DashMatchToken();249 } else if(next() == 0x7c) {250 consume();251 return new ColumnToken();252 } else {253 return new DelimToken(code);254 }255 }256 else if(code == 0x7d) return new CloseCurlyToken();257 else if(code == 0x7e) {258 if(next() == 0x3d) {259 consume();260 return new IncludeMatchToken();261 } else {262 return new DelimToken(code);263 }264 }265 else if(digit(code)) {266 reconsume();267 return consumeANumericToken();268 }269 else if(namestartchar(code)) {270 reconsume();271 return consumeAnIdentlikeToken();272 }273 else if(eof()) return new EOFToken();274 else return new DelimToken(code);275 };276 var consumeComments = function() {277 while(next(1) == 0x2f && next(2) == 0x2a) {278 consume(2);279 while(true) {280 consume();281 if(code == 0x2a && next() == 0x2f) {282 consume();283 break;284 } else if(eof()) {285 tokenizeerror();286 return;287 }288 }289 }290 };291 var consumeANumericToken = function() {292 var num = consumeANumber();293 if(wouldStartAnIdentifier(next(1), next(2), next(3))) {294 var token = new DimensionToken();295 token.value = num.value;296 token.repr = num.repr;297 token.type = num.type;298 token.unit = consumeAName();299 return token;300 } else if(next() == 0x25) {301 consume();302 var token = new PercentageToken();303 token.value = num.value;304 token.repr = num.repr;305 return token;306 } else {307 var token = new NumberToken();308 token.value = num.value;309 token.repr = num.repr;310 token.type = num.type;311 return token;312 }313 };314 var consumeAnIdentlikeToken = function() {315 var str = consumeAName();316 if(str.toLowerCase() == "url" && next() == 0x28) {317 consume();318 while(whitespace(next(1)) && whitespace(next(2))) consume();319 if(next() == 0x22 || next() == 0x27) {320 return new FunctionToken(str);321 } else if(whitespace(next()) && (next(2) == 0x22 || next(2) == 0x27)) {322 return new FunctionToken(str);323 } else {324 return consumeAURLToken();325 }326 } else if(next() == 0x28) {327 consume();328 return new FunctionToken(str);329 } else {330 return new IdentifierToken(str);331 }332 };333 var consumeAStringToken = function(endingCodePoint) {334 if(endingCodePoint === undefined) endingCodePoint = code;335 var string = "";336 while(consume()) {337 if(code == endingCodePoint || eof()) {338 return new StringToken(string);339 } else if(newline(code)) {340 tokenizeerror();341 reconsume();342 return new BadStringToken();343 } else if(code == 0x5c) {344 if(eof(next())) {345 donothing();346 } else if(newline(next())) {347 consume();348 } else {349 string += stringFromCode(consumeEscape())350 }351 } else {352 string += stringFromCode(code);353 }354 }355 };356 var consumeAURLToken = function() {357 var token = new URLToken("");358 while(whitespace(next())) consume();359 if(eof(next())) return token;360 while(consume()) {361 if(code == 0x29 || eof()) {362 return token;363 } else if(whitespace(code)) {364 while(whitespace(next())) consume();365 if(next() == 0x29 || eof(next())) {366 consume();367 return token;368 } else {369 consumeTheRemnantsOfABadURL();370 return new BadURLToken();371 }372 } else if(code == 0x22 || code == 0x27 || code == 0x28 || nonprintable(code)) {373 tokenizeerror();374 consumeTheRemnantsOfABadURL();375 return new BadURLToken();376 } else if(code == 0x5c) {377 if(startsWithAValidEscape()) {378 token.value += stringFromCode(consumeEscape());379 } else {380 tokenizeerror();381 consumeTheRemnantsOfABadURL();382 return new BadURLToken();383 }384 } else {385 token.value += stringFromCode(code);386 }387 }388 };389 var consumeEscape = function() {390 // Assume the the current character is the \391 // and the next code point is not a newline.392 consume();393 if(hexdigit(code)) {394 // Consume 1-6 hex digits395 var digits = [code];396 for(var total = 0; total < 5; total++) {397 if(hexdigit(next())) {398 consume();399 digits.push(code);400 } else {401 break;402 }403 }404 if(whitespace(next())) consume();405 var value = parseInt(digits.map(function(x){return String.fromCharCode(x);}).join(''), 16);406 if( value > maximumallowedcodepoint ) value = 0xfffd;407 return value;408 } else if(eof()) {409 return 0xfffd;410 } else {411 return code;412 }413 };414 var areAValidEscape = function(c1, c2) {415 if(c1 != 0x5c) return false;416 if(newline(c2)) return false;417 return true;418 };419 var startsWithAValidEscape = function() {420 return areAValidEscape(code, next());421 };422 var wouldStartAnIdentifier = function(c1, c2, c3) {423 if(c1 == 0x2d) {424 return namestartchar(c2) || c2 == 0x2d || areAValidEscape(c2, c3);425 } else if(namestartchar(c1)) {426 return true;427 } else if(c1 == 0x5c) {428 return areAValidEscape(c1, c2);429 } else {430 return false;431 }432 };433 var startsWithAnIdentifier = function() {434 return wouldStartAnIdentifier(code, next(1), next(2));435 };436 var wouldStartANumber = function(c1, c2, c3) {437 if(c1 == 0x2b || c1 == 0x2d) {438 if(digit(c2)) return true;439 if(c2 == 0x2e && digit(c3)) return true;440 return false;441 } else if(c1 == 0x2e) {442 if(digit(c2)) return true;443 return false;444 } else if(digit(c1)) {445 return true;446 } else {447 return false;448 }449 };450 var startsWithANumber = function() {451 return wouldStartANumber(code, next(1), next(2));452 };453 var consumeAName = function() {454 var result = "";455 while(consume()) {456 if(namechar(code)) {457 result += stringFromCode(code);458 } else if(startsWithAValidEscape()) {459 result += stringFromCode(consumeEscape());460 } else {461 reconsume();462 return result;463 }464 }465 };466 var consumeANumber = function() {467 var repr = '';468 var type = "integer";469 if(next() == 0x2b || next() == 0x2d) {470 consume();471 repr += stringFromCode(code);472 }473 while(digit(next())) {474 consume();475 repr += stringFromCode(code);476 }477 if(next(1) == 0x2e && digit(next(2))) {478 consume();479 repr += stringFromCode(code);480 consume();481 repr += stringFromCode(code);482 type = "number";483 while(digit(next())) {484 consume();485 repr += stringFromCode(code);486 }487 }488 var c1 = next(1), c2 = next(2), c3 = next(3);489 if((c1 == 0x45 || c1 == 0x65) && digit(c2)) {490 consume();491 repr += stringFromCode(code);492 consume();493 repr += stringFromCode(code);494 type = "number";495 while(digit(next())) {496 consume();497 repr += stringFromCode(code);498 }499 } else if((c1 == 0x45 || c1 == 0x65) && (c2 == 0x2b || c2 == 0x2d) && digit(c3)) {500 consume();501 repr += stringFromCode(code);502 consume();503 repr += stringFromCode(code);504 consume();505 repr += stringFromCode(code);506 type = "number";507 while(digit(next())) {508 consume();509 repr += stringFromCode(code);510 }511 }512 var value = convertAStringToANumber(repr);513 return {type:type, value:value, repr:repr};514 };515 var convertAStringToANumber = function(string) {516 // CSS's number rules are identical to JS, afaik.517 return +string;518 };519 var consumeTheRemnantsOfABadURL = function() {520 while(consume()) {521 if(code == 0x2d || eof()) {522 return;523 } else if(startsWithAValidEscape()) {524 consumeEscape();525 donothing();526 } else {527 donothing();528 }529 }530 };531 var iterationCount = 0;532 while(!eof(next())) {533 tokens.push(consumeAToken());534 if(iterationCount++ > str.length*2) throw new Error("The CSS Tokenizer is infinite-looping");535 }536 return tokens;537}538function CSSParserToken() { return this; }539CSSParserToken.prototype.toJSON = function() {540 return {token: this.tokenType};541}542CSSParserToken.prototype.toString = function() { return this.tokenType; }543CSSParserToken.prototype.toCSSString = function() { return ''+this; }544function BadStringToken() { return this; }545BadStringToken.prototype = new CSSParserToken;546BadStringToken.prototype.tokenType = "BADSTRING";547BadStringToken.prototype.toCSSString = function() { return "'"; }548function BadURLToken() { return this; }549BadURLToken.prototype = new CSSParserToken;550BadURLToken.prototype.tokenType = "BADURL";551BadURLToken.prototype.toCSSString = function() { return "url("; }552function WhitespaceToken() { return this; }553WhitespaceToken.prototype = new CSSParserToken;554WhitespaceToken.prototype.tokenType = "WHITESPACE";555WhitespaceToken.prototype.toString = function() { return "WS"; }556WhitespaceToken.prototype.toCSSString = function() { return " "; }557function CDOToken() { return this; }558CDOToken.prototype = new CSSParserToken;559CDOToken.prototype.tokenType = "CDO";560CDOToken.prototype.toCSSString = function() { return "<!--"; }561function CDCToken() { return this; }562CDCToken.prototype = new CSSParserToken;563CDCToken.prototype.tokenType = "CDC";564CDCToken.prototype.toCSSString = function() { return "-->"; }565function ColonToken() { return this; }566ColonToken.prototype = new CSSParserToken;567ColonToken.prototype.tokenType = ":";568function SemicolonToken() { return this; }569SemicolonToken.prototype = new CSSParserToken;570SemicolonToken.prototype.tokenType = ";";571function CommaToken() { return this; }572CommaToken.prototype = new CSSParserToken;573CommaToken.prototype.tokenType = ",";574CommaToken.prototype.value = ";"; // backwards-compat with DELIM token575function GroupingToken() { return this; }576GroupingToken.prototype = new CSSParserToken;577function OpenCurlyToken() { this.value = "{"; this.mirror = "}"; return this; }578OpenCurlyToken.prototype = new GroupingToken;579OpenCurlyToken.prototype.tokenType = "{";580function CloseCurlyToken() { this.value = "}"; this.mirror = "{"; return this; }581CloseCurlyToken.prototype = new GroupingToken;582CloseCurlyToken.prototype.tokenType = "}";583function OpenSquareToken() { this.value = "["; this.mirror = "]"; return this; }584OpenSquareToken.prototype = new GroupingToken;585OpenSquareToken.prototype.tokenType = "[";586function CloseSquareToken() { this.value = "]"; this.mirror = "["; return this; }587CloseSquareToken.prototype = new GroupingToken;588CloseSquareToken.prototype.tokenType = "]";589function OpenParenToken() { this.value = "("; this.mirror = ")"; return this; }590OpenParenToken.prototype = new GroupingToken;591OpenParenToken.prototype.tokenType = "(";592function CloseParenToken() { this.value = ")"; this.mirror = "("; return this; }593CloseParenToken.prototype = new GroupingToken;594CloseParenToken.prototype.tokenType = ")";595function IncludeMatchToken() { return this; }596IncludeMatchToken.prototype = new CSSParserToken;597IncludeMatchToken.prototype.tokenType = "~=";598function DashMatchToken() { return this; }599DashMatchToken.prototype = new CSSParserToken;600DashMatchToken.prototype.tokenType = "|=";601function PrefixMatchToken() { return this; }602PrefixMatchToken.prototype = new CSSParserToken;603PrefixMatchToken.prototype.tokenType = "^=";604function SuffixMatchToken() { return this; }605SuffixMatchToken.prototype = new CSSParserToken;606SuffixMatchToken.prototype.tokenType = "$=";607function SubstringMatchToken() { return this; }608SubstringMatchToken.prototype = new CSSParserToken;609SubstringMatchToken.prototype.tokenType = "*=";610function ColumnToken() { return this; }611ColumnToken.prototype = new CSSParserToken;612ColumnToken.prototype.tokenType = "||";613function EOFToken() { return this; }614EOFToken.prototype = new CSSParserToken;615EOFToken.prototype.tokenType = "EOF";616EOFToken.prototype.toCSSString = function() { return ""; }617function DelimToken(code) {618 this.value = stringFromCode(code);619 return this;620}621DelimToken.prototype = new CSSParserToken;622DelimToken.prototype.tokenType = "DELIM";623DelimToken.prototype.toString = function() { return "DELIM("+this.value+")"; }624DelimToken.prototype.toCSSString = function() {625 return (this.value == "\\") ? "\\\n" : this.value;626}627function StringValuedToken() { return this; }628StringValuedToken.prototype = new CSSParserToken;629StringValuedToken.prototype.ASCIIMatch = function(str) {630 return this.value.toLowerCase() == str.toLowerCase();631}632function IdentifierToken(val) {...
cssTokenizer.js
Source:cssTokenizer.js
...71 codepoints.push(code);72 }73 return codepoints;74}75function stringFromCode(code) {76 if(code <= 0xffff) return String.fromCharCode(code);77 // Otherwise, encode astral char as surrogate pair.78 code -= Math.pow(2, 16);79 var lead = Math.floor(code/Math.pow(2, 10)) + 0xd800;80 var trail = code % Math.pow(2, 10) + 0xdc00;81 return String.fromCharCode(lead) + String.fromCharCode(trail);82}83function tokenize(str) {84 str = preprocess(str);85 var i = -1;86 var tokens = [];87 var code;88 // Line number information.89 var line = 0;90 var column = 0;91 // The only use of lastLineLength is in reconsume().92 var lastLineLength = 0;93 var incrLineno = function() {94 line += 1;95 lastLineLength = column;96 column = 0;97 };98 var locStart = {line:line, column:column};99 var codepoint = function(i) {100 if(i >= str.length) {101 return -1;102 }103 return str[i];104 }105 var next = function(num) {106 if(num === undefined)107 num = 1;108 if(num > 3)109 throw "Spec Error: no more than three codepoints of lookahead.";110 return codepoint(i+num);111 };112 var consume = function(num) {113 if(num === undefined)114 num = 1;115 i += num;116 code = codepoint(i);117 if(newline(code)) incrLineno();118 else column += num;119 //console.log('Consume '+i+' '+String.fromCharCode(code) + ' 0x' + code.toString(16));120 return true;121 };122 var reconsume = function() {123 i -= 1;124 if (newline(code)) {125 line -= 1;126 column = lastLineLength;127 } else {128 column -= 1;129 }130 locStart.line = line;131 locStart.column = column;132 return true;133 };134 var eof = function(codepoint) {135 if(codepoint === undefined) codepoint = code;136 return codepoint == -1;137 };138 var donothing = function() {};139 var parseerror = function() { console.log("Parse error at index " + i + ", processing codepoint 0x" + code.toString(16) + ".");return true; };140 var consumeAToken = function() {141 consumeComments();142 consume();143 if(whitespace(code)) {144 while(whitespace(next())) consume();145 return new WhitespaceToken;146 }147 else if(code == 0x22) return consumeAStringToken();148 else if(code == 0x23) {149 if(namechar(next()) || areAValidEscape(next(1), next(2))) {150 var token = new HashToken();151 if(wouldStartAnIdentifier(next(1), next(2), next(3))) token.type = "id";152 token.value = consumeAName();153 return token;154 } else {155 return new DelimToken(code);156 }157 }158 else if(code == 0x24) {159 if(next() == 0x3d) {160 consume();161 return new SuffixMatchToken();162 } else {163 return new DelimToken(code);164 }165 }166 else if(code == 0x27) return consumeAStringToken();167 else if(code == 0x28) return new OpenParenToken();168 else if(code == 0x29) return new CloseParenToken();169 else if(code == 0x2a) {170 if(next() == 0x3d) {171 consume();172 return new SubstringMatchToken();173 } else {174 return new DelimToken(code);175 }176 }177 else if(code == 0x2b) {178 if(startsWithANumber()) {179 reconsume();180 return consumeANumericToken();181 } else {182 return new DelimToken(code);183 }184 }185 else if(code == 0x2c) return new CommaToken();186 else if(code == 0x2d) {187 if(startsWithANumber()) {188 reconsume();189 return consumeANumericToken();190 } else if(next(1) == 0x2d && next(2) == 0x3e) {191 consume(2);192 return new CDCToken();193 } else if(startsWithAnIdentifier()) {194 reconsume();195 return consumeAnIdentlikeToken();196 } else {197 return new DelimToken(code);198 }199 }200 else if(code == 0x2e) {201 if(startsWithANumber()) {202 reconsume();203 return consumeANumericToken();204 } else {205 return new DelimToken(code);206 }207 }208 else if(code == 0x3a) return new ColonToken;209 else if(code == 0x3b) return new SemicolonToken;210 else if(code == 0x3c) {211 if(next(1) == 0x21 && next(2) == 0x2d && next(3) == 0x2d) {212 consume(3);213 return new CDOToken();214 } else {215 return new DelimToken(code);216 }217 }218 else if(code == 0x40) {219 if(wouldStartAnIdentifier(next(1), next(2), next(3))) {220 return new AtKeywordToken(consumeAName());221 } else {222 return new DelimToken(code);223 }224 }225 else if(code == 0x5b) return new OpenSquareToken();226 else if(code == 0x5c) {227 if(startsWithAValidEscape()) {228 reconsume();229 return consumeAnIdentlikeToken();230 } else {231 parseerror();232 return new DelimToken(code);233 }234 }235 else if(code == 0x5d) return new CloseSquareToken();236 else if(code == 0x5e) {237 if(next() == 0x3d) {238 consume();239 return new PrefixMatchToken();240 } else {241 return new DelimToken(code);242 }243 }244 else if(code == 0x7b) return new OpenCurlyToken();245 else if(code == 0x7c) {246 if(next() == 0x3d) {247 consume();248 return new DashMatchToken();249 } else if(next() == 0x7c) {250 consume();251 return new ColumnToken();252 } else {253 return new DelimToken(code);254 }255 }256 else if(code == 0x7d) return new CloseCurlyToken();257 else if(code == 0x7e) {258 if(next() == 0x3d) {259 consume();260 return new IncludeMatchToken();261 } else {262 return new DelimToken(code);263 }264 }265 else if(digit(code)) {266 reconsume();267 return consumeANumericToken();268 }269 else if(namestartchar(code)) {270 reconsume();271 return consumeAnIdentlikeToken();272 }273 else if(eof()) return new EOFToken();274 else return new DelimToken(code);275 };276 var consumeComments = function() {277 while(next(1) == 0x2f && next(2) == 0x2a) {278 consume(2);279 while(true) {280 consume();281 if(code == 0x2a && next() == 0x2f) {282 consume();283 break;284 } else if(eof()) {285 parseerror();286 return;287 }288 }289 }290 };291 var consumeANumericToken = function() {292 var num = consumeANumber();293 if(wouldStartAnIdentifier(next(1), next(2), next(3))) {294 var token = new DimensionToken();295 token.value = num.value;296 token.repr = num.repr;297 token.type = num.type;298 token.unit = consumeAName();299 return token;300 } else if(next() == 0x25) {301 consume();302 var token = new PercentageToken();303 token.value = num.value;304 token.repr = num.repr;305 return token;306 } else {307 var token = new NumberToken();308 token.value = num.value;309 token.repr = num.repr;310 token.type = num.type;311 return token;312 }313 };314 var consumeAnIdentlikeToken = function() {315 var str = consumeAName();316 if(str.toLowerCase() == "url" && next() == 0x28) {317 consume();318 while(whitespace(next(1)) && whitespace(next(2))) consume();319 if(next() == 0x22 || next() == 0x27) {320 return new FunctionToken(str);321 } else if(whitespace(next()) && (next(2) == 0x22 || next(2) == 0x27)) {322 return new FunctionToken(str);323 } else {324 return consumeAURLToken();325 }326 } else if(next() == 0x28) {327 consume();328 return new FunctionToken(str);329 } else {330 return new IdentToken(str);331 }332 };333 var consumeAStringToken = function(endingCodePoint) {334 if(endingCodePoint === undefined) endingCodePoint = code;335 var string = "";336 while(consume()) {337 if(code == endingCodePoint || eof()) {338 return new StringToken(string);339 } else if(newline(code)) {340 parseerror();341 reconsume();342 return new BadStringToken();343 } else if(code == 0x5c) {344 if(eof(next())) {345 donothing();346 } else if(newline(next())) {347 consume();348 } else {349 string += stringFromCode(consumeEscape())350 }351 } else {352 string += stringFromCode(code);353 }354 }355 };356 var consumeAURLToken = function() {357 var token = new URLToken("");358 while(whitespace(next())) consume();359 if(eof(next())) return token;360 while(consume()) {361 if(code == 0x29 || eof()) {362 return token;363 } else if(whitespace(code)) {364 while(whitespace(next())) consume();365 if(next() == 0x29 || eof(next())) {366 consume();367 return token;368 } else {369 consumeTheRemnantsOfABadURL();370 return new BadURLToken();371 }372 } else if(code == 0x22 || code == 0x27 || code == 0x28 || nonprintable(code)) {373 parseerror();374 consumeTheRemnantsOfABadURL();375 return new BadURLToken();376 } else if(code == 0x5c) {377 if(startsWithAValidEscape()) {378 token.value += stringFromCode(consumeEscape());379 } else {380 parseerror();381 consumeTheRemnantsOfABadURL();382 return new BadURLToken();383 }384 } else {385 token.value += stringFromCode(code);386 }387 }388 };389 var consumeEscape = function() {390 // Assume the the current character is the \391 // and the next code point is not a newline.392 consume();393 if(hexdigit(code)) {394 // Consume 1-6 hex digits395 var digits = [code];396 for(var total = 0; total < 5; total++) {397 if(hexdigit(next())) {398 consume();399 digits.push(code);400 } else {401 break;402 }403 }404 if(whitespace(next())) consume();405 var value = parseInt(digits.map(function(x){return String.fromCharCode(x);}).join(''), 16);406 if( value > maximumallowedcodepoint ) value = 0xfffd;407 return value;408 } else if(eof()) {409 return 0xfffd;410 } else {411 return code;412 }413 };414 var areAValidEscape = function(c1, c2) {415 if(c1 != 0x5c) return false;416 if(newline(c2)) return false;417 return true;418 };419 var startsWithAValidEscape = function() {420 return areAValidEscape(code, next());421 };422 var wouldStartAnIdentifier = function(c1, c2, c3) {423 if(c1 == 0x2d) {424 return namestartchar(c2) || c2 == 0x2d || areAValidEscape(c2, c3);425 } else if(namestartchar(c1)) {426 return true;427 } else if(c1 == 0x5c) {428 return areAValidEscape(c1, c2);429 } else {430 return false;431 }432 };433 var startsWithAnIdentifier = function() {434 return wouldStartAnIdentifier(code, next(1), next(2));435 };436 var wouldStartANumber = function(c1, c2, c3) {437 if(c1 == 0x2b || c1 == 0x2d) {438 if(digit(c2)) return true;439 if(c2 == 0x2e && digit(c3)) return true;440 return false;441 } else if(c1 == 0x2e) {442 if(digit(c2)) return true;443 return false;444 } else if(digit(c1)) {445 return true;446 } else {447 return false;448 }449 };450 var startsWithANumber = function() {451 return wouldStartANumber(code, next(1), next(2));452 };453 var consumeAName = function() {454 var result = "";455 while(consume()) {456 if(namechar(code)) {457 result += stringFromCode(code);458 } else if(startsWithAValidEscape()) {459 result += stringFromCode(consumeEscape());460 } else {461 reconsume();462 return result;463 }464 }465 };466 var consumeANumber = function() {467 var repr = [];468 var type = "integer";469 if(next() == 0x2b || next() == 0x2d) {470 consume();471 repr += stringFromCode(code);472 }473 while(digit(next())) {474 consume();475 repr += stringFromCode(code);476 }477 if(next(1) == 0x2e && digit(next(2))) {478 consume();479 repr += stringFromCode(code);480 consume();481 repr += stringFromCode(code);482 type = "number";483 while(digit(next())) {484 consume();485 repr += stringFromCode(code);486 }487 }488 var c1 = next(1), c2 = next(2), c3 = next(3);489 if((c1 == 0x45 || c1 == 0x65) && digit(c2)) {490 consume();491 repr += stringFromCode(code);492 consume();493 repr += stringFromCode(code);494 type = "number";495 while(digit(next())) {496 consume();497 repr += stringFromCode(code);498 }499 } else if((c1 == 0x45 || c1 == 0x65) && (c2 == 0x2b || c2 == 0x2d) && digit(c3)) {500 consume();501 repr += stringFromCode(code);502 consume();503 repr += stringFromCode(code);504 consume();505 repr += stringFromCode(code);506 type = "number";507 while(digit(next())) {508 consume();509 repr += stringFromCode(code);510 }511 }512 var value = convertAStringToANumber(repr);513 return {type:type, value:value, repr:repr};514 };515 var convertAStringToANumber = function(string) {516 // CSS's number rules are identical to JS, afaik.517 return +string;518 };519 var consumeTheRemnantsOfABadURL = function() {520 while(consume()) {521 if(code == 0x29 || eof()) {522 return;523 } else if(startsWithAValidEscape()) {524 consumeEscape();525 donothing();526 } else {527 donothing();528 }529 }530 };531 var iterationCount = 0;532 while(!eof(next())) {533 tokens.push(consumeAToken());534 iterationCount++;535 if(iterationCount > str.length*2) return "I'm infinite-looping!";536 }537 return tokens;538}539function CSSParserToken() { throw "Abstract Base Class"; }540CSSParserToken.prototype.toJSON = function() {541 return {token: this.tokenType};542}543CSSParserToken.prototype.toString = function() { return this.tokenType; }544CSSParserToken.prototype.toSource = function() { return ''+this; }545function BadStringToken() { return this; }546BadStringToken.prototype = Object.create(CSSParserToken.prototype);547BadStringToken.prototype.tokenType = "BADSTRING";548function BadURLToken() { return this; }549BadURLToken.prototype = Object.create(CSSParserToken.prototype);550BadURLToken.prototype.tokenType = "BADURL";551function WhitespaceToken() { return this; }552WhitespaceToken.prototype = Object.create(CSSParserToken.prototype);553WhitespaceToken.prototype.tokenType = "WHITESPACE";554WhitespaceToken.prototype.toString = function() { return "WS"; }555WhitespaceToken.prototype.toSource = function() { return " "; }556function CDOToken() { return this; }557CDOToken.prototype = Object.create(CSSParserToken.prototype);558CDOToken.prototype.tokenType = "CDO";559CDOToken.prototype.toSource = function() { return "<!--"; }560function CDCToken() { return this; }561CDCToken.prototype = Object.create(CSSParserToken.prototype);562CDCToken.prototype.tokenType = "CDC";563CDCToken.prototype.toSource = function() { return "-->"; }564function ColonToken() { return this; }565ColonToken.prototype = Object.create(CSSParserToken.prototype);566ColonToken.prototype.tokenType = ":";567function SemicolonToken() { return this; }568SemicolonToken.prototype = Object.create(CSSParserToken.prototype);569SemicolonToken.prototype.tokenType = ";";570function CommaToken() { return this; }571CommaToken.prototype = Object.create(CSSParserToken.prototype);572CommaToken.prototype.tokenType = ",";573function GroupingToken() { throw "Abstract Base Class"; }574GroupingToken.prototype = Object.create(CSSParserToken.prototype);575function OpenCurlyToken() { this.value = "{"; this.mirror = "}"; return this; }576OpenCurlyToken.prototype = Object.create(GroupingToken.prototype);577OpenCurlyToken.prototype.tokenType = "{";578function CloseCurlyToken() { this.value = "}"; this.mirror = "{"; return this; }579CloseCurlyToken.prototype = Object.create(GroupingToken.prototype);580CloseCurlyToken.prototype.tokenType = "}";581function OpenSquareToken() { this.value = "["; this.mirror = "]"; return this; }582OpenSquareToken.prototype = Object.create(GroupingToken.prototype);583OpenSquareToken.prototype.tokenType = "[";584function CloseSquareToken() { this.value = "]"; this.mirror = "["; return this; }585CloseSquareToken.prototype = Object.create(GroupingToken.prototype);586CloseSquareToken.prototype.tokenType = "]";587function OpenParenToken() { this.value = "("; this.mirror = ")"; return this; }588OpenParenToken.prototype = Object.create(GroupingToken.prototype);589OpenParenToken.prototype.tokenType = "(";590function CloseParenToken() { this.value = ")"; this.mirror = "("; return this; }591CloseParenToken.prototype = Object.create(GroupingToken.prototype);592CloseParenToken.prototype.tokenType = ")";593function IncludeMatchToken() { return this; }594IncludeMatchToken.prototype = Object.create(CSSParserToken.prototype);595IncludeMatchToken.prototype.tokenType = "~=";596function DashMatchToken() { return this; }597DashMatchToken.prototype = Object.create(CSSParserToken.prototype);598DashMatchToken.prototype.tokenType = "|=";599function PrefixMatchToken() { return this; }600PrefixMatchToken.prototype = Object.create(CSSParserToken.prototype);601PrefixMatchToken.prototype.tokenType = "^=";602function SuffixMatchToken() { return this; }603SuffixMatchToken.prototype = Object.create(CSSParserToken.prototype);604SuffixMatchToken.prototype.tokenType = "$=";605function SubstringMatchToken() { return this; }606SubstringMatchToken.prototype = Object.create(CSSParserToken.prototype);607SubstringMatchToken.prototype.tokenType = "*=";608function ColumnToken() { return this; }609ColumnToken.prototype = Object.create(CSSParserToken.prototype);610ColumnToken.prototype.tokenType = "||";611function EOFToken() { return this; }612EOFToken.prototype = Object.create(CSSParserToken.prototype);613EOFToken.prototype.tokenType = "EOF";614EOFToken.prototype.toSource = function() { return ""; }615function DelimToken(code) {616 this.value = stringFromCode(code);617 return this;618}619DelimToken.prototype = Object.create(CSSParserToken.prototype);620DelimToken.prototype.tokenType = "DELIM";621DelimToken.prototype.toString = function() { return "DELIM("+this.value+")"; }622DelimToken.prototype.toJSON = function() {623 var json = this.constructor.prototype.constructor.prototype.toJSON.call(this);624 json.value = this.value;625 return json;626}627DelimToken.prototype.toSource = function() {628 if(this.value == "\\")629 return "\\\n";630 else...
rules.js
Source:rules.js
...18 if (contains([8, 0, 37, 39, 9], c) || (e.ctrlKey && contains([120, 118, 99, 97, 88, 86, 67], c))) return true;19 return false;20}21// shortcut for String.fromCharCode22function stringFromCode(c) {23 return String.fromCharCode(c);24}25// shortcut for string match regex call26function match(s, rx) {27 return s.match(rx);28}29/**30 * Returns the value that a field will have, if the given keypress event goes through.31 * 32 * @param {*} e 33 */34function foreseeValue(e) {35 var a = "selectionStart",36 b = "selectionEnd",37 element = e.target,38 value = element.value,39 c = e.keyCode || e.charCode,40 key = stringFromCode(c),41 selected = value.substr(element[a], element[b]),42 beforeSelection = value.substr(0, element[a]),43 afterSelection = value.substr(element[b], value.length);44 return [beforeSelection, key, afterSelection].join("");45}46function onlyDigits(e, c) {47 var c = (e.keyCode || e.charCode), key = stringFromCode(c);48 if (!permittedCharacters(e, c) && !match(key, /\d/)) return false;49 return true;50}51const Constraints = {52 // Allows to input only letters53 letters: function (e, c) {54 var c = (e.keyCode || e.charCode), key = stringFromCode(c);55 if (!permittedCharacters(e, c) && !match(key, /[a-zA-Z]/)) return false;56 return true;57 },58 // Allows to input only digits59 digits: onlyDigits,60 integer: onlyDigits61};62export { 63 Constraints, 64 foreseeValue, 65 permittedCharacters,66 stringFromCode,67 match68}
map-practice-solution.js
Source:map-practice-solution.js
1// 12const lyrics = ['never', 'gonna', 'give', 'you', 'up'];3const uppercaseLyrics = lyrics.map((lyric) => {4 return lyric.toUpperCase();5});6console.log(uppercaseLyrics);7// 28const people = [9 {10 name: 'George Michael',11 age: 14,12 title: 'Mr. Manager',13 },14 {15 name: 'T-Bone',16 age: 34,17 title: 'Arsonist',18 },19 {20 name: 'George Oscar',21 age: 32,22 title: 'Illusionist',23 },24];25const names = people.map((person) => {26 return person.name;27});28console.log(names);29// 330const products = [31 {32 name: 'iPad',33 price: 549.99,34 },35 {36 name: 'iPhone',37 price: 799.99,38 },39 {40 name: 'iPod',41 price: 2.99,42 },43];44const tax = products.map((product) => {45 return product.price * .07;46});47console.log(tax);48// 449const trip = [50 'Visit my parents',51 'Eat at Murray\'s',52 'Washington Square Park',53 'Take the Staten Island Ferry',54 'Whitney Museum'];55const shortenedTrip = trip.map((tripItem) => {56 if (tripItem.length > 20) {57 return `${tripItem.substring(0, 17)}...`;58 } else {59 return tripItem;60 }61});62console.log(shortenedTrip);63// 564const possiblyVowels = [118, 117, 120, 121, 117, 98, 122, 97, 120, 106, 104, 116, 113, 114, 113, 120, 106];65const definitelyVowels = possiblyVowels.map((code) => {66 const stringFromCode = String.fromCharCode(code);67 const vowels = ['a', 'e', 'i', 'o', 'u'];68 if (vowels.includes(stringFromCode)) {69 return stringFromCode;70 }71 return code;72});...
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const str = await page.evaluate(() => {7 const { stringFromCode } = require('playwright/internal/protocol-helper');8 return stringFromCode('a');9 });10 console.log(str);11 await browser.close();12})();
Using AI Code Generation
1const { chromium } = require('playwright');2const { stringFromCode } = require('playwright/internal');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 const text = await page.textContent('.navbar__inner');8 console.log(stringFromCode(text));9 await browser.close();10})();11const { chromium } = require('playwright');12const { stringFromCode } = require('playwright/internal');13(async () => {14 const browser = await chromium.launch();15 const context = await browser.newContext();16 const page = await context.newPage();17 const text = await page.textContent('.navbar__inner');18 console.log(stringFromCode(text));19 await browser.close();20})();21const { chromium } = require('playwright');22const { stringFromCode } = require('playwright/internal');23(async () => {24 const browser = await chromium.launch();25 const context = await browser.newContext();26 const page = await context.newPage();27 const text = await page.textContent('.navbar__inner');28 console.log(stringFromCode(text));29 await browser.close();30})();31const { chromium } = require('playwright');32const { stringFromCode } = require('playwright/internal');33(async () => {34 const browser = await chromium.launch();35 const context = await browser.newContext();36 const page = await context.newPage();37 const text = await page.textContent('.navbar__inner');38 console.log(stringFromCode(text));39 await browser.close();40})();
Using AI Code Generation
1const { stringFromCode } = require('playwright/lib/utils/charCodes');2console.log(stringFromCode(65));3console.log(stringFromCode(66));4console.log(stringFromCode(67));5console.log(stringFromCode(68));6console.log(stringFromCode(69));7console.log(stringFromCode(70));8console.log(stringFromCode(71));9console.log(stringFromCode(72));10console.log(stringFromCode(73));11console.log(stringFromCode(74));12console.log(stringFromCode(75));13console.log(stringFromCode(76));14console.log(stringFromCode(77));15console.log(stringFromCode(78));16console.log(stringFromCode(79));17console.log(stringFromCode(80));18console.log(stringFromCode(81));19console.log(stringFromCode(82));20console.log(stringFromCode(83));21console.log(stringFromCode(84));22console.log(stringFromCode(85));23console.log(stringFromCode(86));24console.log(stringFromCode(87));25console.log(stringFromCode(88));26console.log(stringFromCode(89));27console.log(stringFromCode(90));28console.log(stringFromCode(91));29console.log(stringFromCode(92));30console.log(stringFromCode(93));31console.log(stringFromCode(94));32console.log(stringFromCode(95));33console.log(stringFromCode(96));34console.log(stringFromCode(97));35console.log(stringFromCode(98));36console.log(stringFromCode(99));37console.log(stringFromCode(100));38console.log(stringFromCode(101));39console.log(stringFromCode(102));40console.log(stringFromCode(103));41console.log(stringFromCode(104));42console.log(stringFromCode(105));43console.log(stringFromCode(106));44console.log(stringFromCode(107));45console.log(stringFromCode(108));46console.log(stringFromCode(109));47console.log(stringFromCode(110));48console.log(stringFromCode(111));49console.log(stringFromCode(112));50console.log(stringFromCode(113));51console.log(stringFromCode(114));52console.log(stringFromCode(115));53console.log(stringFromCode(116));54console.log(stringFromCode(117));55console.log(stringFromCode(118));56console.log(stringFromCode(119));57console.log(stringFromCode(120));58console.log(stringFromCode(121));59console.log(stringFromCode(122));60console.log(stringFromCode(123));61console.log(stringFromCode(124));
Using AI Code Generation
1const { stringFromCode } = require('playwright-core/lib/utils/stackTrace');2const { test } = require('@playwright/test');3test('test', async ({ page }) => {4 await page.click('text=Get started');5 await page.click('text=Docs');6 const text = await page.innerText('text=Docs');7 console.log(stringFromCode(text));8});9 at Object.<anonymous> (test.js:12:15)10 ✓ test (2s)11 1 passed (2s)12[Apache 2.0](LICENSE)
Using AI Code Generation
1const { stringFromCode } = require('@playwright/test/lib/utils/stackTrace');2 const { stringFromCode } = require('@playwright/test/lib/utils/stackTrace');3 const code = "console.log('Hello World')";4 console.log(stringFromCode(code));5`;6console.log(stringFromCode(code));
Using AI Code Generation
1const { stringFromCode } = require('playwright/lib/protocol/serializers');2const { test } = require('playwright');3test('test', async ({ page }) => {4 const title = await page.title();5 console.log(stringFromCode(title, 'js'));6});7const { test } = require('playwright');8test('test', async ({ page }) => {9 const title = await page.title();10 console.log('Playwright');11});12[MIT](LICENSE)
Using AI Code Generation
1const { test, expect } = require('@playwright/test');2test('My first test', async ({ page }) => {3 const title = page.locator('text=Get started');4 await expect(title).toBeVisible();5});6test('My second test', async ({ page }) => {7 const title = page.locator('text=Get started');8 await expect(title).toBeVisible();9});
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!