| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/css/parser/CSSTokenizer.h" | 5 #include "core/css/parser/CSSTokenizer.h" |
| 6 | 6 |
| 7 namespace blink { | 7 namespace blink { |
| 8 #include "core/CSSTokenizerCodepoints.cpp" | 8 #include "core/CSSTokenizerCodepoints.cpp" |
| 9 } | 9 } |
| 10 | 10 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 return CSSParserToken(ColonToken); | 239 return CSSParserToken(ColonToken); |
| 240 } | 240 } |
| 241 | 241 |
| 242 CSSParserToken CSSTokenizer::semiColon(UChar cc) | 242 CSSParserToken CSSTokenizer::semiColon(UChar cc) |
| 243 { | 243 { |
| 244 return CSSParserToken(SemicolonToken); | 244 return CSSParserToken(SemicolonToken); |
| 245 } | 245 } |
| 246 | 246 |
| 247 CSSParserToken CSSTokenizer::hash(UChar cc) | 247 CSSParserToken CSSTokenizer::hash(UChar cc) |
| 248 { | 248 { |
| 249 UChar nextChar = m_input.nextInputChar(); | 249 UChar nextChar = m_input.peekWithoutReplacement(0); |
| 250 if (isNameCodePoint(nextChar) || twoCharsAreValidEscape(nextChar, m_input.pe
ekWithoutReplacement(1))) { | 250 if (isNameCodePoint(nextChar) || twoCharsAreValidEscape(nextChar, m_input.pe
ekWithoutReplacement(1))) { |
| 251 HashTokenType type = nextCharsAreIdentifier() ? HashTokenId : HashTokenU
nrestricted; | 251 HashTokenType type = nextCharsAreIdentifier() ? HashTokenId : HashTokenU
nrestricted; |
| 252 return CSSParserToken(type, consumeName()); | 252 return CSSParserToken(type, consumeName()); |
| 253 } | 253 } |
| 254 | 254 |
| 255 return CSSParserToken(DelimiterToken, cc); | 255 return CSSParserToken(DelimiterToken, cc); |
| 256 } | 256 } |
| 257 | 257 |
| 258 CSSParserToken CSSTokenizer::circumflexAccent(UChar cc) | 258 CSSParserToken CSSTokenizer::circumflexAccent(UChar cc) |
| 259 { | 259 { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 CSSParserToken CSSTokenizer::commercialAt(UChar cc) | 292 CSSParserToken CSSTokenizer::commercialAt(UChar cc) |
| 293 { | 293 { |
| 294 ASSERT(cc == '@'); | 294 ASSERT(cc == '@'); |
| 295 if (nextCharsAreIdentifier()) | 295 if (nextCharsAreIdentifier()) |
| 296 return CSSParserToken(AtKeywordToken, consumeName()); | 296 return CSSParserToken(AtKeywordToken, consumeName()); |
| 297 return CSSParserToken(DelimiterToken, '@'); | 297 return CSSParserToken(DelimiterToken, '@'); |
| 298 } | 298 } |
| 299 | 299 |
| 300 CSSParserToken CSSTokenizer::reverseSolidus(UChar cc) | 300 CSSParserToken CSSTokenizer::reverseSolidus(UChar cc) |
| 301 { | 301 { |
| 302 if (twoCharsAreValidEscape(cc, m_input.nextInputChar())) { | 302 if (twoCharsAreValidEscape(cc, m_input.peekWithoutReplacement(0))) { |
| 303 reconsume(cc); | 303 reconsume(cc); |
| 304 return consumeIdentLikeToken(); | 304 return consumeIdentLikeToken(); |
| 305 } | 305 } |
| 306 return CSSParserToken(DelimiterToken, cc); | 306 return CSSParserToken(DelimiterToken, cc); |
| 307 } | 307 } |
| 308 | 308 |
| 309 CSSParserToken CSSTokenizer::asciiDigit(UChar cc) | 309 CSSParserToken CSSTokenizer::asciiDigit(UChar cc) |
| 310 { | 310 { |
| 311 reconsume(cc); | 311 reconsume(cc); |
| 312 return consumeNumericToken(); | 312 return consumeNumericToken(); |
| 313 } | 313 } |
| 314 | 314 |
| 315 CSSParserToken CSSTokenizer::letterU(UChar cc) | 315 CSSParserToken CSSTokenizer::letterU(UChar cc) |
| 316 { | 316 { |
| 317 if (m_input.nextInputChar() == '+' | 317 if (m_input.peekWithoutReplacement(0) == '+' |
| 318 && (isASCIIHexDigit(m_input.peekWithoutReplacement(1)) | 318 && (isASCIIHexDigit(m_input.peekWithoutReplacement(1)) |
| 319 || m_input.peekWithoutReplacement(1) == '?')) { | 319 || m_input.peekWithoutReplacement(1) == '?')) { |
| 320 m_input.advance(); | 320 m_input.advance(); |
| 321 return consumeUnicodeRange(); | 321 return consumeUnicodeRange(); |
| 322 } | 322 } |
| 323 reconsume(cc); | 323 reconsume(cc); |
| 324 return consumeIdentLikeToken(); | 324 return consumeIdentLikeToken(); |
| 325 } | 325 } |
| 326 | 326 |
| 327 CSSParserToken CSSTokenizer::nameStart(UChar cc) | 327 CSSParserToken CSSTokenizer::nameStart(UChar cc) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 codePointFunc = &CSSTokenizer::nameStart; | 359 codePointFunc = &CSSTokenizer::nameStart; |
| 360 } | 360 } |
| 361 | 361 |
| 362 if (codePointFunc) | 362 if (codePointFunc) |
| 363 return ((this)->*(codePointFunc))(cc); | 363 return ((this)->*(codePointFunc))(cc); |
| 364 return CSSParserToken(DelimiterToken, cc); | 364 return CSSParserToken(DelimiterToken, cc); |
| 365 } | 365 } |
| 366 | 366 |
| 367 static NumericSign getSign(CSSTokenizerInputStream& input, unsigned& offset) | 367 static NumericSign getSign(CSSTokenizerInputStream& input, unsigned& offset) |
| 368 { | 368 { |
| 369 if (input.nextInputChar() == '+') { | 369 UChar next = input.peekWithoutReplacement(0); |
| 370 if (next == '+') { |
| 370 ++offset; | 371 ++offset; |
| 371 return PlusSign; | 372 return PlusSign; |
| 372 } | 373 } |
| 373 if (input.nextInputChar() == '-') { | 374 if (next == '-') { |
| 374 ++offset; | 375 ++offset; |
| 375 return MinusSign; | 376 return MinusSign; |
| 376 } | 377 } |
| 377 return NoSign; | 378 return NoSign; |
| 378 } | 379 } |
| 379 | 380 |
| 380 static double getInteger(CSSTokenizerInputStream& input, unsigned& offset) | 381 static double getInteger(CSSTokenizerInputStream& input, unsigned& offset) |
| 381 { | 382 { |
| 382 unsigned intStartPos = offset; | 383 unsigned intStartPos = offset; |
| 383 offset = input.skipWhilePredicate<isASCIIDigit>(offset); | 384 offset = input.skipWhilePredicate<isASCIIDigit>(offset); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 | 461 |
| 461 // http://dev.w3.org/csswg/css-syntax/#consume-ident-like-token | 462 // http://dev.w3.org/csswg/css-syntax/#consume-ident-like-token |
| 462 CSSParserToken CSSTokenizer::consumeIdentLikeToken() | 463 CSSParserToken CSSTokenizer::consumeIdentLikeToken() |
| 463 { | 464 { |
| 464 StringView name = consumeName(); | 465 StringView name = consumeName(); |
| 465 if (consumeIfNext('(')) { | 466 if (consumeIfNext('(')) { |
| 466 if (equalIgnoringASCIICase(name, "url")) { | 467 if (equalIgnoringASCIICase(name, "url")) { |
| 467 // The spec is slightly different so as to avoid dropping whitespace | 468 // The spec is slightly different so as to avoid dropping whitespace |
| 468 // tokens, but they wouldn't be used and this is easier. | 469 // tokens, but they wouldn't be used and this is easier. |
| 469 m_input.advanceUntilNonWhitespace(); | 470 m_input.advanceUntilNonWhitespace(); |
| 470 UChar next = m_input.nextInputChar(); | 471 UChar next = m_input.peekWithoutReplacement(0); |
| 471 if (next != '"' && next != '\'') | 472 if (next != '"' && next != '\'') |
| 472 return consumeUrlToken(); | 473 return consumeUrlToken(); |
| 473 } | 474 } |
| 474 return blockStart(LeftParenthesisToken, FunctionToken, name); | 475 return blockStart(LeftParenthesisToken, FunctionToken, name); |
| 475 } | 476 } |
| 476 return CSSParserToken(IdentToken, name); | 477 return CSSParserToken(IdentToken, name); |
| 477 } | 478 } |
| 478 | 479 |
| 479 // http://dev.w3.org/csswg/css-syntax/#consume-a-string-token | 480 // http://dev.w3.org/csswg/css-syntax/#consume-a-string-token |
| 480 CSSParserToken CSSTokenizer::consumeStringTokenUntil(UChar endingCodePoint) | 481 CSSParserToken CSSTokenizer::consumeStringTokenUntil(UChar endingCodePoint) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 500 UChar cc = consume(); | 501 UChar cc = consume(); |
| 501 if (cc == endingCodePoint || cc == kEndOfFileMarker) | 502 if (cc == endingCodePoint || cc == kEndOfFileMarker) |
| 502 return CSSParserToken(StringToken, registerString(output.toString())
); | 503 return CSSParserToken(StringToken, registerString(output.toString())
); |
| 503 if (isNewLine(cc)) { | 504 if (isNewLine(cc)) { |
| 504 reconsume(cc); | 505 reconsume(cc); |
| 505 return CSSParserToken(BadStringToken); | 506 return CSSParserToken(BadStringToken); |
| 506 } | 507 } |
| 507 if (cc == '\\') { | 508 if (cc == '\\') { |
| 508 if (m_input.nextInputChar() == kEndOfFileMarker) | 509 if (m_input.nextInputChar() == kEndOfFileMarker) |
| 509 continue; | 510 continue; |
| 510 if (isNewLine(m_input.nextInputChar())) | 511 if (isNewLine(m_input.peekWithoutReplacement(0))) |
| 511 consumeSingleWhitespaceIfNext(); // This handles \r\n for us | 512 consumeSingleWhitespaceIfNext(); // This handles \r\n for us |
| 512 else | 513 else |
| 513 output.append(consumeEscape()); | 514 output.append(consumeEscape()); |
| 514 } else { | 515 } else { |
| 515 output.append(cc); | 516 output.append(cc); |
| 516 } | 517 } |
| 517 } | 518 } |
| 518 } | 519 } |
| 519 | 520 |
| 520 CSSParserToken CSSTokenizer::consumeUnicodeRange() | 521 CSSParserToken CSSTokenizer::consumeUnicodeRange() |
| 521 { | 522 { |
| 522 ASSERT(isASCIIHexDigit(m_input.nextInputChar()) || m_input.nextInputChar() =
= '?'); | 523 DCHECK(isASCIIHexDigit(m_input.peekWithoutReplacement(0)) || m_input.peekWit
houtReplacement(0) == '?'); |
| 523 int lengthRemaining = 6; | 524 int lengthRemaining = 6; |
| 524 UChar32 start = 0; | 525 UChar32 start = 0; |
| 525 | 526 |
| 526 while (lengthRemaining && isASCIIHexDigit(m_input.nextInputChar())) { | 527 while (lengthRemaining && isASCIIHexDigit(m_input.peekWithoutReplacement(0))
) { |
| 527 start = start * 16 + toASCIIHexValue(consume()); | 528 start = start * 16 + toASCIIHexValue(consume()); |
| 528 --lengthRemaining; | 529 --lengthRemaining; |
| 529 } | 530 } |
| 530 | 531 |
| 531 UChar32 end = start; | 532 UChar32 end = start; |
| 532 if (lengthRemaining && consumeIfNext('?')) { | 533 if (lengthRemaining && consumeIfNext('?')) { |
| 533 do { | 534 do { |
| 534 start *= 16; | 535 start *= 16; |
| 535 end = end * 16 + 0xF; | 536 end = end * 16 + 0xF; |
| 536 --lengthRemaining; | 537 --lengthRemaining; |
| 537 } while (lengthRemaining && consumeIfNext('?')); | 538 } while (lengthRemaining && consumeIfNext('?')); |
| 538 } else if (m_input.nextInputChar() == '-' && isASCIIHexDigit(m_input.peekWit
houtReplacement(1))) { | 539 } else if (m_input.peekWithoutReplacement(0) == '-' && isASCIIHexDigit(m_inp
ut.peekWithoutReplacement(1))) { |
| 539 m_input.advance(); | 540 m_input.advance(); |
| 540 lengthRemaining = 6; | 541 lengthRemaining = 6; |
| 541 end = 0; | 542 end = 0; |
| 542 do { | 543 do { |
| 543 end = end * 16 + toASCIIHexValue(consume()); | 544 end = end * 16 + toASCIIHexValue(consume()); |
| 544 --lengthRemaining; | 545 --lengthRemaining; |
| 545 } while (lengthRemaining && isASCIIHexDigit(m_input.nextInputChar())); | 546 } while (lengthRemaining && isASCIIHexDigit(m_input.peekWithoutReplaceme
nt(0))); |
| 546 } | 547 } |
| 547 | 548 |
| 548 return CSSParserToken(UnicodeRangeToken, start, end); | 549 return CSSParserToken(UnicodeRangeToken, start, end); |
| 549 } | 550 } |
| 550 | 551 |
| 551 // http://dev.w3.org/csswg/css-syntax/#non-printable-code-point | 552 // http://dev.w3.org/csswg/css-syntax/#non-printable-code-point |
| 552 static bool isNonPrintableCodePoint(UChar cc) | 553 static bool isNonPrintableCodePoint(UChar cc) |
| 553 { | 554 { |
| 554 return (cc >= '\0' && cc <= '\x8') || cc == '\xb' || (cc >= '\xe' && cc <= '
\x1f') || cc == '\x7f'; | 555 return (cc >= '\0' && cc <= '\x8') || cc == '\xb' || (cc >= '\xe' && cc <= '
\x1f') || cc == '\x7f'; |
| 555 } | 556 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 581 m_input.advanceUntilNonWhitespace(); | 582 m_input.advanceUntilNonWhitespace(); |
| 582 if (consumeIfNext(')') || m_input.nextInputChar() == kEndOfFileMarke
r) | 583 if (consumeIfNext(')') || m_input.nextInputChar() == kEndOfFileMarke
r) |
| 583 return CSSParserToken(UrlToken, registerString(result.toString()
)); | 584 return CSSParserToken(UrlToken, registerString(result.toString()
)); |
| 584 break; | 585 break; |
| 585 } | 586 } |
| 586 | 587 |
| 587 if (cc == '"' || cc == '\'' || cc == '(' || isNonPrintableCodePoint(cc)) | 588 if (cc == '"' || cc == '\'' || cc == '(' || isNonPrintableCodePoint(cc)) |
| 588 break; | 589 break; |
| 589 | 590 |
| 590 if (cc == '\\') { | 591 if (cc == '\\') { |
| 591 if (twoCharsAreValidEscape(cc, m_input.nextInputChar())) { | 592 if (twoCharsAreValidEscape(cc, m_input.peekWithoutReplacement(0))) { |
| 592 result.append(consumeEscape()); | 593 result.append(consumeEscape()); |
| 593 continue; | 594 continue; |
| 594 } | 595 } |
| 595 break; | 596 break; |
| 596 } | 597 } |
| 597 | 598 |
| 598 result.append(cc); | 599 result.append(cc); |
| 599 } | 600 } |
| 600 | 601 |
| 601 consumeBadUrlRemnants(); | 602 consumeBadUrlRemnants(); |
| 602 return CSSParserToken(BadUrlToken); | 603 return CSSParserToken(BadUrlToken); |
| 603 } | 604 } |
| 604 | 605 |
| 605 // http://dev.w3.org/csswg/css-syntax/#consume-the-remnants-of-a-bad-url | 606 // http://dev.w3.org/csswg/css-syntax/#consume-the-remnants-of-a-bad-url |
| 606 void CSSTokenizer::consumeBadUrlRemnants() | 607 void CSSTokenizer::consumeBadUrlRemnants() |
| 607 { | 608 { |
| 608 while (true) { | 609 while (true) { |
| 609 UChar cc = consume(); | 610 UChar cc = consume(); |
| 610 if (cc == ')' || cc == kEndOfFileMarker) | 611 if (cc == ')' || cc == kEndOfFileMarker) |
| 611 return; | 612 return; |
| 612 if (twoCharsAreValidEscape(cc, m_input.nextInputChar())) | 613 if (twoCharsAreValidEscape(cc, m_input.peekWithoutReplacement(0))) |
| 613 consumeEscape(); | 614 consumeEscape(); |
| 614 } | 615 } |
| 615 } | 616 } |
| 616 | 617 |
| 617 void CSSTokenizer::consumeSingleWhitespaceIfNext() | 618 void CSSTokenizer::consumeSingleWhitespaceIfNext() |
| 618 { | 619 { |
| 619 // We check for \r\n and HTML spaces since we don't do preprocessing | 620 // We check for \r\n and HTML spaces since we don't do preprocessing |
| 620 UChar c = m_input.nextInputChar(); | 621 UChar next = m_input.peekWithoutReplacement(0); |
| 621 if (c == '\r' && m_input.peekWithoutReplacement(1) == '\n') | 622 if (next == '\r' && m_input.peekWithoutReplacement(1) == '\n') |
| 622 m_input.advance(2); | 623 m_input.advance(2); |
| 623 else if (isHTMLSpace(c)) | 624 else if (isHTMLSpace(next)) |
| 624 m_input.advance(); | 625 m_input.advance(); |
| 625 } | 626 } |
| 626 | 627 |
| 627 void CSSTokenizer::consumeUntilCommentEndFound() | 628 void CSSTokenizer::consumeUntilCommentEndFound() |
| 628 { | 629 { |
| 629 UChar c = consume(); | 630 UChar c = consume(); |
| 630 while (true) { | 631 while (true) { |
| 631 if (c == kEndOfFileMarker) | 632 if (c == kEndOfFileMarker) |
| 632 return; | 633 return; |
| 633 if (c != '*') { | 634 if (c != '*') { |
| 634 c = consume(); | 635 c = consume(); |
| 635 continue; | 636 continue; |
| 636 } | 637 } |
| 637 c = consume(); | 638 c = consume(); |
| 638 if (c == '/') | 639 if (c == '/') |
| 639 return; | 640 return; |
| 640 } | 641 } |
| 641 } | 642 } |
| 642 | 643 |
| 643 bool CSSTokenizer::consumeIfNext(UChar character) | 644 bool CSSTokenizer::consumeIfNext(UChar character) |
| 644 { | 645 { |
| 645 if (m_input.nextInputChar() == character) { | 646 // Since we're not doing replacement we can't tell the difference from |
| 647 // a NUL in the middle and the kEndOfFileMarker, so character must not be |
| 648 // NUL. |
| 649 DCHECK(character); |
| 650 if (m_input.peekWithoutReplacement(0) == character) { |
| 646 m_input.advance(); | 651 m_input.advance(); |
| 647 return true; | 652 return true; |
| 648 } | 653 } |
| 649 return false; | 654 return false; |
| 650 } | 655 } |
| 651 | 656 |
| 652 // http://www.w3.org/TR/css3-syntax/#consume-a-name | 657 // http://www.w3.org/TR/css3-syntax/#consume-a-name |
| 653 StringView CSSTokenizer::consumeName() | 658 StringView CSSTokenizer::consumeName() |
| 654 { | 659 { |
| 655 // Names without escapes get handled without allocations | 660 // Names without escapes get handled without allocations |
| (...skipping 13 matching lines...) Expand all Loading... |
| 669 return m_input.rangeAt(startOffset, size); | 674 return m_input.rangeAt(startOffset, size); |
| 670 } | 675 } |
| 671 | 676 |
| 672 StringBuilder result; | 677 StringBuilder result; |
| 673 while (true) { | 678 while (true) { |
| 674 UChar cc = consume(); | 679 UChar cc = consume(); |
| 675 if (isNameCodePoint(cc)) { | 680 if (isNameCodePoint(cc)) { |
| 676 result.append(cc); | 681 result.append(cc); |
| 677 continue; | 682 continue; |
| 678 } | 683 } |
| 679 if (twoCharsAreValidEscape(cc, m_input.nextInputChar())) { | 684 if (twoCharsAreValidEscape(cc, m_input.peekWithoutReplacement(0))) { |
| 680 result.append(consumeEscape()); | 685 result.append(consumeEscape()); |
| 681 continue; | 686 continue; |
| 682 } | 687 } |
| 683 reconsume(cc); | 688 reconsume(cc); |
| 684 return registerString(result.toString()); | 689 return registerString(result.toString()); |
| 685 } | 690 } |
| 686 } | 691 } |
| 687 | 692 |
| 688 // http://dev.w3.org/csswg/css-syntax/#consume-an-escaped-code-point | 693 // http://dev.w3.org/csswg/css-syntax/#consume-an-escaped-code-point |
| 689 UChar32 CSSTokenizer::consumeEscape() | 694 UChar32 CSSTokenizer::consumeEscape() |
| 690 { | 695 { |
| 691 UChar cc = consume(); | 696 UChar cc = consume(); |
| 692 ASSERT(!isNewLine(cc)); | 697 ASSERT(!isNewLine(cc)); |
| 693 if (isASCIIHexDigit(cc)) { | 698 if (isASCIIHexDigit(cc)) { |
| 694 unsigned consumedHexDigits = 1; | 699 unsigned consumedHexDigits = 1; |
| 695 StringBuilder hexChars; | 700 StringBuilder hexChars; |
| 696 hexChars.append(cc); | 701 hexChars.append(cc); |
| 697 while (consumedHexDigits < 6 && isASCIIHexDigit(m_input.nextInputChar())
) { | 702 while (consumedHexDigits < 6 && isASCIIHexDigit(m_input.peekWithoutRepla
cement(0))) { |
| 698 cc = consume(); | 703 cc = consume(); |
| 699 hexChars.append(cc); | 704 hexChars.append(cc); |
| 700 consumedHexDigits++; | 705 consumedHexDigits++; |
| 701 }; | 706 }; |
| 702 consumeSingleWhitespaceIfNext(); | 707 consumeSingleWhitespaceIfNext(); |
| 703 bool ok = false; | 708 bool ok = false; |
| 704 UChar32 codePoint = hexChars.toString().toUIntStrict(&ok, 16); | 709 UChar32 codePoint = hexChars.toString().toUIntStrict(&ok, 16); |
| 705 ASSERT(ok); | 710 ASSERT(ok); |
| 706 if (codePoint == 0 || (0xD800 <= codePoint && codePoint <= 0xDFFF) || co
dePoint > 0x10FFFF) | 711 if (codePoint == 0 || (0xD800 <= codePoint && codePoint <= 0xDFFF) || co
dePoint > 0x10FFFF) |
| 707 return replacementCharacter; | 712 return replacementCharacter; |
| 708 return codePoint; | 713 return codePoint; |
| 709 } | 714 } |
| 710 | 715 |
| 711 if (cc == kEndOfFileMarker) | 716 if (cc == kEndOfFileMarker) |
| 712 return replacementCharacter; | 717 return replacementCharacter; |
| 713 return cc; | 718 return cc; |
| 714 } | 719 } |
| 715 | 720 |
| 716 bool CSSTokenizer::nextTwoCharsAreValidEscape() | 721 bool CSSTokenizer::nextTwoCharsAreValidEscape() |
| 717 { | 722 { |
| 718 return twoCharsAreValidEscape(m_input.nextInputChar(), m_input.peekWithoutRe
placement(1)); | 723 return twoCharsAreValidEscape(m_input.peekWithoutReplacement(0), m_input.pee
kWithoutReplacement(1)); |
| 719 } | 724 } |
| 720 | 725 |
| 721 // http://www.w3.org/TR/css3-syntax/#starts-with-a-number | 726 // http://www.w3.org/TR/css3-syntax/#starts-with-a-number |
| 722 bool CSSTokenizer::nextCharsAreNumber(UChar first) | 727 bool CSSTokenizer::nextCharsAreNumber(UChar first) |
| 723 { | 728 { |
| 724 UChar second = m_input.nextInputChar(); | 729 UChar second = m_input.peekWithoutReplacement(0); |
| 725 if (isASCIIDigit(first)) | 730 if (isASCIIDigit(first)) |
| 726 return true; | 731 return true; |
| 727 if (first == '+' || first == '-') | 732 if (first == '+' || first == '-') |
| 728 return ((isASCIIDigit(second)) || (second == '.' && isASCIIDigit(m_input
.peekWithoutReplacement(1)))); | 733 return ((isASCIIDigit(second)) || (second == '.' && isASCIIDigit(m_input
.peekWithoutReplacement(1)))); |
| 729 if (first =='.') | 734 if (first =='.') |
| 730 return (isASCIIDigit(second)); | 735 return (isASCIIDigit(second)); |
| 731 return false; | 736 return false; |
| 732 } | 737 } |
| 733 | 738 |
| 734 bool CSSTokenizer::nextCharsAreNumber() | 739 bool CSSTokenizer::nextCharsAreNumber() |
| 735 { | 740 { |
| 736 UChar first = consume(); | 741 UChar first = consume(); |
| 737 bool areNumber = nextCharsAreNumber(first); | 742 bool areNumber = nextCharsAreNumber(first); |
| 738 reconsume(first); | 743 reconsume(first); |
| 739 return areNumber; | 744 return areNumber; |
| 740 } | 745 } |
| 741 | 746 |
| 742 // http://dev.w3.org/csswg/css-syntax/#would-start-an-identifier | 747 // http://dev.w3.org/csswg/css-syntax/#would-start-an-identifier |
| 743 bool CSSTokenizer::nextCharsAreIdentifier(UChar first) | 748 bool CSSTokenizer::nextCharsAreIdentifier(UChar first) |
| 744 { | 749 { |
| 745 UChar second = m_input.nextInputChar(); | 750 UChar second = m_input.peekWithoutReplacement(0); |
| 746 if (isNameStartCodePoint(first) || twoCharsAreValidEscape(first, second)) | 751 if (isNameStartCodePoint(first) || twoCharsAreValidEscape(first, second)) |
| 747 return true; | 752 return true; |
| 748 | 753 |
| 749 if (first == '-') | 754 if (first == '-') |
| 750 return isNameStartCodePoint(second) || second == '-' || nextTwoCharsAreV
alidEscape(); | 755 return isNameStartCodePoint(second) || second == '-' || nextTwoCharsAreV
alidEscape(); |
| 751 | 756 |
| 752 return false; | 757 return false; |
| 753 } | 758 } |
| 754 | 759 |
| 755 bool CSSTokenizer::nextCharsAreIdentifier() | 760 bool CSSTokenizer::nextCharsAreIdentifier() |
| 756 { | 761 { |
| 757 UChar first = consume(); | 762 UChar first = consume(); |
| 758 bool areIdentifier = nextCharsAreIdentifier(first); | 763 bool areIdentifier = nextCharsAreIdentifier(first); |
| 759 reconsume(first); | 764 reconsume(first); |
| 760 return areIdentifier; | 765 return areIdentifier; |
| 761 } | 766 } |
| 762 | 767 |
| 763 StringView CSSTokenizer::registerString(const String& string) | 768 StringView CSSTokenizer::registerString(const String& string) |
| 764 { | 769 { |
| 765 m_scope.storeString(string); | 770 m_scope.storeString(string); |
| 766 return string; | 771 return string; |
| 767 } | 772 } |
| 768 | 773 |
| 769 } // namespace blink | 774 } // namespace blink |
| OLD | NEW |