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