OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) |
3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc.
All rights reserved. | 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc.
All rights reserved. |
5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> | 5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> |
6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> | 6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> |
7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) |
8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. | 8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. |
9 * Copyright (C) 2012 Intel Corporation. All rights reserved. | 9 * Copyright (C) 2012 Intel Corporation. All rights reserved. |
10 * | 10 * |
(...skipping 13 matching lines...) Expand all Loading... |
24 * Boston, MA 02110-1301, USA. | 24 * Boston, MA 02110-1301, USA. |
25 */ | 25 */ |
26 | 26 |
27 #include "config.h" | 27 #include "config.h" |
28 #include "core/css/parser/CSSPropertyParser.h" | 28 #include "core/css/parser/CSSPropertyParser.h" |
29 | 29 |
30 #include "core/StylePropertyShorthand.h" | 30 #include "core/StylePropertyShorthand.h" |
31 #include "core/css/CSSBasicShapeValues.h" | 31 #include "core/css/CSSBasicShapeValues.h" |
32 #include "core/css/CSSBorderImage.h" | 32 #include "core/css/CSSBorderImage.h" |
33 #include "core/css/CSSContentDistributionValue.h" | 33 #include "core/css/CSSContentDistributionValue.h" |
34 #include "core/css/CSSCounterValue.h" | |
35 #include "core/css/CSSCrossfadeValue.h" | 34 #include "core/css/CSSCrossfadeValue.h" |
36 #include "core/css/CSSCustomIdentValue.h" | 35 #include "core/css/CSSCustomIdentValue.h" |
37 #include "core/css/CSSFunctionValue.h" | 36 #include "core/css/CSSFunctionValue.h" |
38 #include "core/css/CSSGridLineNamesValue.h" | 37 #include "core/css/CSSGridLineNamesValue.h" |
39 #include "core/css/CSSImageSetValue.h" | 38 #include "core/css/CSSImageSetValue.h" |
40 #include "core/css/CSSPrimitiveValueMappings.h" | 39 #include "core/css/CSSPrimitiveValueMappings.h" |
41 #include "core/css/CSSProperty.h" | 40 #include "core/css/CSSProperty.h" |
42 #include "core/css/CSSPropertyMetadata.h" | 41 #include "core/css/CSSPropertyMetadata.h" |
43 #include "core/css/CSSQuadValue.h" | 42 #include "core/css/CSSQuadValue.h" |
44 #include "core/css/CSSReflectValue.h" | 43 #include "core/css/CSSReflectValue.h" |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 return CSSPrimitiveValue::create(m_parsedCalculation.release()); | 232 return CSSPrimitiveValue::create(m_parsedCalculation.release()); |
234 } | 233 } |
235 | 234 |
236 ASSERT((value->unit() >= CSSPrimitiveValue::UnitType::Number && value->unit(
) <= CSSPrimitiveValue::UnitType::Kilohertz) | 235 ASSERT((value->unit() >= CSSPrimitiveValue::UnitType::Number && value->unit(
) <= CSSPrimitiveValue::UnitType::Kilohertz) |
237 || (value->unit() >= CSSPrimitiveValue::UnitType::Turns && value->unit()
<= CSSPrimitiveValue::UnitType::Chs) | 236 || (value->unit() >= CSSPrimitiveValue::UnitType::Turns && value->unit()
<= CSSPrimitiveValue::UnitType::Chs) |
238 || (value->unit() >= CSSPrimitiveValue::UnitType::ViewportWidth && value
->unit() <= CSSPrimitiveValue::UnitType::ViewportMax) | 237 || (value->unit() >= CSSPrimitiveValue::UnitType::ViewportWidth && value
->unit() <= CSSPrimitiveValue::UnitType::ViewportMax) |
239 || (value->unit() >= CSSPrimitiveValue::UnitType::DotsPerPixel && value-
>unit() <= CSSPrimitiveValue::UnitType::DotsPerCentimeter)); | 238 || (value->unit() >= CSSPrimitiveValue::UnitType::DotsPerPixel && value-
>unit() <= CSSPrimitiveValue::UnitType::DotsPerCentimeter)); |
240 return cssValuePool().createValue(value->fValue, value->unit()); | 239 return cssValuePool().createValue(value->fValue, value->unit()); |
241 } | 240 } |
242 | 241 |
243 inline PassRefPtrWillBeRawPtr<CSSStringValue> CSSPropertyParser::createPrimitive
StringValue(CSSParserValue* value) | |
244 { | |
245 ASSERT(value->m_unit == CSSParserValue::String || value->m_unit == CSSParser
Value::Identifier); | |
246 return CSSStringValue::create(value->string); | |
247 } | |
248 | |
249 inline PassRefPtrWillBeRawPtr<CSSCustomIdentValue> CSSPropertyParser::createPrim
itiveCustomIdentValue(CSSParserValue* value) | 242 inline PassRefPtrWillBeRawPtr<CSSCustomIdentValue> CSSPropertyParser::createPrim
itiveCustomIdentValue(CSSParserValue* value) |
250 { | 243 { |
251 ASSERT(value->m_unit == CSSParserValue::String || value->m_unit == CSSParser
Value::Identifier); | 244 ASSERT(value->m_unit == CSSParserValue::String || value->m_unit == CSSParser
Value::Identifier); |
252 return CSSCustomIdentValue::create(value->string); | 245 return CSSCustomIdentValue::create(value->string); |
253 } | 246 } |
254 | 247 |
255 static inline bool isComma(CSSParserValue* value) | 248 static inline bool isComma(CSSParserValue* value) |
256 { | 249 { |
257 ASSERT(value); | 250 ASSERT(value); |
258 return value->m_unit == CSSParserValue::Operator && value->iValue == ','; | 251 return value->m_unit == CSSParserValue::Operator && value->iValue == ','; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 return false; | 322 return false; |
330 addProperty(propId, cssValuePool().createIdentifierValue(id), important)
; | 323 addProperty(propId, cssValuePool().createIdentifierValue(id), important)
; |
331 return true; | 324 return true; |
332 } | 325 } |
333 | 326 |
334 bool validPrimitive = false; | 327 bool validPrimitive = false; |
335 Units unitless = FUnknown; | 328 Units unitless = FUnknown; |
336 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; | 329 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; |
337 | 330 |
338 switch (propId) { | 331 switch (propId) { |
339 case CSSPropertyContent: // [ <string> | <uri> | <counter> | at
tr(X) | open-quote | | |
340 // close-quote | no-open-quote | no-close-quote ]+ | inherit | |
341 parsedValue = parseContent(); | |
342 break; | |
343 | |
344 /* Start of supported CSS properties with validation. This is needed for par
seShorthand to work | |
345 * correctly and allows optimization in blink::applyRule(..) | |
346 */ | |
347 | |
348 case CSSPropertyBackgroundColor: // <color> | inherit | 332 case CSSPropertyBackgroundColor: // <color> | inherit |
349 case CSSPropertyBorderTopColor: // <color> | inherit | 333 case CSSPropertyBorderTopColor: // <color> | inherit |
350 case CSSPropertyBorderRightColor: | 334 case CSSPropertyBorderRightColor: |
351 case CSSPropertyBorderBottomColor: | 335 case CSSPropertyBorderBottomColor: |
352 case CSSPropertyBorderLeftColor: | 336 case CSSPropertyBorderLeftColor: |
353 parsedValue = parseColor(m_valueList->current(), inQuirksMode() && (!inS
horthand() || m_currentShorthand == CSSPropertyBorderColor)); | 337 parsedValue = parseColor(m_valueList->current(), inQuirksMode() && (!inS
horthand() || m_currentShorthand == CSSPropertyBorderColor)); |
354 if (parsedValue) | 338 if (parsedValue) |
355 m_valueList->next(); | 339 m_valueList->next(); |
356 break; | 340 break; |
357 | 341 |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 case CSSPropertyCy: | 879 case CSSPropertyCy: |
896 case CSSPropertyX: | 880 case CSSPropertyX: |
897 case CSSPropertyY: | 881 case CSSPropertyY: |
898 case CSSPropertyR: | 882 case CSSPropertyR: |
899 case CSSPropertyRx: | 883 case CSSPropertyRx: |
900 case CSSPropertyRy: | 884 case CSSPropertyRy: |
901 case CSSPropertyScale: | 885 case CSSPropertyScale: |
902 case CSSPropertyTranslate: | 886 case CSSPropertyTranslate: |
903 case CSSPropertyCursor: | 887 case CSSPropertyCursor: |
904 case CSSPropertyTransformOrigin: | 888 case CSSPropertyTransformOrigin: |
| 889 case CSSPropertyContent: |
905 validPrimitive = false; | 890 validPrimitive = false; |
906 break; | 891 break; |
907 | 892 |
908 case CSSPropertyScrollSnapPointsX: | 893 case CSSPropertyScrollSnapPointsX: |
909 case CSSPropertyScrollSnapPointsY: | 894 case CSSPropertyScrollSnapPointsY: |
910 parsedValue = parseScrollSnapPoints(); | 895 parsedValue = parseScrollSnapPoints(); |
911 break; | 896 break; |
912 case CSSPropertyScrollSnapCoordinate: | 897 case CSSPropertyScrollSnapCoordinate: |
913 parsedValue = parseScrollSnapCoordinate(); | 898 parsedValue = parseScrollSnapCoordinate(); |
914 break; | 899 break; |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1251 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseScrollSnapCoordinate() | 1236 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseScrollSnapCoordinate() |
1252 { | 1237 { |
1253 if (m_valueList->current()->id == CSSValueNone) { | 1238 if (m_valueList->current()->id == CSSValueNone) { |
1254 m_valueList->next(); | 1239 m_valueList->next(); |
1255 return cssValuePool().createIdentifierValue(CSSValueNone); | 1240 return cssValuePool().createIdentifierValue(CSSValueNone); |
1256 } | 1241 } |
1257 | 1242 |
1258 return parsePositionList(m_valueList); | 1243 return parsePositionList(m_valueList); |
1259 } | 1244 } |
1260 | 1245 |
1261 // [ <string> | <uri> | <counter> | attr(X) | open-quote | close-quote | no-open
-quote | no-close-quote ]+ | inherit | |
1262 // in CSS 2.1 this got somewhat reduced: | |
1263 // [ <string> | attr(X) | open-quote | close-quote | no-open-quote | no-close-qu
ote ]+ | inherit | |
1264 PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseContent() | |
1265 { | |
1266 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated
(); | |
1267 | |
1268 while (CSSParserValue* val = m_valueList->current()) { | |
1269 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; | |
1270 if (val->m_unit == CSSParserValue::URI) { | |
1271 // url | |
1272 parsedValue = createCSSImageValueWithReferrer(val->string, m_context
); | |
1273 } else if (val->m_unit == CSSParserValue::Function) { | |
1274 // attr(X) | counter(X [,Y]) | counters(X, Y, [,Z]) | -webkit-gradie
nt(...) | |
1275 CSSParserValueList* args = val->function->args.get(); | |
1276 if (!args) | |
1277 return nullptr; | |
1278 if (val->function->id == CSSValueAttr) { | |
1279 parsedValue = parseAttr(args); | |
1280 } else if (val->function->id == CSSValueCounter) { | |
1281 parsedValue = parseCounterContent(args, false); | |
1282 } else if (val->function->id == CSSValueCounters) { | |
1283 parsedValue = parseCounterContent(args, true); | |
1284 } else if (val->function->id == CSSValueWebkitImageSet) { | |
1285 parsedValue = parseImageSet(m_valueList); | |
1286 } else if (CSSPropertyParser::isGeneratedImage(val->function->id)) { | |
1287 if (!parseGeneratedImage(m_valueList, parsedValue)) | |
1288 return nullptr; | |
1289 } | |
1290 } else if (val->m_unit == CSSParserValue::Identifier) { | |
1291 switch (val->id) { | |
1292 case CSSValueOpenQuote: | |
1293 case CSSValueCloseQuote: | |
1294 case CSSValueNoOpenQuote: | |
1295 case CSSValueNoCloseQuote: | |
1296 case CSSValueNone: | |
1297 case CSSValueNormal: | |
1298 parsedValue = cssValuePool().createIdentifierValue(val->id); | |
1299 default: | |
1300 break; | |
1301 } | |
1302 } else if (val->m_unit == CSSParserValue::String) { | |
1303 parsedValue = createPrimitiveStringValue(val); | |
1304 } | |
1305 if (!parsedValue) | |
1306 return nullptr; | |
1307 values->append(parsedValue.release()); | |
1308 m_valueList->next(); | |
1309 } | |
1310 | |
1311 return values.release(); | |
1312 } | |
1313 | |
1314 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAttr(CSSParserValueList
* args) | |
1315 { | |
1316 if (args->size() != 1) | |
1317 return nullptr; | |
1318 | |
1319 CSSParserValue* a = args->current(); | |
1320 | |
1321 if (a->m_unit != CSSParserValue::Identifier) | |
1322 return nullptr; | |
1323 | |
1324 String attrName = a->string; | |
1325 // CSS allows identifiers with "-" at the start, like "-webkit-mask-image". | |
1326 // But HTML attribute names can't have those characters, and we should not | |
1327 // even parse them inside attr(). | |
1328 if (attrName[0] == '-') | |
1329 return nullptr; | |
1330 | |
1331 if (m_context.isHTMLDocument()) | |
1332 attrName = attrName.lower(); | |
1333 | |
1334 RefPtrWillBeRawPtr<CSSFunctionValue> attrValue = CSSFunctionValue::create(CS
SValueAttr); | |
1335 attrValue->append(CSSCustomIdentValue::create(attrName)); | |
1336 return attrValue.release(); | |
1337 } | |
1338 | |
1339 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseColor(const CSSParserVa
lue* value, bool acceptQuirkyColors) | 1246 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseColor(const CSSParserVa
lue* value, bool acceptQuirkyColors) |
1340 { | 1247 { |
1341 CSSValueID id = value->id; | 1248 CSSValueID id = value->id; |
1342 if (isColorKeyword(id)) { | 1249 if (isColorKeyword(id)) { |
1343 if (!isValueAllowedInMode(id, m_context.mode())) | 1250 if (!isValueAllowedInMode(id, m_context.mode())) |
1344 return nullptr; | 1251 return nullptr; |
1345 if (id == CSSValueWebkitText && m_context.useCounter()) | 1252 if (id == CSSValueWebkitText && m_context.useCounter()) |
1346 m_context.useCounter()->count(UseCounter::WebkitTextInColorProperty)
; | 1253 m_context.useCounter()->count(UseCounter::WebkitTextInColorProperty)
; |
1347 return cssValuePool().createIdentifierValue(id); | 1254 return cssValuePool().createIdentifierValue(id); |
1348 } | 1255 } |
(...skipping 1382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2731 default: | 2638 default: |
2732 return parsedValues; | 2639 return parsedValues; |
2733 } | 2640 } |
2734 parsedValues->append(cssValuePool().createIdentifierValue(value->id)); | 2641 parsedValues->append(cssValuePool().createIdentifierValue(value->id)); |
2735 list.next(); | 2642 list.next(); |
2736 } | 2643 } |
2737 | 2644 |
2738 return parsedValues; | 2645 return parsedValues; |
2739 } | 2646 } |
2740 | 2647 |
2741 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseCounterContent(CSSParse
rValueList* args, bool counters) | |
2742 { | |
2743 unsigned numArgs = args->size(); | |
2744 if (counters && numArgs != 3 && numArgs != 5) | |
2745 return nullptr; | |
2746 if (!counters && numArgs != 1 && numArgs != 3) | |
2747 return nullptr; | |
2748 | |
2749 CSSParserValue* i = args->current(); | |
2750 if (i->m_unit != CSSParserValue::Identifier) | |
2751 return nullptr; | |
2752 RefPtrWillBeRawPtr<CSSCustomIdentValue> identifier = createPrimitiveCustomId
entValue(i); | |
2753 | |
2754 RefPtrWillBeRawPtr<CSSCustomIdentValue> separator = nullptr; | |
2755 if (!counters) | |
2756 separator = CSSCustomIdentValue::create(String()); | |
2757 else { | |
2758 args->next(); | |
2759 if (!consumeComma(args)) | |
2760 return nullptr; | |
2761 | |
2762 i = args->current(); | |
2763 if (i->m_unit != CSSParserValue::String) | |
2764 return nullptr; | |
2765 | |
2766 separator = createPrimitiveCustomIdentValue(i); | |
2767 } | |
2768 | |
2769 RefPtrWillBeRawPtr<CSSPrimitiveValue> listStyle = nullptr; | |
2770 i = args->next(); | |
2771 if (!i) // Make the list style default decimal | |
2772 listStyle = cssValuePool().createIdentifierValue(CSSValueDecimal); | |
2773 else { | |
2774 if (!consumeComma(args)) | |
2775 return nullptr; | |
2776 | |
2777 i = args->current(); | |
2778 if (i->m_unit != CSSParserValue::Identifier) | |
2779 return nullptr; | |
2780 | |
2781 CSSValueID listStyleID = CSSValueInvalid; | |
2782 if (i->id == CSSValueNone || (i->id >= CSSValueDisc && i->id <= CSSValue
KatakanaIroha)) | |
2783 listStyleID = i->id; | |
2784 else | |
2785 return nullptr; | |
2786 | |
2787 listStyle = cssValuePool().createIdentifierValue(listStyleID); | |
2788 } | |
2789 | |
2790 return CSSCounterValue::create(identifier.release(), listStyle.release(), se
parator.release()); | |
2791 } | |
2792 | |
2793 static void completeBorderRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[4]) | 2648 static void completeBorderRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[4]) |
2794 { | 2649 { |
2795 if (radii[3]) | 2650 if (radii[3]) |
2796 return; | 2651 return; |
2797 if (!radii[2]) { | 2652 if (!radii[2]) { |
2798 if (!radii[1]) | 2653 if (!radii[1]) |
2799 radii[1] = radii[0]; | 2654 radii[1] = radii[0]; |
2800 radii[2] = radii[0]; | 2655 radii[2] = radii[0]; |
2801 } | 2656 } |
2802 radii[3] = radii[1]; | 2657 radii[3] = radii[1]; |
(...skipping 2124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4927 ASSERT(!m_parsedCalculation); | 4782 ASSERT(!m_parsedCalculation); |
4928 m_parsedCalculation = CSSCalcValue::create(args, range); | 4783 m_parsedCalculation = CSSCalcValue::create(args, range); |
4929 | 4784 |
4930 if (!m_parsedCalculation) | 4785 if (!m_parsedCalculation) |
4931 return false; | 4786 return false; |
4932 | 4787 |
4933 return true; | 4788 return true; |
4934 } | 4789 } |
4935 | 4790 |
4936 } // namespace blink | 4791 } // namespace blink |
OLD | NEW |