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.cpp890
1 files changed, 656 insertions, 234 deletions
diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp
index 55175a2..b7030b2 100644
--- a/Source/WebCore/css/CSSParser.cpp
+++ b/Source/WebCore/css/CSSParser.cpp
@@ -36,10 +36,12 @@
#include "CSSImportRule.h"
#include "CSSInheritedValue.h"
#include "CSSInitialValue.h"
+#include "CSSLineBoxContainValue.h"
#include "CSSMediaRule.h"
#include "CSSMutableStyleDeclaration.h"
#include "CSSPageRule.h"
#include "CSSPrimitiveValue.h"
+#include "CSSPrimitiveValueCache.h"
#include "CSSProperty.h"
#include "CSSPropertyNames.h"
#include "CSSPropertySourceData.h"
@@ -71,6 +73,7 @@
#include "WebKitCSSKeyframesRule.h"
#include "WebKitCSSTransformValue.h"
#include <limits.h>
+#include <wtf/HexNumber.h>
#include <wtf/dtoa.h>
#include <wtf/text/StringBuffer.h>
@@ -96,6 +99,7 @@ using namespace WTF;
namespace WebCore {
static const unsigned INVALID_NUM_PARSED_PROPERTIES = UINT_MAX;
+static const double MAX_SCALE = 1000000;
static bool equal(const CSSParserString& a, const char* b)
{
@@ -176,6 +180,7 @@ CSSParser::~CSSParser()
fastFree(m_data);
fastDeleteAllValues(m_floatingSelectors);
+ deleteAllValues(m_floatingSelectorVectors);
deleteAllValues(m_floatingValueLists);
deleteAllValues(m_floatingFunctions);
}
@@ -228,7 +233,7 @@ void CSSParser::parseSheet(CSSStyleSheet* sheet, const String& string, int start
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter);
#endif
- m_styleSheet = sheet;
+ setStyleSheet(sheet);
m_defaultNamespace = starAtom; // Reset the default namespace.
m_ruleRangeMap = ruleRangeMap;
if (ruleRangeMap) {
@@ -252,7 +257,7 @@ PassRefPtr<CSSRule> CSSParser::parseRule(CSSStyleSheet* sheet, const String& str
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter);
#endif
- m_styleSheet = sheet;
+ setStyleSheet(sheet);
m_allowNamespaceDeclarations = false;
setupParser("@-webkit-rule{", string, "} ");
cssyyparse(this);
@@ -267,7 +272,7 @@ PassRefPtr<CSSRule> CSSParser::parseKeyframeRule(CSSStyleSheet *sheet, const Str
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter);
#endif
- m_styleSheet = sheet;
+ setStyleSheet(sheet);
setupParser("@-webkit-keyframe-rule{ ", string, "} ");
cssyyparse(this);
#ifdef ANDROID_INSTRUMENT
@@ -276,17 +281,174 @@ 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);
#endif
ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet());
- m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet());
+ setStyleSheet(static_cast<CSSStyleSheet*>(declaration->stylesheet()));
setupParser("@-webkit-value{", string, "} ");
- m_id = id;
+ m_id = propertyId;
m_important = important;
cssyyparse(this);
@@ -341,7 +503,7 @@ bool CSSParser::parseColor(CSSMutableStyleDeclaration* declaration, const String
android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter);
#endif
ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet());
- m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet());
+ setStyleSheet(static_cast<CSSStyleSheet*>(declaration->stylesheet()));
setupParser("@-webkit-decls{color:", string, "} ");
cssyyparse(this);
@@ -376,7 +538,7 @@ void CSSParser::parseSelector(const String& string, Document* doc, CSSSelectorLi
#endif
RefPtr<CSSStyleSheet> dummyStyleSheet = CSSStyleSheet::create(doc);
- m_styleSheet = dummyStyleSheet.get();
+ setStyleSheet(dummyStyleSheet.get());
m_selectorListForParseSelector = &selectorList;
setupParser("@-webkit-selector{", string, "}");
@@ -403,7 +565,7 @@ bool CSSParser::parseDeclaration(CSSMutableStyleDeclaration* declaration, const
static const unsigned prefixLength = 15;
ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet());
- m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet());
+ setStyleSheet(static_cast<CSSStyleSheet*>(declaration->stylesheet()));
if (styleSourceData) {
m_currentRuleData = CSSRuleSourceData::create();
m_currentRuleData->styleSourceData = CSSStyleSourceData::create();
@@ -501,6 +663,12 @@ void CSSParser::clearProperties()
m_numParsedPropertiesBeforeMarginBox = INVALID_NUM_PARSED_PROPERTIES;
m_hasFontFaceOnlyValues = false;
}
+
+void CSSParser::setStyleSheet(CSSStyleSheet* styleSheet)
+{
+ m_styleSheet = styleSheet;
+ m_primitiveValueCache = document() ? document()->cssPrimitiveValueCache() : CSSPrimitiveValueCache::create();
+}
Document* CSSParser::document() const
{
@@ -688,11 +856,14 @@ bool CSSParser::parseValue(int propId, bool important)
case CSSPropertyQuotes: // [<string> <string>]+ | none | inherit
if (id)
validPrimitive = true;
+ else
+ return parseQuotes(propId, important);
break;
- case CSSPropertyUnicodeBidi: // normal | embed | bidi-override | inherit
- if (id == CSSValueNormal ||
- id == CSSValueEmbed ||
- id == CSSValueBidiOverride)
+ case CSSPropertyUnicodeBidi: // normal | embed | bidi-override | isolate | inherit
+ if (id == CSSValueNormal
+ || id == CSSValueEmbed
+ || id == CSSValueBidiOverride
+ || id == CSSValueWebkitIsolate)
validPrimitive = true;
break;
@@ -829,9 +1000,10 @@ bool CSSParser::parseValue(int propId, bool important)
break;
case CSSPropertyTextAlign:
- // left | right | center | justify | webkit_left | webkit_right | webkit_center | start | end | <string> | inherit
- if ((id >= CSSValueWebkitAuto && id <= CSSValueWebkitCenter) || id == CSSValueStart || id == CSSValueEnd ||
- value->unit == CSSPrimitiveValue::CSS_STRING)
+ // left | right | center | justify | webkit_left | webkit_right | webkit_center | webkit_match_parent |
+ // start | end | <string> | inherit
+ if ((id >= CSSValueWebkitAuto && id <= CSSValueWebkitMatchParent) || id == CSSValueStart || id == CSSValueEnd
+ || value->unit == CSSPrimitiveValue::CSS_STRING)
validPrimitive = true;
break;
@@ -958,9 +1130,9 @@ bool CSSParser::parseValue(int propId, bool important)
if (list->length() != 1)
return false;
} else if (!m_strict && value->id == CSSValueHand) // MSIE 5 compatibility :/
- list->append(CSSPrimitiveValue::createIdentifier(CSSValuePointer));
+ list->append(primitiveValueCache()->createIdentifierValue(CSSValuePointer));
else if (value && ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone))
- list->append(CSSPrimitiveValue::createIdentifier(value->id));
+ list->append(primitiveValueCache()->createIdentifierValue(value->id));
m_valueList->next();
parsedValue = list.release();
break;
@@ -1217,7 +1389,7 @@ bool CSSParser::parseValue(int propId, bool important)
case CSSValueUnderline:
case CSSValueOverline:
case CSSValueLineThrough:
- list->append(CSSPrimitiveValue::createIdentifier(value->id));
+ list->append(primitiveValueCache()->createIdentifierValue(value->id));
break;
default:
isValid = false;
@@ -1276,19 +1448,19 @@ bool CSSParser::parseValue(int propId, bool important)
validPrimitive = validUnit(value, FLength | FPercent, m_strict);
if (!validPrimitive)
return false;
- RefPtr<CSSPrimitiveValue> parsedValue1 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ RefPtr<CSSPrimitiveValue> parsedValue1 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
RefPtr<CSSPrimitiveValue> parsedValue2;
if (num == 2) {
value = m_valueList->next();
validPrimitive = validUnit(value, FLength | FPercent, m_strict);
if (!validPrimitive)
return false;
- parsedValue2 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ parsedValue2 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
} else
parsedValue2 = parsedValue1;
RefPtr<Pair> pair = Pair::create(parsedValue1.release(), parsedValue2.release());
- RefPtr<CSSPrimitiveValue> val = CSSPrimitiveValue::create(pair.release());
+ RefPtr<CSSPrimitiveValue> val = primitiveValueCache()->createValue(pair.release());
addProperty(propId, val.release(), important);
return true;
}
@@ -1467,7 +1639,7 @@ bool CSSParser::parseValue(int propId, bool important)
else {
// Accepting valueless numbers is a quirk of the -webkit prefixed version of the property.
if (validUnit(value, FNumber | FLength | FNonNeg, m_strict)) {
- RefPtr<CSSValue> val = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ RefPtr<CSSValue> val = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
if (val) {
addProperty(propId, val.release(), important);
return true;
@@ -1651,7 +1823,13 @@ bool CSSParser::parseValue(int propId, bool important)
validPrimitive = true;
break;
- case CSSPropertyWebkitHyphenateLocale:
+ case CSSPropertyWebkitHyphenateLimitBefore:
+ case CSSPropertyWebkitHyphenateLimitAfter:
+ if (id == CSSValueAuto || validUnit(value, FInteger | FNonNeg, true))
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyWebkitLocale:
if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING)
validPrimitive = true;
break;
@@ -1872,6 +2050,19 @@ bool CSSParser::parseValue(int propId, bool important)
case CSSPropertyWebkitTextEmphasisStyle:
return parseTextEmphasisStyle(important);
+ case CSSPropertyWebkitTextOrientation:
+ // FIXME: For now just support upright and vertical-right.
+ if (id == CSSValueVerticalRight || id == CSSValueUpright)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyWebkitLineBoxContain:
+ if (id == CSSValueNone)
+ validPrimitive = true;
+ else
+ return parseLineBoxContain(important);
+ break;
+
#ifdef ANDROID_CSS_RING
case CSSPropertyWebkitRing:
{
@@ -1918,13 +2109,13 @@ bool CSSParser::parseValue(int propId, bool important)
if (validPrimitive) {
if (id != 0)
- parsedValue = CSSPrimitiveValue::createIdentifier(id);
+ parsedValue = primitiveValueCache()->createIdentifierValue(id);
else if (value->unit == CSSPrimitiveValue::CSS_STRING)
- parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
+ parsedValue = primitiveValueCache()->createValue(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
- parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+ parsedValue = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
else if (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_REMS)
- parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+ parsedValue = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
else if (value->unit >= CSSParserValue::Q_EMS)
parsedValue = CSSQuirkPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_EMS);
m_valueList->next();
@@ -1948,7 +2139,7 @@ PassRefPtr<CSSValue> CSSParser::parseWCSSInputProperty()
inputProperty = String(value->string);
if (!inputProperty.isEmpty())
- parsedValue = CSSPrimitiveValue::create(inputProperty, CSSPrimitiveValue::CSS_STRING);
+ parsedValue = primitiveValueCache()->createValue(inputProperty, CSSPrimitiveValue::CSS_STRING);
while (m_valueList->next()) {
// pass all other values, if any. If we don't do this,
@@ -1976,11 +2167,11 @@ void CSSParser::addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval)
lval = rval;
}
-static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtr<CSSValue>& cssValue)
+static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtr<CSSValue>& cssValue, CSSPrimitiveValueCache* primitiveValueCache)
{
if (parserValue->id == CSSValueBorderBox || parserValue->id == CSSValuePaddingBox
|| parserValue->id == CSSValueContentBox || parserValue->id == CSSValueWebkitText) {
- cssValue = CSSPrimitiveValue::createIdentifier(parserValue->id);
+ cssValue = primitiveValueCache->createIdentifierValue(parserValue->id);
return true;
}
return false;
@@ -2048,7 +2239,7 @@ bool CSSParser::parseFillShorthand(int propId, const int* properties, int numPro
addFillValue(repeatYValue, val2.release());
if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
// Reparse the value as a clip, and see if we succeed.
- if (parseBackgroundClip(parserValue, val1))
+ if (parseBackgroundClip(parserValue, val1, primitiveValueCache()))
addFillValue(clipValue, val1.release()); // The property parsed successfully.
else
addFillValue(clipValue, CSSInitialValue::createImplicit()); // Some value was used for origin that is not supported by clip. Just reset clip instead.
@@ -2365,10 +2556,10 @@ bool CSSParser::parsePage(int propId, bool important)
return false;
if (value->id == CSSValueAuto) {
- addProperty(propId, CSSPrimitiveValue::createIdentifier(value->id), important);
+ addProperty(propId, primitiveValueCache()->createIdentifierValue(value->id), important);
return true;
} else if (value->id == 0 && value->unit == CSSPrimitiveValue::CSS_IDENT) {
- addProperty(propId, CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_STRING), important);
+ addProperty(propId, primitiveValueCache()->createValue(value->string, CSSPrimitiveValue::CSS_STRING), important);
return true;
}
return false;
@@ -2410,14 +2601,14 @@ CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList* parsedV
switch (value->id) {
case CSSValueAuto:
if (prevParamType == None) {
- parsedValues->append(CSSPrimitiveValue::createIdentifier(value->id));
+ parsedValues->append(primitiveValueCache()->createIdentifierValue(value->id));
return Auto;
}
return None;
case CSSValueLandscape:
case CSSValuePortrait:
if (prevParamType == None || prevParamType == PageSize) {
- parsedValues->append(CSSPrimitiveValue::createIdentifier(value->id));
+ parsedValues->append(primitiveValueCache()->createIdentifierValue(value->id));
return Orientation;
}
return None;
@@ -2432,13 +2623,13 @@ CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList* parsedV
if (prevParamType == None || prevParamType == Orientation) {
// Normalize to Page Size then Orientation order by prepending.
// This is not specified by the CSS3 Paged Media specification, but for simpler processing later (CSSStyleSelector::applyPageSizeProperty).
- parsedValues->prepend(CSSPrimitiveValue::createIdentifier(value->id));
+ parsedValues->prepend(primitiveValueCache()->createIdentifierValue(value->id));
return PageSize;
}
return None;
case 0:
if (validUnit(value, FLength | FNonNeg, m_strict) && (prevParamType == None || prevParamType == Length)) {
- parsedValues->append(CSSPrimitiveValue::create(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)));
+ parsedValues->append(primitiveValueCache()->createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)));
return Length;
}
return None;
@@ -2447,6 +2638,28 @@ CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList* parsedV
}
}
+// [ <string> <string> ]+ | inherit | none
+// inherit and none are handled in parseValue.
+bool CSSParser::parseQuotes(int propId, bool important)
+{
+ RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
+ while (CSSParserValue* val = m_valueList->current()) {
+ RefPtr<CSSValue> parsedValue;
+ if (val->unit == CSSPrimitiveValue::CSS_STRING)
+ parsedValue = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING);
+ else
+ break;
+ values->append(parsedValue.release());
+ m_valueList->next();
+ }
+ if (values->length()) {
+ addProperty(propId, values.release(), important);
+ m_valueList->next();
+ return true;
+ }
+ return false;
+}
+
// [ <string> | <uri> | <counter> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
// in CSS 2.1 this got somewhat reduced:
// [ <string> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
@@ -2499,10 +2712,10 @@ bool CSSParser::parseContent(int propId, bool important)
case CSSValueNoCloseQuote:
case CSSValueNone:
case CSSValueNormal:
- parsedValue = CSSPrimitiveValue::createIdentifier(val->id);
+ parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
}
} else if (val->unit == CSSPrimitiveValue::CSS_STRING) {
- parsedValue = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING);
+ parsedValue = primitiveValueCache()->createValue(val->string, CSSPrimitiveValue::CSS_STRING);
}
if (!parsedValue)
break;
@@ -2539,7 +2752,7 @@ PassRefPtr<CSSValue> CSSParser::parseAttr(CSSParserValueList* args)
if (document() && document()->isHTMLDocument())
attrName = attrName.lower();
- return CSSPrimitiveValue::create(attrName, CSSPrimitiveValue::CSS_ATTR);
+ return primitiveValueCache()->createValue(attrName, CSSPrimitiveValue::CSS_ATTR);
}
PassRefPtr<CSSValue> CSSParser::parseBackgroundColor()
@@ -2547,7 +2760,7 @@ PassRefPtr<CSSValue> CSSParser::parseBackgroundColor()
int id = m_valueList->current()->id;
if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor ||
(id >= CSSValueGrey && id < CSSValueWebkitText && !m_strict))
- return CSSPrimitiveValue::createIdentifier(id);
+ return primitiveValueCache()->createIdentifierValue(id);
return parseColor();
}
@@ -2571,34 +2784,80 @@ bool CSSParser::parseFillImage(RefPtr<CSSValue>& value)
return false;
}
-PassRefPtr<CSSValue> CSSParser::parseFillPositionXY(CSSParserValueList* valueList, bool& xFound, bool& yFound)
+PassRefPtr<CSSValue> CSSParser::parseFillPositionX(CSSParserValueList* valueList)
+{
+ int id = valueList->current()->id;
+ if (id == CSSValueLeft || id == CSSValueRight || id == CSSValueCenter) {
+ int percent = 0;
+ if (id == CSSValueRight)
+ percent = 100;
+ else if (id == CSSValueCenter)
+ percent = 50;
+ return primitiveValueCache()->createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+ }
+ if (validUnit(valueList->current(), FPercent | FLength, m_strict))
+ return primitiveValueCache()->createValue(valueList->current()->fValue,
+ (CSSPrimitiveValue::UnitTypes)valueList->current()->unit);
+ return 0;
+}
+
+PassRefPtr<CSSValue> CSSParser::parseFillPositionY(CSSParserValueList* valueList)
+{
+ int id = valueList->current()->id;
+ if (id == CSSValueTop || id == CSSValueBottom || id == CSSValueCenter) {
+ int percent = 0;
+ if (id == CSSValueBottom)
+ percent = 100;
+ else if (id == CSSValueCenter)
+ percent = 50;
+ return primitiveValueCache()->createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+ }
+ if (validUnit(valueList->current(), FPercent | FLength, m_strict))
+ return primitiveValueCache()->createValue(valueList->current()->fValue,
+ (CSSPrimitiveValue::UnitTypes)valueList->current()->unit);
+ return 0;
+}
+
+PassRefPtr<CSSValue> CSSParser::parseFillPositionComponent(CSSParserValueList* valueList, unsigned& cumulativeFlags, FillPositionFlag& individualFlag)
{
int id = valueList->current()->id;
if (id == CSSValueLeft || id == CSSValueTop || id == CSSValueRight || id == CSSValueBottom || id == CSSValueCenter) {
int percent = 0;
if (id == CSSValueLeft || id == CSSValueRight) {
- if (xFound)
+ if (cumulativeFlags & XFillPosition)
return 0;
- xFound = true;
+ cumulativeFlags |= XFillPosition;
+ individualFlag = XFillPosition;
if (id == CSSValueRight)
percent = 100;
}
else if (id == CSSValueTop || id == CSSValueBottom) {
- if (yFound)
+ if (cumulativeFlags & YFillPosition)
return 0;
- yFound = true;
+ cumulativeFlags |= YFillPosition;
+ individualFlag = YFillPosition;
if (id == CSSValueBottom)
percent = 100;
- }
- else if (id == CSSValueCenter)
+ } else if (id == CSSValueCenter) {
// Center is ambiguous, so we're not sure which position we've found yet, an x or a y.
percent = 50;
- return CSSPrimitiveValue::create(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+ cumulativeFlags |= AmbiguousFillPosition;
+ individualFlag = AmbiguousFillPosition;
+ }
+ return primitiveValueCache()->createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+ }
+ if (validUnit(valueList->current(), FPercent | FLength, m_strict)) {
+ if (!cumulativeFlags) {
+ cumulativeFlags |= XFillPosition;
+ individualFlag = XFillPosition;
+ } else if (cumulativeFlags & (XFillPosition | AmbiguousFillPosition)) {
+ cumulativeFlags |= YFillPosition;
+ individualFlag = YFillPosition;
+ } else
+ return 0;
+ return primitiveValueCache()->createValue(valueList->current()->fValue,
+ (CSSPrimitiveValue::UnitTypes)valueList->current()->unit);
}
- if (validUnit(valueList->current(), FPercent | FLength, m_strict))
- return CSSPrimitiveValue::create(valueList->current()->fValue,
- (CSSPrimitiveValue::UnitTypes)valueList->current()->unit);
-
return 0;
}
@@ -2607,8 +2866,10 @@ void CSSParser::parseFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue
CSSParserValue* value = valueList->current();
// Parse the first value. We're just making sure that it is one of the valid keywords or a percentage/length.
- bool value1IsX = false, value1IsY = false;
- value1 = parseFillPositionXY(valueList, value1IsX, value1IsY);
+ unsigned cumulativeFlags = 0;
+ FillPositionFlag value1Flag = InvalidFillPosition;
+ FillPositionFlag value2Flag = InvalidFillPosition;
+ value1 = parseFillPositionComponent(valueList, cumulativeFlags, value1Flag);
if (!value1)
return;
@@ -2621,9 +2882,8 @@ void CSSParser::parseFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue
if (value && value->unit == CSSParserValue::Operator && value->iValue == ',')
value = 0;
- bool value2IsX = false, value2IsY = false;
if (value) {
- value2 = parseFillPositionXY(valueList, value2IsX, value2IsY);
+ value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag);
if (value2)
valueList->next();
else {
@@ -2639,9 +2899,9 @@ void CSSParser::parseFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue
// is simply 50%. This is our default.
// For keywords, the keyword was either an x-keyword (left/right), a y-keyword (top/bottom), or an ambiguous keyword (center).
// For left/right/center, the default of 50% in the y is still correct.
- value2 = CSSPrimitiveValue::create(50, CSSPrimitiveValue::CSS_PERCENTAGE);
+ value2 = primitiveValueCache()->createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE);
- if (value1IsY || value2IsX)
+ if (value1Flag == YFillPosition || value2Flag == XFillPosition)
value1.swap(value2);
}
@@ -2652,20 +2912,20 @@ void CSSParser::parseFillRepeat(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& valu
int id = m_valueList->current()->id;
if (id == CSSValueRepeatX) {
m_implicitShorthand = true;
- value1 = CSSPrimitiveValue::createIdentifier(CSSValueRepeat);
- value2 = CSSPrimitiveValue::createIdentifier(CSSValueNoRepeat);
+ value1 = primitiveValueCache()->createIdentifierValue(CSSValueRepeat);
+ value2 = primitiveValueCache()->createIdentifierValue(CSSValueNoRepeat);
m_valueList->next();
return;
}
if (id == CSSValueRepeatY) {
m_implicitShorthand = true;
- value1 = CSSPrimitiveValue::createIdentifier(CSSValueNoRepeat);
- value2 = CSSPrimitiveValue::createIdentifier(CSSValueRepeat);
+ value1 = primitiveValueCache()->createIdentifierValue(CSSValueNoRepeat);
+ value2 = primitiveValueCache()->createIdentifierValue(CSSValueRepeat);
m_valueList->next();
return;
}
if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace)
- value1 = CSSPrimitiveValue::createIdentifier(id);
+ value1 = primitiveValueCache()->createIdentifierValue(id);
else {
value1 = 0;
return;
@@ -2681,12 +2941,12 @@ void CSSParser::parseFillRepeat(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& valu
id = m_valueList->current()->id;
if (value && (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace)) {
- value2 = CSSPrimitiveValue::createIdentifier(id);
+ value2 = primitiveValueCache()->createIdentifierValue(id);
m_valueList->next();
} else {
// If only one value was specified, value2 is the same as value1.
m_implicitShorthand = true;
- value2 = CSSPrimitiveValue::createIdentifier(static_cast<CSSPrimitiveValue*>(value1.get())->getIdent());
+ value2 = primitiveValueCache()->createIdentifierValue(static_cast<CSSPrimitiveValue*>(value1.get())->getIdent());
}
}
@@ -2696,39 +2956,39 @@ PassRefPtr<CSSValue> CSSParser::parseFillSize(int propId, bool& allowComma)
CSSParserValue* value = m_valueList->current();
if (value->id == CSSValueContain || value->id == CSSValueCover)
- return CSSPrimitiveValue::createIdentifier(value->id);
+ return primitiveValueCache()->createIdentifierValue(value->id);
RefPtr<CSSPrimitiveValue> parsedValue1;
if (value->id == CSSValueAuto)
- parsedValue1 = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_UNKNOWN);
+ parsedValue1 = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_UNKNOWN);
else {
if (!validUnit(value, FLength | FPercent, m_strict))
return 0;
- parsedValue1 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ parsedValue1 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
}
CSSPropertyID property = static_cast<CSSPropertyID>(propId);
RefPtr<CSSPrimitiveValue> parsedValue2;
if ((value = m_valueList->next())) {
if (value->id == CSSValueAuto)
- parsedValue2 = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_UNKNOWN);
+ parsedValue2 = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_UNKNOWN);
else if (value->unit == CSSParserValue::Operator && value->iValue == ',')
allowComma = false;
else {
if (!validUnit(value, FLength | FPercent, m_strict))
return 0;
- parsedValue2 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ parsedValue2 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
}
}
if (!parsedValue2) {
if (property == CSSPropertyWebkitBackgroundSize || property == CSSPropertyWebkitMaskSize)
parsedValue2 = parsedValue1;
else
- parsedValue2 = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_UNKNOWN);
+ parsedValue2 = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_UNKNOWN);
}
- return CSSPrimitiveValue::create(Pair::create(parsedValue1.release(), parsedValue2.release()));
+ return primitiveValueCache()->createValue(Pair::create(parsedValue1.release(), parsedValue2.release()));
}
bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
@@ -2779,7 +3039,7 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
case CSSPropertyBackgroundAttachment:
case CSSPropertyWebkitMaskAttachment:
if (val->id == CSSValueScroll || val->id == CSSValueFixed || val->id == CSSValueLocal) {
- currValue = CSSPrimitiveValue::createIdentifier(val->id);
+ currValue = primitiveValueCache()->createIdentifierValue(val->id);
m_valueList->next();
}
break;
@@ -2798,17 +3058,17 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox ||
((propId == CSSPropertyWebkitBackgroundClip || propId == CSSPropertyWebkitMaskClip) &&
(val->id == CSSValueText || val->id == CSSValueWebkitText))) {
- currValue = CSSPrimitiveValue::createIdentifier(val->id);
+ currValue = primitiveValueCache()->createIdentifierValue(val->id);
m_valueList->next();
}
break;
case CSSPropertyBackgroundClip:
- if (parseBackgroundClip(val, currValue))
+ if (parseBackgroundClip(val, currValue, primitiveValueCache()))
m_valueList->next();
break;
case CSSPropertyBackgroundOrigin:
if (val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox) {
- currValue = CSSPrimitiveValue::createIdentifier(val->id);
+ currValue = primitiveValueCache()->createIdentifierValue(val->id);
m_valueList->next();
}
break;
@@ -2819,16 +3079,14 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
break;
case CSSPropertyBackgroundPositionX:
case CSSPropertyWebkitMaskPositionX: {
- bool xFound = false, yFound = true;
- currValue = parseFillPositionXY(m_valueList, xFound, yFound);
+ currValue = parseFillPositionX(m_valueList);
if (currValue)
m_valueList->next();
break;
}
case CSSPropertyBackgroundPositionY:
case CSSPropertyWebkitMaskPositionY: {
- bool xFound = true, yFound = false;
- currValue = parseFillPositionXY(m_valueList, xFound, yFound);
+ currValue = parseFillPositionY(m_valueList);
if (currValue)
m_valueList->next();
break;
@@ -2836,7 +3094,7 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
case CSSPropertyWebkitBackgroundComposite:
case CSSPropertyWebkitMaskComposite:
if ((val->id >= CSSValueClear && val->id <= CSSValuePlusLighter) || val->id == CSSValueHighlight) {
- currValue = CSSPrimitiveValue::createIdentifier(val->id);
+ currValue = primitiveValueCache()->createIdentifierValue(val->id);
m_valueList->next();
}
break;
@@ -2903,7 +3161,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationDelay()
{
CSSParserValue* value = m_valueList->current();
if (validUnit(value, FTime, m_strict))
- return CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ return primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
return 0;
}
@@ -2911,7 +3169,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationDirection()
{
CSSParserValue* value = m_valueList->current();
if (value->id == CSSValueNormal || value->id == CSSValueAlternate)
- return CSSPrimitiveValue::createIdentifier(value->id);
+ return primitiveValueCache()->createIdentifierValue(value->id);
return 0;
}
@@ -2919,7 +3177,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationDuration()
{
CSSParserValue* value = m_valueList->current();
if (validUnit(value, FTime | FNonNeg, m_strict))
- return CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ return primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
return 0;
}
@@ -2927,7 +3185,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationFillMode()
{
CSSParserValue* value = m_valueList->current();
if (value->id == CSSValueNone || value->id == CSSValueForwards || value->id == CSSValueBackwards || value->id == CSSValueBoth)
- return CSSPrimitiveValue::createIdentifier(value->id);
+ return primitiveValueCache()->createIdentifierValue(value->id);
return 0;
}
@@ -2935,9 +3193,9 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationIterationCount()
{
CSSParserValue* value = m_valueList->current();
if (value->id == CSSValueInfinite)
- return CSSPrimitiveValue::createIdentifier(value->id);
+ return primitiveValueCache()->createIdentifierValue(value->id);
if (validUnit(value, FInteger | FNonNeg, m_strict))
- return CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ return primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
return 0;
}
@@ -2946,9 +3204,9 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationName()
CSSParserValue* value = m_valueList->current();
if (value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT) {
if (value->id == CSSValueNone || (value->unit == CSSPrimitiveValue::CSS_STRING && equalIgnoringCase(value->string, "none"))) {
- return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+ return primitiveValueCache()->createIdentifierValue(CSSValueNone);
} else {
- return CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_STRING);
+ return primitiveValueCache()->createValue(value->string, CSSPrimitiveValue::CSS_STRING);
}
}
return 0;
@@ -2958,7 +3216,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationPlayState()
{
CSSParserValue* value = m_valueList->current();
if (value->id == CSSValueRunning || value->id == CSSValuePaused)
- return CSSPrimitiveValue::createIdentifier(value->id);
+ return primitiveValueCache()->createIdentifierValue(value->id);
return 0;
}
@@ -2969,11 +3227,11 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationProperty()
return 0;
int result = cssPropertyID(value->string);
if (result)
- return CSSPrimitiveValue::createIdentifier(result);
+ return primitiveValueCache()->createIdentifierValue(result);
if (equalIgnoringCase(value->string, "all"))
- return CSSPrimitiveValue::createIdentifier(CSSValueAll);
+ return primitiveValueCache()->createIdentifierValue(CSSValueAll);
if (equalIgnoringCase(value->string, "none"))
- return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+ return primitiveValueCache()->createIdentifierValue(CSSValueNone);
return 0;
}
@@ -2984,7 +3242,7 @@ bool CSSParser::parseTransformOriginShorthand(RefPtr<CSSValue>& value1, RefPtr<C
// now get z
if (m_valueList->current()) {
if (validUnit(m_valueList->current(), FLength, m_strict)) {
- value3 = CSSPrimitiveValue::create(m_valueList->current()->fValue,
+ value3 = primitiveValueCache()->createValue(m_valueList->current()->fValue,
(CSSPrimitiveValue::UnitTypes)m_valueList->current()->unit);
m_valueList->next();
return true;
@@ -3017,7 +3275,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationTimingFunction()
CSSParserValue* value = m_valueList->current();
if (value->id == CSSValueEase || value->id == CSSValueLinear || value->id == CSSValueEaseIn || value->id == CSSValueEaseOut
|| value->id == CSSValueEaseInOut || value->id == CSSValueStepStart || value->id == CSSValueStepEnd)
- return CSSPrimitiveValue::createIdentifier(value->id);
+ return primitiveValueCache()->createIdentifierValue(value->id);
// We must be a function.
if (value->unit != CSSParserValue::Function)
@@ -3207,7 +3465,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important)
if (value->id == CSSValueNone) {
if (m_valueList->next())
return false;
- addProperty(propId, CSSPrimitiveValue::createIdentifier(value->id), important);
+ addProperty(propId, primitiveValueCache()->createIdentifierValue(value->id), important);
return valid;
}
@@ -3277,7 +3535,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important)
if (numArgs == DASHBOARD_REGION_SHORT_NUM_PARAMETERS || numArgs == (DASHBOARD_REGION_SHORT_NUM_PARAMETERS*2-1)) {
// This originally used CSSValueInvalid by accident. It might be more logical to use something else.
- RefPtr<CSSPrimitiveValue> amount = CSSPrimitiveValue::createIdentifier(CSSValueInvalid);
+ RefPtr<CSSPrimitiveValue> amount = primitiveValueCache()->createIdentifierValue(CSSValueInvalid);
region->setTop(amount);
region->setRight(amount);
@@ -3295,8 +3553,8 @@ bool CSSParser::parseDashboardRegions(int propId, bool important)
break;
RefPtr<CSSPrimitiveValue> amount = arg->id == CSSValueAuto ?
- CSSPrimitiveValue::createIdentifier(CSSValueAuto) :
- CSSPrimitiveValue::create(arg->fValue, (CSSPrimitiveValue::UnitTypes) arg->unit);
+ primitiveValueCache()->createIdentifierValue(CSSValueAuto) :
+ primitiveValueCache()->createValue(arg->fValue, (CSSPrimitiveValue::UnitTypes) arg->unit);
if (i == 0)
region->setTop(amount);
@@ -3316,7 +3574,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important)
}
if (valid)
- addProperty(propId, CSSPrimitiveValue::create(firstRegion.release()), important);
+ addProperty(propId, primitiveValueCache()->createValue(firstRegion.release()), important);
return valid;
}
@@ -3334,11 +3592,11 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bo
CSSParserValue* i = args->current();
if (i->unit != CSSPrimitiveValue::CSS_IDENT)
return 0;
- RefPtr<CSSPrimitiveValue> identifier = CSSPrimitiveValue::create(i->string, CSSPrimitiveValue::CSS_STRING);
+ RefPtr<CSSPrimitiveValue> identifier = primitiveValueCache()->createValue(i->string, CSSPrimitiveValue::CSS_STRING);
RefPtr<CSSPrimitiveValue> separator;
if (!counters)
- separator = CSSPrimitiveValue::create(String(), CSSPrimitiveValue::CSS_STRING);
+ separator = primitiveValueCache()->createValue(String(), CSSPrimitiveValue::CSS_STRING);
else {
i = args->next();
if (i->unit != CSSParserValue::Operator || i->iValue != ',')
@@ -3348,13 +3606,13 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bo
if (i->unit != CSSPrimitiveValue::CSS_STRING)
return 0;
- separator = CSSPrimitiveValue::create(i->string, (CSSPrimitiveValue::UnitTypes) i->unit);
+ separator = primitiveValueCache()->createValue(i->string, (CSSPrimitiveValue::UnitTypes) i->unit);
}
RefPtr<CSSPrimitiveValue> listStyle;
i = args->next();
if (!i) // Make the list style default decimal
- listStyle = CSSPrimitiveValue::create(CSSValueDecimal - CSSValueDisc, CSSPrimitiveValue::CSS_NUMBER);
+ listStyle = primitiveValueCache()->createValue(CSSValueDecimal - CSSValueDisc, CSSPrimitiveValue::CSS_NUMBER);
else {
if (i->unit != CSSParserValue::Operator || i->iValue != ',')
return 0;
@@ -3371,10 +3629,10 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bo
else
return 0;
- listStyle = CSSPrimitiveValue::create(ls, (CSSPrimitiveValue::UnitTypes) i->unit);
+ listStyle = primitiveValueCache()->createValue(ls, (CSSPrimitiveValue::UnitTypes) i->unit);
}
- return CSSPrimitiveValue::create(Counter::create(identifier.release(), listStyle.release(), separator.release()));
+ return primitiveValueCache()->createValue(Counter::create(identifier.release(), listStyle.release(), separator.release()));
}
bool CSSParser::parseShape(int propId, bool important)
@@ -3397,8 +3655,8 @@ bool CSSParser::parseShape(int propId, bool important)
if (!valid)
break;
RefPtr<CSSPrimitiveValue> length = a->id == CSSValueAuto ?
- CSSPrimitiveValue::createIdentifier(CSSValueAuto) :
- CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
+ primitiveValueCache()->createIdentifierValue(CSSValueAuto) :
+ primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
if (i == 0)
rect->setTop(length);
else if (i == 1)
@@ -3419,7 +3677,7 @@ bool CSSParser::parseShape(int propId, bool important)
i++;
}
if (valid) {
- addProperty(propId, CSSPrimitiveValue::create(rect.release()), important);
+ addProperty(propId, primitiveValueCache()->createValue(rect.release()), important);
m_valueList->next();
return true;
}
@@ -3441,15 +3699,15 @@ bool CSSParser::parseFont(bool important)
} else if (id == CSSValueItalic || id == CSSValueOblique) {
if (font->style)
return false;
- font->style = CSSPrimitiveValue::createIdentifier(id);
+ font->style = primitiveValueCache()->createIdentifierValue(id);
} else if (id == CSSValueSmallCaps) {
if (font->variant)
return false;
- font->variant = CSSPrimitiveValue::createIdentifier(id);
+ font->variant = primitiveValueCache()->createIdentifierValue(id);
} else if (id >= CSSValueBold && id <= CSSValueLighter) {
if (font->weight)
return false;
- font->weight = CSSPrimitiveValue::createIdentifier(id);
+ font->weight = primitiveValueCache()->createIdentifierValue(id);
} else {
valid = false;
}
@@ -3476,7 +3734,7 @@ bool CSSParser::parseFont(bool important)
val = CSSValue900;
if (val)
- font->weight = CSSPrimitiveValue::createIdentifier(val);
+ font->weight = primitiveValueCache()->createIdentifierValue(val);
else
valid = false;
} else {
@@ -3491,18 +3749,18 @@ bool CSSParser::parseFont(bool important)
// set undefined values to default
if (!font->style)
- font->style = CSSPrimitiveValue::createIdentifier(CSSValueNormal);
+ font->style = primitiveValueCache()->createIdentifierValue(CSSValueNormal);
if (!font->variant)
- font->variant = CSSPrimitiveValue::createIdentifier(CSSValueNormal);
+ font->variant = primitiveValueCache()->createIdentifierValue(CSSValueNormal);
if (!font->weight)
- font->weight = CSSPrimitiveValue::createIdentifier(CSSValueNormal);
+ font->weight = primitiveValueCache()->createIdentifierValue(CSSValueNormal);
// now a font size _must_ come
// <absolute-size> | <relative-size> | <length> | <percentage> | inherit
if (value->id >= CSSValueXxSmall && value->id <= CSSValueLarger)
- font->size = CSSPrimitiveValue::createIdentifier(value->id);
+ font->size = primitiveValueCache()->createIdentifierValue(value->id);
else if (validUnit(value, FLength | FPercent | FNonNeg, m_strict))
- font->size = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+ font->size = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
value = m_valueList->next();
if (!font->size || !value)
return false;
@@ -3515,7 +3773,7 @@ bool CSSParser::parseFont(bool important)
if (value->id == CSSValueNormal) {
// default value, nothing to do
} else if (validUnit(value, FNumber | FLength | FPercent | FNonNeg, m_strict))
- font->lineHeight = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+ font->lineHeight = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
else
return false;
value = m_valueList->next();
@@ -3524,7 +3782,7 @@ bool CSSParser::parseFont(bool important)
}
if (!font->lineHeight)
- font->lineHeight = CSSPrimitiveValue::createIdentifier(CSSValueNormal);
+ font->lineHeight = primitiveValueCache()->createIdentifierValue(CSSValueNormal);
// font family must come now
font->family = parseFontFamily();
@@ -3554,7 +3812,7 @@ PassRefPtr<CSSValueList> CSSParser::parseFontFamily()
if (currFamily)
currFamily->appendSpaceSeparated(value->string.characters, value->string.length);
else if (nextValBreaksFont || !nextValIsFontName)
- list->append(CSSPrimitiveValue::createIdentifier(value->id));
+ list->append(primitiveValueCache()->createIdentifierValue(value->id));
else {
RefPtr<FontFamilyValue> newFamily = FontFamilyValue::create(value->string);
currFamily = newFamily.get();
@@ -3607,12 +3865,12 @@ bool CSSParser::parseFontStyle(bool important)
if (!expectComma) {
expectComma = true;
if (val->id == CSSValueNormal || val->id == CSSValueItalic || val->id == CSSValueOblique)
- parsedValue = CSSPrimitiveValue::createIdentifier(val->id);
+ parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
else if (val->id == CSSValueAll && !values) {
// 'all' is only allowed in @font-face and with no other values. Make a value list to
// indicate that we are in the @font-face case.
values = CSSValueList::createCommaSeparated();
- parsedValue = CSSPrimitiveValue::createIdentifier(val->id);
+ parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
}
} else if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
expectComma = false;
@@ -3654,12 +3912,12 @@ bool CSSParser::parseFontVariant(bool important)
if (!expectComma) {
expectComma = true;
if (val->id == CSSValueNormal || val->id == CSSValueSmallCaps)
- parsedValue = CSSPrimitiveValue::createIdentifier(val->id);
+ parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
else if (val->id == CSSValueAll && !values) {
// 'all' is only allowed in @font-face and with no other values. Make a value list to
// indicate that we are in the @font-face case.
values = CSSValueList::createCommaSeparated();
- parsedValue = CSSPrimitiveValue::createIdentifier(val->id);
+ parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
}
} else if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
expectComma = false;
@@ -3702,17 +3960,17 @@ bool CSSParser::parseFontWeight(bool important)
expectComma = true;
if (val->unit == CSSPrimitiveValue::CSS_IDENT) {
if (val->id >= CSSValueNormal && val->id <= CSSValue900)
- parsedValue = CSSPrimitiveValue::createIdentifier(val->id);
+ parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
else if (val->id == CSSValueAll && !values) {
// 'all' is only allowed in @font-face and with no other values. Make a value list to
// indicate that we are in the @font-face case.
values = CSSValueList::createCommaSeparated();
- parsedValue = CSSPrimitiveValue::createIdentifier(val->id);
+ parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
}
} else if (validUnit(val, FInteger | FNonNeg, false)) {
int weight = static_cast<int>(val->fValue);
if (!(weight % 100) && weight >= 100 && weight <= 900)
- parsedValue = CSSPrimitiveValue::createIdentifier(CSSValue100 + weight / 100 - 1);
+ parsedValue = primitiveValueCache()->createIdentifierValue(CSSValue100 + weight / 100 - 1);
}
} else if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
expectComma = false;
@@ -3903,10 +4161,76 @@ bool CSSParser::parseFontFaceUnicodeRange()
return true;
}
-static inline bool parseColorInt(const UChar*& string, const UChar* end, UChar terminator, int& value)
+// Returns the number of characters which form a valid double
+// and are terminated by the given terminator character
+static int checkForValidDouble(const UChar* string, const UChar* end, const char terminator)
+{
+ int length = end - string;
+ if (length < 1)
+ return 0;
+
+ bool decimalMarkSeen = false;
+ int processedLength = 0;
+
+ for (int i = 0; i < length; ++i) {
+ if (string[i] == terminator) {
+ processedLength = i;
+ break;
+ }
+ if (!isASCIIDigit(string[i])) {
+ if (!decimalMarkSeen && string[i] == '.')
+ decimalMarkSeen = true;
+ else
+ return 0;
+ }
+ }
+
+ if (decimalMarkSeen && processedLength == 1)
+ return 0;
+
+ return processedLength;
+}
+
+// Returns the number of characters consumed for parsing a valid double
+// terminated by the given terminator character
+static int parseDouble(const UChar* string, const UChar* end, const char terminator, double& value)
+{
+ int length = checkForValidDouble(string, end, terminator);
+ if (!length)
+ return 0;
+
+ int position = 0;
+ double localValue = 0;
+
+ // The consumed characters here are guaranteed to be
+ // ASCII digits with or without a decimal mark
+ for (; position < length; ++position) {
+ if (string[position] == '.')
+ break;
+ localValue = localValue * 10 + string[position] - '0';
+ }
+
+ if (++position == length) {
+ value = localValue;
+ return length;
+ }
+
+ double fraction = 0;
+ double scale = 1;
+
+ while (position < length && scale < MAX_SCALE) {
+ fraction = fraction * 10 + string[position++] - '0';
+ scale *= 10;
+ }
+
+ value = localValue + fraction / scale;
+ return length;
+}
+
+static bool parseColorIntOrPercentage(const UChar*& string, const UChar* end, const char terminator, CSSPrimitiveValue::UnitTypes& expect, int& value)
{
const UChar* current = string;
- int localValue = 0;
+ double localValue = 0;
bool negative = false;
while (current != end && isHTMLSpace(*current))
current++;
@@ -3917,7 +4241,7 @@ static inline bool parseColorInt(const UChar*& string, const UChar* end, UChar t
if (current == end || !isASCIIDigit(*current))
return false;
while (current != end && isASCIIDigit(*current)) {
- int newValue = localValue * 10 + *current++ - '0';
+ double newValue = localValue * 10 + *current++ - '0';
if (newValue >= 255) {
// Clamp values at 255.
localValue = 255;
@@ -3927,12 +4251,42 @@ static inline bool parseColorInt(const UChar*& string, const UChar* end, UChar t
}
localValue = newValue;
}
+
+ if (expect == CSSPrimitiveValue::CSS_NUMBER && (*current == '.' || *current == '%'))
+ return false;
+
+ if (*current == '.') {
+ // We already parsed the integral part, try to parse
+ // the fraction part of the percentage value.
+ double percentage = 0;
+ int numCharactersParsed = parseDouble(current, end, '%', percentage);
+ if (!numCharactersParsed)
+ return false;
+ current += numCharactersParsed;
+ if (*current != '%')
+ return false;
+ localValue += percentage;
+ }
+
+ if (expect == CSSPrimitiveValue::CSS_PERCENTAGE && *current != '%')
+ return false;
+
+ if (*current == '%') {
+ expect = CSSPrimitiveValue::CSS_PERCENTAGE;
+ localValue = localValue / 100.0 * 256.0;
+ // Clamp values at 255 for percentages over 100%
+ if (localValue > 255)
+ localValue = 255;
+ current++;
+ } else
+ expect = CSSPrimitiveValue::CSS_NUMBER;
+
while (current != end && isHTMLSpace(*current))
current++;
if (current == end || *current++ != terminator)
return false;
// Clamp negative values at zero.
- value = negative ? 0 : localValue;
+ value = negative ? 0 : static_cast<int>(localValue);
string = current;
return true;
}
@@ -3950,48 +4304,55 @@ static inline bool isTenthAlpha(const UChar* string, const int length)
return false;
}
-static inline bool parseAlphaValue(const UChar*& string, const UChar* end, UChar terminator, int& value)
+static inline bool parseAlphaValue(const UChar*& string, const UChar* end, const char terminator, int& value)
{
while (string != end && isHTMLSpace(*string))
string++;
+ bool negative = false;
+
+ if (string != end && *string == '-') {
+ negative = true;
+ string++;
+ }
+
value = 0;
int length = end - string;
if (length < 2)
return false;
- if (string[0] != '0' && string[0] != '1' && string[0] != '.')
+ if (string[length - 1] != terminator)
return false;
- if (string[length - 1] != terminator)
+ if (string[0] != '0' && string[0] != '1' && string[0] != '.') {
+ if (checkForValidDouble(string, end, terminator)) {
+ value = negative ? 0 : 255;
+ string = end;
+ return true;
+ }
return false;
+ }
if (length == 2 && string[0] != '.') {
- value = string[0] == '1' ? 255 : 0;
+ value = !negative && string[0] == '1' ? 255 : 0;
string = end;
return true;
}
if (isTenthAlpha(string, length - 1)) {
static const int tenthAlphaValues[] = { 0, 25, 51, 76, 102, 127, 153, 179, 204, 230 };
- value = tenthAlphaValues[string[length - 2] - '0'];
+ value = negative ? 0 : tenthAlphaValues[string[length - 2] - '0'];
string = end;
return true;
}
- Vector<char, 8> bytes(length + 1);
- for (int i = 0; i < length; ++i) {
- if (!isASCIIDigit(string[i]) && string[i] != '.' && string[i] != terminator)
- return false;
- bytes[i] = string[i];
- }
- bytes[length] = '\0';
- char* foundTerminator;
- double d = WTF::strtod(bytes.data(), &foundTerminator);
- value = static_cast<int>(d * nextafter(256.0, 0.0));
- string += (foundTerminator - bytes.data()) + 1;
- return *foundTerminator == terminator;
+ double alpha = 0;
+ if (!parseDouble(string, end, terminator, alpha))
+ return false;
+ value = negative ? 0 : static_cast<int>(alpha * nextafter(256.0, 0.0));
+ string = end;
+ return true;
}
static inline bool mightBeRGBA(const UChar* characters, unsigned length)
@@ -4019,6 +4380,7 @@ bool CSSParser::parseColor(const String &name, RGBA32& rgb, bool strict)
{
const UChar* characters = name.characters();
unsigned length = name.length();
+ CSSPrimitiveValue::UnitTypes expect = CSSPrimitiveValue::CSS_UNKNOWN;
if (!strict && length >= 3) {
if (name[0] == '#') {
@@ -4038,11 +4400,12 @@ bool CSSParser::parseColor(const String &name, RGBA32& rgb, bool strict)
int green;
int blue;
int alpha;
- if (!parseColorInt(current, end, ',', red))
+
+ if (!parseColorIntOrPercentage(current, end, ',', expect, red))
return false;
- if (!parseColorInt(current, end, ',', green))
+ if (!parseColorIntOrPercentage(current, end, ',', expect, green))
return false;
- if (!parseColorInt(current, end, ',', blue))
+ if (!parseColorIntOrPercentage(current, end, ',', expect, blue))
return false;
if (!parseAlphaValue(current, end, ')', alpha))
return false;
@@ -4059,11 +4422,11 @@ bool CSSParser::parseColor(const String &name, RGBA32& rgb, bool strict)
int red;
int green;
int blue;
- if (!parseColorInt(current, end, ',', red))
+ if (!parseColorIntOrPercentage(current, end, ',', expect, red))
return false;
- if (!parseColorInt(current, end, ',', green))
+ if (!parseColorIntOrPercentage(current, end, ',', expect, green))
return false;
- if (!parseColorInt(current, end, ')', blue))
+ if (!parseColorIntOrPercentage(current, end, ')', expect, blue))
return false;
if (current != end)
return false;
@@ -4174,7 +4537,7 @@ PassRefPtr<CSSPrimitiveValue> CSSParser::parseColor(CSSParserValue* value)
RGBA32 c = Color::transparent;
if (!parseColorFromValue(value ? value : m_valueList->current(), c))
return 0;
- return CSSPrimitiveValue::createColor(c);
+ return primitiveValueCache()->createColorValue(c);
}
bool CSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c)
@@ -4232,8 +4595,9 @@ bool CSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c)
// This class tracks parsing state for shadow values. If it goes out of scope (e.g., due to an early return)
// without the allowBreak bit being set, then it will clean up all of the objects and destroy them.
struct ShadowParseContext {
- ShadowParseContext(CSSPropertyID prop)
+ ShadowParseContext(CSSPropertyID prop, CSSPrimitiveValueCache* primitiveValueCache)
: property(prop)
+ , m_primitiveValueCache(primitiveValueCache)
, allowX(true)
, allowY(false)
, allowBlur(false)
@@ -4276,7 +4640,7 @@ struct ShadowParseContext {
void commitLength(CSSParserValue* v)
{
- RefPtr<CSSPrimitiveValue> val = CSSPrimitiveValue::create(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
+ RefPtr<CSSPrimitiveValue> val = m_primitiveValueCache->createValue(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
if (allowX) {
x = val.release();
@@ -4318,7 +4682,7 @@ struct ShadowParseContext {
void commitStyle(CSSParserValue* v)
{
- style = CSSPrimitiveValue::createIdentifier(v->id);
+ style = m_primitiveValueCache->createIdentifierValue(v->id);
allowStyle = false;
if (allowX)
allowBreak = false;
@@ -4330,6 +4694,7 @@ struct ShadowParseContext {
}
CSSPropertyID property;
+ CSSPrimitiveValueCache* m_primitiveValueCache;
RefPtr<CSSValueList> values;
RefPtr<CSSPrimitiveValue> x;
@@ -4350,7 +4715,7 @@ struct ShadowParseContext {
bool CSSParser::parseShadow(int propId, bool important)
{
- ShadowParseContext context(static_cast<CSSPropertyID>(propId));
+ ShadowParseContext context(static_cast<CSSPropertyID>(propId), primitiveValueCache());
CSSParserValue* val;
while ((val = m_valueList->current())) {
// Check for a comma break first.
@@ -4386,7 +4751,7 @@ bool CSSParser::parseShadow(int propId, bool important)
if (isColor) {
if (!context.allowColor)
return false;
- parsedColor = CSSPrimitiveValue::createIdentifier(val->id);
+ parsedColor = primitiveValueCache()->createIdentifierValue(val->id);
}
if (!parsedColor)
@@ -4443,11 +4808,11 @@ bool CSSParser::parseReflect(int propId, bool important)
val = m_valueList->next();
RefPtr<CSSPrimitiveValue> offset;
if (!val)
- offset = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_PX);
+ offset = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_PX);
else {
if (!validUnit(val, FLength | FPercent, m_strict))
return false;
- offset = CSSPrimitiveValue::create(val->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(val->unit));
+ offset = primitiveValueCache()->createValue(val->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(val->unit));
}
// Now for the mask.
@@ -4465,8 +4830,9 @@ bool CSSParser::parseReflect(int propId, bool important)
}
struct BorderImageParseContext {
- BorderImageParseContext()
- : m_allowBreak(false)
+ BorderImageParseContext(CSSPrimitiveValueCache* primitiveValueCache)
+ : m_primitiveValueCache(primitiveValueCache)
+ , m_allowBreak(false)
, m_allowNumber(false)
, m_allowSlash(false)
, m_allowWidth(false)
@@ -4488,7 +4854,7 @@ struct BorderImageParseContext {
void commitImage(PassRefPtr<CSSValue> image) { m_image = image; m_allowNumber = true; }
void commitNumber(CSSParserValue* v)
{
- PassRefPtr<CSSPrimitiveValue> val = CSSPrimitiveValue::create(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
+ PassRefPtr<CSSPrimitiveValue> val = m_primitiveValueCache->createValue(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
if (!m_top)
m_top = val;
else if (!m_right)
@@ -4532,16 +4898,16 @@ struct BorderImageParseContext {
{
// We need to clone and repeat values for any omissions.
if (!m_right) {
- m_right = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
- m_bottom = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
- m_left = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+ m_right = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+ m_bottom = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+ m_left = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
}
if (!m_bottom) {
- m_bottom = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
- m_left = CSSPrimitiveValue::create(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
+ m_bottom = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+ m_left = m_primitiveValueCache->createValue(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
}
if (!m_left)
- m_left = CSSPrimitiveValue::create(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
+ m_left = m_primitiveValueCache->createValue(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
// Now build a rect value to hold all four of our primitive values.
RefPtr<Rect> rect = Rect::create();
@@ -4578,6 +4944,8 @@ struct BorderImageParseContext {
// Make our new border image value now.
return CSSBorderImageValue::create(m_image, rect.release(), m_horizontalRule, m_verticalRule);
}
+
+ CSSPrimitiveValueCache* m_primitiveValueCache;
bool m_allowBreak;
bool m_allowNumber;
@@ -4604,7 +4972,7 @@ struct BorderImageParseContext {
bool CSSParser::parseBorderImage(int propId, bool important, RefPtr<CSSValue>& result)
{
// Look for an image initially. If the first value is not a URI, then we're done.
- BorderImageParseContext context;
+ BorderImageParseContext context(primitiveValueCache());
CSSParserValue* val = m_valueList->current();
if (val->unit == CSSPrimitiveValue::CSS_URI && m_styleSheet) {
// FIXME: The completeURL call should be done when using the CSSImageValue,
@@ -4638,7 +5006,7 @@ bool CSSParser::parseBorderImage(int propId, bool important, RefPtr<CSSValue>& r
if (context.allowNumber() && propId != CSSPropertyWebkitBorderImage) {
// Allow the slices to be omitted for images that don't fit to a border. We just set the slices to be 0.
- context.m_top = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_NUMBER);
+ context.m_top = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_NUMBER);
context.m_allowBreak = true;
}
@@ -4693,7 +5061,7 @@ bool CSSParser::parseBorderRadius(int propId, bool important)
if (!validUnit(value, FLength | FPercent, m_strict))
return false;
- RefPtr<CSSPrimitiveValue> radius = CSSPrimitiveValue::create(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit));
+ RefPtr<CSSPrimitiveValue> radius = primitiveValueCache()->createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit));
if (!indexAfterSlash) {
radii[0][i] = radius;
@@ -4715,10 +5083,10 @@ bool CSSParser::parseBorderRadius(int propId, bool important)
completeBorderRadii(radii[1]);
m_implicitShorthand = true;
- addProperty(CSSPropertyBorderTopLeftRadius, CSSPrimitiveValue::create(Pair::create(radii[0][0].release(), radii[1][0].release())), important);
- addProperty(CSSPropertyBorderTopRightRadius, CSSPrimitiveValue::create(Pair::create(radii[0][1].release(), radii[1][1].release())), important);
- addProperty(CSSPropertyBorderBottomRightRadius, CSSPrimitiveValue::create(Pair::create(radii[0][2].release(), radii[1][2].release())), important);
- addProperty(CSSPropertyBorderBottomLeftRadius, CSSPrimitiveValue::create(Pair::create(radii[0][3].release(), radii[1][3].release())), important);
+ addProperty(CSSPropertyBorderTopLeftRadius, primitiveValueCache()->createValue(Pair::create(radii[0][0].release(), radii[1][0].release())), important);
+ addProperty(CSSPropertyBorderTopRightRadius, primitiveValueCache()->createValue(Pair::create(radii[0][1].release(), radii[1][1].release())), important);
+ addProperty(CSSPropertyBorderBottomRightRadius, primitiveValueCache()->createValue(Pair::create(radii[0][2].release(), radii[1][2].release())), important);
+ addProperty(CSSPropertyBorderBottomLeftRadius, primitiveValueCache()->createValue(Pair::create(radii[0][3].release(), radii[1][3].release())), important);
m_implicitShorthand = false;
return true;
}
@@ -4735,7 +5103,7 @@ bool CSSParser::parseCounter(int propId, int defaultValue, bool important)
switch (state) {
case ID:
if (val && val->unit == CSSPrimitiveValue::CSS_IDENT) {
- counterName = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING);
+ counterName = primitiveValueCache()->createValue(val->string, CSSPrimitiveValue::CSS_STRING);
state = VAL;
m_valueList->next();
continue;
@@ -4748,8 +5116,8 @@ bool CSSParser::parseCounter(int propId, int defaultValue, bool important)
m_valueList->next();
}
- list->append(CSSPrimitiveValue::create(Pair::create(counterName.release(),
- CSSPrimitiveValue::create(i, CSSPrimitiveValue::CSS_NUMBER))));
+ list->append(primitiveValueCache()->createValue(Pair::create(counterName.release(),
+ primitiveValueCache()->createValue(i, CSSPrimitiveValue::CSS_NUMBER))));
state = ID;
continue;
}
@@ -4766,20 +5134,20 @@ bool CSSParser::parseCounter(int propId, int defaultValue, bool important)
}
// This should go away once we drop support for -webkit-gradient
-static PassRefPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue* a, bool horizontal)
+static PassRefPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue* a, bool horizontal, CSSPrimitiveValueCache* primitiveValueCache)
{
RefPtr<CSSPrimitiveValue> result;
if (a->unit == CSSPrimitiveValue::CSS_IDENT) {
if ((equalIgnoringCase(a->string, "left") && horizontal) ||
(equalIgnoringCase(a->string, "top") && !horizontal))
- result = CSSPrimitiveValue::create(0., CSSPrimitiveValue::CSS_PERCENTAGE);
+ result = primitiveValueCache->createValue(0., CSSPrimitiveValue::CSS_PERCENTAGE);
else if ((equalIgnoringCase(a->string, "right") && horizontal) ||
(equalIgnoringCase(a->string, "bottom") && !horizontal))
- result = CSSPrimitiveValue::create(100., CSSPrimitiveValue::CSS_PERCENTAGE);
+ result = primitiveValueCache->createValue(100., CSSPrimitiveValue::CSS_PERCENTAGE);
else if (equalIgnoringCase(a->string, "center"))
- result = CSSPrimitiveValue::create(50., CSSPrimitiveValue::CSS_PERCENTAGE);
+ result = primitiveValueCache->createValue(50., CSSPrimitiveValue::CSS_PERCENTAGE);
} else if (a->unit == CSSPrimitiveValue::CSS_NUMBER || a->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
- result = CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit);
+ result = primitiveValueCache->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit);
return result;
}
@@ -4804,13 +5172,13 @@ static bool parseDeprecatedGradientColorStop(CSSParser* p, CSSParserValue* a, CS
return false;
if (equalIgnoringCase(a->function->name, "from("))
- stop.m_position = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_NUMBER);
+ stop.m_position = p->primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_NUMBER);
else
- stop.m_position = CSSPrimitiveValue::create(1, CSSPrimitiveValue::CSS_NUMBER);
+ stop.m_position = p->primitiveValueCache()->createValue(1, CSSPrimitiveValue::CSS_NUMBER);
int id = args->current()->id;
if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
- stop.m_color = CSSPrimitiveValue::createIdentifier(id);
+ stop.m_color = p->primitiveValueCache()->createIdentifierValue(id);
else
stop.m_color = p->parseColor(args->current());
if (!stop.m_color)
@@ -4824,9 +5192,9 @@ static bool parseDeprecatedGradientColorStop(CSSParser* p, CSSParserValue* a, CS
CSSParserValue* stopArg = args->current();
if (stopArg->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
- stop.m_position = CSSPrimitiveValue::create(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER);
+ stop.m_position = p->primitiveValueCache()->createValue(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER);
else if (stopArg->unit == CSSPrimitiveValue::CSS_NUMBER)
- stop.m_position = CSSPrimitiveValue::create(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER);
+ stop.m_position = p->primitiveValueCache()->createValue(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER);
else
return false;
@@ -4837,7 +5205,7 @@ static bool parseDeprecatedGradientColorStop(CSSParser* p, CSSParserValue* a, CS
stopArg = args->next();
int id = stopArg->id;
if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
- stop.m_color = CSSPrimitiveValue::createIdentifier(id);
+ stop.m_color = p->primitiveValueCache()->createIdentifierValue(id);
else
stop.m_color = p->parseColor(stopArg);
if (!stop.m_color)
@@ -4887,7 +5255,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
a = args->next();
if (!a)
return false;
- RefPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(a, true);
+ RefPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(a, true, primitiveValueCache());
if (!point)
return false;
result->setFirstX(point.release());
@@ -4896,7 +5264,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
a = args->next();
if (!a)
return false;
- point = parseDeprecatedGradientPoint(a, false);
+ point = parseDeprecatedGradientPoint(a, false, primitiveValueCache());
if (!point)
return false;
result->setFirstY(point.release());
@@ -4911,7 +5279,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
a = args->next();
if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
return false;
- static_cast<CSSRadialGradientValue*>(result.get())->setFirstRadius(CSSPrimitiveValue::create(a->fValue, CSSPrimitiveValue::CSS_NUMBER));
+ static_cast<CSSRadialGradientValue*>(result.get())->setFirstRadius(primitiveValueCache()->createValue(a->fValue, CSSPrimitiveValue::CSS_NUMBER));
// Comma after the first radius.
a = args->next();
@@ -4924,7 +5292,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
a = args->next();
if (!a)
return false;
- point = parseDeprecatedGradientPoint(a, true);
+ point = parseDeprecatedGradientPoint(a, true, primitiveValueCache());
if (!point)
return false;
result->setSecondX(point.release());
@@ -4933,7 +5301,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
a = args->next();
if (!a)
return false;
- point = parseDeprecatedGradientPoint(a, false);
+ point = parseDeprecatedGradientPoint(a, false, primitiveValueCache());
if (!point)
return false;
result->setSecondY(point.release());
@@ -4948,7 +5316,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
a = args->next();
if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
return false;
- static_cast<CSSRadialGradientValue*>(result.get())->setSecondRadius(CSSPrimitiveValue::create(a->fValue, CSSPrimitiveValue::CSS_NUMBER));
+ static_cast<CSSRadialGradientValue*>(result.get())->setSecondRadius(primitiveValueCache()->createValue(a->fValue, CSSPrimitiveValue::CSS_NUMBER));
}
// We now will accept any number of stops (0 or more).
@@ -4977,7 +5345,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
return true;
}
-static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, bool& isHorizontal)
+static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, bool& isHorizontal, CSSPrimitiveValueCache* primitiveValueCache)
{
if (a->unit != CSSPrimitiveValue::CSS_IDENT)
return 0;
@@ -4994,14 +5362,14 @@ static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, boo
default:
return 0;
}
- return CSSPrimitiveValue::createIdentifier(a->id);
+ return primitiveValueCache->createIdentifierValue(a->id);
}
static PassRefPtr<CSSPrimitiveValue> parseGradientColorOrKeyword(CSSParser* p, CSSParserValue* value)
{
int id = value->id;
if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
- return CSSPrimitiveValue::createIdentifier(id);
+ return p->primitiveValueCache()->createIdentifierValue(id);
return p->parseColor(value);
}
@@ -5022,7 +5390,7 @@ bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
bool expectComma = false;
// Look for angle.
if (validUnit(a, FAngle, true)) {
- result->setAngle(CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit));
+ result->setAngle(primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit));
a = args->next();
expectComma = true;
@@ -5032,7 +5400,7 @@ bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
RefPtr<CSSPrimitiveValue> location;
bool isHorizontal = false;
- if ((location = valueFromSideKeyword(a, isHorizontal))) {
+ if ((location = valueFromSideKeyword(a, isHorizontal, primitiveValueCache()))) {
if (isHorizontal)
startX = location;
else
@@ -5040,7 +5408,7 @@ bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
a = args->next();
if (a) {
- if ((location = valueFromSideKeyword(a, isHorizontal))) {
+ if ((location = valueFromSideKeyword(a, isHorizontal, primitiveValueCache()))) {
if (isHorizontal) {
if (startX)
return false;
@@ -5059,7 +5427,7 @@ bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
}
if (!startX && !startY)
- startY = CSSPrimitiveValue::createIdentifier(CSSValueTop);
+ startY = primitiveValueCache()->createIdentifierValue(CSSValueTop);
result->setFirstX(startX.release());
result->setFirstY(startY.release());
@@ -5129,7 +5497,7 @@ bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
switch (a->id) {
case CSSValueCircle:
case CSSValueEllipse:
- shapeValue = CSSPrimitiveValue::createIdentifier(a->id);
+ shapeValue = primitiveValueCache()->createIdentifierValue(a->id);
foundValue = true;
break;
case CSSValueClosestSide:
@@ -5138,7 +5506,7 @@ bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
case CSSValueFarthestCorner:
case CSSValueContain:
case CSSValueCover:
- sizeValue = CSSPrimitiveValue::createIdentifier(a->id);
+ sizeValue = primitiveValueCache()->createIdentifierValue(a->id);
foundValue = true;
break;
}
@@ -5161,7 +5529,7 @@ bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
if (!shapeValue && !sizeValue) {
if (validUnit(a, FLength | FPercent, m_strict)) {
- horizontalSize = CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
+ horizontalSize = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
a = args->next();
if (!a)
return false;
@@ -5170,7 +5538,7 @@ bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
}
if (validUnit(a, FLength | FPercent, m_strict)) {
- verticalSize = CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
+ verticalSize = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
a = args->next();
if (!a)
@@ -5218,7 +5586,7 @@ bool CSSParser::parseGradientColorStops(CSSParserValueList* valueList, CSSGradie
a = valueList->next();
if (a) {
if (validUnit(a, FLength | FPercent, m_strict)) {
- stop.m_position = CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit);
+ stop.m_position = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit);
a = valueList->next();
}
}
@@ -5439,7 +5807,7 @@ PassRefPtr<CSSValueList> CSSParser::parseTransform()
return 0;
// Add the value to the current transform operation.
- transformValue->append(CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit));
+ transformValue->append(primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit));
a = args->next();
if (!a)
@@ -5473,22 +5841,20 @@ bool CSSParser::parseTransformOrigin(int propId, int& propId1, int& propId2, int
// parseTransformOriginShorthand advances the m_valueList pointer
break;
case CSSPropertyWebkitTransformOriginX: {
- bool xFound = false, yFound = true;
- value = parseFillPositionXY(m_valueList, xFound, yFound);
+ value = parseFillPositionX(m_valueList);
if (value)
m_valueList->next();
break;
}
case CSSPropertyWebkitTransformOriginY: {
- bool xFound = true, yFound = false;
- value = parseFillPositionXY(m_valueList, xFound, yFound);
+ value = parseFillPositionY(m_valueList);
if (value)
m_valueList->next();
break;
}
case CSSPropertyWebkitTransformOriginZ: {
if (validUnit(m_valueList->current(), FLength, m_strict))
- value = CSSPrimitiveValue::create(m_valueList->current()->fValue, (CSSPrimitiveValue::UnitTypes)m_valueList->current()->unit);
+ value = primitiveValueCache()->createValue(m_valueList->current()->fValue, (CSSPrimitiveValue::UnitTypes)m_valueList->current()->unit);
if (value)
m_valueList->next();
break;
@@ -5512,15 +5878,13 @@ bool CSSParser::parsePerspectiveOrigin(int propId, int& propId1, int& propId2, R
parseFillPosition(m_valueList, value, value2);
break;
case CSSPropertyWebkitPerspectiveOriginX: {
- bool xFound = false, yFound = true;
- value = parseFillPositionXY(m_valueList, xFound, yFound);
+ value = parseFillPositionX(m_valueList);
if (value)
m_valueList->next();
break;
}
case CSSPropertyWebkitPerspectiveOriginY: {
- bool xFound = true, yFound = false;
- value = parseFillPositionXY(m_valueList, xFound, yFound);
+ value = parseFillPositionY(m_valueList);
if (value)
m_valueList->next();
break;
@@ -5541,7 +5905,7 @@ bool CSSParser::parseTextEmphasisStyle(bool important)
if (value->unit == CSSPrimitiveValue::CSS_STRING) {
if (fill || shape || (valueListSize != 1 && !inShorthand()))
return false;
- addProperty(CSSPropertyWebkitTextEmphasisStyle, CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_STRING), important);
+ addProperty(CSSPropertyWebkitTextEmphasisStyle, primitiveValueCache()->createValue(value->string, CSSPrimitiveValue::CSS_STRING), important);
m_valueList->next();
return true;
}
@@ -5549,7 +5913,7 @@ bool CSSParser::parseTextEmphasisStyle(bool important)
if (value->id == CSSValueNone) {
if (fill || shape || (valueListSize != 1 && !inShorthand()))
return false;
- addProperty(CSSPropertyWebkitTextEmphasisStyle, CSSPrimitiveValue::createIdentifier(CSSValueNone), important);
+ addProperty(CSSPropertyWebkitTextEmphasisStyle, primitiveValueCache()->createIdentifierValue(CSSValueNone), important);
m_valueList->next();
return true;
}
@@ -5557,11 +5921,11 @@ bool CSSParser::parseTextEmphasisStyle(bool important)
if (value->id == CSSValueOpen || value->id == CSSValueFilled) {
if (fill)
return false;
- fill = CSSPrimitiveValue::createIdentifier(value->id);
+ fill = primitiveValueCache()->createIdentifierValue(value->id);
} else if (value->id == CSSValueDot || value->id == CSSValueCircle || value->id == CSSValueDoubleCircle || value->id == CSSValueTriangle || value->id == CSSValueSesame) {
if (shape)
return false;
- shape = CSSPrimitiveValue::createIdentifier(value->id);
+ shape = primitiveValueCache()->createIdentifierValue(value->id);
} else if (!inShorthand())
return false;
else
@@ -5587,6 +5951,46 @@ bool CSSParser::parseTextEmphasisStyle(bool important)
return false;
}
+bool CSSParser::parseLineBoxContain(bool important)
+{
+ LineBoxContain lineBoxContain = LineBoxContainNone;
+
+ for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+ if (value->id == CSSValueBlock) {
+ if (lineBoxContain & LineBoxContainBlock)
+ return false;
+ lineBoxContain |= LineBoxContainBlock;
+ } else if (value->id == CSSValueInline) {
+ if (lineBoxContain & LineBoxContainInline)
+ return false;
+ lineBoxContain |= LineBoxContainInline;
+ } else if (value->id == CSSValueFont) {
+ if (lineBoxContain & LineBoxContainFont)
+ return false;
+ lineBoxContain |= LineBoxContainFont;
+ } else if (value->id == CSSValueGlyphs) {
+ if (lineBoxContain & LineBoxContainGlyphs)
+ return false;
+ lineBoxContain |= LineBoxContainGlyphs;
+ } else if (value->id == CSSValueReplaced) {
+ if (lineBoxContain & LineBoxContainReplaced)
+ return false;
+ lineBoxContain |= LineBoxContainReplaced;
+ } else if (value->id == CSSValueInlineBox) {
+ if (lineBoxContain & LineBoxContainInlineBox)
+ return false;
+ lineBoxContain |= LineBoxContainInlineBox;
+ } else
+ return false;
+ }
+
+ if (!lineBoxContain)
+ return false;
+
+ addProperty(CSSPropertyWebkitLineBoxContain, CSSLineBoxContainValue::create(lineBoxContain), important);
+ return true;
+}
+
static inline int yyerror(const char*) { return 1; }
#define END_TOKEN 0
@@ -5618,6 +6022,7 @@ int CSSParser::lex(void* yylvalWithoutType)
case DIMEN:
case UNICODERANGE:
case FUNCTION:
+ case ANYFUNCTION:
case NOTFUNCTION:
yylval->string.characters = t;
yylval->string.length = length;
@@ -5831,6 +6236,22 @@ PassOwnPtr<CSSParserSelector> CSSParser::sinkFloatingSelector(CSSParserSelector*
return adoptPtr(selector);
}
+Vector<OwnPtr<CSSParserSelector> >* CSSParser::createFloatingSelectorVector()
+{
+ Vector<OwnPtr<CSSParserSelector> >* selectorVector = new Vector<OwnPtr<CSSParserSelector> >;
+ m_floatingSelectorVectors.add(selectorVector);
+ return selectorVector;
+}
+
+PassOwnPtr<Vector<OwnPtr<CSSParserSelector> > > CSSParser::sinkFloatingSelectorVector(Vector<OwnPtr<CSSParserSelector> >* selectorVector)
+{
+ if (selectorVector) {
+ ASSERT(m_floatingSelectorVectors.contains(selectorVector));
+ m_floatingSelectorVectors.remove(selectorVector);
+ }
+ return adoptPtr(selectorVector);
+}
+
CSSParserValueList* CSSParser::createFloatingValueList()
{
CSSParserValueList* list = new CSSParserValueList;
@@ -6041,9 +6462,6 @@ void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePre
return;
}
- if (Document* doc = document())
- doc->setUsesDescendantRules(true);
-
specifiers->setRelation(CSSSelector::ShadowDescendant);
if (CSSParserSelector* history = specifiers->tagHistory()) {
history->setTag(tag);
@@ -6266,6 +6684,13 @@ static int cssPropertyID(const UChar* propertyName, unsigned length)
const char* const opacity = "opacity";
name = opacity;
length = strlen(opacity);
+#if PLATFORM(IOS)
+ } else if (!strcmp(buffer, "-webkit-hyphenate-locale")) {
+ // Worked in iOS 4.2.
+ const char* const webkitLocale = "-webkit-locale";
+ name = webkitLocale;
+ length = strlen(webkitLocale);
+#endif
} else if (hasPrefix(buffer + 7, length - 7, "-border-")) {
// -webkit-border-*-*-radius worked in Safari 4 and earlier. -webkit-border-radius syntax
// differs from border-radius, so it is remains as a distinct property.
@@ -6410,11 +6835,8 @@ String quoteCSSString(const String& string)
buffer[index++] = ch;
afterEscape = false;
} else if (ch < 0x20 || ch == 0x7F) { // Control characters.
- static const char hexDigits[17] = "0123456789abcdef";
buffer[index++] = '\\';
- if (ch >= 0x10)
- buffer[index++] = hexDigits[ch >> 4];
- buffer[index++] = hexDigits[ch & 0xF];
+ placeByteAsHexCompressIfPossible(ch, buffer, index, Lowercase);
afterEscape = true;
} else {
// Space character may be required to separate backslash-escape sequence and normal characters.