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

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 ASSERT 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
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 981 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« Source/core/css/parser/CSSPropertyParser.h ('K') | « Source/core/css/parser/CSSPropertyParser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698