OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "config.h" | 5 #include "config.h" |
6 #include "core/css/parser/CSSPropertyParser.h" | 6 #include "core/css/parser/CSSPropertyParser.h" |
7 | 7 |
8 #include "core/StylePropertyShorthand.h" | 8 #include "core/StylePropertyShorthand.h" |
9 #include "core/css/CSSCalculationValue.h" | 9 #include "core/css/CSSCalculationValue.h" |
10 #include "core/css/CSSFontFaceSrcValue.h" | |
11 #include "core/css/CSSFontFeatureValue.h" | |
12 #include "core/css/CSSUnicodeRangeValue.h" | |
10 #include "core/css/CSSValuePool.h" | 13 #include "core/css/CSSValuePool.h" |
11 #include "core/css/parser/CSSParserFastPaths.h" | 14 #include "core/css/parser/CSSParserFastPaths.h" |
12 #include "core/css/parser/CSSParserValues.h" | 15 #include "core/css/parser/CSSParserValues.h" |
13 #include "core/frame/UseCounter.h" | 16 #include "core/frame/UseCounter.h" |
14 | 17 |
15 namespace blink { | 18 namespace blink { |
16 | 19 |
17 CSSPropertyParser::CSSPropertyParser(CSSParserValueList* valueList, const CSSPar serTokenRange& range, | 20 CSSPropertyParser::CSSPropertyParser(CSSParserValueList* valueList, const CSSPar serTokenRange& range, |
18 const CSSParserContext& context, WillBeHeapVector<CSSProperty, 256>& parsedP roperties, | 21 const CSSParserContext& context, WillBeHeapVector<CSSProperty, 256>& parsedP roperties, |
19 StyleRule::Type ruleType) | 22 StyleRule::Type ruleType) |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
84 return cssValuePool().createValue(range.consumeIncludingWhitespace().value() , CSSPrimitiveValue::UnitType::CustomIdentifier); | 87 return cssValuePool().createValue(range.consumeIncludingWhitespace().value() , CSSPrimitiveValue::UnitType::CustomIdentifier); |
85 } | 88 } |
86 | 89 |
87 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeString(CSSParserTokenRan ge& range) | 90 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeString(CSSParserTokenRan ge& range) |
88 { | 91 { |
89 if (range.peek().type() != StringToken) | 92 if (range.peek().type() != StringToken) |
90 return nullptr; | 93 return nullptr; |
91 return cssValuePool().createValue(range.consumeIncludingWhitespace().value() , CSSPrimitiveValue::UnitType::String); | 94 return cssValuePool().createValue(range.consumeIncludingWhitespace().value() , CSSPrimitiveValue::UnitType::String); |
92 } | 95 } |
93 | 96 |
97 static String consumeUrl(CSSParserTokenRange& range) | |
98 { | |
99 const CSSParserToken& token = range.peek(); | |
100 if (token.type() == UrlToken) { | |
101 range.consumeIncludingWhitespace(); | |
102 return token.value(); | |
103 } | |
104 if (token.functionId() == CSSValueUrl) { | |
105 CSSParserTokenRange urlRange = range; | |
106 CSSParserTokenRange urlArgs = urlRange.consumeBlock(); | |
107 const CSSParserToken& next = urlArgs.consumeIncludingWhitespace(); | |
108 if (next.type() == BadStringToken || !urlArgs.atEnd()) | |
109 return String(); | |
110 ASSERT(next.type() == StringToken); | |
111 range = urlRange; | |
112 range.consumeWhitespace(); | |
113 return next.value(); | |
114 } | |
115 | |
116 return String(); | |
117 } | |
118 | |
119 static CSSParserTokenRange consumeFunction(CSSParserTokenRange& range) | |
120 { | |
121 ASSERT(range.peek().type() == FunctionToken); | |
122 CSSParserTokenRange contens = range.consumeBlock(); | |
Timothy Loh
2015/09/16 03:22:28
contens -> contents? :-)
| |
123 range.consumeWhitespace(); | |
124 return contens; | |
125 } | |
126 | |
127 static inline bool isComma(const CSSParserToken& value) | |
128 { | |
129 return value.type() == CommaToken; | |
130 } | |
131 | |
94 // Methods for consuming non-shorthand properties starts here. | 132 // Methods for consuming non-shorthand properties starts here. |
95 static PassRefPtrWillBeRawPtr<CSSValue> consumeWillChange(CSSParserTokenRange& r ange) | 133 static PassRefPtrWillBeRawPtr<CSSValue> consumeWillChange(CSSParserTokenRange& r ange) |
96 { | 134 { |
97 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); | 135 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); |
98 if (range.peek().id() == CSSValueAuto) { | 136 if (range.peek().id() == CSSValueAuto) { |
99 // FIXME: This will be read back as an empty string instead of auto | 137 // FIXME: This will be read back as an empty string instead of auto |
100 return values.release(); | 138 return values.release(); |
101 } | 139 } |
102 | 140 |
103 // Every comma-separated list of identifiers is a valid will-change value, | 141 // Every comma-separated list of identifiers is a valid will-change value, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
135 | 173 |
136 if (range.atEnd()) | 174 if (range.atEnd()) |
137 break; | 175 break; |
138 if (!consumeCommaIncludingWhitespace(range)) | 176 if (!consumeCommaIncludingWhitespace(range)) |
139 return nullptr; | 177 return nullptr; |
140 } | 178 } |
141 | 179 |
142 return values.release(); | 180 return values.release(); |
143 } | 181 } |
144 | 182 |
183 static PassRefPtrWillBeRawPtr<CSSValue> consumeFontVariantLigatures(CSSParserTok enRange& range) | |
Timothy Loh
2015/09/16 03:22:28
Can we move the properties which are not @font-fac
| |
184 { | |
185 if (range.peek().id() == CSSValueNormal) | |
186 return consumeIdent(range); | |
187 RefPtrWillBeRawPtr<CSSValueList> ligatureValues = CSSValueList::createSpaceS eparated(); | |
188 bool sawCommonLigaturesValue = false; | |
189 bool sawDiscretionaryLigaturesValue = false; | |
190 bool sawHistoricalLigaturesValue = false; | |
191 bool sawContextualLigaturesValue = false; | |
192 do { | |
193 CSSValueID id = range.peek().id(); | |
194 switch (id) { | |
195 case CSSValueNoCommonLigatures: | |
196 case CSSValueCommonLigatures: | |
197 if (sawCommonLigaturesValue) | |
198 return nullptr; | |
199 sawCommonLigaturesValue = true; | |
200 break; | |
201 case CSSValueNoDiscretionaryLigatures: | |
202 case CSSValueDiscretionaryLigatures: | |
203 if (sawDiscretionaryLigaturesValue) | |
204 return nullptr; | |
205 sawDiscretionaryLigaturesValue = true; | |
206 break; | |
207 case CSSValueNoHistoricalLigatures: | |
208 case CSSValueHistoricalLigatures: | |
209 if (sawHistoricalLigaturesValue) | |
210 return nullptr; | |
211 sawHistoricalLigaturesValue = true; | |
212 break; | |
213 case CSSValueNoContextual: | |
214 case CSSValueContextual: | |
215 if (sawContextualLigaturesValue) | |
216 return nullptr; | |
217 sawContextualLigaturesValue = true; | |
218 break; | |
219 default: | |
220 return nullptr; | |
221 } | |
222 ligatureValues->append(consumeIdent(range)); | |
223 } while (!range.atEnd()); | |
224 | |
225 if (!ligatureValues->length()) | |
Timothy Loh
2015/09/16 03:22:28
The list will never be empty here
| |
226 return nullptr; | |
227 | |
228 return ligatureValues.release(); | |
229 } | |
230 | |
231 static bool consumeFontFeatureTag(CSSParserTokenRange& range, CSSValueList* sett ings) | |
Timothy Loh
2015/09/16 03:22:28
should probably just return a CSSFontFeatureValue
| |
232 { | |
233 // Feature tag name consists of 4-letter characters. | |
234 static const unsigned tagNameLength = 4; | |
235 | |
236 CSSParserToken token = range.peek(); | |
Timothy Loh
2015/09/16 03:22:28
const CSSParserToken&. Also maybe easier if this i
| |
237 // Feature tag name comes first | |
238 if (token.type() != StringToken) | |
239 return false; | |
240 if (token.value().length() != tagNameLength) | |
241 return false; | |
242 AtomicString tag = token.value(); | |
243 for (unsigned i = 0; i < tagNameLength; ++i) { | |
244 // Limits the range of characters to 0x20-0x7E, following the tag name r ules defiend in the OpenType specification. | |
245 UChar character = tag[i]; | |
246 if (character < 0x20 || character > 0x7E) | |
247 return false; | |
248 } | |
249 | |
250 int tagValue = 1; | |
251 // Feature tag values could follow: <integer> | on | off | |
252 range.consumeIncludingWhitespace(); | |
253 if (!range.atEnd()) { | |
Timothy Loh
2015/09/16 03:22:28
don't need this check, peek() will just return EOF
| |
254 if (range.peek().type() == NumberToken && range.peek().numericValueType( ) == IntegerValueType && range.peek().numericValue() >= 0) { | |
255 tagValue = clampTo<int>(range.peek().numericValue()); | |
Timothy Loh
2015/09/16 03:22:28
range.consumeIncludingWhitespace().numericValue()?
| |
256 if (tagValue < 0) | |
257 return false; | |
Timothy Loh
2015/09/16 03:22:28
does this ever get hit?
| |
258 range.consumeIncludingWhitespace(); | |
259 } else if (range.peek().id() == CSSValueOn || range.peek().id() == CSSVa lueOff) { | |
260 tagValue = range.peek().id() == CSSValueOn; | |
Timothy Loh
2015/09/16 03:22:28
range.consumeIncludingWhitespace().id()
| |
261 range.consumeIncludingWhitespace(); | |
262 } | |
263 } | |
264 settings->append(CSSFontFeatureValue::create(tag, tagValue)); | |
265 return true; | |
266 } | |
267 | |
268 static PassRefPtrWillBeRawPtr<CSSValue> consumeFontFeatureSettings(CSSParserToke nRange& range) | |
Timothy Loh
2015/09/16 03:22:28
this one too, separate patch
| |
269 { | |
270 if (range.peek().id() == CSSValueNormal) | |
271 return consumeIdent(range); | |
272 RefPtrWillBeRawPtr<CSSValueList> settings = CSSValueList::createCommaSeparat ed(); | |
273 do { | |
274 if (!consumeFontFeatureTag(range, settings.get())) | |
275 return nullptr; | |
276 if (range.atEnd()) | |
Timothy Loh
2015/09/16 03:22:28
I think just return the value outside the loop and
| |
277 return settings.release(); | |
278 } while (consumeCommaIncludingWhitespace(range)); | |
279 return nullptr; | |
280 } | |
281 | |
145 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumePage(CSSParserTokenRange & range) | 282 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumePage(CSSParserTokenRange & range) |
146 { | 283 { |
147 if (range.peek().id() == CSSValueAuto) | 284 if (range.peek().id() == CSSValueAuto) |
148 return consumeIdent(range); | 285 return consumeIdent(range); |
149 return consumeCustomIdent(range); | 286 return consumeCustomIdent(range); |
150 } | 287 } |
151 | 288 |
152 // [ <string> <string> ]+ | none | 289 // [ <string> <string> ]+ | none |
153 static PassRefPtrWillBeRawPtr<CSSValue> consumeQuotes(CSSParserTokenRange& range ) | 290 static PassRefPtrWillBeRawPtr<CSSValue> consumeQuotes(CSSParserTokenRange& range ) |
154 { | 291 { |
(...skipping 11 matching lines...) Expand all Loading... | |
166 return nullptr; | 303 return nullptr; |
167 } | 304 } |
168 | 305 |
169 static PassRefPtrWillBeRawPtr<CSSValue> consumeWebkitHighlight(CSSParserTokenRan ge& range) | 306 static PassRefPtrWillBeRawPtr<CSSValue> consumeWebkitHighlight(CSSParserTokenRan ge& range) |
170 { | 307 { |
171 if (range.peek().id() == CSSValueNone) | 308 if (range.peek().id() == CSSValueNone) |
172 return consumeIdent(range); | 309 return consumeIdent(range); |
173 return consumeString(range); | 310 return consumeString(range); |
174 } | 311 } |
175 | 312 |
313 // normal | small-caps | inherit | |
Timothy Loh
2015/09/16 03:22:28
Comment is wrong, let's just drop these (as well a
| |
314 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::consumeFontVariant() | |
Timothy Loh
2015/09/16 03:22:28
static for consistency?
| |
315 { | |
316 RefPtrWillBeRawPtr<CSSValueList> values = nullptr; | |
Timothy Loh
2015/09/16 03:22:28
Can we rewrite this function so it isn't super com
| |
317 bool expectComma = false; | |
318 while (!m_range.atEnd()) { | |
319 RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue = nullptr; | |
320 if (!expectComma) { | |
321 expectComma = true; | |
322 if (m_range.peek().id() == CSSValueNormal || m_range.peek().id() == CSSValueSmallCaps) { | |
323 parsedValue = consumeIdent(m_range); | |
324 } else if (m_range.peek().id() == CSSValueAll && !values) { | |
325 // FIXME: CSSPropertyParser::parseFontVariant() implements | |
326 // the old css3 draft: | |
327 // http://www.w3.org/TR/2002/WD-css3-webfonts-20020802/#font-var iant | |
328 // 'all' is only allowed in @font-face and with no other values. Make a value list to | |
329 // indicate that we are in the @font-face case. | |
330 values = CSSValueList::createCommaSeparated(); | |
331 parsedValue = consumeIdent(m_range); | |
332 } | |
333 } else if (consumeCommaIncludingWhitespace(m_range)) { | |
334 expectComma = false; | |
335 continue; | |
336 } | |
337 | |
338 if (!parsedValue) | |
339 return nullptr; | |
340 | |
341 if (isComma(m_range.peek())) | |
342 values = CSSValueList::createCommaSeparated(); | |
343 | |
344 if (values) | |
345 values->append(parsedValue.release()); | |
346 else | |
347 return parsedValue.release(); | |
348 } | |
349 | |
350 if (values && values->length()) { | |
351 if (m_ruleType != StyleRule::FontFace) | |
352 return nullptr; | |
353 return values.release(); | |
354 } | |
355 | |
356 return nullptr; | |
357 } | |
358 | |
176 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty ID propId) | 359 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty ID propId) |
177 { | 360 { |
178 m_range.consumeWhitespace(); | 361 m_range.consumeWhitespace(); |
179 switch (propId) { | 362 switch (propId) { |
180 case CSSPropertyWillChange: | 363 case CSSPropertyWillChange: |
181 return consumeWillChange(m_range); | 364 return consumeWillChange(m_range); |
182 case CSSPropertyPage: | 365 case CSSPropertyPage: |
183 return consumePage(m_range); | 366 return consumePage(m_range); |
184 case CSSPropertyQuotes: | 367 case CSSPropertyQuotes: |
185 return consumeQuotes(m_range); | 368 return consumeQuotes(m_range); |
186 case CSSPropertyWebkitHighlight: | 369 case CSSPropertyWebkitHighlight: |
187 return consumeWebkitHighlight(m_range); | 370 return consumeWebkitHighlight(m_range); |
371 case CSSPropertyFontVariantLigatures: | |
372 return consumeFontVariantLigatures(m_range); | |
373 case CSSPropertyWebkitFontFeatureSettings: | |
374 return consumeFontFeatureSettings(m_range); | |
375 case CSSPropertyFontVariant: | |
376 return consumeFontVariant(); | |
377 case CSSPropertyFontFamily: | |
378 // [[ <family-name> | <generic-family> ],]* [<family-name> | <generic-fa mily>] | inherit | |
379 return consumeFontFamily(); | |
188 default: | 380 default: |
189 return nullptr; | 381 return nullptr; |
190 } | 382 } |
191 } | 383 } |
192 | 384 |
385 static PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFaceUnicodeRange(CSSParse rTokenRange& range) | |
386 { | |
387 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); | |
388 | |
389 do { | |
390 const CSSParserToken& token = range.consumeIncludingWhitespace(); | |
391 if (token.type() != UnicodeRangeToken) | |
392 return nullptr; | |
393 | |
394 UChar32 start = token.unicodeRangeStart(); | |
395 UChar32 end = token.unicodeRangeEnd(); | |
396 if (start > end) | |
397 return nullptr; | |
398 values->append(CSSUnicodeRangeValue::create(start, end)); | |
399 } while (consumeCommaIncludingWhitespace(range)); | |
400 | |
401 return values.release(); | |
402 } | |
403 | |
404 bool CSSPropertyParser::consumeFontFaceSrcURI(CSSValueList* valueList) | |
Timothy Loh
2015/09/16 03:22:28
return a CSSValue instead of updating a CSSValueLi
| |
405 { | |
406 String url = consumeUrl(m_range); | |
407 if (url.isNull()) | |
408 return false; | |
409 RefPtrWillBeRawPtr<CSSFontFaceSrcValue> uriValue(CSSFontFaceSrcValue::create (completeURL(url), m_context.shouldCheckContentSecurityPolicy())); | |
410 uriValue->setReferrer(m_context.referrer()); | |
411 | |
412 if (m_range.peek().functionId() != CSSValueFormat) { | |
413 valueList->append(uriValue.release()); | |
414 return true; | |
415 } | |
416 | |
417 // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20111004/ says that format () contains a comma-separated list of strings, | |
Timothy Loh
2015/09/16 03:22:28
Should update the URL (https://drafts.csswg.org/cs
| |
418 // but CSSFontFaceSrcValue stores only one format. Allowing one format for n ow. | |
419 CSSParserTokenRange args = consumeFunction(m_range); | |
420 if (args.peek().type() != StringToken && args.peek().type() != IdentToken) | |
421 return false; | |
422 uriValue->setFormat(args.consumeIncludingWhitespace().value()); | |
Timothy Loh
2015/09/16 03:22:28
need to check for any tokens after the string?
| |
423 valueList->append(uriValue.release()); | |
424 return true; | |
425 } | |
426 | |
427 bool CSSPropertyParser::consumeFontFaceSrcLocal(CSSValueList* valueList) | |
Timothy Loh
2015/09/16 03:22:28
return a CSSValue
| |
428 { | |
429 CSSParserTokenRange args = consumeFunction(m_range); | |
430 if (args.atEnd()) | |
431 return false; | |
432 | |
433 const CSSParserToken& arg = args.consumeIncludingWhitespace(); | |
Timothy Loh
2015/09/16 03:22:28
This is just <family-name>, right? We should share
| |
434 ContentSecurityPolicyDisposition shouldCheckContentSecurityPolicy = m_contex t.shouldCheckContentSecurityPolicy(); | |
435 if (arg.type() == StringToken) { | |
436 if (!args.atEnd()) | |
437 return false; | |
438 valueList->append(CSSFontFaceSrcValue::createLocal(arg.value(), shouldCh eckContentSecurityPolicy)); | |
439 } else if (arg.type() == IdentToken) { | |
440 StringBuilder builder; | |
441 builder.append(arg.value()); | |
442 while (!args.atEnd()) { | |
443 CSSParserToken localValue = args.consumeIncludingWhitespace(); | |
444 if (localValue.type() != IdentToken) | |
445 return false; | |
446 if (!builder.isEmpty()) | |
447 builder.append(' '); | |
448 builder.append(localValue.value()); | |
449 } | |
450 valueList->append(CSSFontFaceSrcValue::createLocal(builder.toString(), s houldCheckContentSecurityPolicy)); | |
451 } else { | |
452 return false; | |
453 } | |
454 | |
455 return true; | |
456 } | |
457 | |
458 PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::consumeFontFaceSrc() | |
459 { | |
460 RefPtrWillBeRawPtr<CSSValueList> values(CSSValueList::createCommaSeparated() ); | |
461 | |
462 do { | |
463 const CSSParserToken& token = m_range.peek(); | |
464 if (token.functionId() == CSSValueLocal) { | |
465 if (!consumeFontFaceSrcLocal(values.get())) | |
466 return nullptr; | |
467 } else if (!consumeFontFaceSrcURI(values.get())) { | |
468 return nullptr; | |
469 } | |
470 | |
471 if (m_range.atEnd()) | |
472 return values.release(); | |
473 } while (consumeCommaIncludingWhitespace(m_range)); | |
474 return nullptr; | |
475 } | |
476 | |
477 static inline bool isCSSWideKeyword(const CSSParserToken& token) | |
478 { | |
479 return token.id() == CSSValueInitial || token.id() == CSSValueInherit || tok en.id() == CSSValueUnset || token.id() == CSSValueDefault; | |
Timothy Loh
2015/09/16 03:22:28
I know id() has a cache but can we pull the value
| |
480 } | |
481 | |
482 PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::consumeFontFamily() | |
483 { | |
484 RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated() ; | |
485 CSSParserToken token = m_range.consumeIncludingWhitespace(); | |
486 | |
487 FontFamilyValueBuilder familyBuilder(list.get()); | |
488 bool inFamily = false; | |
489 | |
490 while (token.type() != EOFToken) { | |
491 const CSSParserToken& nextToken = m_range.consumeIncludingWhitespace(); | |
492 bool nextValBreaksFont = nextToken.type() == EOFToken || isComma(nextTok en); | |
493 bool nextValIsFontName = ((nextToken.id() >= CSSValueSerif && nextToken. id() <= CSSValueWebkitBody) | |
494 || (nextToken.type() == StringToken || nextToken.type() == IdentToke n)); | |
495 | |
496 if (isCSSWideKeyword(token) && !inFamily) { | |
497 if (nextValBreaksFont) | |
498 return nullptr; | |
499 if (nextValIsFontName) | |
500 token = nextToken; | |
501 continue; | |
502 } | |
503 | |
504 if (token.id() >= CSSValueSerif && token.id() <= CSSValueWebkitBody) { | |
505 if (inFamily) { | |
506 familyBuilder.add(token.value()); | |
507 } else if (nextValBreaksFont || !nextValIsFontName) { | |
508 list->append(cssValuePool().createIdentifierValue(token.id())); | |
509 } else { | |
510 familyBuilder.commit(); | |
511 familyBuilder.add(token.value()); | |
512 inFamily = true; | |
513 } | |
514 } else if (token.type() == StringToken) { | |
515 // Strings never share in a family name. | |
516 inFamily = false; | |
517 familyBuilder.commit(); | |
518 list->append(cssValuePool().createFontFamilyValue(token.value())); | |
519 } else if (token.type() == IdentToken) { | |
520 if (inFamily) { | |
521 familyBuilder.add(token.value()); | |
522 } else if (nextValBreaksFont || !nextValIsFontName) { | |
523 list->append(cssValuePool().createFontFamilyValue(token.value()) ); | |
524 } else { | |
525 familyBuilder.commit(); | |
526 familyBuilder.add(token.value()); | |
527 inFamily = true; | |
528 } | |
529 } else { | |
530 break; | |
531 } | |
532 | |
533 if (nextToken.type() == EOFToken) | |
534 break; | |
535 | |
536 if (nextValBreaksFont) { | |
537 token = m_range.consumeIncludingWhitespace(); | |
538 familyBuilder.commit(); | |
539 inFamily = false; | |
540 } else if (nextValIsFontName) { | |
541 token = nextToken; | |
542 } else { | |
543 break; | |
544 } | |
545 } | |
546 familyBuilder.commit(); | |
547 if (!list->length() || (m_ruleType == StyleRule::FontFace && list->length() > 1)) | |
548 list = nullptr; | |
549 return list.release(); | |
550 } | |
551 | |
552 static PassRefPtrWillBeRawPtr<CSSValue> consumeFontWeight(CSSParserTokenRange& r ange) | |
553 { | |
554 const CSSParserToken& token = range.peek(); | |
555 if (token.id() >= CSSValueNormal && token.id() <= CSSValueLighter) | |
556 return consumeIdent(range); | |
557 if (token.type() != NumberToken) | |
Timothy Loh
2015/09/16 03:22:28
|| token.numericValueType() != IntegerValueType?
| |
558 return nullptr; | |
559 int weight = static_cast<int>(token.numericValue()); | |
560 if ((weight % 100) || weight < 100 || weight > 900) | |
561 return nullptr; | |
562 range.consumeIncludingWhitespace(); | |
563 return cssValuePool().createIdentifierValue(static_cast<CSSValueID>(CSSValue 100 + weight / 100 - 1)); | |
564 } | |
565 | |
566 bool CSSPropertyParser::parseFontFaceDescriptor(CSSPropertyID propId) | |
Timothy Loh
2015/09/16 03:22:28
I think we decided a while ago to split this into
| |
567 { | |
568 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; | |
569 | |
570 m_range.consumeWhitespace(); | |
571 switch (propId) { | |
572 case CSSPropertyFontFamily: | |
573 // <family-name> | |
574 // TODO(rwlbuis): check there is only one family-name | |
575 parsedValue = consumeFontFamily(); | |
576 break; | |
577 case CSSPropertySrc: // This is a list of urls or local references. | |
578 parsedValue = consumeFontFaceSrc(); | |
579 break; | |
580 case CSSPropertyUnicodeRange: | |
581 parsedValue = consumeFontFaceUnicodeRange(m_range); | |
582 break; | |
583 case CSSPropertyFontWeight: // normal | bold | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | |
584 parsedValue = consumeFontWeight(m_range); | |
585 break; | |
586 case CSSPropertyFontStretch: | |
587 case CSSPropertyFontStyle: { | |
588 CSSValueID id = m_range.consumeIncludingWhitespace().id(); | |
589 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(propId, id)) | |
590 return false; | |
591 addProperty(propId, cssValuePool().createIdentifierValue(id), false); | |
Timothy Loh
2015/09/16 03:22:28
parsedValue = ?
| |
592 return true; | |
593 } | |
594 case CSSPropertyFontVariant: // normal | small-caps | inherit | |
595 parsedValue = consumeFontVariant(); | |
596 break; | |
597 case CSSPropertyWebkitFontFeatureSettings: | |
598 parsedValue = parseSingleValue(propId); | |
599 break; | |
600 default: | |
601 break; | |
602 } | |
603 | |
604 if (!parsedValue || !m_range.atEnd()) | |
605 return false; | |
606 | |
607 addProperty(propId, parsedValue.release(), false); | |
608 return true; | |
609 } | |
610 | |
193 bool CSSPropertyParser::parseShorthand(CSSPropertyID propId, bool important) | 611 bool CSSPropertyParser::parseShorthand(CSSPropertyID propId, bool important) |
194 { | 612 { |
195 m_range.consumeWhitespace(); | 613 m_range.consumeWhitespace(); |
196 switch (propId) { | 614 switch (propId) { |
197 case CSSPropertyWebkitMarginCollapse: { | 615 case CSSPropertyWebkitMarginCollapse: { |
198 CSSValueID id = m_range.consumeIncludingWhitespace().id(); | 616 CSSValueID id = m_range.consumeIncludingWhitespace().id(); |
199 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(CSSPropertyWebki tMarginBeforeCollapse, id)) | 617 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(CSSPropertyWebki tMarginBeforeCollapse, id)) |
200 return false; | 618 return false; |
201 RefPtrWillBeRawPtr<CSSValue> beforeCollapse = cssValuePool().createIdent ifierValue(id); | 619 RefPtrWillBeRawPtr<CSSValue> beforeCollapse = cssValuePool().createIdent ifierValue(id); |
202 addProperty(CSSPropertyWebkitMarginBeforeCollapse, beforeCollapse, impor tant); | 620 addProperty(CSSPropertyWebkitMarginBeforeCollapse, beforeCollapse, impor tant); |
(...skipping 28 matching lines...) Expand all Loading... | |
231 addProperty(CSSPropertyOverflowX, overflowXValue.release(), important); | 649 addProperty(CSSPropertyOverflowX, overflowXValue.release(), important); |
232 addProperty(CSSPropertyOverflowY, overflowYValue.release(), important); | 650 addProperty(CSSPropertyOverflowY, overflowYValue.release(), important); |
233 return true; | 651 return true; |
234 } | 652 } |
235 default: | 653 default: |
236 return false; | 654 return false; |
237 } | 655 } |
238 } | 656 } |
239 | 657 |
240 } // namespace blink | 658 } // namespace blink |
OLD | NEW |