| 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 |