Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: Source/core/css/parser/CSSPropertyParser.cpp

Issue 1318093002: Simplify parseShadowValue (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix more problems Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/css/parser/CSSPropertyParser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/css/parser/CSSPropertyParser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698