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

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

Issue 2200313002: Move consumeImage to CSSPropertyParserHelpers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rename enum Created 4 years, 4 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/parser/CSSPropertyParserHelpers.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/parser/CSSPropertyParserHelpers.h" 5 #include "core/css/parser/CSSPropertyParserHelpers.h"
6 6
7 #include "core/css/CSSCalculationValue.h" 7 #include "core/css/CSSCalculationValue.h"
8 #include "core/css/CSSColorValue.h" 8 #include "core/css/CSSColorValue.h"
9 #include "core/css/CSSCrossfadeValue.h"
10 #include "core/css/CSSGradientValue.h"
11 #include "core/css/CSSImageSetValue.h"
12 #include "core/css/CSSImageValue.h"
13 #include "core/css/CSSPaintValue.h"
9 #include "core/css/CSSStringValue.h" 14 #include "core/css/CSSStringValue.h"
10 #include "core/css/CSSValuePair.h" 15 #include "core/css/CSSValuePair.h"
16 #include "core/frame/UseCounter.h"
11 17
12 namespace blink { 18 namespace blink {
13 19
14 namespace CSSPropertyParserHelpers { 20 namespace CSSPropertyParserHelpers {
15 21
16 bool consumeCommaIncludingWhitespace(CSSParserTokenRange& range) 22 bool consumeCommaIncludingWhitespace(CSSParserTokenRange& range)
17 { 23 {
18 CSSParserToken value = range.peek(); 24 CSSParserToken value = range.peek();
19 if (value.type() != CommaToken) 25 if (value.type() != CommaToken)
20 return false; 26 return false;
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 if (!value1) 612 if (!value1)
607 return false; 613 return false;
608 CSSPrimitiveValue* value2 = consumePositionComponent(range, cssParserMode, u nitless); 614 CSSPrimitiveValue* value2 = consumePositionComponent(range, cssParserMode, u nitless);
609 if (!value2) { 615 if (!value2) {
610 positionFromOneValue(value1, resultX, resultY); 616 positionFromOneValue(value1, resultX, resultY);
611 return true; 617 return true;
612 } 618 }
613 return positionFromTwoValues(value1, value2, resultX, resultY); 619 return positionFromTwoValues(value1, value2, resultX, resultY);
614 } 620 }
615 621
622 // This should go away once we drop support for -webkit-gradient
623 static CSSPrimitiveValue* consumeDeprecatedGradientPoint(CSSParserTokenRange& ar gs, bool horizontal)
624 {
625 if (args.peek().type() == IdentToken) {
626 if ((horizontal && consumeIdent<CSSValueLeft>(args)) || (!horizontal && consumeIdent<CSSValueTop>(args)))
627 return CSSPrimitiveValue::create(0., CSSPrimitiveValue::UnitType::Pe rcentage);
628 if ((horizontal && consumeIdent<CSSValueRight>(args)) || (!horizontal && consumeIdent<CSSValueBottom>(args)))
629 return CSSPrimitiveValue::create(100., CSSPrimitiveValue::UnitType:: Percentage);
630 if (consumeIdent<CSSValueCenter>(args))
631 return CSSPrimitiveValue::create(50., CSSPrimitiveValue::UnitType::P ercentage);
632 return nullptr;
633 }
634 CSSPrimitiveValue* result = consumePercent(args, ValueRangeAll);
635 if (!result)
636 result = consumeNumber(args, ValueRangeAll);
637 return result;
638 }
639
640 // Used to parse colors for -webkit-gradient(...).
641 static CSSValue* consumeDeprecatedGradientStopColor(CSSParserTokenRange& args, C SSParserMode cssParserMode)
642 {
643 if (args.peek().id() == CSSValueCurrentcolor)
644 return nullptr;
645 return consumeColor(args, cssParserMode);
646 }
647
648 static bool consumeDeprecatedGradientColorStop(CSSParserTokenRange& range, CSSGr adientColorStop& stop, CSSParserMode cssParserMode)
649 {
650 CSSValueID id = range.peek().functionId();
651 if (id != CSSValueFrom && id != CSSValueTo && id != CSSValueColorStop)
652 return false;
653
654 CSSParserTokenRange args = consumeFunction(range);
655 double position;
656 if (id == CSSValueFrom || id == CSSValueTo) {
657 position = (id == CSSValueFrom) ? 0 : 1;
658 } else {
659 DCHECK(id == CSSValueColorStop);
660 const CSSParserToken& arg = args.consumeIncludingWhitespace();
661 if (arg.type() == PercentageToken)
662 position = arg.numericValue() / 100.0;
663 else if (arg.type() == NumberToken)
664 position = arg.numericValue();
665 else
666 return false;
667
668 if (!consumeCommaIncludingWhitespace(args))
669 return false;
670 }
671
672 stop.m_position = CSSPrimitiveValue::create(position, CSSPrimitiveValue::Uni tType::Number);
673 stop.m_color = consumeDeprecatedGradientStopColor(args, cssParserMode);
674 return stop.m_color && args.atEnd();
675 }
676
677 static CSSValue* consumeDeprecatedGradient(CSSParserTokenRange& args, CSSParserM ode cssParserMode)
678 {
679 CSSGradientValue* result = nullptr;
680 CSSValueID id = args.consumeIncludingWhitespace().id();
681 bool isDeprecatedRadialGradient = (id == CSSValueRadial);
682 if (isDeprecatedRadialGradient)
683 result = CSSRadialGradientValue::create(NonRepeating, CSSDeprecatedRadia lGradient);
684 else if (id == CSSValueLinear)
685 result = CSSLinearGradientValue::create(NonRepeating, CSSDeprecatedLinea rGradient);
686 if (!result || !consumeCommaIncludingWhitespace(args))
687 return nullptr;
688
689 CSSPrimitiveValue* point = consumeDeprecatedGradientPoint(args, true);
690 if (!point)
691 return nullptr;
692 result->setFirstX(point);
693 point = consumeDeprecatedGradientPoint(args, false);
694 if (!point)
695 return nullptr;
696 result->setFirstY(point);
697
698 if (!consumeCommaIncludingWhitespace(args))
699 return nullptr;
700
701 // For radial gradients only, we now expect a numeric radius.
702 if (isDeprecatedRadialGradient) {
703 CSSPrimitiveValue* radius = consumeNumber(args, ValueRangeAll);
704 if (!radius || !consumeCommaIncludingWhitespace(args))
705 return nullptr;
706 toCSSRadialGradientValue(result)->setFirstRadius(radius);
707 }
708
709 point = consumeDeprecatedGradientPoint(args, true);
710 if (!point)
711 return nullptr;
712 result->setSecondX(point);
713 point = consumeDeprecatedGradientPoint(args, false);
714 if (!point)
715 return nullptr;
716 result->setSecondY(point);
717
718 // For radial gradients only, we now expect the second radius.
719 if (isDeprecatedRadialGradient) {
720 if (!consumeCommaIncludingWhitespace(args))
721 return nullptr;
722 CSSPrimitiveValue* radius = consumeNumber(args, ValueRangeAll);
723 if (!radius)
724 return nullptr;
725 toCSSRadialGradientValue(result)->setSecondRadius(radius);
726 }
727
728 CSSGradientColorStop stop;
729 while (consumeCommaIncludingWhitespace(args)) {
730 if (!consumeDeprecatedGradientColorStop(args, stop, cssParserMode))
731 return nullptr;
732 result->addStop(stop);
733 }
734
735 return result;
736 }
737
738 static bool consumeGradientColorStops(CSSParserTokenRange& range, CSSParserMode cssParserMode, CSSGradientValue* gradient)
739 {
740 bool supportsColorHints = gradient->gradientType() == CSSLinearGradient || g radient->gradientType() == CSSRadialGradient;
741
742 // The first color stop cannot be a color hint.
743 bool previousStopWasColorHint = true;
744 do {
745 CSSGradientColorStop stop;
746 stop.m_color = consumeColor(range, cssParserMode);
747 // Two hints in a row are not allowed.
748 if (!stop.m_color && (!supportsColorHints || previousStopWasColorHint))
749 return false;
750 previousStopWasColorHint = !stop.m_color;
751 stop.m_position = consumeLengthOrPercent(range, cssParserMode, ValueRang eAll);
752 if (!stop.m_color && !stop.m_position)
753 return false;
754 gradient->addStop(stop);
755 } while (consumeCommaIncludingWhitespace(range));
756
757 // The last color stop cannot be a color hint.
758 if (previousStopWasColorHint)
759 return false;
760
761 // Must have 2 or more stops to be valid.
762 return gradient->stopCount() >= 2;
763 }
764
765 static CSSValue* consumeDeprecatedRadialGradient(CSSParserTokenRange& args, CSSP arserMode cssParserMode, CSSGradientRepeat repeating)
766 {
767 CSSRadialGradientValue* result = CSSRadialGradientValue::create(repeating, C SSPrefixedRadialGradient);
768 CSSValue* centerX = nullptr;
769 CSSValue* centerY = nullptr;
770 consumeOneOrTwoValuedPosition(args, cssParserMode, UnitlessQuirk::Forbid, ce nterX, centerY);
771 if ((centerX || centerY) && !consumeCommaIncludingWhitespace(args))
772 return nullptr;
773
774 result->setFirstX(toCSSPrimitiveValue(centerX));
775 result->setSecondX(toCSSPrimitiveValue(centerX));
776 result->setFirstY(toCSSPrimitiveValue(centerY));
777 result->setSecondY(toCSSPrimitiveValue(centerY));
778
779 CSSPrimitiveValue* shape = consumeIdent<CSSValueCircle, CSSValueEllipse>(arg s);
780 CSSPrimitiveValue* sizeKeyword = consumeIdent<CSSValueClosestSide, CSSValueC losestCorner, CSSValueFarthestSide, CSSValueFarthestCorner, CSSValueContain, CSS ValueCover>(args);
781 if (!shape)
782 shape = consumeIdent<CSSValueCircle, CSSValueEllipse>(args);
783 result->setShape(shape);
784 result->setSizingBehavior(sizeKeyword);
785
786 // Or, two lengths or percentages
787 if (!shape && !sizeKeyword) {
788 CSSPrimitiveValue* horizontalSize = consumeLengthOrPercent(args, cssPars erMode, ValueRangeAll);
789 CSSPrimitiveValue* verticalSize = nullptr;
790 if (horizontalSize) {
791 verticalSize = consumeLengthOrPercent(args, cssParserMode, ValueRang eAll);
792 if (!verticalSize)
793 return nullptr;
794 consumeCommaIncludingWhitespace(args);
795 result->setEndHorizontalSize(horizontalSize);
796 result->setEndVerticalSize(verticalSize);
797 }
798 } else {
799 consumeCommaIncludingWhitespace(args);
800 }
801 if (!consumeGradientColorStops(args, cssParserMode, result))
802 return nullptr;
803
804 return result;
805 }
806
807 static CSSValue* consumeRadialGradient(CSSParserTokenRange& args, CSSParserMode cssParserMode, CSSGradientRepeat repeating)
808 {
809 CSSRadialGradientValue* result = CSSRadialGradientValue::create(repeating, C SSRadialGradient);
810
811 CSSPrimitiveValue* shape = nullptr;
812 CSSPrimitiveValue* sizeKeyword = nullptr;
813 CSSPrimitiveValue* horizontalSize = nullptr;
814 CSSPrimitiveValue* verticalSize = nullptr;
815
816 // First part of grammar, the size/shape clause:
817 // [ circle || <length> ] |
818 // [ ellipse || [ <length> | <percentage> ]{2} ] |
819 // [ [ circle | ellipse] || <size-keyword> ]
820 for (int i = 0; i < 3; ++i) {
821 if (args.peek().type() == IdentToken) {
822 CSSValueID id = args.peek().id();
823 if (id == CSSValueCircle || id == CSSValueEllipse) {
824 if (shape)
825 return nullptr;
826 shape = consumeIdent(args);
827 } else if (id == CSSValueClosestSide || id == CSSValueClosestCorner || id == CSSValueFarthestSide || id == CSSValueFarthestCorner) {
828 if (sizeKeyword)
829 return nullptr;
830 sizeKeyword = consumeIdent(args);
831 } else {
832 break;
833 }
834 } else {
835 CSSPrimitiveValue* center = consumeLengthOrPercent(args, cssParserMo de, ValueRangeAll);
836 if (!center)
837 break;
838 if (horizontalSize)
839 return nullptr;
840 horizontalSize = center;
841 center = consumeLengthOrPercent(args, cssParserMode, ValueRangeAll);
842 if (center) {
843 verticalSize = center;
844 ++i;
845 }
846 }
847 }
848
849 // You can specify size as a keyword or a length/percentage, not both.
850 if (sizeKeyword && horizontalSize)
851 return nullptr;
852 // Circles must have 0 or 1 lengths.
853 if (shape && shape->getValueID() == CSSValueCircle && verticalSize)
854 return nullptr;
855 // Ellipses must have 0 or 2 length/percentages.
856 if (shape && shape->getValueID() == CSSValueEllipse && horizontalSize && !ve rticalSize)
857 return nullptr;
858 // If there's only one size, it must be a length.
859 if (!verticalSize && horizontalSize && horizontalSize->isPercentage())
860 return nullptr;
861 if ((horizontalSize && horizontalSize->isCalculatedPercentageWithLength())
862 || (verticalSize && verticalSize->isCalculatedPercentageWithLength()))
863 return nullptr;
864
865 result->setShape(shape);
866 result->setSizingBehavior(sizeKeyword);
867 result->setEndHorizontalSize(horizontalSize);
868 result->setEndVerticalSize(verticalSize);
869
870 CSSValue* centerX = nullptr;
871 CSSValue* centerY = nullptr;
872 if (args.peek().id() == CSSValueAt) {
873 args.consumeIncludingWhitespace();
874 consumePosition(args, cssParserMode, UnitlessQuirk::Forbid, centerX, cen terY);
875 if (!(centerX && centerY))
876 return nullptr;
877 result->setFirstX(centerX);
878 result->setFirstY(centerY);
879 // Right now, CSS radial gradients have the same start and end centers.
880 result->setSecondX(centerX);
881 result->setSecondY(centerY);
882 }
883
884 if ((shape || sizeKeyword || horizontalSize || centerX || centerY) && !consu meCommaIncludingWhitespace(args))
885 return nullptr;
886 if (!consumeGradientColorStops(args, cssParserMode, result))
887 return nullptr;
888 return result;
889 }
890
891 static CSSValue* consumeLinearGradient(CSSParserTokenRange& args, CSSParserMode cssParserMode, CSSGradientRepeat repeating, CSSGradientType gradientType)
892 {
893 CSSLinearGradientValue* result = CSSLinearGradientValue::create(repeating, g radientType);
894
895 bool expectComma = true;
896 CSSPrimitiveValue* angle = consumeAngle(args);
897 if (angle) {
898 result->setAngle(angle);
899 } else if (gradientType == CSSPrefixedLinearGradient || consumeIdent<CSSValu eTo>(args)) {
900 CSSPrimitiveValue* endX = consumeIdent<CSSValueLeft, CSSValueRight>(args );
901 CSSPrimitiveValue* endY = consumeIdent<CSSValueBottom, CSSValueTop>(args );
902 if (!endX && !endY) {
903 if (gradientType == CSSLinearGradient)
904 return nullptr;
905 endY = CSSPrimitiveValue::createIdentifier(CSSValueTop);
906 expectComma = false;
907 } else if (!endX) {
908 endX = consumeIdent<CSSValueLeft, CSSValueRight>(args);
909 }
910
911 result->setFirstX(endX);
912 result->setFirstY(endY);
913 } else {
914 expectComma = false;
915 }
916
917 if (expectComma && !consumeCommaIncludingWhitespace(args))
918 return nullptr;
919 if (!consumeGradientColorStops(args, cssParserMode, result))
920 return nullptr;
921 return result;
922 }
923
924 CSSValue* consumeImageOrNone(CSSParserTokenRange& range, CSSParserContext contex t)
925 {
926 if (range.peek().id() == CSSValueNone)
927 return consumeIdent(range);
928 return consumeImage(range, context);
929 }
930
931 static CSSValue* consumeCrossFade(CSSParserTokenRange& args, CSSParserContext co ntext)
932 {
933 CSSValue* fromImageValue = consumeImageOrNone(args, context);
934 if (!fromImageValue || !consumeCommaIncludingWhitespace(args))
935 return nullptr;
936 CSSValue* toImageValue = consumeImageOrNone(args, context);
937 if (!toImageValue || !consumeCommaIncludingWhitespace(args))
938 return nullptr;
939
940 CSSPrimitiveValue* percentage = nullptr;
941 const CSSParserToken& percentageArg = args.consumeIncludingWhitespace();
942 if (percentageArg.type() == PercentageToken)
943 percentage = CSSPrimitiveValue::create(clampTo<double>(percentageArg.num ericValue() / 100, 0, 1), CSSPrimitiveValue::UnitType::Number);
944 else if (percentageArg.type() == NumberToken)
945 percentage = CSSPrimitiveValue::create(clampTo<double>(percentageArg.num ericValue(), 0, 1), CSSPrimitiveValue::UnitType::Number);
946
947 if (!percentage)
948 return nullptr;
949 return CSSCrossfadeValue::create(fromImageValue, toImageValue, percentage);
950 }
951
952 static CSSValue* consumePaint(CSSParserTokenRange& args, CSSParserContext contex t)
953 {
954 DCHECK(RuntimeEnabledFeatures::cssPaintAPIEnabled());
955
956 CSSCustomIdentValue* name = consumeCustomIdent(args);
957 if (!name)
958 return nullptr;
959
960 return CSSPaintValue::create(name);
961 }
962
963 static CSSValue* consumeGeneratedImage(CSSParserTokenRange& range, CSSParserCont ext context)
964 {
965 CSSValueID id = range.peek().functionId();
966 CSSParserTokenRange rangeCopy = range;
967 CSSParserTokenRange args = consumeFunction(rangeCopy);
968 CSSValue* result = nullptr;
969 if (id == CSSValueRadialGradient) {
970 result = consumeRadialGradient(args, context.mode(), NonRepeating);
971 } else if (id == CSSValueRepeatingRadialGradient) {
972 result = consumeRadialGradient(args, context.mode(), Repeating);
973 } else if (id == CSSValueWebkitLinearGradient) {
974 // FIXME: This should send a deprecation message.
975 if (context.useCounter())
976 context.useCounter()->count(UseCounter::DeprecatedWebKitLinearGradie nt);
977 result = consumeLinearGradient(args, context.mode(), NonRepeating, CSSPr efixedLinearGradient);
978 } else if (id == CSSValueWebkitRepeatingLinearGradient) {
979 // FIXME: This should send a deprecation message.
980 if (context.useCounter())
981 context.useCounter()->count(UseCounter::DeprecatedWebKitRepeatingLin earGradient);
982 result = consumeLinearGradient(args, context.mode(), Repeating, CSSPrefi xedLinearGradient);
983 } else if (id == CSSValueRepeatingLinearGradient) {
984 result = consumeLinearGradient(args, context.mode(), Repeating, CSSLinea rGradient);
985 } else if (id == CSSValueLinearGradient) {
986 result = consumeLinearGradient(args, context.mode(), NonRepeating, CSSLi nearGradient);
987 } else if (id == CSSValueWebkitGradient) {
988 // FIXME: This should send a deprecation message.
989 if (context.useCounter())
990 context.useCounter()->count(UseCounter::DeprecatedWebKitGradient);
991 result = consumeDeprecatedGradient(args, context.mode());
992 } else if (id == CSSValueWebkitRadialGradient) {
993 // FIXME: This should send a deprecation message.
994 if (context.useCounter())
995 context.useCounter()->count(UseCounter::DeprecatedWebKitRadialGradie nt);
996 result = consumeDeprecatedRadialGradient(args, context.mode(), NonRepeat ing);
997 } else if (id == CSSValueWebkitRepeatingRadialGradient) {
998 if (context.useCounter())
999 context.useCounter()->count(UseCounter::DeprecatedWebKitRepeatingRad ialGradient);
1000 result = consumeDeprecatedRadialGradient(args, context.mode(), Repeating );
1001 } else if (id == CSSValueWebkitCrossFade) {
1002 result = consumeCrossFade(args, context);
1003 } else if (id == CSSValuePaint) {
1004 result = RuntimeEnabledFeatures::cssPaintAPIEnabled() ? consumePaint(arg s, context) : nullptr;
1005 }
1006 if (!result || !args.atEnd())
1007 return nullptr;
1008 range = rangeCopy;
1009 return result;
1010 }
1011
1012 static CSSValue* createCSSImageValueWithReferrer(const AtomicString& rawValue, c onst CSSParserContext& context)
1013 {
1014 CSSValue* imageValue = CSSImageValue::create(rawValue, context.completeURL(r awValue));
1015 toCSSImageValue(imageValue)->setReferrer(context.referrer());
1016 return imageValue;
1017 }
1018
1019 static CSSValue* consumeImageSet(CSSParserTokenRange& range, const CSSParserCont ext& context)
1020 {
1021 CSSParserTokenRange rangeCopy = range;
1022 CSSParserTokenRange args = consumeFunction(rangeCopy);
1023 CSSImageSetValue* imageSet = CSSImageSetValue::create();
1024 do {
1025 AtomicString urlValue = consumeUrl(args).toAtomicString();
1026 if (urlValue.isNull())
1027 return nullptr;
1028
1029 CSSValue* image = createCSSImageValueWithReferrer(urlValue, context);
1030 imageSet->append(*image);
1031
1032 const CSSParserToken& token = args.consumeIncludingWhitespace();
1033 if (token.type() != DimensionToken)
1034 return nullptr;
1035 if (token.value() != "x")
1036 return nullptr;
1037 DCHECK(token.unitType() == CSSPrimitiveValue::UnitType::Unknown);
1038 double imageScaleFactor = token.numericValue();
1039 if (imageScaleFactor <= 0)
1040 return nullptr;
1041 imageSet->append(*CSSPrimitiveValue::create(imageScaleFactor, CSSPrimiti veValue::UnitType::Number));
1042 } while (consumeCommaIncludingWhitespace(args));
1043 if (!args.atEnd())
1044 return nullptr;
1045 range = rangeCopy;
1046 return imageSet;
1047 }
1048
1049 static bool isGeneratedImage(CSSValueID id)
1050 {
1051 return id == CSSValueLinearGradient || id == CSSValueRadialGradient
1052 || id == CSSValueRepeatingLinearGradient || id == CSSValueRepeatingRadia lGradient
1053 || id == CSSValueWebkitLinearGradient || id == CSSValueWebkitRadialGradi ent
1054 || id == CSSValueWebkitRepeatingLinearGradient || id == CSSValueWebkitRe peatingRadialGradient
1055 || id == CSSValueWebkitGradient || id == CSSValueWebkitCrossFade || id = = CSSValuePaint;
1056 }
1057
1058 CSSValue* consumeImage(CSSParserTokenRange& range, CSSParserContext context, Con sumeGeneratedImage generatedImage)
1059 {
1060 AtomicString uri = consumeUrl(range).toAtomicString();
1061 if (!uri.isNull())
1062 return createCSSImageValueWithReferrer(uri, context);
1063 if (range.peek().type() == FunctionToken) {
1064 CSSValueID id = range.peek().functionId();
1065 if (id == CSSValueWebkitImageSet)
1066 return consumeImageSet(range, context);
1067 if (generatedImage == ConsumeGeneratedImage::Allow && isGeneratedImage(i d))
1068 return consumeGeneratedImage(range, context);
1069 }
1070 return nullptr;
1071 }
1072
616 } // namespace CSSPropertyParserHelpers 1073 } // namespace CSSPropertyParserHelpers
617 1074
618 } // namespace blink 1075 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/css/parser/CSSPropertyParserHelpers.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698