summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/css/CSSParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/css/CSSParser.cpp')
-rw-r--r--Source/WebCore/css/CSSParser.cpp165
1 files changed, 161 insertions, 4 deletions
diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp
index a941600..b7030b2 100644
--- a/Source/WebCore/css/CSSParser.cpp
+++ b/Source/WebCore/css/CSSParser.cpp
@@ -281,7 +281,164 @@ PassRefPtr<CSSRule> CSSParser::parseKeyframeRule(CSSStyleSheet *sheet, const Str
return m_keyframe.release();
}
-bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int id, const String& string, bool important)
+static inline bool isColorPropertyID(int propertyId)
+{
+ switch (propertyId) {
+ case CSSPropertyColor:
+ case CSSPropertyBackgroundColor:
+ case CSSPropertyBorderBottomColor:
+ case CSSPropertyBorderLeftColor:
+ case CSSPropertyBorderRightColor:
+ case CSSPropertyBorderTopColor:
+ case CSSPropertyOutlineColor:
+ case CSSPropertyTextLineThroughColor:
+ case CSSPropertyTextOverlineColor:
+ case CSSPropertyTextUnderlineColor:
+ case CSSPropertyWebkitBorderAfterColor:
+ case CSSPropertyWebkitBorderBeforeColor:
+ case CSSPropertyWebkitBorderEndColor:
+ case CSSPropertyWebkitBorderStartColor:
+ case CSSPropertyWebkitColumnRuleColor:
+ case CSSPropertyWebkitTextEmphasisColor:
+ case CSSPropertyWebkitTextFillColor:
+ case CSSPropertyWebkitTextStrokeColor:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool parseColorValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important, bool strict)
+{
+ if (!string.length())
+ return false;
+ if (!isColorPropertyID(propertyId))
+ return false;
+ CSSParserString cssString;
+ cssString.characters = const_cast<UChar*>(string.characters());
+ cssString.length = string.length();
+ int valueID = cssValueKeywordID(cssString);
+ bool validPrimitive = false;
+ if (valueID == CSSValueWebkitText)
+ validPrimitive = true;
+ else if (valueID == CSSValueCurrentcolor)
+ validPrimitive = true;
+ else if ((valueID >= CSSValueAqua && valueID <= CSSValueWindowtext) || valueID == CSSValueMenu
+ || (valueID >= CSSValueWebkitFocusRingColor && valueID < CSSValueWebkitText && !strict)) {
+ validPrimitive = true;
+ }
+
+ CSSStyleSheet* stylesheet = static_cast<CSSStyleSheet*>(declaration->stylesheet());
+ if (!stylesheet || !stylesheet->document())
+ return false;
+ if (validPrimitive) {
+ CSSProperty property(propertyId, stylesheet->document()->cssPrimitiveValueCache()->createIdentifierValue(valueID), important);
+ declaration->addParsedProperty(property);
+ return true;
+ }
+ RGBA32 color;
+ if (!CSSParser::parseColor(string, color, strict && string[0] != '#'))
+ return false;
+ CSSProperty property(propertyId, stylesheet->document()->cssPrimitiveValueCache()->createColorValue(color), important);
+ declaration->addParsedProperty(property);
+ return true;
+}
+
+static inline bool isSimpleLengthPropertyID(int propertyId, bool& acceptsNegativeNumbers)
+{
+ switch (propertyId) {
+ case CSSPropertyFontSize:
+ case CSSPropertyHeight:
+ case CSSPropertyWidth:
+ case CSSPropertyMinHeight:
+ case CSSPropertyMinWidth:
+ case CSSPropertyPaddingBottom:
+ case CSSPropertyPaddingLeft:
+ case CSSPropertyPaddingRight:
+ case CSSPropertyPaddingTop:
+ case CSSPropertyWebkitLogicalWidth:
+ case CSSPropertyWebkitLogicalHeight:
+ case CSSPropertyWebkitMinLogicalWidth:
+ case CSSPropertyWebkitMinLogicalHeight:
+ case CSSPropertyWebkitPaddingAfter:
+ case CSSPropertyWebkitPaddingBefore:
+ case CSSPropertyWebkitPaddingEnd:
+ case CSSPropertyWebkitPaddingStart:
+ acceptsNegativeNumbers = false;
+ return true;
+ case CSSPropertyBottom:
+ case CSSPropertyLeft:
+ case CSSPropertyMarginBottom:
+ case CSSPropertyMarginLeft:
+ case CSSPropertyMarginRight:
+ case CSSPropertyMarginTop:
+ case CSSPropertyRight:
+ case CSSPropertyTextIndent:
+ case CSSPropertyTop:
+ case CSSPropertyWebkitMarginAfter:
+ case CSSPropertyWebkitMarginBefore:
+ case CSSPropertyWebkitMarginEnd:
+ case CSSPropertyWebkitMarginStart:
+ acceptsNegativeNumbers = true;
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool parseSimpleLengthValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important, bool strict)
+{
+ const UChar* characters = string.characters();
+ unsigned length = string.length();
+ if (!characters || !length)
+ return false;
+ bool acceptsNegativeNumbers;
+ if (!isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers))
+ return false;
+
+ CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER;
+ if (length > 2 && characters[length - 2] == 'p' && characters[length - 1] == 'x') {
+ length -= 2;
+ unit = CSSPrimitiveValue::CSS_PX;
+ } else if (length > 1 && characters[length - 1] == '%') {
+ length -= 1;
+ unit = CSSPrimitiveValue::CSS_PERCENTAGE;
+ }
+
+ // We rely on charactersToDouble for validation as well. The function
+ // will set "ok" to "false" if the entire passed-in character range does
+ // not represent a double.
+ bool ok;
+ double number = charactersToDouble(characters, length, &ok);
+ if (!ok)
+ return false;
+ if (unit == CSSPrimitiveValue::CSS_NUMBER) {
+ if (number && strict)
+ return false;
+ unit = CSSPrimitiveValue::CSS_PX;
+ }
+ if (number < 0 && !acceptsNegativeNumbers)
+ return false;
+
+ CSSStyleSheet* stylesheet = static_cast<CSSStyleSheet*>(declaration->stylesheet());
+ if (!stylesheet || !stylesheet->document())
+ return false;
+ CSSProperty property(propertyId, stylesheet->document()->cssPrimitiveValueCache()->createValue(number, unit), important);
+ declaration->addParsedProperty(property);
+ return true;
+}
+
+bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important, bool strict)
+{
+ if (parseSimpleLengthValue(declaration, propertyId, string, important, strict))
+ return true;
+ if (parseColorValue(declaration, propertyId, string, important, strict))
+ return true;
+ CSSParser parser(strict);
+ return parser.parseValue(declaration, propertyId, string, important);
+}
+
+bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important)
{
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter);
@@ -291,7 +448,7 @@ bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int id, cons
setupParser("@-webkit-value{", string, "} ");
- m_id = id;
+ m_id = propertyId;
m_important = important;
cssyyparse(this);
@@ -6086,13 +6243,13 @@ Vector<OwnPtr<CSSParserSelector> >* CSSParser::createFloatingSelectorVector()
return selectorVector;
}
-Vector<OwnPtr<CSSParserSelector> >* CSSParser::sinkFloatingSelectorVector(Vector<OwnPtr<CSSParserSelector> >* selectorVector)
+PassOwnPtr<Vector<OwnPtr<CSSParserSelector> > > CSSParser::sinkFloatingSelectorVector(Vector<OwnPtr<CSSParserSelector> >* selectorVector)
{
if (selectorVector) {
ASSERT(m_floatingSelectorVectors.contains(selectorVector));
m_floatingSelectorVectors.remove(selectorVector);
}
- return selectorVector;
+ return adoptPtr(selectorVector);
}
CSSParserValueList* CSSParser::createFloatingValueList()