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

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

Issue 1512243005: Finish support for <image> type parsing using CSSParserTokens (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix final issue Created 5 years 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 | « no previous file | 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 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/CSSCrossfadeValue.h" 10 #include "core/css/CSSCrossfadeValue.h"
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 825
826 static PassRefPtrWillBeRawPtr<CSSValue> consumePosition(CSSParserTokenRange& ran ge, CSSParserMode cssParserMode, UnitlessQuirk unitless) 826 static PassRefPtrWillBeRawPtr<CSSValue> consumePosition(CSSParserTokenRange& ran ge, CSSParserMode cssParserMode, UnitlessQuirk unitless)
827 { 827 {
828 RefPtrWillBeRawPtr<CSSValue> resultX = nullptr; 828 RefPtrWillBeRawPtr<CSSValue> resultX = nullptr;
829 RefPtrWillBeRawPtr<CSSValue> resultY = nullptr; 829 RefPtrWillBeRawPtr<CSSValue> resultY = nullptr;
830 if (consumePosition(range, cssParserMode, unitless, resultX, resultY)) 830 if (consumePosition(range, cssParserMode, unitless, resultX, resultY))
831 return CSSValuePair::create(resultX.release(), resultY.release(), CSSVal uePair::KeepIdenticalValues); 831 return CSSValuePair::create(resultX.release(), resultY.release(), CSSVal uePair::KeepIdenticalValues);
832 return nullptr; 832 return nullptr;
833 } 833 }
834 834
835 static bool consumeTransformOrigin(CSSParserTokenRange& range, CSSParserMode css ParserMode, UnitlessQuirk unitless, RefPtrWillBeRawPtr<CSSValue>& resultX, RefPt rWillBeRawPtr<CSSValue>& resultY) 835 static bool consumeOneOrTwoValuedPosition(CSSParserTokenRange& range, CSSParserM ode cssParserMode, UnitlessQuirk unitless, RefPtrWillBeRawPtr<CSSValue>& resultX , RefPtrWillBeRawPtr<CSSValue>& resultY)
836 { 836 {
837 RefPtrWillBeRawPtr<CSSPrimitiveValue> value1 = consumePositionComponent(rang e, cssParserMode, unitless); 837 RefPtrWillBeRawPtr<CSSPrimitiveValue> value1 = consumePositionComponent(rang e, cssParserMode, unitless);
838 if (!value1) 838 if (!value1)
839 return false; 839 return false;
840 RefPtrWillBeRawPtr<CSSPrimitiveValue> value2 = consumePositionComponent(rang e, cssParserMode, unitless); 840 RefPtrWillBeRawPtr<CSSPrimitiveValue> value2 = consumePositionComponent(rang e, cssParserMode, unitless);
841 if (!value2) { 841 if (!value2) {
842 positionFromOneValue(value1.release(), resultX, resultY); 842 positionFromOneValue(value1.release(), resultX, resultY);
843 return true; 843 return true;
844 } 844 }
845 return positionFromTwoValues(value1.release(), value2.release(), resultX, re sultY); 845 return positionFromTwoValues(value1.release(), value2.release(), resultX, re sultY);
846 } 846 }
847 847
848 static PassRefPtrWillBeRawPtr<CSSValueList> consumeTransformOrigin(CSSParserToke nRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless) 848 static PassRefPtrWillBeRawPtr<CSSValueList> consumeTransformOrigin(CSSParserToke nRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless)
849 { 849 {
850 RefPtrWillBeRawPtr<CSSValue> resultX = nullptr; 850 RefPtrWillBeRawPtr<CSSValue> resultX = nullptr;
851 RefPtrWillBeRawPtr<CSSValue> resultY = nullptr; 851 RefPtrWillBeRawPtr<CSSValue> resultY = nullptr;
852 if (consumeTransformOrigin(range, cssParserMode, unitless, resultX, resultY) ) { 852 if (consumeOneOrTwoValuedPosition(range, cssParserMode, unitless, resultX, r esultY)) {
853 RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparat ed(); 853 RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparat ed();
854 list->append(resultX.release()); 854 list->append(resultX.release());
855 list->append(resultY.release()); 855 list->append(resultY.release());
856 RefPtrWillBeRawPtr<CSSValue> resultZ = consumeLength(range, cssParserMod e, ValueRangeAll); 856 RefPtrWillBeRawPtr<CSSValue> resultZ = consumeLength(range, cssParserMod e, ValueRangeAll);
857 if (!resultZ) 857 if (!resultZ)
858 resultZ = cssValuePool().createValue(0, CSSPrimitiveValue::UnitType: :Pixels); 858 resultZ = cssValuePool().createValue(0, CSSPrimitiveValue::UnitType: :Pixels);
859 list->append(resultZ.release()); 859 list->append(resultZ.release());
860 return list.release(); 860 return list.release();
861 } 861 }
862 return nullptr; 862 return nullptr;
(...skipping 1536 matching lines...) Expand 10 before | Expand all | Expand 10 after
2399 cursorType = consumeIdent(range); 2399 cursorType = consumeIdent(range);
2400 } 2400 }
2401 2401
2402 if (!list) 2402 if (!list)
2403 return cursorType.release(); 2403 return cursorType.release();
2404 if (cursorType) 2404 if (cursorType)
2405 list->append(cursorType.release()); 2405 list->append(cursorType.release());
2406 return list.release(); 2406 return list.release();
2407 } 2407 }
2408 2408
2409 // This should go away once we drop support for -webkit-gradient
2410 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeDeprecatedGradientPoint( CSSParserTokenRange& args, bool horizontal)
2411 {
2412 if (args.peek().type() == IdentToken) {
2413 if ((horizontal && consumeIdent<CSSValueLeft>(args)) || (!horizontal && consumeIdent<CSSValueTop>(args)))
2414 return cssValuePool().createValue(0., CSSPrimitiveValue::UnitType::P ercentage);
2415 if ((horizontal && consumeIdent<CSSValueRight>(args)) || (!horizontal && consumeIdent<CSSValueBottom>(args)))
2416 return cssValuePool().createValue(100., CSSPrimitiveValue::UnitType: :Percentage);
2417 if (consumeIdent<CSSValueCenter>(args))
2418 return cssValuePool().createValue(50., CSSPrimitiveValue::UnitType:: Percentage);
2419 return nullptr;
2420 }
2421 RefPtrWillBeRawPtr<CSSPrimitiveValue> result = consumePercent(args, ValueRan geAll);
2422 if (!result)
2423 result = consumeNumber(args, ValueRangeAll);
2424 return result;
2425 }
2426
2427 // Used to parse colors for -webkit-gradient(...).
2428 static PassRefPtrWillBeRawPtr<CSSValue> consumeDeprecatedGradientStopColor(CSSPa rserTokenRange& args, CSSParserMode cssParserMode)
2429 {
2430 if (args.peek().id() == CSSValueCurrentcolor)
2431 return nullptr;
2432 return consumeColor(args, cssParserMode);
2433 }
2434
2435 static bool consumeDeprecatedGradientColorStop(CSSParserTokenRange& range, CSSGr adientColorStop& stop, CSSParserMode cssParserMode)
2436 {
2437 CSSValueID id = range.peek().functionId();
2438 if (id != CSSValueFrom && id != CSSValueTo && id != CSSValueColorStop)
2439 return false;
2440
2441 CSSParserTokenRange args = consumeFunction(range);
2442 const CSSParserToken& arg = args.consumeIncludingWhitespace();
Timothy Loh 2015/12/14 23:30:40 Probably should be in the else branch, since we do
2443 double position;
2444 if (id == CSSValueFrom || id == CSSValueTo) {
2445 position = (id == CSSValueFrom) ? 0 : 1;
2446 } else {
2447 ASSERT(id == CSSValueColorStop);
2448 if (arg.type() == PercentageToken)
2449 position = arg.numericValue() / 100.0;
2450 else if (arg.type() == NumberToken)
2451 position = arg.numericValue();
2452 else
2453 return false;
2454
2455 if (!consumeCommaIncludingWhitespace(args))
2456 return false;
2457 }
2458
2459 stop.m_position = cssValuePool().createValue(position, CSSPrimitiveValue::Un itType::Number);
2460 stop.m_color = consumeDeprecatedGradientStopColor(args, cssParserMode);
2461 return stop.m_color && args.atEnd();
2462 }
2463
2464 static PassRefPtrWillBeRawPtr<CSSValue> consumeDeprecatedGradient(CSSParserToken Range& args, CSSParserMode cssParserMode)
2465 {
2466 RefPtrWillBeRawPtr<CSSGradientValue> result = nullptr;
2467 CSSValueID id = args.consumeIncludingWhitespace().id();
2468 bool isDeprecatedRadialGradient = (id == CSSValueRadial);
2469 if (isDeprecatedRadialGradient)
2470 result = CSSRadialGradientValue::create(NonRepeating, CSSDeprecatedRadia lGradient);
2471 else if (id == CSSValueLinear)
2472 result = CSSLinearGradientValue::create(NonRepeating, CSSDeprecatedLinea rGradient);
2473 if (!result || !consumeCommaIncludingWhitespace(args))
2474 return nullptr;
2475
2476 RefPtrWillBeRawPtr<CSSPrimitiveValue> point = consumeDeprecatedGradientPoint (args, true);
2477 if (!point)
2478 return nullptr;
2479 result->setFirstX(point.release());
2480 point = consumeDeprecatedGradientPoint(args, false);
2481 if (!point)
2482 return nullptr;
2483 result->setFirstY(point.release());
2484
2485 if (!consumeCommaIncludingWhitespace(args))
2486 return nullptr;
2487
2488 // For radial gradients only, we now expect a numeric radius.
2489 if (isDeprecatedRadialGradient) {
2490 RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = consumeNumber(args, Value RangeAll);
2491 if (!radius || !consumeCommaIncludingWhitespace(args))
2492 return nullptr;
2493 toCSSRadialGradientValue(result.get())->setFirstRadius(radius.release()) ;
2494 }
2495
2496 point = consumeDeprecatedGradientPoint(args, true);
2497 if (!point)
2498 return nullptr;
2499 result->setSecondX(point.release());
2500 point = consumeDeprecatedGradientPoint(args, false);
2501 if (!point)
2502 return nullptr;
2503 result->setSecondY(point.release());
2504
2505 // For radial gradients only, we now expect the second radius.
2506 if (isDeprecatedRadialGradient) {
2507 if (!consumeCommaIncludingWhitespace(args))
2508 return nullptr;
2509 RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = consumeNumber(args, Value RangeAll);
2510 if (!radius)
2511 return nullptr;
2512 toCSSRadialGradientValue(result.get())->setSecondRadius(radius.release() );
2513 }
2514
2515 CSSGradientColorStop stop;
2516 while (consumeCommaIncludingWhitespace(args)) {
2517 if (!consumeDeprecatedGradientColorStop(args, stop, cssParserMode))
2518 return nullptr;
2519 result->addStop(stop);
2520 }
2521
2522 return result.release();
2523 }
2524
2409 static bool consumeGradientColorStops(CSSParserTokenRange& range, CSSParserMode cssParserMode, CSSGradientValue* gradient) 2525 static bool consumeGradientColorStops(CSSParserTokenRange& range, CSSParserMode cssParserMode, CSSGradientValue* gradient)
2410 { 2526 {
2411 bool supportsColorHints = gradient->gradientType() == CSSLinearGradient || g radient->gradientType() == CSSRadialGradient; 2527 bool supportsColorHints = gradient->gradientType() == CSSLinearGradient || g radient->gradientType() == CSSRadialGradient;
2412 2528
2413 // The first color stop cannot be a color hint. 2529 // The first color stop cannot be a color hint.
2414 bool previousStopWasColorHint = true; 2530 bool previousStopWasColorHint = true;
2415 do { 2531 do {
2416 CSSGradientColorStop stop; 2532 CSSGradientColorStop stop;
2417 stop.m_color = consumeColor(range, cssParserMode); 2533 stop.m_color = consumeColor(range, cssParserMode);
2418 // Two hints in a row are not allowed. 2534 // Two hints in a row are not allowed.
2419 if (!stop.m_color && (!supportsColorHints || previousStopWasColorHint)) 2535 if (!stop.m_color && (!supportsColorHints || previousStopWasColorHint))
2420 return false; 2536 return false;
2421 previousStopWasColorHint = !stop.m_color; 2537 previousStopWasColorHint = !stop.m_color;
2422 stop.m_position = consumeLengthOrPercent(range, cssParserMode, ValueRang eAll); 2538 stop.m_position = consumeLengthOrPercent(range, cssParserMode, ValueRang eAll);
2423 if (!stop.m_color && !stop.m_position) 2539 if (!stop.m_color && !stop.m_position)
2424 return false; 2540 return false;
2425 gradient->addStop(stop); 2541 gradient->addStop(stop);
2426 } while (consumeCommaIncludingWhitespace(range)); 2542 } while (consumeCommaIncludingWhitespace(range));
2427 2543
2428 // The last color stop cannot be a color hint. 2544 // The last color stop cannot be a color hint.
2429 if (previousStopWasColorHint) 2545 if (previousStopWasColorHint)
2430 return false; 2546 return false;
2431 2547
2432 // Must have 2 or more stops to be valid. 2548 // Must have 2 or more stops to be valid.
2433 return gradient->stopCount() >= 2; 2549 return gradient->stopCount() >= 2;
2434 } 2550 }
2435 2551
2552 static PassRefPtrWillBeRawPtr<CSSValue> consumeDeprecatedRadialGradient(CSSParse rTokenRange& args, CSSParserMode cssParserMode, CSSGradientRepeat repeating)
2553 {
2554 RefPtrWillBeRawPtr<CSSRadialGradientValue> result = CSSRadialGradientValue:: create(repeating, CSSPrefixedRadialGradient);
2555 RefPtrWillBeRawPtr<CSSValue> centerX = nullptr;
2556 RefPtrWillBeRawPtr<CSSValue> centerY = nullptr;
2557 consumeOneOrTwoValuedPosition(args, cssParserMode, UnitlessQuirk::Forbid, ce nterX, centerY);
2558 if ((centerX || centerY) && !consumeCommaIncludingWhitespace(args))
2559 return nullptr;
2560
2561 result->setFirstX(toCSSPrimitiveValue(centerX.get()));
2562 result->setSecondX(toCSSPrimitiveValue(centerX.get()));
2563 result->setFirstY(toCSSPrimitiveValue(centerY.get()));
2564 result->setSecondY(toCSSPrimitiveValue(centerY.get()));
2565
2566 RefPtrWillBeRawPtr<CSSPrimitiveValue> shape = consumeIdent<CSSValueCircle, C SSValueEllipse>(args);
2567 RefPtrWillBeRawPtr<CSSPrimitiveValue> sizeKeyword = consumeIdent<CSSValueClo sestSide, CSSValueClosestCorner, CSSValueFarthestSide, CSSValueFarthestCorner, C SSValueContain, CSSValueCover>(args);
2568 if (!shape)
2569 shape = consumeIdent<CSSValueCircle, CSSValueEllipse>(args);
2570 result->setShape(shape);
2571 result->setSizingBehavior(sizeKeyword);
2572
2573 // Or, two lengths or percentages
2574 if (!shape && !sizeKeyword) {
2575 RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalSize = nullptr;
2576 RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalSize = nullptr;
2577 if ((horizontalSize = consumeLengthOrPercent(args, cssParserMode, ValueR angeAll))) {
2578 verticalSize = consumeLengthOrPercent(args, cssParserMode, ValueRang eAll);
2579 if (!verticalSize)
2580 return nullptr;
2581 consumeCommaIncludingWhitespace(args);
2582 result->setEndHorizontalSize(horizontalSize);
2583 result->setEndVerticalSize(verticalSize);
2584 }
2585 } else {
2586 consumeCommaIncludingWhitespace(args);
2587 }
2588 if (!consumeGradientColorStops(args, cssParserMode, result.get()))
2589 return nullptr;
2590
2591 return result.release();
2592 }
2593
2436 static PassRefPtrWillBeRawPtr<CSSValue> consumeRadialGradient(CSSParserTokenRang e& args, CSSParserMode cssParserMode, CSSGradientRepeat repeating) 2594 static PassRefPtrWillBeRawPtr<CSSValue> consumeRadialGradient(CSSParserTokenRang e& args, CSSParserMode cssParserMode, CSSGradientRepeat repeating)
2437 { 2595 {
2438 RefPtrWillBeRawPtr<CSSRadialGradientValue> result = CSSRadialGradientValue:: create(repeating, CSSRadialGradient); 2596 RefPtrWillBeRawPtr<CSSRadialGradientValue> result = CSSRadialGradientValue:: create(repeating, CSSRadialGradient);
2439 2597
2440 RefPtrWillBeRawPtr<CSSPrimitiveValue> shape = nullptr; 2598 RefPtrWillBeRawPtr<CSSPrimitiveValue> shape = nullptr;
2441 RefPtrWillBeRawPtr<CSSPrimitiveValue> sizeKeyword = nullptr; 2599 RefPtrWillBeRawPtr<CSSPrimitiveValue> sizeKeyword = nullptr;
2442 RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalSize = nullptr; 2600 RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalSize = nullptr;
2443 RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalSize = nullptr; 2601 RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalSize = nullptr;
2444 2602
2445 // First part of grammar, the size/shape clause: 2603 // First part of grammar, the size/shape clause:
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
2583 if (context.useCounter()) 2741 if (context.useCounter())
2584 context.useCounter()->count(UseCounter::DeprecatedWebKitLinearGradie nt); 2742 context.useCounter()->count(UseCounter::DeprecatedWebKitLinearGradie nt);
2585 result = consumeLinearGradient(args, context.mode(), NonRepeating, CSSPr efixedLinearGradient); 2743 result = consumeLinearGradient(args, context.mode(), NonRepeating, CSSPr efixedLinearGradient);
2586 } else if (id == CSSValueWebkitRepeatingLinearGradient) { 2744 } else if (id == CSSValueWebkitRepeatingLinearGradient) {
2587 // FIXME: This should send a deprecation message. 2745 // FIXME: This should send a deprecation message.
2588 if (context.useCounter()) 2746 if (context.useCounter())
2589 context.useCounter()->count(UseCounter::DeprecatedWebKitRepeatingLin earGradient); 2747 context.useCounter()->count(UseCounter::DeprecatedWebKitRepeatingLin earGradient);
2590 result = consumeLinearGradient(args, context.mode(), Repeating, CSSPrefi xedLinearGradient); 2748 result = consumeLinearGradient(args, context.mode(), Repeating, CSSPrefi xedLinearGradient);
2591 } else if (id == CSSValueLinearGradient) { 2749 } else if (id == CSSValueLinearGradient) {
2592 result = consumeLinearGradient(args, context.mode(), NonRepeating, CSSLi nearGradient); 2750 result = consumeLinearGradient(args, context.mode(), NonRepeating, CSSLi nearGradient);
2751 } else if (id == CSSValueWebkitGradient) {
2752 // FIXME: This should send a deprecation message.
2753 if (context.useCounter())
2754 context.useCounter()->count(UseCounter::DeprecatedWebKitGradient);
2755 result = consumeDeprecatedGradient(args, context.mode());
2756 } else if (id == CSSValueWebkitRadialGradient) {
2757 // FIXME: This should send a deprecation message.
2758 if (context.useCounter())
2759 context.useCounter()->count(UseCounter::DeprecatedWebKitRadialGradie nt);
2760 result = consumeDeprecatedRadialGradient(args, context.mode(), NonRepeat ing);
2761 } else if (id == CSSValueWebkitRepeatingRadialGradient) {
2762 if (context.useCounter())
2763 context.useCounter()->count(UseCounter::DeprecatedWebKitRepeatingRad ialGradient);
2764 result = consumeDeprecatedRadialGradient(args, context.mode(), Repeating );
2593 } else if (id == CSSValueWebkitCrossFade) { 2765 } else if (id == CSSValueWebkitCrossFade) {
2594 result = consumeCrossFade(args, context); 2766 result = consumeCrossFade(args, context);
2595 } 2767 }
2596 if (!result || !args.atEnd()) 2768 if (!result || !args.atEnd())
2597 return nullptr; 2769 return nullptr;
2598 range = rangeCopy; 2770 range = rangeCopy;
2599 return result; 2771 return result;
2600 } 2772 }
2601 2773
2602 static PassRefPtrWillBeRawPtr<CSSValue> consumeImage(CSSParserTokenRange& range, CSSParserContext context) 2774 static PassRefPtrWillBeRawPtr<CSSValue> consumeImage(CSSParserTokenRange& range, CSSParserContext context)
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after
3446 return consumeShorthandGreedily(flexFlowShorthand(), important); 3618 return consumeShorthandGreedily(flexFlowShorthand(), important);
3447 case CSSPropertyWebkitColumnRule: 3619 case CSSPropertyWebkitColumnRule:
3448 return consumeShorthandGreedily(webkitColumnRuleShorthand(), important); 3620 return consumeShorthandGreedily(webkitColumnRuleShorthand(), important);
3449 default: 3621 default:
3450 m_currentShorthand = oldShorthand; 3622 m_currentShorthand = oldShorthand;
3451 return false; 3623 return false;
3452 } 3624 }
3453 } 3625 }
3454 3626
3455 } // namespace blink 3627 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698