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" |
11 #include "core/css/CSSFontFeatureValue.h" | 11 #include "core/css/CSSFontFeatureValue.h" |
12 #include "core/css/CSSPrimitiveValueMappings.h" | |
12 #include "core/css/CSSUnicodeRangeValue.h" | 13 #include "core/css/CSSUnicodeRangeValue.h" |
13 #include "core/css/CSSValuePool.h" | 14 #include "core/css/CSSValuePool.h" |
15 #include "core/css/FontFace.h" | |
14 #include "core/css/parser/CSSParserFastPaths.h" | 16 #include "core/css/parser/CSSParserFastPaths.h" |
15 #include "core/css/parser/CSSParserValues.h" | 17 #include "core/css/parser/CSSParserValues.h" |
16 #include "core/frame/UseCounter.h" | 18 #include "core/frame/UseCounter.h" |
19 #include "core/layout/LayoutTheme.h" | |
17 #include "wtf/text/StringBuilder.h" | 20 #include "wtf/text/StringBuilder.h" |
18 | 21 |
19 namespace blink { | 22 namespace blink { |
20 | 23 |
21 CSSPropertyParser::CSSPropertyParser(CSSParserValueList* valueList, const CSSPar serTokenRange& range, | 24 CSSPropertyParser::CSSPropertyParser(CSSParserValueList* valueList, const CSSPar serTokenRange& range, |
22 const CSSParserContext& context, WillBeHeapVector<CSSProperty, 256>& parsedP roperties, | 25 const CSSParserContext& context, WillBeHeapVector<CSSProperty, 256>& parsedP roperties, |
23 StyleRule::Type ruleType) | 26 StyleRule::Type ruleType) |
24 : m_valueList(valueList) | 27 : m_valueList(valueList) |
25 , m_range(range) | 28 , m_range(range) |
26 , m_context(context) | 29 , m_context(context) |
27 , m_parsedProperties(parsedProperties) | 30 , m_parsedProperties(parsedProperties) |
28 , m_ruleType(ruleType) | |
29 , m_inParseShorthand(0) | 31 , m_inParseShorthand(0) |
30 , m_currentShorthand(CSSPropertyInvalid) | 32 , m_currentShorthand(CSSPropertyInvalid) |
31 , m_implicitShorthand(false) | 33 , m_implicitShorthand(false) |
32 { | 34 { |
33 } | 35 } |
34 | 36 |
35 bool CSSPropertyParser::parseValue(CSSPropertyID unresolvedProperty, bool import ant, | 37 bool CSSPropertyParser::parseValue(CSSPropertyID unresolvedProperty, bool import ant, |
36 const CSSParserTokenRange& range, const CSSParserContext& context, | 38 const CSSParserTokenRange& range, const CSSParserContext& context, |
37 WillBeHeapVector<CSSProperty, 256>& parsedProperties, StyleRule::Type ruleTy pe) | 39 WillBeHeapVector<CSSProperty, 256>& parsedProperties, StyleRule::Type ruleTy pe) |
38 { | 40 { |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
493 if (fontVariant) | 495 if (fontVariant) |
494 values->append(fontVariant.release()); | 496 values->append(fontVariant.release()); |
495 } while (consumeCommaIncludingWhitespace(range)); | 497 } while (consumeCommaIncludingWhitespace(range)); |
496 | 498 |
497 if (values->length()) | 499 if (values->length()) |
498 return values.release(); | 500 return values.release(); |
499 | 501 |
500 return nullptr; | 502 return nullptr; |
501 } | 503 } |
502 | 504 |
503 static PassRefPtrWillBeRawPtr<CSSValue> consumeFontWeight(CSSParserTokenRange& r ange) | 505 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeFontWeight(CSSParserToke nRange& range) |
504 { | 506 { |
505 const CSSParserToken& token = range.peek(); | 507 const CSSParserToken& token = range.peek(); |
506 if (token.id() >= CSSValueNormal && token.id() <= CSSValueLighter) | 508 if (token.id() >= CSSValueNormal && token.id() <= CSSValueLighter) |
507 return consumeIdent(range); | 509 return consumeIdent(range); |
508 if (token.type() != NumberToken || token.numericValueType() != IntegerValueT ype) | 510 if (token.type() != NumberToken || token.numericValueType() != IntegerValueT ype) |
509 return nullptr; | 511 return nullptr; |
510 int weight = static_cast<int>(token.numericValue()); | 512 int weight = static_cast<int>(token.numericValue()); |
511 if ((weight % 100) || weight < 100 || weight > 900) | 513 if ((weight % 100) || weight < 100 || weight > 900) |
512 return nullptr; | 514 return nullptr; |
513 range.consumeIncludingWhitespace(); | 515 range.consumeIncludingWhitespace(); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
575 } | 577 } |
576 | 578 |
577 static PassRefPtrWillBeRawPtr<CSSValue> consumeTabSize(CSSParserTokenRange& rang e, CSSParserMode cssParserMode) | 579 static PassRefPtrWillBeRawPtr<CSSValue> consumeTabSize(CSSParserTokenRange& rang e, CSSParserMode cssParserMode) |
578 { | 580 { |
579 RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue = consumeInteger(range, cs sParserMode, 0); | 581 RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue = consumeInteger(range, cs sParserMode, 0); |
580 if (parsedValue) | 582 if (parsedValue) |
581 return parsedValue; | 583 return parsedValue; |
582 return consumeLength(range, cssParserMode, ValueRangeNonNegative); | 584 return consumeLength(range, cssParserMode, ValueRangeNonNegative); |
583 } | 585 } |
584 | 586 |
585 static PassRefPtrWillBeRawPtr<CSSValue> consumeFontSize(CSSParserTokenRange& ran ge, CSSParserMode cssParserMode) | 587 static PassRefPtrWillBeRawPtr<CSSValue> consumeFontSize(CSSParserTokenRange& ran ge, CSSParserMode cssParserMode, UnitlessQuirk unitless = UnitlessQuirk::Forbid) |
586 { | 588 { |
587 if (range.peek().id() >= CSSValueXxSmall && range.peek().id() <= CSSValueLar ger) | 589 if (range.peek().id() >= CSSValueXxSmall && range.peek().id() <= CSSValueLar ger) |
588 return consumeIdent(range); | 590 return consumeIdent(range); |
589 return consumeLengthOrPercent(range, cssParserMode, ValueRangeNonNegative, U nitlessQuirk::Allow); | 591 return consumeLengthOrPercent(range, cssParserMode, ValueRangeNonNegative, u nitless); |
590 } | 592 } |
591 | 593 |
592 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeLineHeight(CSSParserToke nRange& range, CSSParserMode cssParserMode) | 594 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeLineHeight(CSSParserToke nRange& range, CSSParserMode cssParserMode) |
593 { | 595 { |
594 if (range.peek().id() == CSSValueNormal) | 596 if (range.peek().id() == CSSValueNormal) |
595 return consumeIdent(range); | 597 return consumeIdent(range); |
596 | 598 |
597 RefPtrWillBeRawPtr<CSSPrimitiveValue> lineHeight = consumeNumber(range, Valu eRangeNonNegative); | 599 RefPtrWillBeRawPtr<CSSPrimitiveValue> lineHeight = consumeNumber(range, Valu eRangeNonNegative); |
598 if (lineHeight) | 600 if (lineHeight) |
599 return lineHeight; | 601 return lineHeight; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
644 case CSSPropertyFontFamily: | 646 case CSSPropertyFontFamily: |
645 return consumeFontFamily(m_range); | 647 return consumeFontFamily(m_range); |
646 case CSSPropertyFontWeight: | 648 case CSSPropertyFontWeight: |
647 return consumeFontWeight(m_range); | 649 return consumeFontWeight(m_range); |
648 case CSSPropertyLetterSpacing: | 650 case CSSPropertyLetterSpacing: |
649 case CSSPropertyWordSpacing: | 651 case CSSPropertyWordSpacing: |
650 return consumeSpacing(m_range, m_context.mode()); | 652 return consumeSpacing(m_range, m_context.mode()); |
651 case CSSPropertyTabSize: | 653 case CSSPropertyTabSize: |
652 return consumeTabSize(m_range, m_context.mode()); | 654 return consumeTabSize(m_range, m_context.mode()); |
653 case CSSPropertyFontSize: | 655 case CSSPropertyFontSize: |
654 return consumeFontSize(m_range, m_context.mode()); | 656 return consumeFontSize(m_range, m_context.mode(), UnitlessQuirk::Allow); |
655 case CSSPropertyLineHeight: | 657 case CSSPropertyLineHeight: |
656 return consumeLineHeight(m_range, m_context.mode()); | 658 return consumeLineHeight(m_range, m_context.mode()); |
657 case CSSPropertyRotate: | 659 case CSSPropertyRotate: |
658 return consumeRotation(m_range); | 660 return consumeRotation(m_range); |
659 default: | 661 default: |
660 return nullptr; | 662 return nullptr; |
661 } | 663 } |
662 } | 664 } |
663 | 665 |
664 static PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFaceUnicodeRange(CSSParse rTokenRange& range) | 666 static PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFaceUnicodeRange(CSSParse rTokenRange& range) |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
777 break; | 779 break; |
778 } | 780 } |
779 | 781 |
780 if (!parsedValue || !m_range.atEnd()) | 782 if (!parsedValue || !m_range.atEnd()) |
781 return false; | 783 return false; |
782 | 784 |
783 addProperty(propId, parsedValue.release(), false); | 785 addProperty(propId, parsedValue.release(), false); |
784 return true; | 786 return true; |
785 } | 787 } |
786 | 788 |
789 bool CSSPropertyParser::consumeSystemFont(bool important) | |
790 { | |
791 CSSValueID systemFontID = m_range.consumeIncludingWhitespace().id(); | |
792 ASSERT(systemFontID >= CSSValueCaption && systemFontID <= CSSValueStatusBar) ; | |
793 if (!m_range.atEnd()) | |
794 return false; | |
795 | |
796 FontStyle fontStyle = FontStyleNormal; | |
797 FontWeight fontWeight = FontWeightNormal; | |
798 float fontSize = 0; | |
799 AtomicString fontFamily; | |
800 LayoutTheme::theme().systemFont(systemFontID, fontStyle, fontWeight, fontSiz e, fontFamily); | |
801 | |
802 addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(fontS tyle == FontStyleItalic ? CSSValueItalic : CSSValueNormal), important); | |
803 addProperty(CSSPropertyFontWeight, cssValuePool().createValue(fontWeight), i mportant); | |
804 addProperty(CSSPropertyFontSize, cssValuePool().createValue(fontSize, CSSPri mitiveValue::UnitType::Pixels), important); | |
805 RefPtrWillBeRawPtr<CSSValueList> fontFamilyList = CSSValueList::createCommaS eparated(); | |
806 fontFamilyList->append(cssValuePool().createFontFamilyValue(fontFamily)); | |
807 addProperty(CSSPropertyFontFamily, fontFamilyList.release(), important); | |
808 | |
809 addProperty(CSSPropertyFontStretch, cssValuePool().createIdentifierValue(CSS ValueNormal), important); | |
810 addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue(CSS ValueNormal), important); | |
811 addProperty(CSSPropertyLineHeight, cssValuePool().createIdentifierValue(CSSV alueNormal), important); | |
812 return true; | |
813 } | |
814 | |
815 bool CSSPropertyParser::consumeFont(bool important) | |
816 { | |
817 // Let's check if there is an inherit or initial somewhere in the shorthand. | |
818 CSSParserTokenRange range = m_range; | |
819 while (!range.atEnd()) { | |
820 CSSValueID id = range.consumeIncludingWhitespace().id(); | |
821 if (id == CSSValueInherit || id == CSSValueInitial) | |
822 return false; | |
823 } | |
824 // Optional font-style, font-variant, font-stretch and font-weight. | |
825 RefPtrWillBeRawPtr<CSSPrimitiveValue> fontStyle = nullptr; | |
826 RefPtrWillBeRawPtr<CSSPrimitiveValue> fontVariant = nullptr; | |
827 RefPtrWillBeRawPtr<CSSPrimitiveValue> fontWeight = nullptr; | |
828 RefPtrWillBeRawPtr<CSSPrimitiveValue> fontStretch = nullptr; | |
829 while (!m_range.atEnd()) { | |
830 CSSValueID id = m_range.peek().id(); | |
831 if (!fontStyle && CSSParserFastPaths::isValidKeywordPropertyAndValue(CSS PropertyFontStyle, id)) { | |
832 fontStyle = consumeIdent(m_range); | |
833 continue; | |
834 } | |
835 if (!fontVariant) { | |
836 // Font variant in the shorthand is particular, it only accepts norm al or small-caps. | |
837 fontVariant = consumeFontVariant(m_range); | |
838 if (fontVariant) | |
839 continue; | |
840 } | |
841 if (!fontWeight) { | |
842 fontWeight = consumeFontWeight(m_range); | |
843 if (fontWeight) | |
844 continue; | |
845 } | |
846 if (!fontStretch && CSSParserFastPaths::isValidKeywordPropertyAndValue(C SSPropertyFontStretch, id)) | |
847 fontStretch = consumeIdent(m_range); | |
848 else | |
849 break; | |
850 } | |
851 | |
852 if (m_range.atEnd()) | |
853 return false; | |
854 | |
855 addProperty(CSSPropertyFontStyle, fontStyle ? fontStyle.release() : cssValue Pool().createIdentifierValue(CSSValueNormal), important); | |
856 addProperty(CSSPropertyFontVariant, fontVariant ? fontVariant.release() : cs sValuePool().createIdentifierValue(CSSValueNormal), important); | |
857 addProperty(CSSPropertyFontWeight, fontWeight ? fontWeight.release() : cssVa luePool().createIdentifierValue(CSSValueNormal), important); | |
858 addProperty(CSSPropertyFontStretch, fontStretch ? fontStretch.release() : cs sValuePool().createIdentifierValue(CSSValueNormal), important); | |
859 | |
860 // Now a font size _must_ come. | |
861 RefPtrWillBeRawPtr<CSSValue> fontSize = consumeFontSize(m_range, m_context.m ode()); | |
862 if (!fontSize || m_range.atEnd()) | |
863 return false; | |
864 | |
865 addProperty(CSSPropertyFontSize, fontSize.release(), important); | |
866 | |
867 if (m_range.peek().type() == DelimiterToken && m_range.peek().delimiter() == '/') { | |
868 m_range.consumeIncludingWhitespace(); | |
869 RefPtrWillBeRawPtr<CSSPrimitiveValue> lineHeight = consumeLineHeight(m_r ange, m_context.mode()); | |
870 if (!lineHeight) | |
871 return false; | |
872 addProperty(CSSPropertyLineHeight, lineHeight.release(), important); | |
873 } else { | |
874 addProperty(CSSPropertyLineHeight, cssValuePool().createIdentifierValue( CSSValueNormal), important, true); | |
Timothy Loh
2015/10/06 23:45:04
implicit value here can be removed too
| |
875 } | |
876 | |
877 // Font family must come now. | |
878 RefPtrWillBeRawPtr<CSSValue> parsedFamilyValue = consumeFontFamily(m_range); | |
879 if (!parsedFamilyValue) | |
880 return false; | |
881 | |
882 addProperty(CSSPropertyFontFamily, parsedFamilyValue.release(), important); | |
883 | |
884 // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20110324/#font-prop requir es that | |
885 // "font-stretch", "font-size-adjust", and "font-kerning" be reset to their initial values | |
886 // but we don't seem to support them at the moment. They should also be adde d here once implemented. | |
887 return m_range.atEnd(); | |
888 } | |
889 | |
787 bool CSSPropertyParser::parseShorthand(CSSPropertyID propId, bool important) | 890 bool CSSPropertyParser::parseShorthand(CSSPropertyID propId, bool important) |
788 { | 891 { |
789 m_range.consumeWhitespace(); | 892 m_range.consumeWhitespace(); |
893 CSSPropertyID oldShorthand = m_currentShorthand; | |
Timothy Loh
2015/10/06 23:45:04
// TODO(rob.buis): Remove this when the legacy pro
| |
894 m_currentShorthand = propId; | |
790 switch (propId) { | 895 switch (propId) { |
791 case CSSPropertyWebkitMarginCollapse: { | 896 case CSSPropertyWebkitMarginCollapse: { |
792 CSSValueID id = m_range.consumeIncludingWhitespace().id(); | 897 CSSValueID id = m_range.consumeIncludingWhitespace().id(); |
793 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(CSSPropertyWebki tMarginBeforeCollapse, id)) | 898 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(CSSPropertyWebki tMarginBeforeCollapse, id)) |
794 return false; | 899 return false; |
795 RefPtrWillBeRawPtr<CSSValue> beforeCollapse = cssValuePool().createIdent ifierValue(id); | 900 RefPtrWillBeRawPtr<CSSValue> beforeCollapse = cssValuePool().createIdent ifierValue(id); |
796 addProperty(CSSPropertyWebkitMarginBeforeCollapse, beforeCollapse, impor tant); | 901 addProperty(CSSPropertyWebkitMarginBeforeCollapse, beforeCollapse, impor tant); |
797 if (m_range.atEnd()) { | 902 if (m_range.atEnd()) { |
798 addProperty(CSSPropertyWebkitMarginAfterCollapse, beforeCollapse, im portant); | 903 addProperty(CSSPropertyWebkitMarginAfterCollapse, beforeCollapse, im portant); |
799 return true; | 904 return true; |
(...skipping 19 matching lines...) Expand all Loading... | |
819 // pagination controls, it should default to hidden. If the overflow-y v alue is anything but | 924 // pagination controls, it should default to hidden. If the overflow-y v alue is anything but |
820 // paged-x or paged-y, then overflow-x and overflow-y should have the sa me value. | 925 // paged-x or paged-y, then overflow-x and overflow-y should have the sa me value. |
821 if (id == CSSValueWebkitPagedX || id == CSSValueWebkitPagedY) | 926 if (id == CSSValueWebkitPagedX || id == CSSValueWebkitPagedY) |
822 overflowXValue = cssValuePool().createIdentifierValue(CSSValueAuto); | 927 overflowXValue = cssValuePool().createIdentifierValue(CSSValueAuto); |
823 else | 928 else |
824 overflowXValue = overflowYValue; | 929 overflowXValue = overflowYValue; |
825 addProperty(CSSPropertyOverflowX, overflowXValue.release(), important); | 930 addProperty(CSSPropertyOverflowX, overflowXValue.release(), important); |
826 addProperty(CSSPropertyOverflowY, overflowYValue.release(), important); | 931 addProperty(CSSPropertyOverflowY, overflowYValue.release(), important); |
827 return true; | 932 return true; |
828 } | 933 } |
934 case CSSPropertyFont: { | |
935 const CSSParserToken& token = m_range.peek(); | |
936 if (token.id() >= CSSValueCaption && token.id() <= CSSValueStatusBar) | |
937 return consumeSystemFont(important); | |
938 return consumeFont(important); | |
939 } | |
829 default: | 940 default: |
941 m_currentShorthand = oldShorthand; | |
830 return false; | 942 return false; |
831 } | 943 } |
832 } | 944 } |
833 | 945 |
834 } // namespace blink | 946 } // namespace blink |
OLD | NEW |