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/CSSCursorImageValue.h" | 10 #include "core/css/CSSCursorImageValue.h" |
11 #include "core/css/CSSCustomIdentValue.h" | 11 #include "core/css/CSSCustomIdentValue.h" |
12 #include "core/css/CSSFontFaceSrcValue.h" | 12 #include "core/css/CSSFontFaceSrcValue.h" |
13 #include "core/css/CSSFontFeatureValue.h" | 13 #include "core/css/CSSFontFeatureValue.h" |
14 #include "core/css/CSSFunctionValue.h" | 14 #include "core/css/CSSFunctionValue.h" |
15 #include "core/css/CSSImageSetValue.h" | 15 #include "core/css/CSSImageSetValue.h" |
16 #include "core/css/CSSPathValue.h" | 16 #include "core/css/CSSPathValue.h" |
17 #include "core/css/CSSPrimitiveValueMappings.h" | 17 #include "core/css/CSSPrimitiveValueMappings.h" |
18 #include "core/css/CSSQuadValue.h" | 18 #include "core/css/CSSQuadValue.h" |
19 #include "core/css/CSSSVGDocumentValue.h" | 19 #include "core/css/CSSSVGDocumentValue.h" |
20 #include "core/css/CSSShadowValue.h" | 20 #include "core/css/CSSShadowValue.h" |
21 #include "core/css/CSSStringValue.h" | 21 #include "core/css/CSSStringValue.h" |
22 #include "core/css/CSSTimingFunctionValue.h" | 22 #include "core/css/CSSTimingFunctionValue.h" |
23 #include "core/css/CSSURIValue.h" | 23 #include "core/css/CSSURIValue.h" |
24 #include "core/css/CSSUnicodeRangeValue.h" | 24 #include "core/css/CSSUnicodeRangeValue.h" |
25 #include "core/css/CSSValuePair.h" | 25 #include "core/css/CSSValuePair.h" |
26 #include "core/css/CSSValuePool.h" | 26 #include "core/css/CSSValuePool.h" |
27 #include "core/css/CSSVariableReferenceValue.h" | 27 #include "core/css/CSSVariableReferenceValue.h" |
28 #include "core/css/FontFace.h" | 28 #include "core/css/FontFace.h" |
| 29 #include "core/css/HashTools.h" |
29 #include "core/css/parser/CSSParserFastPaths.h" | 30 #include "core/css/parser/CSSParserFastPaths.h" |
30 #include "core/css/parser/CSSParserValues.h" | 31 #include "core/css/parser/CSSParserValues.h" |
31 #include "core/css/parser/CSSVariableParser.h" | 32 #include "core/css/parser/CSSVariableParser.h" |
32 #include "core/frame/UseCounter.h" | 33 #include "core/frame/UseCounter.h" |
33 #include "core/layout/LayoutTheme.h" | 34 #include "core/layout/LayoutTheme.h" |
34 #include "core/svg/SVGPathUtilities.h" | 35 #include "core/svg/SVGPathUtilities.h" |
35 #include "wtf/text/StringBuilder.h" | 36 #include "wtf/text/StringBuilder.h" |
36 | 37 |
37 namespace blink { | 38 namespace blink { |
38 | 39 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 if (RuntimeEnabledFeatures::cssVariablesEnabled() && CSSVariableParser::cont
ainsValidVariableReferences(originalRange)) { | 126 if (RuntimeEnabledFeatures::cssVariablesEnabled() && CSSVariableParser::cont
ainsValidVariableReferences(originalRange)) { |
126 // We don't expand the shorthand here because crazypants. | 127 // We don't expand the shorthand here because crazypants. |
127 RefPtrWillBeRawPtr<CSSVariableReferenceValue> variable = CSSVariableRefe
renceValue::create(CSSVariableData::create(originalRange)); | 128 RefPtrWillBeRawPtr<CSSVariableReferenceValue> variable = CSSVariableRefe
renceValue::create(CSSVariableData::create(originalRange)); |
128 addProperty(propertyId, variable.release(), important); | 129 addProperty(propertyId, variable.release(), important); |
129 return true; | 130 return true; |
130 } | 131 } |
131 | 132 |
132 return false; | 133 return false; |
133 } | 134 } |
134 | 135 |
| 136 bool CSSPropertyParser::isColorKeyword(CSSValueID id) |
| 137 { |
| 138 // Named colors and color keywords: |
| 139 // |
| 140 // <named-color> |
| 141 // 'aqua', 'black', 'blue', ..., 'yellow' (CSS3: "basic color keywords") |
| 142 // 'aliceblue', ..., 'yellowgreen' (CSS3: "extended color keywords"
) |
| 143 // 'transparent' |
| 144 // |
| 145 // 'currentcolor' |
| 146 // |
| 147 // <deprecated-system-color> |
| 148 // 'ActiveBorder', ..., 'WindowText' |
| 149 // |
| 150 // WebKit proprietary/internal: |
| 151 // '-webkit-link' |
| 152 // '-webkit-activelink' |
| 153 // '-internal-active-list-box-selection' |
| 154 // '-internal-active-list-box-selection-text' |
| 155 // '-internal-inactive-list-box-selection' |
| 156 // '-internal-inactive-list-box-selection-text' |
| 157 // '-webkit-focus-ring-color' |
| 158 // '-webkit-text' |
| 159 // |
| 160 return (id >= CSSValueAqua && id <= CSSValueWebkitText) |
| 161 || (id >= CSSValueAliceblue && id <= CSSValueYellowgreen) |
| 162 || id == CSSValueMenu; |
| 163 } |
| 164 |
| 165 bool CSSPropertyParser::isSystemColor(CSSValueID id) |
| 166 { |
| 167 return (id >= CSSValueActiveborder && id <= CSSValueWindowtext) || id == CSS
ValueMenu; |
| 168 } |
| 169 |
| 170 template <typename CharacterType> |
| 171 static CSSPropertyID unresolvedCSSPropertyID(const CharacterType* propertyName,
unsigned length) |
| 172 { |
| 173 char buffer[maxCSSPropertyNameLength + 1]; // 1 for null character |
| 174 |
| 175 for (unsigned i = 0; i != length; ++i) { |
| 176 CharacterType c = propertyName[i]; |
| 177 if (c == 0 || c >= 0x7F) |
| 178 return CSSPropertyInvalid; // illegal character |
| 179 buffer[i] = toASCIILower(c); |
| 180 } |
| 181 buffer[length] = '\0'; |
| 182 |
| 183 const char* name = buffer; |
| 184 const Property* hashTableEntry = findProperty(name, length); |
| 185 if (!hashTableEntry) |
| 186 return CSSPropertyInvalid; |
| 187 CSSPropertyID property = static_cast<CSSPropertyID>(hashTableEntry->id); |
| 188 if (!CSSPropertyMetadata::isEnabledProperty(property)) |
| 189 return CSSPropertyInvalid; |
| 190 return property; |
| 191 } |
| 192 |
| 193 CSSPropertyID unresolvedCSSPropertyID(const String& string) |
| 194 { |
| 195 unsigned length = string.length(); |
| 196 |
| 197 if (!length) |
| 198 return CSSPropertyInvalid; |
| 199 if (length > maxCSSPropertyNameLength) |
| 200 return CSSPropertyInvalid; |
| 201 |
| 202 return string.is8Bit() ? unresolvedCSSPropertyID(string.characters8(), lengt
h) : unresolvedCSSPropertyID(string.characters16(), length); |
| 203 } |
| 204 |
| 205 CSSPropertyID unresolvedCSSPropertyID(const CSSParserString& string) |
| 206 { |
| 207 unsigned length = string.length(); |
| 208 |
| 209 if (!length) |
| 210 return CSSPropertyInvalid; |
| 211 if (length > maxCSSPropertyNameLength) |
| 212 return CSSPropertyInvalid; |
| 213 |
| 214 return string.is8Bit() ? unresolvedCSSPropertyID(string.characters8(), lengt
h) : unresolvedCSSPropertyID(string.characters16(), length); |
| 215 } |
| 216 |
| 217 template <typename CharacterType> |
| 218 static CSSValueID cssValueKeywordID(const CharacterType* valueKeyword, unsigned
length) |
| 219 { |
| 220 char buffer[maxCSSValueKeywordLength + 1]; // 1 for null character |
| 221 |
| 222 for (unsigned i = 0; i != length; ++i) { |
| 223 CharacterType c = valueKeyword[i]; |
| 224 if (c == 0 || c >= 0x7F) |
| 225 return CSSValueInvalid; // illegal character |
| 226 buffer[i] = WTF::toASCIILower(c); |
| 227 } |
| 228 buffer[length] = '\0'; |
| 229 |
| 230 const Value* hashTableEntry = findValue(buffer, length); |
| 231 return hashTableEntry ? static_cast<CSSValueID>(hashTableEntry->id) : CSSVal
ueInvalid; |
| 232 } |
| 233 |
| 234 CSSValueID cssValueKeywordID(const CSSParserString& string) |
| 235 { |
| 236 unsigned length = string.length(); |
| 237 if (!length) |
| 238 return CSSValueInvalid; |
| 239 if (length > maxCSSValueKeywordLength) |
| 240 return CSSValueInvalid; |
| 241 |
| 242 return string.is8Bit() ? cssValueKeywordID(string.characters8(), length) : c
ssValueKeywordID(string.characters16(), length); |
| 243 } |
| 244 |
135 bool CSSPropertyParser::consumeCSSWideKeyword(CSSPropertyID unresolvedProperty,
bool important) | 245 bool CSSPropertyParser::consumeCSSWideKeyword(CSSPropertyID unresolvedProperty,
bool important) |
136 { | 246 { |
137 CSSParserTokenRange rangeCopy = m_range; | 247 CSSParserTokenRange rangeCopy = m_range; |
138 CSSValueID id = rangeCopy.consumeIncludingWhitespace().id(); | 248 CSSValueID id = rangeCopy.consumeIncludingWhitespace().id(); |
139 if (!rangeCopy.atEnd()) | 249 if (!rangeCopy.atEnd()) |
140 return false; | 250 return false; |
141 | 251 |
142 RefPtrWillBeRawPtr<CSSValue> value = nullptr; | 252 RefPtrWillBeRawPtr<CSSValue> value = nullptr; |
143 if (id == CSSValueInitial) | 253 if (id == CSSValueInitial) |
144 value = cssValuePool().createExplicitInitialValue(); | 254 value = cssValuePool().createExplicitInitialValue(); |
(...skipping 2396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2541 UChar32 start = token.unicodeRangeStart(); | 2651 UChar32 start = token.unicodeRangeStart(); |
2542 UChar32 end = token.unicodeRangeEnd(); | 2652 UChar32 end = token.unicodeRangeEnd(); |
2543 if (start > end) | 2653 if (start > end) |
2544 return nullptr; | 2654 return nullptr; |
2545 values->append(CSSUnicodeRangeValue::create(start, end)); | 2655 values->append(CSSUnicodeRangeValue::create(start, end)); |
2546 } while (consumeCommaIncludingWhitespace(range)); | 2656 } while (consumeCommaIncludingWhitespace(range)); |
2547 | 2657 |
2548 return values.release(); | 2658 return values.release(); |
2549 } | 2659 } |
2550 | 2660 |
2551 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::consumeFontFaceSrcURI() | 2661 static PassRefPtrWillBeRawPtr<CSSValue> consumeFontFaceSrcURI(CSSParserTokenRang
e& range, CSSParserContext context) |
2552 { | 2662 { |
2553 String url = consumeUrl(m_range); | 2663 String url = consumeUrl(range); |
2554 if (url.isNull()) | 2664 if (url.isNull()) |
2555 return nullptr; | 2665 return nullptr; |
2556 RefPtrWillBeRawPtr<CSSFontFaceSrcValue> uriValue(CSSFontFaceSrcValue::create
(m_context.completeURL(url), m_context.shouldCheckContentSecurityPolicy())); | 2666 RefPtrWillBeRawPtr<CSSFontFaceSrcValue> uriValue(CSSFontFaceSrcValue::create
(context.completeURL(url), context.shouldCheckContentSecurityPolicy())); |
2557 uriValue->setReferrer(m_context.referrer()); | 2667 uriValue->setReferrer(context.referrer()); |
2558 | 2668 |
2559 if (m_range.peek().functionId() != CSSValueFormat) | 2669 if (range.peek().functionId() != CSSValueFormat) |
2560 return uriValue.release(); | 2670 return uriValue.release(); |
2561 | 2671 |
2562 // FIXME: https://drafts.csswg.org/css-fonts says that format() contains a c
omma-separated list of strings, | 2672 // FIXME: https://drafts.csswg.org/css-fonts says that format() contains a c
omma-separated list of strings, |
2563 // but CSSFontFaceSrcValue stores only one format. Allowing one format for n
ow. | 2673 // but CSSFontFaceSrcValue stores only one format. Allowing one format for n
ow. |
2564 // FIXME: IdentToken should not be supported here. | 2674 // FIXME: IdentToken should not be supported here. |
2565 CSSParserTokenRange args = consumeFunction(m_range); | 2675 CSSParserTokenRange args = consumeFunction(range); |
2566 const CSSParserToken& arg = args.consumeIncludingWhitespace(); | 2676 const CSSParserToken& arg = args.consumeIncludingWhitespace(); |
2567 if ((arg.type() != StringToken && arg.type() != IdentToken) || !args.atEnd()
) | 2677 if ((arg.type() != StringToken && arg.type() != IdentToken) || !args.atEnd()
) |
2568 return nullptr; | 2678 return nullptr; |
2569 uriValue->setFormat(arg.value()); | 2679 uriValue->setFormat(arg.value()); |
2570 return uriValue.release(); | 2680 return uriValue.release(); |
2571 } | 2681 } |
2572 | 2682 |
2573 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::consumeFontFaceSrcLocal() | 2683 static PassRefPtrWillBeRawPtr<CSSValue> consumeFontFaceSrcLocal(CSSParserTokenRa
nge& range, CSSParserContext context) |
2574 { | 2684 { |
2575 CSSParserTokenRange args = consumeFunction(m_range); | 2685 CSSParserTokenRange args = consumeFunction(range); |
2576 ContentSecurityPolicyDisposition shouldCheckContentSecurityPolicy = m_contex
t.shouldCheckContentSecurityPolicy(); | 2686 ContentSecurityPolicyDisposition shouldCheckContentSecurityPolicy = context.
shouldCheckContentSecurityPolicy(); |
2577 if (args.peek().type() == StringToken) { | 2687 if (args.peek().type() == StringToken) { |
2578 const CSSParserToken& arg = args.consumeIncludingWhitespace(); | 2688 const CSSParserToken& arg = args.consumeIncludingWhitespace(); |
2579 if (!args.atEnd()) | 2689 if (!args.atEnd()) |
2580 return nullptr; | 2690 return nullptr; |
2581 return CSSFontFaceSrcValue::createLocal(arg.value(), shouldCheckContentS
ecurityPolicy); | 2691 return CSSFontFaceSrcValue::createLocal(arg.value(), shouldCheckContentS
ecurityPolicy); |
2582 } | 2692 } |
2583 if (args.peek().type() == IdentToken) { | 2693 if (args.peek().type() == IdentToken) { |
2584 String familyName = concatenateFamilyName(args); | 2694 String familyName = concatenateFamilyName(args); |
2585 if (!args.atEnd()) | 2695 if (!args.atEnd()) |
2586 return nullptr; | 2696 return nullptr; |
2587 return CSSFontFaceSrcValue::createLocal(familyName, shouldCheckContentSe
curityPolicy); | 2697 return CSSFontFaceSrcValue::createLocal(familyName, shouldCheckContentSe
curityPolicy); |
2588 } | 2698 } |
2589 return nullptr; | 2699 return nullptr; |
2590 } | 2700 } |
2591 | 2701 |
2592 PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::consumeFontFaceSrc() | 2702 static PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFaceSrc(CSSParserTokenRan
ge& range, CSSParserContext context) |
2593 { | 2703 { |
2594 RefPtrWillBeRawPtr<CSSValueList> values(CSSValueList::createCommaSeparated()
); | 2704 RefPtrWillBeRawPtr<CSSValueList> values(CSSValueList::createCommaSeparated()
); |
2595 | 2705 |
2596 do { | 2706 do { |
2597 const CSSParserToken& token = m_range.peek(); | 2707 const CSSParserToken& token = range.peek(); |
2598 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; | 2708 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; |
2599 if (token.functionId() == CSSValueLocal) | 2709 if (token.functionId() == CSSValueLocal) |
2600 parsedValue = consumeFontFaceSrcLocal(); | 2710 parsedValue = consumeFontFaceSrcLocal(range, context); |
2601 else | 2711 else |
2602 parsedValue = consumeFontFaceSrcURI(); | 2712 parsedValue = consumeFontFaceSrcURI(range, context); |
2603 if (!parsedValue) | 2713 if (!parsedValue) |
2604 return nullptr; | 2714 return nullptr; |
2605 values->append(parsedValue); | 2715 values->append(parsedValue); |
2606 } while (consumeCommaIncludingWhitespace(m_range)); | 2716 } while (consumeCommaIncludingWhitespace(range)); |
2607 return values.release(); | 2717 return values.release(); |
2608 } | 2718 } |
2609 | 2719 |
2610 bool CSSPropertyParser::parseFontFaceDescriptor(CSSPropertyID propId) | 2720 bool CSSPropertyParser::parseFontFaceDescriptor(CSSPropertyID propId) |
2611 { | 2721 { |
2612 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; | 2722 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; |
2613 switch (propId) { | 2723 switch (propId) { |
2614 case CSSPropertyFontFamily: | 2724 case CSSPropertyFontFamily: |
2615 if (consumeGenericFamily(m_range)) | 2725 if (consumeGenericFamily(m_range)) |
2616 return false; | 2726 return false; |
2617 parsedValue = consumeFamilyName(m_range); | 2727 parsedValue = consumeFamilyName(m_range); |
2618 break; | 2728 break; |
2619 case CSSPropertySrc: // This is a list of urls or local references. | 2729 case CSSPropertySrc: // This is a list of urls or local references. |
2620 parsedValue = consumeFontFaceSrc(); | 2730 parsedValue = consumeFontFaceSrc(m_range, m_context); |
2621 break; | 2731 break; |
2622 case CSSPropertyUnicodeRange: | 2732 case CSSPropertyUnicodeRange: |
2623 parsedValue = consumeFontFaceUnicodeRange(m_range); | 2733 parsedValue = consumeFontFaceUnicodeRange(m_range); |
2624 break; | 2734 break; |
2625 case CSSPropertyFontDisplay: | 2735 case CSSPropertyFontDisplay: |
2626 case CSSPropertyFontStretch: | 2736 case CSSPropertyFontStretch: |
2627 case CSSPropertyFontStyle: { | 2737 case CSSPropertyFontStyle: { |
2628 CSSValueID id = m_range.consumeIncludingWhitespace().id(); | 2738 CSSValueID id = m_range.consumeIncludingWhitespace().id(); |
2629 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(propId, id)) | 2739 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(propId, id)) |
2630 return false; | 2740 return false; |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3114 return consumeShorthandGreedily(flexFlowShorthand(), important); | 3224 return consumeShorthandGreedily(flexFlowShorthand(), important); |
3115 case CSSPropertyWebkitColumnRule: | 3225 case CSSPropertyWebkitColumnRule: |
3116 return consumeShorthandGreedily(webkitColumnRuleShorthand(), important); | 3226 return consumeShorthandGreedily(webkitColumnRuleShorthand(), important); |
3117 default: | 3227 default: |
3118 m_currentShorthand = oldShorthand; | 3228 m_currentShorthand = oldShorthand; |
3119 return false; | 3229 return false; |
3120 } | 3230 } |
3121 } | 3231 } |
3122 | 3232 |
3123 } // namespace blink | 3233 } // namespace blink |
OLD | NEW |