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 986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
997 case CSSPropertyBorderRadius: | 997 case CSSPropertyBorderRadius: |
998 case CSSPropertyAliasWebkitBorderRadius: | 998 case CSSPropertyAliasWebkitBorderRadius: |
999 return parseBorderRadius(unresolvedProperty, important); | 999 return parseBorderRadius(unresolvedProperty, important); |
1000 case CSSPropertyOutlineOffset: | 1000 case CSSPropertyOutlineOffset: |
1001 validPrimitive = validUnit(value, FLength); | 1001 validPrimitive = validUnit(value, FLength); |
1002 break; | 1002 break; |
1003 case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS 3, so treat as CSS3 | 1003 case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS 3, so treat as CSS3 |
1004 case CSSPropertyBoxShadow: | 1004 case CSSPropertyBoxShadow: |
1005 if (id == CSSValueNone) | 1005 if (id == CSSValueNone) |
1006 validPrimitive = true; | 1006 validPrimitive = true; |
1007 else { | 1007 else |
1008 RefPtrWillBeRawPtr<CSSValueList> shadowValueList = parseShadow(m_val ueList, propId); | 1008 return parseShadow(m_valueList, propId, important); |
Timothy Loh
2015/09/01 07:18:08
parsedValue = parseShadow(..) and remove the impor
rwlbuis
2015/09/02 22:38:58
Done.
| |
1009 if (shadowValueList) { | |
1010 addProperty(propId, shadowValueList.release(), important); | |
1011 m_valueList->next(); | |
1012 return true; | |
1013 } | |
1014 return false; | |
1015 } | |
1016 break; | 1009 break; |
1017 case CSSPropertyWebkitBoxReflect: | 1010 case CSSPropertyWebkitBoxReflect: |
1018 if (id == CSSValueNone) | 1011 if (id == CSSValueNone) |
1019 validPrimitive = true; | 1012 validPrimitive = true; |
1020 else | 1013 else |
1021 parsedValue = parseReflect(); | 1014 parsedValue = parseReflect(); |
1022 break; | 1015 break; |
1023 case CSSPropertyFontSizeAdjust: // none | <number> | 1016 case CSSPropertyFontSizeAdjust: // none | <number> |
1024 ASSERT(RuntimeEnabledFeatures::cssFontSizeAdjustEnabled()); | 1017 ASSERT(RuntimeEnabledFeatures::cssFontSizeAdjustEnabled()); |
1025 validPrimitive = (id == CSSValueNone) ? true : validUnit(value, FNumber | FNonNeg); | 1018 validPrimitive = (id == CSSValueNone) ? true : validUnit(value, FNumber | FNonNeg); |
(...skipping 4110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5136 return false; | 5129 return false; |
5137 result = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValue s[2], colorValues[3]); | 5130 result = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValue s[2], colorValues[3]); |
5138 } else { | 5131 } else { |
5139 return false; | 5132 return false; |
5140 } | 5133 } |
5141 } | 5134 } |
5142 | 5135 |
5143 return true; | 5136 return true; |
5144 } | 5137 } |
5145 | 5138 |
5146 // This class tracks parsing state for shadow values. If it goes out of scope ( e.g., due to an early return) | 5139 bool CSSPropertyParser::parseShadow(CSSParserValueList* valueList, CSSPropertyID propID, bool important) |
5147 // without the allowBreak bit being set, then it will clean up all of the object s and destroy them. | 5140 { |
5148 class ShadowParseContext { | 5141 RefPtrWillBeRawPtr<CSSValueList> shadowValueList = CSSValueList::createComma Separated(); |
5149 STACK_ALLOCATED(); | 5142 while (RefPtrWillBeRawPtr<CSSShadowValue> shadowValue = parseSingleShadow(va lueList, propID == CSSPropertyBoxShadow, true, propID == CSSPropertyBoxShadow ? 4 : 3)) { |
5150 public: | 5143 shadowValueList->append(shadowValue); |
5151 ShadowParseContext(CSSPropertyID prop) | 5144 if (!valueList->current()) |
5152 : property(prop) | 5145 break; |
5153 , allowX(true) | 5146 if (!isComma(valueList->current())) |
Timothy Loh
2015/09/01 07:18:08
!consumeComma and then you don't need the next() b
rwlbuis
2015/09/02 22:38:58
Done.
| |
5154 , allowY(false) | 5147 return false; |
5155 , allowBlur(false) | 5148 valueList->next(); |
5156 , allowSpread(false) | |
5157 , allowColor(true) | |
5158 , allowStyle(prop == CSSPropertyBoxShadow) | |
5159 , allowBreak(true) | |
5160 { | |
5161 } | 5149 } |
5150 if (shadowValueList->length() == 0 || valueList->current()) | |
5151 return false; | |
5152 addProperty(propID, shadowValueList.release(), important); | |
5153 return true; | |
5154 } | |
5162 | 5155 |
5163 bool allowLength() { return allowX || allowY || allowBlur || allowSpread; } | 5156 PassRefPtrWillBeRawPtr<CSSShadowValue> CSSPropertyParser::parseSingleShadow(CSSP arserValueList* valueList, bool allowInset, bool allowBreak, unsigned maxLength) |
5157 { | |
5158 RefPtrWillBeMember<CSSPrimitiveValue> style; | |
5159 RefPtrWillBeMember<CSSPrimitiveValue> color; | |
5160 RefPtrWillBeRawPtr<CSSValueList> lengths = CSSValueList::createSpaceSeparate d(); | |
Timothy Loh
2015/09/01 07:18:08
Probably just use a vector (or have four CSSValues
rwlbuis
2015/09/02 22:38:58
Done.
| |
5164 | 5161 |
5165 void commitValue() | 5162 CSSParserValue* val = valueList->current(); |
5166 { | 5163 if (!val) |
5167 // Handle the ,, case gracefully by doing nothing. | 5164 return nullptr; |
5168 if (x || y || blur || spread || color || style) { | 5165 if (val->id == CSSValueInset) { |
5169 if (!values) | 5166 if (!allowInset) |
5170 values = CSSValueList::createCommaSeparated(); | 5167 return nullptr; |
5168 style = cssValuePool().createIdentifierValue(val->id); | |
5169 val = valueList->next(); | |
5170 if (!val) | |
5171 return nullptr; | |
5172 } | |
5173 if ((color = parseColor(val))) | |
5174 val = valueList->next(); | |
5171 | 5175 |
5172 // Construct the current shadow value and add it to the list. | 5176 if (!val || !validUnit(val, FLength, HTMLStandardMode)) |
Timothy Loh
2015/09/01 07:18:08
Doesn't this fail if we have: color inset length l
rwlbuis
2015/09/02 22:38:58
In fact that syntax is not allowed, see fast/box-s
| |
5173 values->append(CSSShadowValue::create(x.release(), y.release(), blur .release(), spread.release(), style.release(), color.release())); | 5177 return nullptr; |
5174 } | 5178 lengths->append(createPrimitiveNumericValue(val)); |
5179 val = valueList->next(); | |
5175 | 5180 |
5176 // Now reset for the next shadow value. | 5181 if (!val || !validUnit(val, FLength, HTMLStandardMode)) |
5177 x = nullptr; | 5182 return nullptr; |
5178 y = nullptr; | 5183 lengths->append(createPrimitiveNumericValue(val)); |
5179 blur = nullptr; | 5184 val = valueList->next(); |
5180 spread = nullptr; | |
5181 style = nullptr; | |
5182 color = nullptr; | |
5183 | 5185 |
5184 allowX = true; | 5186 if (val && validUnit(val, FLength, HTMLStandardMode)) { |
5185 allowColor = true; | 5187 // Blur radius must be non-negative. |
5186 allowBreak = true; | 5188 if (m_parsedCalculation ? m_parsedCalculation->isNegative() : !validUnit (val, FLength | FNonNeg, HTMLStandardMode)) |
5187 allowY = false; | 5189 return nullptr; |
5188 allowBlur = false; | 5190 lengths->append(createPrimitiveNumericValue(val)); |
5189 allowSpread = false; | 5191 val = valueList->next(); |
5190 allowStyle = property == CSSPropertyBoxShadow; | 5192 if (val && validUnit(val, FLength, HTMLStandardMode)) { |
5191 } | 5193 lengths->append(createPrimitiveNumericValue(val)); |
5192 | 5194 val = valueList->next(); |
5193 void commitLength(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) | |
5194 { | |
5195 if (allowX) { | |
5196 x = val; | |
5197 allowX = false; | |
5198 allowY = true; | |
5199 allowColor = false; | |
5200 allowStyle = false; | |
5201 allowBreak = false; | |
5202 } else if (allowY) { | |
5203 y = val; | |
5204 allowY = false; | |
5205 allowBlur = true; | |
5206 allowColor = true; | |
5207 allowStyle = property == CSSPropertyBoxShadow; | |
5208 allowBreak = true; | |
5209 } else if (allowBlur) { | |
5210 blur = val; | |
5211 allowBlur = false; | |
5212 allowSpread = property == CSSPropertyBoxShadow; | |
5213 } else if (allowSpread) { | |
5214 spread = val; | |
5215 allowSpread = false; | |
5216 } | 5195 } |
5217 } | 5196 } |
5218 | 5197 |
5219 void commitColor(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) | 5198 if (val) { |
5220 { | 5199 if (RefPtrWillBeMember<CSSPrimitiveValue> colorValue = parseColor(val)) { |
5221 color = val; | 5200 if (color) |
5222 allowColor = false; | 5201 return nullptr; |
5223 if (allowX) { | 5202 color = colorValue; |
5224 allowStyle = false; | 5203 val = valueList->next(); |
5225 allowBreak = false; | 5204 } |
5226 } else { | 5205 if (val && val->id == CSSValueInset) { |
5227 allowBlur = false; | 5206 if (!allowInset || style) |
5228 allowSpread = false; | 5207 return nullptr; |
5229 allowStyle = property == CSSPropertyBoxShadow; | 5208 style = cssValuePool().createIdentifierValue(val->id); |
5209 val = valueList->next(); | |
5230 } | 5210 } |
5231 } | 5211 } |
5232 | 5212 |
5233 void commitStyle(CSSParserValue* v) | 5213 if (val && val->m_unit == CSSParserValue::Operator) { |
Timothy Loh
2015/09/01 07:18:08
We don't really need a check like this here (or th
rwlbuis
2015/09/02 22:38:58
Done.
| |
5234 { | 5214 if (val->iValue != ',' || !allowBreak) { |
5235 style = cssValuePool().createIdentifierValue(v->id); | 5215 // Other operators aren't legal or we aren't done with the current s hadow |
5236 allowStyle = false; | 5216 // value. Treat as invalid. |
5237 if (allowX) | 5217 return nullptr; |
5238 allowBreak = false; | |
5239 else { | |
5240 allowBlur = false; | |
5241 allowSpread = false; | |
5242 allowColor = false; | |
5243 } | 5218 } |
5244 } | 5219 } |
5245 | 5220 unsigned lengthsSeen = lengths->length(); |
5246 CSSPropertyID property; | 5221 if (lengthsSeen > maxLength) |
5247 | 5222 return nullptr; |
5248 RefPtrWillBeMember<CSSValueList> values; | 5223 return CSSShadowValue::create(toCSSPrimitiveValue(lengths->item(0)), toCSSPr imitiveValue(lengths->item(1)), |
5249 RefPtrWillBeMember<CSSPrimitiveValue> x; | 5224 lengthsSeen > 2 ? toCSSPrimitiveValue(lengt hs->item(2)) : nullptr, |
5250 RefPtrWillBeMember<CSSPrimitiveValue> y; | 5225 lengthsSeen > 3 ? toCSSPrimitiveValue(lengt hs->item(3)) : nullptr, |
5251 RefPtrWillBeMember<CSSPrimitiveValue> blur; | 5226 style.release(), color.release()); |
5252 RefPtrWillBeMember<CSSPrimitiveValue> spread; | |
5253 RefPtrWillBeMember<CSSPrimitiveValue> style; | |
5254 RefPtrWillBeMember<CSSPrimitiveValue> color; | |
5255 | |
5256 bool allowX; | |
5257 bool allowY; | |
5258 bool allowBlur; | |
5259 bool allowSpread; | |
5260 bool allowColor; | |
5261 bool allowStyle; // inset or not. | |
5262 bool allowBreak; | |
5263 }; | |
5264 | |
5265 PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseShadow(CSSParserVal ueList* valueList, CSSPropertyID propId) | |
5266 { | |
5267 ShadowParseContext context(propId); | |
5268 for (CSSParserValue* val = valueList->current(); val; val = valueList->next( )) { | |
5269 // Check for a comma break first. | |
5270 if (val->m_unit == CSSParserValue::Operator) { | |
5271 if (val->iValue != ',' || !context.allowBreak) { | |
5272 // Other operators aren't legal or we aren't done with the curre nt shadow | |
5273 // value. Treat as invalid. | |
5274 return nullptr; | |
5275 } | |
5276 // The value is good. Commit it. | |
5277 context.commitValue(); | |
5278 } else if (validUnit(val, FLength, HTMLStandardMode)) { | |
5279 // We required a length and didn't get one. Invalid. | |
5280 if (!context.allowLength()) | |
5281 return nullptr; | |
5282 | |
5283 // Blur radius must be non-negative. | |
5284 if (context.allowBlur && (m_parsedCalculation ? m_parsedCalculation- >isNegative() : !validUnit(val, FLength | FNonNeg, HTMLStandardMode))) | |
5285 return nullptr; | |
5286 | |
5287 // A length is allowed here. Construct the value and add it. | |
5288 RefPtrWillBeRawPtr<CSSPrimitiveValue> length = createPrimitiveNumeri cValue(val); | |
5289 context.commitLength(length.release()); | |
5290 } else if (val->id == CSSValueInset) { | |
5291 if (!context.allowStyle) | |
5292 return nullptr; | |
5293 | |
5294 context.commitStyle(val); | |
5295 } else { | |
5296 if (!context.allowColor) | |
5297 return nullptr; | |
5298 | |
5299 // The only other type of value that's ok is a color value. | |
5300 RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedColor = parseColor(val); | |
5301 if (!parsedColor) | |
5302 return nullptr; | |
5303 | |
5304 context.commitColor(parsedColor.release()); | |
5305 } | |
5306 } | |
5307 | |
5308 if (context.allowBreak) { | |
5309 context.commitValue(); | |
5310 if (context.values && context.values->length()) | |
5311 return context.values.release(); | |
5312 } | |
5313 | |
5314 return nullptr; | |
5315 } | 5227 } |
5316 | 5228 |
5317 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseReflect() | 5229 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseReflect() |
5318 { | 5230 { |
5319 // box-reflect: <direction> <offset> <mask> | 5231 // box-reflect: <direction> <offset> <mask> |
5320 | 5232 |
5321 // Direction comes first. | 5233 // Direction comes first. |
5322 CSSParserValue* val = m_valueList->current(); | 5234 CSSParserValue* val = m_valueList->current(); |
5323 RefPtrWillBeRawPtr<CSSPrimitiveValue> direction = nullptr; | 5235 RefPtrWillBeRawPtr<CSSPrimitiveValue> direction = nullptr; |
5324 switch (val->id) { | 5236 switch (val->id) { |
(...skipping 1626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6951 CSSParserValue* argument = args->current(); | 6863 CSSParserValue* argument = args->current(); |
6952 if (!validUnit(argument, FLength | FNonNeg, HTMLStandardMode)) | 6864 if (!validUnit(argument, FLength | FNonNeg, HTMLStandardMode)) |
6953 return nullptr; | 6865 return nullptr; |
6954 | 6866 |
6955 filterValue->append(createPrimitiveNumericValue(argument)); | 6867 filterValue->append(createPrimitiveNumericValue(argument)); |
6956 } | 6868 } |
6957 break; | 6869 break; |
6958 } | 6870 } |
6959 case CSSValueDropShadow: { | 6871 case CSSValueDropShadow: { |
6960 // drop-shadow() takes a single shadow. | 6872 // drop-shadow() takes a single shadow. |
6961 RefPtrWillBeRawPtr<CSSValueList> shadowValueList = parseShadow(args, CSS PropertyWebkitFilter); | 6873 RefPtrWillBeRawPtr<CSSShadowValue> shadowValue = parseSingleShadow(args) ; |
6962 if (!shadowValueList || shadowValueList->length() != 1) | 6874 if (!shadowValue) |
6963 return nullptr; | 6875 return nullptr; |
6964 | 6876 filterValue->append(shadowValue.release()); |
6965 filterValue->append((shadowValueList.release())->item(0)); | |
6966 break; | 6877 break; |
6967 } | 6878 } |
6968 default: | 6879 default: |
6969 return nullptr; | 6880 return nullptr; |
6970 } | 6881 } |
6971 return filterValue.release(); | 6882 return filterValue.release(); |
6972 } | 6883 } |
6973 | 6884 |
6974 PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseFilter() | 6885 PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseFilter() |
6975 { | 6886 { |
(...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8093 } | 8004 } |
8094 } | 8005 } |
8095 | 8006 |
8096 if (!list->length()) | 8007 if (!list->length()) |
8097 return nullptr; | 8008 return nullptr; |
8098 | 8009 |
8099 return list.release(); | 8010 return list.release(); |
8100 } | 8011 } |
8101 | 8012 |
8102 } // namespace blink | 8013 } // namespace blink |
OLD | NEW |