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 |
| 11 #include "core/css/parser/CSSParserIdioms.h" |
11 #include "core/css/parser/CSSParserObserverWrapper.h" | 12 #include "core/css/parser/CSSParserObserverWrapper.h" |
12 #include "core/css/parser/CSSParserTokenRange.h" | 13 #include "core/css/parser/CSSParserTokenRange.h" |
13 #include "core/css/parser/CSSTokenizerInputStream.h" | 14 #include "core/css/parser/CSSTokenizerInputStream.h" |
14 #include "core/html/parser/HTMLParserIdioms.h" | 15 #include "core/html/parser/HTMLParserIdioms.h" |
15 #include "wtf/text/CharacterNames.h" | 16 #include "wtf/text/CharacterNames.h" |
16 | 17 |
17 namespace blink { | 18 namespace blink { |
18 | 19 |
19 CSSTokenizer::Scope::Scope(const String& string) | 20 CSSTokenizer::Scope::Scope(const String& string) |
20 : m_string(string) | 21 : m_string(string) |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 CSSParserTokenRange CSSTokenizer::Scope::tokenRange() | 77 CSSParserTokenRange CSSTokenizer::Scope::tokenRange() |
77 { | 78 { |
78 return m_tokens; | 79 return m_tokens; |
79 } | 80 } |
80 | 81 |
81 unsigned CSSTokenizer::Scope::tokenCount() | 82 unsigned CSSTokenizer::Scope::tokenCount() |
82 { | 83 { |
83 return m_tokens.size(); | 84 return m_tokens.size(); |
84 } | 85 } |
85 | 86 |
86 // http://dev.w3.org/csswg/css-syntax/#name-start-code-point | |
87 static bool isNameStart(UChar c) | |
88 { | |
89 if (isASCIIAlpha(c)) | |
90 return true; | |
91 if (c == '_') | |
92 return true; | |
93 return !isASCII(c); | |
94 } | |
95 | |
96 // http://dev.w3.org/csswg/css-syntax/#name-code-point | |
97 static bool isNameChar(UChar c) | |
98 { | |
99 return isNameStart(c) || isASCIIDigit(c) || c == '-'; | |
100 } | |
101 | |
102 static bool isNewLine(UChar cc) | 87 static bool isNewLine(UChar cc) |
103 { | 88 { |
104 // We check \r and \f here, since we have no preprocessing stage | 89 // We check \r and \f here, since we have no preprocessing stage |
105 return (cc == '\r' || cc == '\n' || cc == '\f'); | 90 return (cc == '\r' || cc == '\n' || cc == '\f'); |
106 } | 91 } |
107 | 92 |
108 // http://dev.w3.org/csswg/css-syntax/#check-if-two-code-points-are-a-valid-esca
pe | 93 // http://dev.w3.org/csswg/css-syntax/#check-if-two-code-points-are-a-valid-esca
pe |
109 static bool twoCharsAreValidEscape(UChar first, UChar second) | 94 static bool twoCharsAreValidEscape(UChar first, UChar second) |
110 { | 95 { |
111 return first == '\\' && !isNewLine(second); | 96 return first == '\\' && !isNewLine(second); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 } | 249 } |
265 | 250 |
266 CSSParserToken CSSTokenizer::semiColon(UChar cc) | 251 CSSParserToken CSSTokenizer::semiColon(UChar cc) |
267 { | 252 { |
268 return CSSParserToken(SemicolonToken); | 253 return CSSParserToken(SemicolonToken); |
269 } | 254 } |
270 | 255 |
271 CSSParserToken CSSTokenizer::hash(UChar cc) | 256 CSSParserToken CSSTokenizer::hash(UChar cc) |
272 { | 257 { |
273 UChar nextChar = m_input.nextInputChar(); | 258 UChar nextChar = m_input.nextInputChar(); |
274 if (isNameChar(nextChar) || twoCharsAreValidEscape(nextChar, m_input.peek(1)
)) { | 259 if (isNameCodePoint(nextChar) || twoCharsAreValidEscape(nextChar, m_input.pe
ek(1))) { |
275 HashTokenType type = nextCharsAreIdentifier() ? HashTokenId : HashTokenU
nrestricted; | 260 HashTokenType type = nextCharsAreIdentifier() ? HashTokenId : HashTokenU
nrestricted; |
276 return CSSParserToken(type, consumeName()); | 261 return CSSParserToken(type, consumeName()); |
277 } | 262 } |
278 | 263 |
279 return CSSParserToken(DelimiterToken, cc); | 264 return CSSParserToken(DelimiterToken, cc); |
280 } | 265 } |
281 | 266 |
282 CSSParserToken CSSTokenizer::circumflexAccent(UChar cc) | 267 CSSParserToken CSSTokenizer::circumflexAccent(UChar cc) |
283 { | 268 { |
284 ASSERT(cc == '^'); | 269 ASSERT(cc == '^'); |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 } | 662 } |
678 | 663 |
679 // http://www.w3.org/TR/css3-syntax/#consume-a-name | 664 // http://www.w3.org/TR/css3-syntax/#consume-a-name |
680 CSSParserString CSSTokenizer::consumeName() | 665 CSSParserString CSSTokenizer::consumeName() |
681 { | 666 { |
682 // Names without escapes get handled without allocations | 667 // Names without escapes get handled without allocations |
683 for (unsigned size = 0; ; ++size) { | 668 for (unsigned size = 0; ; ++size) { |
684 UChar cc = m_input.peekWithoutReplacement(size); | 669 UChar cc = m_input.peekWithoutReplacement(size); |
685 if (cc == '\0' || cc == '\\') | 670 if (cc == '\0' || cc == '\\') |
686 break; | 671 break; |
687 if (!isNameChar(cc)) { | 672 if (!isNameCodePoint(cc)) { |
688 unsigned startOffset = m_input.offset(); | 673 unsigned startOffset = m_input.offset(); |
689 m_input.advance(size); | 674 m_input.advance(size); |
690 return m_input.rangeAsCSSParserString(startOffset, size); | 675 return m_input.rangeAsCSSParserString(startOffset, size); |
691 } | 676 } |
692 } | 677 } |
693 | 678 |
694 StringBuilder result; | 679 StringBuilder result; |
695 while (true) { | 680 while (true) { |
696 UChar cc = consume(); | 681 UChar cc = consume(); |
697 if (isNameChar(cc)) { | 682 if (isNameCodePoint(cc)) { |
698 result.append(cc); | 683 result.append(cc); |
699 continue; | 684 continue; |
700 } | 685 } |
701 if (twoCharsAreValidEscape(cc, m_input.nextInputChar())) { | 686 if (twoCharsAreValidEscape(cc, m_input.nextInputChar())) { |
702 result.append(consumeEscape()); | 687 result.append(consumeEscape()); |
703 continue; | 688 continue; |
704 } | 689 } |
705 reconsume(cc); | 690 reconsume(cc); |
706 return registerString(result.toString()); | 691 return registerString(result.toString()); |
707 } | 692 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 UChar first = consume(); | 743 UChar first = consume(); |
759 bool areNumber = nextCharsAreNumber(first); | 744 bool areNumber = nextCharsAreNumber(first); |
760 reconsume(first); | 745 reconsume(first); |
761 return areNumber; | 746 return areNumber; |
762 } | 747 } |
763 | 748 |
764 // http://dev.w3.org/csswg/css-syntax/#would-start-an-identifier | 749 // http://dev.w3.org/csswg/css-syntax/#would-start-an-identifier |
765 bool CSSTokenizer::nextCharsAreIdentifier(UChar first) | 750 bool CSSTokenizer::nextCharsAreIdentifier(UChar first) |
766 { | 751 { |
767 UChar second = m_input.nextInputChar(); | 752 UChar second = m_input.nextInputChar(); |
768 if (isNameStart(first) || twoCharsAreValidEscape(first, second)) | 753 if (isNameStartCodePoint(first) || twoCharsAreValidEscape(first, second)) |
769 return true; | 754 return true; |
770 | 755 |
771 if (first == '-') | 756 if (first == '-') |
772 return isNameStart(second) || second == '-' || nextTwoCharsAreValidEscap
e(); | 757 return isNameStartCodePoint(second) || second == '-' || nextTwoCharsAreV
alidEscape(); |
773 | 758 |
774 return false; | 759 return false; |
775 } | 760 } |
776 | 761 |
777 bool CSSTokenizer::nextCharsAreIdentifier() | 762 bool CSSTokenizer::nextCharsAreIdentifier() |
778 { | 763 { |
779 UChar first = consume(); | 764 UChar first = consume(); |
780 bool areIdentifier = nextCharsAreIdentifier(first); | 765 bool areIdentifier = nextCharsAreIdentifier(first); |
781 reconsume(first); | 766 reconsume(first); |
782 return areIdentifier; | 767 return areIdentifier; |
783 } | 768 } |
784 | 769 |
785 CSSParserString CSSTokenizer::registerString(const String& string) | 770 CSSParserString CSSTokenizer::registerString(const String& string) |
786 { | 771 { |
787 m_scope.storeString(string); | 772 m_scope.storeString(string); |
788 CSSParserString result; | 773 CSSParserString result; |
789 result.init(string); | 774 result.init(string); |
790 return result; | 775 return result; |
791 } | 776 } |
792 | 777 |
793 } // namespace blink | 778 } // namespace blink |
OLD | NEW |