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" | 10 #include "core/css/CSSFontFaceSrcValue.h" |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 return consumeIdent(range); | 337 return consumeIdent(range); |
338 if (token.type() != NumberToken || token.numericValueType() != IntegerValueT
ype) | 338 if (token.type() != NumberToken || token.numericValueType() != IntegerValueT
ype) |
339 return nullptr; | 339 return nullptr; |
340 int weight = static_cast<int>(token.numericValue()); | 340 int weight = static_cast<int>(token.numericValue()); |
341 if ((weight % 100) || weight < 100 || weight > 900) | 341 if ((weight % 100) || weight < 100 || weight > 900) |
342 return nullptr; | 342 return nullptr; |
343 range.consumeIncludingWhitespace(); | 343 range.consumeIncludingWhitespace(); |
344 return cssValuePool().createIdentifierValue(static_cast<CSSValueID>(CSSValue
100 + weight / 100 - 1)); | 344 return cssValuePool().createIdentifierValue(static_cast<CSSValueID>(CSSValue
100 + weight / 100 - 1)); |
345 } | 345 } |
346 | 346 |
| 347 static String concatenateFamilyName(CSSParserTokenRange& range) |
| 348 { |
| 349 StringBuilder builder; |
| 350 bool addedSpace = false; |
| 351 const CSSParserToken& firstToken = range.peek(); |
| 352 while (range.peek().type() == IdentToken) { |
| 353 if (!builder.isEmpty()) { |
| 354 builder.append(' '); |
| 355 addedSpace = true; |
| 356 } |
| 357 builder.append(range.consumeIncludingWhitespace().value()); |
| 358 } |
| 359 if (!addedSpace && isCSSWideKeyword(firstToken.id())) |
| 360 return String(); |
| 361 return builder.toString(); |
| 362 } |
| 363 |
| 364 static PassRefPtrWillBeRawPtr<CSSValue> consumeFamilyName(CSSParserTokenRange& r
ange) |
| 365 { |
| 366 if (range.peek().type() == StringToken) |
| 367 return cssValuePool().createFontFamilyValue(range.consumeIncludingWhites
pace().value()); |
| 368 if (range.peek().type() != IdentToken) |
| 369 return nullptr; |
| 370 String familyName = concatenateFamilyName(range); |
| 371 if (familyName.isNull()) |
| 372 return nullptr; |
| 373 return cssValuePool().createFontFamilyValue(familyName); |
| 374 } |
| 375 |
| 376 static PassRefPtrWillBeRawPtr<CSSValue> consumeGenericFamily(CSSParserTokenRange
& range) |
| 377 { |
| 378 if (range.peek().id() >= CSSValueSerif && range.peek().id() <= CSSValueWebki
tBody) |
| 379 return consumeIdent(range); |
| 380 return nullptr; |
| 381 } |
| 382 |
| 383 static PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFamily(CSSParserTokenRang
e& range) |
| 384 { |
| 385 RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated()
; |
| 386 do { |
| 387 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; |
| 388 if ((parsedValue = consumeGenericFamily(range))) { |
| 389 list->append(parsedValue); |
| 390 } else if ((parsedValue = consumeFamilyName(range))) { |
| 391 list->append(parsedValue); |
| 392 } else { |
| 393 return nullptr; |
| 394 } |
| 395 } while (consumeCommaIncludingWhitespace(range)); |
| 396 return list.release(); |
| 397 } |
| 398 |
347 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty
ID propId) | 399 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty
ID propId) |
348 { | 400 { |
349 m_range.consumeWhitespace(); | 401 m_range.consumeWhitespace(); |
350 switch (propId) { | 402 switch (propId) { |
351 case CSSPropertyWillChange: | 403 case CSSPropertyWillChange: |
352 return consumeWillChange(m_range); | 404 return consumeWillChange(m_range); |
353 case CSSPropertyPage: | 405 case CSSPropertyPage: |
354 return consumePage(m_range); | 406 return consumePage(m_range); |
355 case CSSPropertyQuotes: | 407 case CSSPropertyQuotes: |
356 return consumeQuotes(m_range); | 408 return consumeQuotes(m_range); |
357 case CSSPropertyWebkitHighlight: | 409 case CSSPropertyWebkitHighlight: |
358 return consumeWebkitHighlight(m_range); | 410 return consumeWebkitHighlight(m_range); |
359 case CSSPropertyFontVariantLigatures: | 411 case CSSPropertyFontVariantLigatures: |
360 return consumeFontVariantLigatures(m_range); | 412 return consumeFontVariantLigatures(m_range); |
361 case CSSPropertyWebkitFontFeatureSettings: | 413 case CSSPropertyWebkitFontFeatureSettings: |
362 return consumeFontFeatureSettings(m_range); | 414 return consumeFontFeatureSettings(m_range); |
363 case CSSPropertyFontVariant: | 415 case CSSPropertyFontVariant: |
364 return consumeFontVariant(); | 416 return consumeFontVariant(); |
365 case CSSPropertyFontFamily: | 417 case CSSPropertyFontFamily: |
366 return consumeFontFamily(); | 418 return consumeFontFamily(m_range); |
367 case CSSPropertyFontWeight: | 419 case CSSPropertyFontWeight: |
368 return consumeFontWeight(m_range); | 420 return consumeFontWeight(m_range); |
369 default: | 421 default: |
370 return nullptr; | 422 return nullptr; |
371 } | 423 } |
372 } | 424 } |
373 | 425 |
374 static PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFaceUnicodeRange(CSSParse
rTokenRange& range) | 426 static PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFaceUnicodeRange(CSSParse
rTokenRange& range) |
375 { | 427 { |
376 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated
(); | 428 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated
(); |
(...skipping 28 matching lines...) Expand all Loading... |
405 // but CSSFontFaceSrcValue stores only one format. Allowing one format for n
ow. | 457 // but CSSFontFaceSrcValue stores only one format. Allowing one format for n
ow. |
406 // FIXME: IdentToken should not be supported here. | 458 // FIXME: IdentToken should not be supported here. |
407 CSSParserTokenRange args = consumeFunction(m_range); | 459 CSSParserTokenRange args = consumeFunction(m_range); |
408 const CSSParserToken& arg = args.consumeIncludingWhitespace(); | 460 const CSSParserToken& arg = args.consumeIncludingWhitespace(); |
409 if ((arg.type() != StringToken && arg.type() != IdentToken) || !args.atEnd()
) | 461 if ((arg.type() != StringToken && arg.type() != IdentToken) || !args.atEnd()
) |
410 return nullptr; | 462 return nullptr; |
411 uriValue->setFormat(arg.value()); | 463 uriValue->setFormat(arg.value()); |
412 return uriValue.release(); | 464 return uriValue.release(); |
413 } | 465 } |
414 | 466 |
415 static String concatenateFamilyName(CSSParserTokenRange& range) | |
416 { | |
417 StringBuilder builder; | |
418 bool addedSpace = false; | |
419 const CSSParserToken& firstToken = range.peek(); | |
420 while (range.peek().type() == IdentToken) { | |
421 if (!builder.isEmpty()) { | |
422 builder.append(' '); | |
423 addedSpace = true; | |
424 } | |
425 builder.append(range.consumeIncludingWhitespace().value()); | |
426 } | |
427 if (!addedSpace && isCSSWideKeyword(firstToken.id())) { | |
428 return String(); | |
429 } | |
430 return builder.toString(); | |
431 } | |
432 | |
433 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::consumeFontFaceSrcLocal() | 467 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::consumeFontFaceSrcLocal() |
434 { | 468 { |
435 CSSParserTokenRange args = consumeFunction(m_range); | 469 CSSParserTokenRange args = consumeFunction(m_range); |
436 ContentSecurityPolicyDisposition shouldCheckContentSecurityPolicy = m_contex
t.shouldCheckContentSecurityPolicy(); | 470 ContentSecurityPolicyDisposition shouldCheckContentSecurityPolicy = m_contex
t.shouldCheckContentSecurityPolicy(); |
437 if (args.peek().type() == StringToken) { | 471 if (args.peek().type() == StringToken) { |
438 const CSSParserToken& arg = args.consumeIncludingWhitespace(); | 472 const CSSParserToken& arg = args.consumeIncludingWhitespace(); |
439 if (!args.atEnd()) | 473 if (!args.atEnd()) |
440 return nullptr; | 474 return nullptr; |
441 return CSSFontFaceSrcValue::createLocal(arg.value(), shouldCheckContentS
ecurityPolicy); | 475 return CSSFontFaceSrcValue::createLocal(arg.value(), shouldCheckContentS
ecurityPolicy); |
442 } | 476 } |
(...skipping 17 matching lines...) Expand all Loading... |
460 parsedValue = consumeFontFaceSrcLocal(); | 494 parsedValue = consumeFontFaceSrcLocal(); |
461 else | 495 else |
462 parsedValue = consumeFontFaceSrcURI(); | 496 parsedValue = consumeFontFaceSrcURI(); |
463 if (!parsedValue) | 497 if (!parsedValue) |
464 return nullptr; | 498 return nullptr; |
465 values->append(parsedValue); | 499 values->append(parsedValue); |
466 } while (consumeCommaIncludingWhitespace(m_range)); | 500 } while (consumeCommaIncludingWhitespace(m_range)); |
467 return values.release(); | 501 return values.release(); |
468 } | 502 } |
469 | 503 |
470 static PassRefPtrWillBeRawPtr<CSSValue> consumeFamilyName(CSSParserTokenRange& r
ange) | |
471 { | |
472 if (range.peek().type() == StringToken) | |
473 return cssValuePool().createFontFamilyValue(range.consumeIncludingWhites
pace().value()); | |
474 if (range.peek().type() != IdentToken) | |
475 return nullptr; | |
476 String familyName = concatenateFamilyName(range); | |
477 if (familyName.isNull()) | |
478 return nullptr; | |
479 return cssValuePool().createFontFamilyValue(familyName); | |
480 } | |
481 | |
482 static PassRefPtrWillBeRawPtr<CSSValue> consumeGenericFamily(CSSParserTokenRange
& range) | |
483 { | |
484 if (range.peek().id() >= CSSValueSerif && range.peek().id() <= CSSValueWebki
tBody) | |
485 return consumeIdent(range); | |
486 return nullptr; | |
487 } | |
488 | |
489 PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::consumeFontFamily() | |
490 { | |
491 RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated()
; | |
492 do { | |
493 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; | |
494 if ((parsedValue = consumeGenericFamily(m_range))) { | |
495 list->append(parsedValue); | |
496 } else if ((parsedValue = consumeFamilyName(m_range))) { | |
497 list->append(parsedValue); | |
498 } else { | |
499 return nullptr; | |
500 } | |
501 } while (consumeCommaIncludingWhitespace(m_range)); | |
502 if (m_ruleType == StyleRule::FontFace && list->length() > 1) | |
503 return nullptr; | |
504 return list.release(); | |
505 } | |
506 | |
507 bool CSSPropertyParser::parseFontFaceDescriptor(CSSPropertyID propId) | 504 bool CSSPropertyParser::parseFontFaceDescriptor(CSSPropertyID propId) |
508 { | 505 { |
509 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; | 506 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; |
510 | 507 |
511 m_range.consumeWhitespace(); | 508 m_range.consumeWhitespace(); |
512 switch (propId) { | 509 switch (propId) { |
| 510 case CSSPropertyFontFamily: |
| 511 if (consumeGenericFamily(m_range)) |
| 512 return false; |
| 513 parsedValue = consumeFamilyName(m_range); |
| 514 break; |
513 case CSSPropertySrc: // This is a list of urls or local references. | 515 case CSSPropertySrc: // This is a list of urls or local references. |
514 parsedValue = consumeFontFaceSrc(); | 516 parsedValue = consumeFontFaceSrc(); |
515 break; | 517 break; |
516 case CSSPropertyUnicodeRange: | 518 case CSSPropertyUnicodeRange: |
517 parsedValue = consumeFontFaceUnicodeRange(m_range); | 519 parsedValue = consumeFontFaceUnicodeRange(m_range); |
518 break; | 520 break; |
519 case CSSPropertyFontStretch: | 521 case CSSPropertyFontStretch: |
520 case CSSPropertyFontStyle: { | 522 case CSSPropertyFontStyle: { |
521 CSSValueID id = m_range.consumeIncludingWhitespace().id(); | 523 CSSValueID id = m_range.consumeIncludingWhitespace().id(); |
522 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(propId, id)) | 524 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(propId, id)) |
523 return false; | 525 return false; |
524 parsedValue = cssValuePool().createIdentifierValue(id); | 526 parsedValue = cssValuePool().createIdentifierValue(id); |
525 break; | 527 break; |
526 } | 528 } |
527 // TODO(rwlbuis): check there is only one family-name in font-face descripto
r case | |
528 case CSSPropertyFontFamily: | |
529 case CSSPropertyFontVariant: | 529 case CSSPropertyFontVariant: |
530 case CSSPropertyFontWeight: | 530 case CSSPropertyFontWeight: |
531 case CSSPropertyWebkitFontFeatureSettings: | 531 case CSSPropertyWebkitFontFeatureSettings: |
532 parsedValue = parseSingleValue(propId); | 532 parsedValue = parseSingleValue(propId); |
533 break; | 533 break; |
534 default: | 534 default: |
535 break; | 535 break; |
536 } | 536 } |
537 | 537 |
538 if (!parsedValue || !m_range.atEnd()) | 538 if (!parsedValue || !m_range.atEnd()) |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 addProperty(CSSPropertyOverflowX, overflowXValue.release(), important); | 583 addProperty(CSSPropertyOverflowX, overflowXValue.release(), important); |
584 addProperty(CSSPropertyOverflowY, overflowYValue.release(), important); | 584 addProperty(CSSPropertyOverflowY, overflowYValue.release(), important); |
585 return true; | 585 return true; |
586 } | 586 } |
587 default: | 587 default: |
588 return false; | 588 return false; |
589 } | 589 } |
590 } | 590 } |
591 | 591 |
592 } // namespace blink | 592 } // namespace blink |
OLD | NEW |