Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(653)

Side by Side Diff: third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.cpp

Issue 2330893002: CSS Properties and Values API: Support more syntax strings (Closed)
Patch Set: move some syntax parsing logic into helpers Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/CSSSyntaxDescriptor.h" 5 #include "core/css/CSSSyntaxDescriptor.h"
6 6
7 #include "core/css/CSSCustomPropertyDeclaration.h" 7 #include "core/css/CSSCustomPropertyDeclaration.h"
8 #include "core/css/CSSURIValue.h" 8 #include "core/css/CSSURIValue.h"
9 #include "core/css/CSSValueList.h" 9 #include "core/css/CSSValueList.h"
10 #include "core/css/CSSVariableReferenceValue.h" 10 #include "core/css/CSSVariableReferenceValue.h"
11 #include "core/css/parser/CSSParserIdioms.h"
11 #include "core/css/parser/CSSPropertyParserHelpers.h" 12 #include "core/css/parser/CSSPropertyParserHelpers.h"
12 #include "core/css/parser/CSSTokenizer.h" 13 #include "core/css/parser/CSSTokenizer.h"
13 #include "core/css/parser/CSSVariableParser.h" 14 #include "core/css/parser/CSSVariableParser.h"
15 #include "core/html/parser/HTMLParserIdioms.h"
14 16
15 namespace blink { 17 namespace blink {
16 18
19 void consumeWhitespace(const String& string, size_t& offset)
20 {
21 while (isHTMLSpace(string[offset]))
22 offset++;
23 }
24
25 bool consumeCharacterAndWhitespace(const String& string, char character, size_t& offset)
26 {
27 if (string[offset] != character)
28 return false;
29 offset++;
30 consumeWhitespace(string, offset);
31 return true;
32 }
33
34 CSSSyntaxType parseSyntaxType(String type)
35 {
36 // TODO(timloh): Are these supposed to be case sensitive?
37 if (type == "length")
38 return CSSSyntaxType::Length;
39 if (type == "number")
40 return CSSSyntaxType::Number;
41 if (type == "percentage")
42 return CSSSyntaxType::Percentage;
43 if (type == "length-percentage")
44 return CSSSyntaxType::LengthPercentage;
45 if (type == "color")
46 return CSSSyntaxType::Color;
47 if (type == "image")
48 return CSSSyntaxType::Image;
49 if (type == "url")
50 return CSSSyntaxType::Url;
51 if (type == "integer")
52 return CSSSyntaxType::Integer;
53 if (type == "angle")
54 return CSSSyntaxType::Angle;
55 if (type == "time")
56 return CSSSyntaxType::Time;
57 if (type == "resolution")
58 return CSSSyntaxType::Resolution;
59 if (type == "transform-function")
60 return CSSSyntaxType::TransformFunction;
61 if (type == "custom-ident")
62 return CSSSyntaxType::CustomIdent;
63 // Not an Ident, just used to indicate failure
64 return CSSSyntaxType::Ident;
65 }
66
67 bool consumeSyntaxType(const String& input, size_t& offset, CSSSyntaxType& type)
68 {
69 DCHECK_EQ(input[offset], '<');
70 offset++;
71 size_t typeStart = offset;
72 while (offset < input.length() && input[offset] != '>')
73 offset++;
74 if (offset == input.length())
75 return false;
76 type = parseSyntaxType(input.substring(typeStart, offset - typeStart));
77 if (type == CSSSyntaxType::Ident)
78 return false;
79 offset++;
80 return true;
81 }
82
83 bool consumeSyntaxIdent(const String& input, size_t& offset, String& ident)
84 {
85 // TODO(timloh): Are CSS-wide keywords allowed here?
86 size_t identStart = offset;
87 while (isNameCodePoint(input[offset]))
88 offset++;
89 if (offset == identStart)
90 return false;
91 ident = input.substring(identStart, offset - identStart);
92 return true;
93 }
94
17 CSSSyntaxDescriptor::CSSSyntaxDescriptor(String input) 95 CSSSyntaxDescriptor::CSSSyntaxDescriptor(String input)
18 { 96 {
19 // TODO(timloh): Implement proper parsing 97 size_t offset = 0;
20 if (input.contains('*')) 98 consumeWhitespace(input, offset);
21 m_syntaxComponents.append(CSSSyntaxComponent(CSSSyntaxType::TokenStream) ); 99
22 else 100 if (consumeCharacterAndWhitespace(input, '*', offset)) {
23 m_syntaxComponents.append(CSSSyntaxComponent(CSSSyntaxType::Length)); 101 if (offset != input.length())
102 return;
103 m_syntaxComponents.append(CSSSyntaxComponent(CSSSyntaxType::TokenStream, emptyString(), false));
104 return;
105 }
106
107 do {
108 CSSSyntaxType type;
109 String ident;
110 bool success;
111
112 if (input[offset] == '<') {
113 success = consumeSyntaxType(input, offset, type);
114 } else {
115 type = CSSSyntaxType::Ident;
116 success = consumeSyntaxIdent(input, offset, ident);
117 }
118
119 if (!success) {
120 m_syntaxComponents.clear();
121 return;
122 }
123
124 bool repeatable = consumeCharacterAndWhitespace(input, '+', offset);
125 consumeWhitespace(input, offset);
126 m_syntaxComponents.append(CSSSyntaxComponent(type, ident, repeatable));
127
128 } while (consumeCharacterAndWhitespace(input, '|', offset));
129
130 if (offset != input.length())
131 m_syntaxComponents.clear();
24 } 132 }
25 133
26 const CSSValue* consumeSingleType(const CSSSyntaxComponent& syntax, CSSParserTok enRange& range) 134 const CSSValue* consumeSingleType(const CSSSyntaxComponent& syntax, CSSParserTok enRange& range)
27 { 135 {
28 using namespace CSSPropertyParserHelpers; 136 using namespace CSSPropertyParserHelpers;
29 137
30 // TODO(timloh): Calc values need to be normalized 138 // TODO(timloh): Calc values need to be normalized
31 switch (syntax.m_type) { 139 switch (syntax.m_type) {
140 case CSSSyntaxType::Ident:
141 if (range.peek().type() == IdentToken
142 && range.peek().value() == syntax.m_string) {
143 range.consumeIncludingWhitespace();
144 return CSSCustomIdentValue::create(AtomicString(syntax.m_string));
145 }
146 return nullptr;
32 case CSSSyntaxType::Length: 147 case CSSSyntaxType::Length:
33 return consumeLength(range, HTMLStandardMode, ValueRange::ValueRangeAll) ; 148 return consumeLength(range, HTMLStandardMode, ValueRange::ValueRangeAll) ;
149 case CSSSyntaxType::Number:
150 return consumeNumber(range, ValueRange::ValueRangeAll);
151 case CSSSyntaxType::Percentage:
152 return consumePercent(range, ValueRange::ValueRangeAll);
153 case CSSSyntaxType::LengthPercentage:
154 return consumeLengthOrPercent(range, HTMLStandardMode, ValueRange::Value RangeAll);
155 case CSSSyntaxType::Color:
156 return consumeColor(range, HTMLStandardMode);
157 case CSSSyntaxType::Image:
158 // TODO(timloh): This probably needs a proper parser context for relativ e URL resolution.
159 return consumeImage(range, strictCSSParserContext());
160 case CSSSyntaxType::Url:
161 return consumeUrl(range);
162 case CSSSyntaxType::Integer:
163 return consumeInteger(range);
164 case CSSSyntaxType::Angle:
165 return consumeAngle(range);
166 case CSSSyntaxType::Time:
167 return consumeTime(range, ValueRange::ValueRangeAll);
168 case CSSSyntaxType::Resolution:
169 return nullptr; // TODO(timloh): Implement this.
170 case CSSSyntaxType::TransformFunction:
171 return nullptr; // TODO(timloh): Implement this.
172 case CSSSyntaxType::CustomIdent:
173 return consumeCustomIdent(range);
34 default: 174 default:
35 NOTREACHED(); 175 NOTREACHED();
36 return nullptr; 176 return nullptr;
37 } 177 }
38 } 178 }
39 179
40 const CSSValue* consumeSyntaxComponent(const CSSSyntaxComponent& syntax, CSSPars erTokenRange range) 180 const CSSValue* consumeSyntaxComponent(const CSSSyntaxComponent& syntax, CSSPars erTokenRange range)
41 { 181 {
42 // CSS-wide keywords are already handled by the CSSPropertyParser 182 // CSS-wide keywords are already handled by the CSSPropertyParser
183 if (syntax.m_repeatable) {
184 CSSValueList* list = CSSValueList::createSpaceSeparated();
185 while (!range.atEnd()) {
186 const CSSValue* value = consumeSingleType(syntax, range);
187 if (!value)
188 return nullptr;
189 list->append(*value);
190 }
191 return list;
192 }
43 const CSSValue* result = consumeSingleType(syntax, range); 193 const CSSValue* result = consumeSingleType(syntax, range);
44 if (!range.atEnd()) 194 if (!range.atEnd())
45 return nullptr; 195 return nullptr;
46 return result; 196 return result;
47 } 197 }
48 198
49 const CSSValue* CSSSyntaxDescriptor::parse(const String& value) const 199 const CSSValue* CSSSyntaxDescriptor::parse(const String& value) const
50 { 200 {
51 CSSTokenizer::Scope scope(value); 201 CSSTokenizer::Scope scope(value);
52 return parse(scope.tokenRange()); 202 return parse(scope.tokenRange());
53 } 203 }
54 204
55 const CSSValue* CSSSyntaxDescriptor::parse(CSSParserTokenRange range) const 205 const CSSValue* CSSSyntaxDescriptor::parse(CSSParserTokenRange range) const
56 { 206 {
57 if (isTokenStream()) 207 if (isTokenStream())
58 return CSSVariableParser::parseRegisteredPropertyValue(range, false); 208 return CSSVariableParser::parseRegisteredPropertyValue(range, false);
59 range.consumeWhitespace(); 209 range.consumeWhitespace();
60 for (const CSSSyntaxComponent& component : m_syntaxComponents) { 210 for (const CSSSyntaxComponent& component : m_syntaxComponents) {
61 if (const CSSValue* result = consumeSyntaxComponent(component, range)) 211 if (const CSSValue* result = consumeSyntaxComponent(component, range))
62 return result; 212 return result;
63 } 213 }
64 return CSSVariableParser::parseRegisteredPropertyValue(range, true); 214 return CSSVariableParser::parseRegisteredPropertyValue(range, true);
65 } 215 }
66 216
67 } // namespace blink 217 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/css/CSSSyntaxDescriptor.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698