diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/WebCore/css/CSSParser.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/WebCore/css/CSSParser.cpp')
-rw-r--r-- | Source/WebCore/css/CSSParser.cpp | 6547 |
1 files changed, 2593 insertions, 3954 deletions
diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp index 9aec1c8ac..837d0a2e0 100644 --- a/Source/WebCore/css/CSSParser.cpp +++ b/Source/WebCore/css/CSSParser.cpp @@ -1,13 +1,12 @@ /* * Copyright (C) 2003 Lars Knoll (knoll@kde.org) * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) - * Copyright (C) 2004-2015 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> * Copyright (C) 2008 Eric Seidel <eric@webkit.org> * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved. * Copyright (C) 2012 Intel Corporation. All rights reserved. - * Copyright (C) 2014 Google Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -28,15 +27,12 @@ #include "config.h" #include "CSSParser.h" -#include "CSSAnimationTriggerScrollValue.h" #include "CSSAspectRatioValue.h" #include "CSSBasicShapes.h" #include "CSSBorderImage.h" #include "CSSCanvasValue.h" -#include "CSSContentDistributionValue.h" #include "CSSCrossfadeValue.h" #include "CSSCursorImageValue.h" -#include "CSSCustomPropertyValue.h" #include "CSSFilterImageValue.h" #include "CSSFontFaceRule.h" #include "CSSFontFaceSrcValue.h" @@ -44,49 +40,39 @@ #include "CSSFontValue.h" #include "CSSFunctionValue.h" #include "CSSGradientValue.h" +#include "CSSGridTemplateValue.h" #include "CSSImageValue.h" #include "CSSInheritedValue.h" #include "CSSInitialValue.h" -#include "CSSKeyframeRule.h" -#include "CSSKeyframesRule.h" #include "CSSLineBoxContainValue.h" #include "CSSMediaRule.h" -#include "CSSNamedImageValue.h" #include "CSSPageRule.h" #include "CSSPrimitiveValue.h" -#include "CSSPrimitiveValueMappings.h" #include "CSSPropertySourceData.h" #include "CSSReflectValue.h" -#include "CSSRevertValue.h" #include "CSSSelector.h" #include "CSSShadowValue.h" #include "CSSStyleSheet.h" #include "CSSTimingFunctionValue.h" #include "CSSUnicodeRangeValue.h" -#include "CSSUnsetValue.h" #include "CSSValueKeywords.h" #include "CSSValueList.h" #include "CSSValuePool.h" -#include "CSSVariableDependentValue.h" #include "Counter.h" #include "Document.h" #include "FloatConversion.h" -#include "GridCoordinate.h" #include "HTMLParserIdioms.h" #include "HashTools.h" +#include "HistogramSupport.h" #include "MediaList.h" #include "MediaQueryExp.h" #include "Page.h" -#include "PageConsoleClient.h" +#include "PageConsole.h" #include "Pair.h" #include "Rect.h" #include "RenderTheme.h" #include "RuntimeEnabledFeatures.h" #include "SVGParserUtilities.h" -#include "SVGPathByteStream.h" -#include "SVGPathUtilities.h" -#include "SelectorChecker.h" -#include "SelectorCheckerTestFunctions.h" #include "Settings.h" #include "StyleProperties.h" #include "StylePropertyShorthand.h" @@ -94,31 +80,25 @@ #include "StyleRuleImport.h" #include "StyleSheetContents.h" #include "TextEncoding.h" -#include "WebKitCSSFilterValue.h" +#include "WebKitCSSKeyframeRule.h" +#include "WebKitCSSKeyframesRule.h" #include "WebKitCSSRegionRule.h" #include "WebKitCSSTransformValue.h" -#include <JavaScriptCore/Profile.h> #include <bitset> #include <limits.h> #include <wtf/HexNumber.h> -#include <wtf/NeverDestroyed.h> #include <wtf/StdLibExtras.h> #include <wtf/dtoa.h> #include <wtf/text/StringBuffer.h> #include <wtf/text/StringBuilder.h> #include <wtf/text/StringImpl.h> -#if ENABLE(CSS_GRID_LAYOUT) -#include "CSSGridLineNamesValue.h" -#include "CSSGridTemplateAreasValue.h" -#endif - #if ENABLE(CSS_IMAGE_SET) #include "CSSImageSetValue.h" #endif -#if ENABLE(CSS_SCROLL_SNAP) -#include "LengthRepeat.h" +#if ENABLE(CSS_FILTERS) +#include "WebKitCSSFilterValue.h" #endif #if ENABLE(DASHBOARD_SUPPORT) @@ -145,19 +125,19 @@ enum PropertyType { class ImplicitScope { WTF_MAKE_NONCOPYABLE(ImplicitScope); public: - ImplicitScope(WebCore::CSSParser& parser, PropertyType propertyType) + ImplicitScope(WebCore::CSSParser* parser, PropertyType propertyType) : m_parser(parser) { - m_parser.m_implicitShorthand = propertyType == PropertyImplicit; + m_parser->m_implicitShorthand = propertyType == PropertyImplicit; } ~ImplicitScope() { - m_parser.m_implicitShorthand = false; + m_parser->m_implicitShorthand = false; } private: - WebCore::CSSParser& m_parser; + WebCore::CSSParser* m_parser; }; } // namespace @@ -167,10 +147,31 @@ namespace WebCore { static const unsigned INVALID_NUM_PARSED_PROPERTIES = UINT_MAX; static const double MAX_SCALE = 1000000; -template<unsigned length> bool equalLettersIgnoringASCIICase(const CSSParserValue& value, const char (&lowercaseLetters)[length]) +template <unsigned N> +static bool equal(const CSSParserString& a, const char (&b)[N]) { - ASSERT(value.unit == CSSPrimitiveValue::CSS_IDENT || value.unit == CSSPrimitiveValue::CSS_STRING); - return equalLettersIgnoringASCIICase(value.string, lowercaseLetters); + unsigned length = N - 1; // Ignore the trailing null character + if (a.length() != length) + return false; + + return a.is8Bit() ? WTF::equal(a.characters8(), reinterpret_cast<const LChar*>(b), length) : WTF::equal(a.characters16(), reinterpret_cast<const LChar*>(b), length); +} + +template <unsigned N> +static bool equalIgnoringCase(const CSSParserString& a, const char (&b)[N]) +{ + unsigned length = N - 1; // Ignore the trailing null character + if (a.length() != length) + return false; + + return a.is8Bit() ? WTF::equalIgnoringCase(b, a.characters8(), length) : WTF::equalIgnoringCase(b, a.characters16(), length); +} + +template <unsigned N> +static bool equalIgnoringCase(CSSParserValue* value, const char (&b)[N]) +{ + ASSERT(value->unit == CSSPrimitiveValue::CSS_IDENT || value->unit == CSSPrimitiveValue::CSS_STRING); + return equalIgnoringCase(value->string, b); } static bool hasPrefix(const char* string, unsigned length, const char* prefix) @@ -184,10 +185,9 @@ static bool hasPrefix(const char* string, unsigned length, const char* prefix) return false; } -template<typename... Args> -static Ref<CSSPrimitiveValue> createPrimitiveValuePair(Args&&... args) +static PassRefPtr<CSSPrimitiveValue> createPrimitiveValuePair(PassRefPtr<CSSPrimitiveValue> first, PassRefPtr<CSSPrimitiveValue> second) { - return CSSValuePool::singleton().createValue(Pair::create(std::forward<Args>(args)...)); + return cssValuePool().createValue(Pair::create(first, second)); } class AnimationParseContext { @@ -237,7 +237,7 @@ private: const CSSParserContext& strictCSSParserContext() { - static NeverDestroyed<CSSParserContext> strictContext(CSSStrictMode); + DEFINE_STATIC_LOCAL(CSSParserContext, strictContext, (CSSStrictMode)); return strictContext; } @@ -245,8 +245,10 @@ CSSParserContext::CSSParserContext(CSSParserMode mode, const URL& baseURL) : baseURL(baseURL) , mode(mode) , isHTMLDocument(false) - , isCSSRegionsEnabled(RuntimeEnabledFeatures::sharedFeatures().cssRegionsEnabled()) - , isCSSCompositingEnabled(RuntimeEnabledFeatures::sharedFeatures().cssCompositingEnabled()) + , isCSSStickyPositionEnabled(false) + , isCSSRegionsEnabled(false) + , isCSSCompositingEnabled(false) + , isCSSGridLayoutEnabled(false) , needsSiteSpecificQuirks(false) , enforcesCSSMIMETypeInNoQuirksMode(true) , useLegacyBackgroundSizeShorthandBehavior(false) @@ -264,8 +266,10 @@ CSSParserContext::CSSParserContext(Document& document, const URL& baseURL, const , charset(charset) , mode(document.inQuirksMode() ? CSSQuirksMode : CSSStrictMode) , isHTMLDocument(document.isHTMLDocument()) + , isCSSStickyPositionEnabled(document.cssStickyPositionEnabled()) , isCSSRegionsEnabled(document.cssRegionsEnabled()) , isCSSCompositingEnabled(document.cssCompositingEnabled()) + , isCSSGridLayoutEnabled(document.cssGridLayoutEnabled()) , needsSiteSpecificQuirks(document.settings() ? document.settings()->needsSiteSpecificQuirks() : false) , enforcesCSSMIMETypeInNoQuirksMode(!document.settings() || document.settings()->enforceCSSMIMETypeInNoQuirksMode()) , useLegacyBackgroundSizeShorthandBehavior(document.settings() ? document.settings()->useLegacyBackgroundSizeShorthandBehavior() : false) @@ -284,8 +288,10 @@ bool operator==(const CSSParserContext& a, const CSSParserContext& b) && a.charset == b.charset && a.mode == b.mode && a.isHTMLDocument == b.isHTMLDocument + && a.isCSSStickyPositionEnabled == b.isCSSStickyPositionEnabled && a.isCSSRegionsEnabled == b.isCSSRegionsEnabled && a.isCSSCompositingEnabled == b.isCSSCompositingEnabled + && a.isCSSGridLayoutEnabled == b.isCSSGridLayoutEnabled && a.needsSiteSpecificQuirks == b.needsSiteSpecificQuirks && a.enforcesCSSMIMETypeInNoQuirksMode == b.enforcesCSSMIMETypeInNoQuirksMode && a.useLegacyBackgroundSizeShorthandBehavior == b.useLegacyBackgroundSizeShorthandBehavior; @@ -295,34 +301,32 @@ CSSParser::CSSParser(const CSSParserContext& context) : m_context(context) , m_important(false) , m_id(CSSPropertyInvalid) - , m_styleSheet(nullptr) + , m_styleSheet(0) +#if ENABLE(CSS3_CONDITIONAL_RULES) , m_supportsCondition(false) - , m_selectorListForParseSelector(nullptr) +#endif + , m_selectorListForParseSelector(0) , m_numParsedPropertiesBeforeMarginBox(INVALID_NUM_PARSED_PROPERTIES) , m_inParseShorthand(0) , m_currentShorthand(CSSPropertyInvalid) , m_implicitShorthand(false) + , m_hasFontFaceOnlyValues(false) , m_hadSyntacticallyValidCSSRule(false) , m_logErrors(false) , m_ignoreErrorsInDeclaration(false) , m_defaultNamespace(starAtom) , m_parsedTextPrefixLength(0) - , m_nestedSelectorLevel(0) , m_propertyRange(UINT_MAX, UINT_MAX) - , m_ruleSourceDataResult(nullptr) + , m_ruleSourceDataResult(0) , m_parsingMode(NormalMode) , m_is8BitSource(false) - , m_currentCharacter8(nullptr) - , m_currentCharacter16(nullptr) + , m_currentCharacter8(0) + , m_currentCharacter16(0) , m_length(0) , m_token(0) , m_lineNumber(0) , m_tokenStartLineNumber(0) - , m_tokenStartColumnNumber(0) , m_lastSelectorLineNumber(0) - , m_columnOffsetForLine(0) - , m_sheetStartLineNumber(0) - , m_sheetStartColumnNumber(0) , m_allowImportRules(true) , m_allowNamespaceDeclarations(true) #if ENABLE(CSS_DEVICE_ADAPTATION) @@ -332,7 +336,7 @@ CSSParser::CSSParser(const CSSParserContext& context) #if YYDEBUG > 0 cssyydebug = 1; #endif - m_tokenStart.ptr8 = nullptr; + m_tokenStart.ptr8 = 0; } CSSParser::~CSSParser() @@ -340,21 +344,37 @@ CSSParser::~CSSParser() clearProperties(); } -template<typename CharacterType> ALWAYS_INLINE static void convertToASCIILowercaseInPlace(CharacterType* characters, unsigned length) +template <typename CharacterType> +ALWAYS_INLINE static void makeLower(const CharacterType* input, CharacterType* output, unsigned length) { - for (unsigned i = 0; i < length; ++i) - characters[i] = toASCIILower(characters[i]); + // FIXME: If we need Unicode lowercasing here, then we probably want the real kind + // that can potentially change the length of the string rather than the character + // by character kind. If we don't need Unicode lowercasing, it would be good to + // simplify this function. + + if (charactersAreAllASCII(input, length)) { + // Fast case for all-ASCII. + for (unsigned i = 0; i < length; i++) + output[i] = toASCIILower(input[i]); + } else { + for (unsigned i = 0; i < length; i++) { + ASSERT(u_tolower(input[i]) <= 0xFFFF); + output[i] = u_tolower(input[i]); + } + } } -void CSSParserString::convertToASCIILowercaseInPlace() +void CSSParserString::lower() { - if (is8Bit()) - WebCore::convertToASCIILowercaseInPlace(characters8(), length()); - else - WebCore::convertToASCIILowercaseInPlace(characters16(), length()); + if (is8Bit()) { + makeLower(characters8(), characters8(), length()); + return; + } + + makeLower(characters16(), characters16(), length()); } -void CSSParser::setupParser(const char* prefix, unsigned prefixLength, StringView string, const char* suffix, unsigned suffixLength) +void CSSParser::setupParser(const char* prefix, unsigned prefixLength, const String& string, const char* suffix, unsigned suffixLength) { m_parsedTextPrefixLength = prefixLength; unsigned stringLength = string.length(); @@ -363,7 +383,7 @@ void CSSParser::setupParser(const char* prefix, unsigned prefixLength, StringVie if (!stringLength || string.is8Bit()) { m_dataStart8 = std::make_unique<LChar[]>(length); - for (unsigned i = 0; i < m_parsedTextPrefixLength; ++i) + for (unsigned i = 0; i < m_parsedTextPrefixLength; i++) m_dataStart8[i] = prefix[i]; if (stringLength) @@ -374,18 +394,18 @@ void CSSParser::setupParser(const char* prefix, unsigned prefixLength, StringVie for (unsigned i = start; i < end; i++) m_dataStart8[i] = suffix[i - start]; - m_dataStart8[length - 1] = '\0'; + m_dataStart8[length - 1] = 0; m_is8BitSource = true; m_currentCharacter8 = m_dataStart8.get(); - m_currentCharacter16 = nullptr; + m_currentCharacter16 = 0; setTokenStart<LChar>(m_currentCharacter8); m_lexFunc = &CSSParser::realLex<LChar>; return; } m_dataStart16 = std::make_unique<UChar[]>(length); - for (unsigned i = 0; i < m_parsedTextPrefixLength; ++i) + for (unsigned i = 0; i < m_parsedTextPrefixLength; i++) m_dataStart16[i] = prefix[i]; ASSERT(stringLength); @@ -396,65 +416,62 @@ void CSSParser::setupParser(const char* prefix, unsigned prefixLength, StringVie for (unsigned i = start; i < end; i++) m_dataStart16[i] = suffix[i - start]; - m_dataStart16[length - 1] = '\0'; + m_dataStart16[length - 1] = 0; m_is8BitSource = false; - m_currentCharacter8 = nullptr; + m_currentCharacter8 = 0; m_currentCharacter16 = m_dataStart16.get(); setTokenStart<UChar>(m_currentCharacter16); m_lexFunc = &CSSParser::realLex<UChar>; } -void CSSParser::parseSheet(StyleSheetContents* sheet, const String& string, const TextPosition& textPosition, RuleSourceDataList* ruleSourceDataResult, bool logErrors) +void CSSParser::parseSheet(StyleSheetContents* sheet, const String& string, int startLineNumber, RuleSourceDataList* ruleSourceDataResult, bool logErrors) { setStyleSheet(sheet); m_defaultNamespace = starAtom; // Reset the default namespace. if (ruleSourceDataResult) - m_currentRuleDataStack = std::make_unique<RuleSourceDataList>(); + m_currentRuleDataStack = adoptPtr(new RuleSourceDataList()); m_ruleSourceDataResult = ruleSourceDataResult; m_logErrors = logErrors && sheet->singleOwnerDocument() && !sheet->baseURL().isEmpty() && sheet->singleOwnerDocument()->page(); m_ignoreErrorsInDeclaration = false; - m_sheetStartLineNumber = textPosition.m_line.zeroBasedInt(); - m_sheetStartColumnNumber = textPosition.m_column.zeroBasedInt(); - m_lineNumber = m_sheetStartLineNumber; - m_columnOffsetForLine = 0; + m_lineNumber = startLineNumber; setupParser("", string, ""); cssyyparse(this); sheet->shrinkToFit(); - m_currentRuleDataStack.reset(); - m_ruleSourceDataResult = nullptr; - m_rule = nullptr; + m_currentRuleDataStack.clear(); + m_ruleSourceDataResult = 0; + m_rule = 0; m_ignoreErrorsInDeclaration = false; m_logErrors = false; } -RefPtr<StyleRuleBase> CSSParser::parseRule(StyleSheetContents* sheet, const String& string) +PassRefPtr<StyleRuleBase> CSSParser::parseRule(StyleSheetContents* sheet, const String& string) { setStyleSheet(sheet); m_allowNamespaceDeclarations = false; setupParser("@-webkit-rule{", string, "} "); cssyyparse(this); - return m_rule; + return m_rule.release(); } -RefPtr<StyleKeyframe> CSSParser::parseKeyframeRule(StyleSheetContents* sheet, const String& string) +PassRefPtr<StyleKeyframe> CSSParser::parseKeyframeRule(StyleSheetContents* sheet, const String& string) { setStyleSheet(sheet); setupParser("@-webkit-keyframe-rule{ ", string, "} "); cssyyparse(this); - return m_keyframe; + return m_keyframe.release(); } +#if ENABLE(CSS3_CONDITIONAL_RULES) bool CSSParser::parseSupportsCondition(const String& string) { m_supportsCondition = false; - // can't use { because tokenizer state switches from supports to initial state when it sees { token. - // instead insert one " " (which is WHITESPACE in CSSGrammar.y) - setupParser("@-webkit-supports-condition ", string, "} "); + setupParser("@-webkit-supports-condition{ ", string, "} "); cssyyparse(this); return m_supportsCondition; } +#endif static inline bool isColorPropertyID(CSSPropertyID propertyId) { @@ -473,7 +490,7 @@ static inline bool isColorPropertyID(CSSPropertyID propertyId) case CSSPropertyWebkitBorderBeforeColor: case CSSPropertyWebkitBorderEndColor: case CSSPropertyWebkitBorderStartColor: - case CSSPropertyColumnRuleColor: + case CSSPropertyWebkitColumnRuleColor: case CSSPropertyWebkitTextDecorationColor: case CSSPropertyWebkitTextEmphasisColor: case CSSPropertyWebkitTextFillColor: @@ -484,38 +501,36 @@ static inline bool isColorPropertyID(CSSPropertyID propertyId) } } -bool CSSParser::isValidSystemColorValue(CSSValueID valueID) -{ - return valueID >= CSSValueAqua && valueID <= CSSValueAppleSystemYellow; -} - -static bool validPrimitiveValueColor(CSSValueID valueID, bool strict = false) -{ - return (valueID == CSSValueWebkitText || valueID == CSSValueCurrentcolor || valueID == CSSValueMenu - || CSSParser::isValidSystemColorValue(valueID) || valueID == CSSValueAlpha - || (valueID >= CSSValueWebkitFocusRingColor && valueID < CSSValueWebkitText && !strict)); -} - -static CSSParser::ParseResult parseColorValue(MutableStyleProperties* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode) +static bool parseColorValue(MutableStyleProperties* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode) { ASSERT(!string.isEmpty()); bool strict = isStrictParserMode(cssParserMode); if (!isColorPropertyID(propertyId)) - return CSSParser::ParseResult::Error; - + return false; CSSParserString cssString; cssString.init(string); CSSValueID valueID = cssValueKeywordID(cssString); - if (validPrimitiveValueColor(valueID, strict)) { - RefPtr<CSSValue> value = CSSValuePool::singleton().createIdentifierValue(valueID); - return declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged; + 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; + } + + if (validPrimitive) { + RefPtr<CSSValue> value = cssValuePool().createIdentifierValue(valueID); + declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important)); + return true; } RGBA32 color; if (!CSSParser::fastParseColor(color, string, strict && string[0] != '#')) - return CSSParser::ParseResult::Error; - - RefPtr<CSSValue> value = CSSValuePool::singleton().createColorValue(color); - return declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged; + return false; + RefPtr<CSSValue> value = cssValuePool().createColorValue(color); + declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important)); + return true; } static inline bool isSimpleLengthPropertyID(CSSPropertyID propertyId, bool& acceptsNegativeNumbers) @@ -538,36 +553,26 @@ static inline bool isSimpleLengthPropertyID(CSSPropertyID propertyId, bool& acce case CSSPropertyWebkitPaddingBefore: case CSSPropertyWebkitPaddingEnd: case CSSPropertyWebkitPaddingStart: -#if ENABLE(CSS_GRID_LAYOUT) - case CSSPropertyWebkitGridColumnGap: - case CSSPropertyWebkitGridRowGap: -#endif acceptsNegativeNumbers = false; return true; #if ENABLE(CSS_SHAPES) case CSSPropertyWebkitShapeMargin: + case CSSPropertyWebkitShapePadding: acceptsNegativeNumbers = false; return RuntimeEnabledFeatures::sharedFeatures().cssShapesEnabled(); #endif case CSSPropertyBottom: - case CSSPropertyCx: - case CSSPropertyCy: case CSSPropertyLeft: case CSSPropertyMarginBottom: case CSSPropertyMarginLeft: case CSSPropertyMarginRight: case CSSPropertyMarginTop: - case CSSPropertyR: - case CSSPropertyRx: - case CSSPropertyRy: case CSSPropertyRight: case CSSPropertyTop: case CSSPropertyWebkitMarginAfter: case CSSPropertyWebkitMarginBefore: case CSSPropertyWebkitMarginEnd: case CSSPropertyWebkitMarginStart: - case CSSPropertyX: - case CSSPropertyY: acceptsNegativeNumbers = true; return true; default: @@ -594,12 +599,12 @@ static inline bool parseSimpleLength(const CharacterType* characters, unsigned& return ok; } -static CSSParser::ParseResult parseSimpleLengthValue(MutableStyleProperties* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode) +static bool parseSimpleLengthValue(MutableStyleProperties* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode) { ASSERT(!string.isEmpty()); bool acceptsNegativeNumbers; if (!isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers)) - return CSSParser::ParseResult::Error; + return false; unsigned length = string.length(); double number; @@ -607,27 +612,26 @@ static CSSParser::ParseResult parseSimpleLengthValue(MutableStyleProperties* dec if (string.is8Bit()) { if (!parseSimpleLength(string.characters8(), length, unit, number)) - return CSSParser::ParseResult::Error; + return false; } else { if (!parseSimpleLength(string.characters16(), length, unit, number)) - return CSSParser::ParseResult::Error; + return false; } if (unit == CSSPrimitiveValue::CSS_NUMBER) { if (number && isStrictParserMode(cssParserMode)) - return CSSParser::ParseResult::Error; + return false; unit = CSSPrimitiveValue::CSS_PX; } if (number < 0 && !acceptsNegativeNumbers) - return CSSParser::ParseResult::Error; - if (std::isinf(number)) - return CSSParser::ParseResult::Error; + return false; - RefPtr<CSSValue> value = CSSValuePool::singleton().createValue(number, unit); - return declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged; + RefPtr<CSSValue> value = cssValuePool().createValue(number, unit); + declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important)); + return true; } -static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int valueID, const CSSParserContext& parserContext, StyleSheetContents* styleSheetContents) +static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int valueID, const CSSParserContext& parserContext) { if (!valueID) return false; @@ -645,7 +649,7 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int case CSSPropertyWebkitBorderBeforeStyle: case CSSPropertyWebkitBorderEndStyle: case CSSPropertyWebkitBorderStartStyle: - case CSSPropertyColumnRuleStyle: + case CSSPropertyWebkitColumnRuleStyle: if (valueID >= CSSValueNone && valueID <= CSSValueDouble) return true; break; @@ -666,16 +670,14 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int return true; break; case CSSPropertyDisplay: - // inline | block | list-item | inline-block | table | + // inline | block | list-item | run-in | inline-block | table | // inline-table | table-row-group | table-header-group | table-footer-group | table-row | // table-column-group | table-column | table-cell | table-caption | -webkit-box | -webkit-inline-box | none | inherit - // flex | -webkit-flex | inline-flex | -webkit-inline-flex | -webkit-grid | -webkit-inline-grid + // -webkit-flex | -webkit-inline-flex | -webkit-grid | -webkit-inline-grid if ((valueID >= CSSValueInline && valueID <= CSSValueWebkitInlineFlex) || valueID == CSSValueNone) return true; -#if ENABLE(CSS_GRID_LAYOUT) - if (valueID == CSSValueWebkitGrid || valueID == CSSValueWebkitInlineGrid) + if (parserContext.isCSSGridLayoutEnabled && (valueID == CSSValueWebkitGrid || valueID == CSSValueWebkitInlineGrid)) return true; -#endif break; case CSSPropertyEmptyCells: // show | hide | inherit @@ -690,10 +692,9 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int if (valueID == CSSValueNormal || valueID == CSSValueItalic || valueID == CSSValueOblique) return true; break; - case CSSPropertyImageRendering: // auto | optimizeSpeed | optimizeQuality | -webkit-crisp-edges | -webkit-optimize-contrast | crisp-edges | pixelated - // optimizeSpeed and optimizeQuality are deprecated; a user agent must accept them as valid values but must treat them as having the same behavior as pixelated and auto respectively. + case CSSPropertyImageRendering: // auto | optimizeSpeed | optimizeQuality | -webkit-crisp-edges | -webkit-optimize-contrast if (valueID == CSSValueAuto || valueID == CSSValueOptimizespeed || valueID == CSSValueOptimizequality - || valueID == CSSValueWebkitCrispEdges || valueID == CSSValueWebkitOptimizeContrast || valueID == CSSValueCrispEdges || valueID == CSSValuePixelated) + || valueID == CSSValueWebkitCrispEdges || valueID == CSSValueWebkitOptimizeContrast) return true; break; case CSSPropertyListStylePosition: // inside | outside | inherit @@ -719,18 +720,6 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int if (valueID == CSSValueNormal || valueID == CSSValueBreakWord) return true; break; -#if ENABLE(TOUCH_EVENTS) - case CSSPropertyTouchAction: // auto | manipulation - if (valueID == CSSValueAuto || valueID == CSSValueManipulation) - return true; - break; -#endif -#if ENABLE(CSS_SCROLL_SNAP) - case CSSPropertyWebkitScrollSnapType: // none | mandatory | proximity - if (valueID == CSSValueNone || valueID == CSSValueMandatory || valueID == CSSValueProximity) - return true; - break; -#endif case CSSPropertyOverflowX: // visible | hidden | scroll | auto | marquee | overlay | inherit if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay || valueID == CSSValueWebkitMarquee) return true; @@ -758,7 +747,11 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int return true; break; case CSSPropertyPosition: // static | relative | absolute | fixed | sticky | inherit - if (valueID == CSSValueStatic || valueID == CSSValueRelative || valueID == CSSValueAbsolute || valueID == CSSValueFixed || valueID == CSSValueWebkitSticky) + if (valueID == CSSValueStatic || valueID == CSSValueRelative || valueID == CSSValueAbsolute || valueID == CSSValueFixed +#if ENABLE(CSS_STICKY_POSITION) + || (parserContext.isCSSStickyPositionEnabled && valueID == CSSValueWebkitSticky) +#endif + ) return true; break; case CSSPropertyResize: // none | both | horizontal | vertical | auto @@ -802,7 +795,7 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int return true; break; case CSSPropertyWebkitAppearance: - if ((valueID >= CSSValueCheckbox && valueID <= CSSValueCapsLockIndicator) || valueID == CSSValueNone) + if ((valueID >= CSSValueCheckbox && valueID <= CSSValueTextarea) || valueID == CSSValueNone) return true; break; case CSSPropertyWebkitBackfaceVisibility: @@ -810,15 +803,12 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int return true; break; #if ENABLE(CSS_COMPOSITING) - case CSSPropertyMixBlendMode: + case CSSPropertyWebkitBlendMode: if (parserContext.isCSSCompositingEnabled && (valueID == CSSValueNormal || valueID == CSSValueMultiply || valueID == CSSValueScreen || valueID == CSSValueOverlay || valueID == CSSValueDarken || valueID == CSSValueLighten || valueID == CSSValueColorDodge || valueID == CSSValueColorBurn || valueID == CSSValueHardLight || valueID == CSSValueSoftLight || valueID == CSSValueDifference - || valueID == CSSValueExclusion || valueID == CSSValuePlusDarker || valueID == CSSValuePlusLighter)) - return true; - break; - case CSSPropertyIsolation: - if (parserContext.isCSSCompositingEnabled && (valueID == CSSValueAuto || valueID == CSSValueIsolate)) + || valueID == CSSValueExclusion || valueID == CSSValueHue || valueID == CSSValueSaturation || valueID == CSSValueColor + || valueID == CSSValueLuminosity)) return true; break; #endif @@ -852,18 +842,38 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueJustify) return true; break; - case CSSPropertyColumnFill: + case CSSPropertyWebkitColorCorrection: + if (valueID == CSSValueSrgb || valueID == CSSValueDefault) + return true; + break; + case CSSPropertyWebkitColumnFill: if (valueID == CSSValueAuto || valueID == CSSValueBalance) return true; break; - case CSSPropertyFlexDirection: + case CSSPropertyWebkitAlignContent: + if (valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround || valueID == CSSValueStretch) + return true; + break; + case CSSPropertyWebkitAlignItems: + if (valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch) + return true; + break; + case CSSPropertyWebkitAlignSelf: + if (valueID == CSSValueAuto || valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch) + return true; + break; + case CSSPropertyWebkitFlexDirection: if (valueID == CSSValueRow || valueID == CSSValueRowReverse || valueID == CSSValueColumn || valueID == CSSValueColumnReverse) return true; break; - case CSSPropertyFlexWrap: + case CSSPropertyWebkitFlexWrap: if (valueID == CSSValueNowrap || valueID == CSSValueWrap || valueID == CSSValueWrapReverse) return true; break; + case CSSPropertyWebkitJustifyContent: + if (valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround) + return true; + break; case CSSPropertyWebkitFontKerning: if (valueID == CSSValueAuto || valueID == CSSValueNormal || valueID == CSSValueNone) return true; @@ -876,6 +886,10 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int if (valueID == CSSValueNone || valueID == CSSValueManual || valueID == CSSValueAuto) return true; break; + case CSSPropertyWebkitGridAutoFlow: + if (valueID == CSSValueNone || valueID == CSSValueRow || valueID == CSSValueColumn) + return true; + break; case CSSPropertyWebkitLineAlign: if (valueID == CSSValueNone || valueID == CSSValueEdges) return true; @@ -939,7 +953,7 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int break; case CSSPropertyWebkitRubyPosition: - if (valueID == CSSValueBefore || valueID == CSSValueAfter || valueID == CSSValueInterCharacter) + if (valueID == CSSValueBefore || valueID == CSSValueAfter) return true; break; @@ -956,8 +970,8 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int break; #if ENABLE(CSS3_TEXT) case CSSPropertyWebkitTextJustify: - // auto | none | inter-word | distribute - if (valueID == CSSValueInterWord || valueID == CSSValueDistribute || valueID == CSSValueAuto || valueID == CSSValueNone) + // auto | none | inter-word | inter-ideograph | inter-cluster | distribute | kashida + if ((valueID >= CSSValueInterWord && valueID <= CSSValueKashida) || valueID == CSSValueAuto || valueID == CSSValueNone) return true; break; #endif // CSS3_TEXT @@ -972,7 +986,6 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int return true; break; #endif - case CSSPropertyTransformStyle: case CSSPropertyWebkitTransformStyle: if (valueID == CSSValueFlat || valueID == CSSValuePreserve3d) return true; @@ -982,72 +995,43 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int return true; break; case CSSPropertyWebkitUserModify: // read-only | read-write - if (valueID == CSSValueReadOnly || valueID == CSSValueReadWrite || valueID == CSSValueReadWritePlaintextOnly) { - if (styleSheetContents) - styleSheetContents->parserSetUsesStyleBasedEditability(); + if (valueID == CSSValueReadOnly || valueID == CSSValueReadWrite || valueID == CSSValueReadWritePlaintextOnly) return true; - } break; case CSSPropertyWebkitUserSelect: // auto | none | text | all - if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueText) - return true; - if (valueID == CSSValueAll) { - if (styleSheetContents) - styleSheetContents->parserSetUsesStyleBasedEditability(); - return true; - } - break; - case CSSPropertyWebkitWritingMode: - if (valueID >= CSSValueHorizontalTb && valueID <= CSSValueHorizontalBt) - return true; - break; - case CSSPropertyWhiteSpace: // normal | pre | nowrap | inherit - if (valueID == CSSValueNormal || valueID == CSSValuePre || valueID == CSSValuePreWrap || valueID == CSSValuePreLine || valueID == CSSValueNowrap) + if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueText || valueID == CSSValueAll) return true; break; - case CSSPropertyWordBreak: // normal | break-all | keep-all | break-word (this is a custom extension) - if (valueID == CSSValueNormal || valueID == CSSValueBreakAll || valueID == CSSValueKeepAll || valueID == CSSValueBreakWord) +#if ENABLE(CSS_EXCLUSIONS) + case CSSPropertyWebkitWrapFlow: + if (!RuntimeEnabledFeatures::sharedFeatures().cssExclusionsEnabled()) + return false; + if (valueID == CSSValueAuto || valueID == CSSValueBoth || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueMaximum || valueID == CSSValueClear) return true; break; -#if ENABLE(CSS_TRAILING_WORD) - case CSSPropertyAppleTrailingWord: // auto | -apple-partially-balanced - if (valueID == CSSValueAuto || valueID == CSSValueWebkitPartiallyBalanced) + case CSSPropertyWebkitWrapThrough: + if (!RuntimeEnabledFeatures::sharedFeatures().cssExclusionsEnabled()) + return false; + if (valueID == CSSValueWrap || valueID == CSSValueNone) return true; break; #endif - case CSSPropertyFontVariantPosition: // normal | sub | super - if (valueID == CSSValueNormal || valueID == CSSValueSub || valueID == CSSValueSuper) - return true; - break; - case CSSPropertyFontVariantCaps: // normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps - if (valueID == CSSValueNormal || valueID == CSSValueSmallCaps || valueID == CSSValueAllSmallCaps || valueID == CSSValuePetiteCaps || valueID == CSSValueAllPetiteCaps || valueID == CSSValueUnicase || valueID == CSSValueTitlingCaps) - return true; - break; - case CSSPropertyFontVariantAlternates: // We only support the normal and historical-forms values. - if (valueID == CSSValueNormal || valueID == CSSValueHistoricalForms) + case CSSPropertyWebkitWritingMode: + if (valueID >= CSSValueHorizontalTb && valueID <= CSSValueHorizontalBt) return true; break; - - case CSSPropertyBreakAfter: - case CSSPropertyBreakBefore: - // auto | avoid | left | right | recto | verso | column | page | region | avoid-page | avoid-column | avoid-region - if (valueID == CSSValueAuto || valueID == CSSValueAvoid || valueID == CSSValueLeft || valueID == CSSValueRight - || valueID == CSSValueRecto || valueID == CSSValueVerso || valueID == CSSValueColumn || valueID == CSSValuePage - || valueID == CSSValueRegion || valueID == CSSValueAvoidColumn || valueID == CSSValueAvoidPage || valueID == CSSValueAvoidRegion) + case CSSPropertyWhiteSpace: // normal | pre | nowrap | inherit + if (valueID == CSSValueNormal || valueID == CSSValuePre || valueID == CSSValuePreWrap || valueID == CSSValuePreLine || valueID == CSSValueNowrap) return true; break; - case CSSPropertyBreakInside: - // auto | avoid | avoid-page | avoid-column | avoid-region - if (valueID == CSSValueAuto || valueID == CSSValueAvoid || valueID == CSSValueAvoidColumn || valueID == CSSValueAvoidPage || valueID == CSSValueAvoidRegion) + case CSSPropertyWordBreak: // normal | break-all | break-word (this is a custom extension) + if (valueID == CSSValueNormal || valueID == CSSValueBreakAll || valueID == CSSValueBreakWord) return true; break; default: ASSERT_NOT_REACHED(); return false; } -#if !ENABLE(CSS_COMPOSITING) && !ENABLE(CSS_REGIONS) - UNUSED_PARAM(parserContext); -#endif return false; } @@ -1060,9 +1044,6 @@ static inline bool isKeywordPropertyID(CSSPropertyID propertyId) case CSSPropertyBorderRightStyle: case CSSPropertyBorderTopStyle: case CSSPropertyBoxSizing: - case CSSPropertyBreakAfter: - case CSSPropertyBreakBefore: - case CSSPropertyBreakInside: case CSSPropertyCaptionSide: case CSSPropertyClear: case CSSPropertyDirection: @@ -1098,8 +1079,7 @@ static inline bool isKeywordPropertyID(CSSPropertyID propertyId) case CSSPropertyVisibility: case CSSPropertyWebkitAppearance: #if ENABLE(CSS_COMPOSITING) - case CSSPropertyMixBlendMode: - case CSSPropertyIsolation: + case CSSPropertyWebkitBlendMode: #endif case CSSPropertyWebkitBackfaceVisibility: case CSSPropertyWebkitBorderAfterStyle: @@ -1115,16 +1095,22 @@ static inline bool isKeywordPropertyID(CSSPropertyID propertyId) case CSSPropertyWebkitBoxLines: case CSSPropertyWebkitBoxOrient: case CSSPropertyWebkitBoxPack: + case CSSPropertyWebkitColorCorrection: case CSSPropertyWebkitColumnBreakAfter: case CSSPropertyWebkitColumnBreakBefore: case CSSPropertyWebkitColumnBreakInside: - case CSSPropertyColumnFill: - case CSSPropertyColumnRuleStyle: - case CSSPropertyFlexDirection: - case CSSPropertyFlexWrap: + case CSSPropertyWebkitColumnFill: + case CSSPropertyWebkitColumnRuleStyle: + case CSSPropertyWebkitAlignContent: + case CSSPropertyWebkitAlignItems: + case CSSPropertyWebkitAlignSelf: + case CSSPropertyWebkitFlexDirection: + case CSSPropertyWebkitFlexWrap: + case CSSPropertyWebkitJustifyContent: case CSSPropertyWebkitFontKerning: case CSSPropertyWebkitFontSmoothing: case CSSPropertyWebkitHyphens: + case CSSPropertyWebkitGridAutoFlow: case CSSPropertyWebkitLineAlign: case CSSPropertyWebkitLineBreak: case CSSPropertyWebkitLineSnap: @@ -1155,53 +1141,37 @@ static inline bool isKeywordPropertyID(CSSPropertyID propertyId) case CSSPropertyWebkitTextJustify: #endif // CSS3_TEXT case CSSPropertyWebkitTextSecurity: - case CSSPropertyTransformStyle: case CSSPropertyWebkitTransformStyle: case CSSPropertyWebkitUserDrag: case CSSPropertyWebkitUserModify: case CSSPropertyWebkitUserSelect: +#if ENABLE(CSS_EXCLUSIONS) + case CSSPropertyWebkitWrapFlow: + case CSSPropertyWebkitWrapThrough: +#endif case CSSPropertyWebkitWritingMode: case CSSPropertyWhiteSpace: case CSSPropertyWordBreak: case CSSPropertyWordWrap: -#if ENABLE(TOUCH_EVENTS) - case CSSPropertyTouchAction: -#endif -#if ENABLE(CSS_SCROLL_SNAP) - case CSSPropertyWebkitScrollSnapType: -#endif -#if ENABLE(CSS_TRAILING_WORD) - case CSSPropertyAppleTrailingWord: -#endif - case CSSPropertyFontVariantPosition: - case CSSPropertyFontVariantCaps: - case CSSPropertyFontVariantAlternates: return true; default: return false; } } -static bool isUniversalKeyword(const String& string) -{ - // These keywords can be used for all properties. - return equalLettersIgnoringASCIICase(string, "initial") - || equalLettersIgnoringASCIICase(string, "inherit") - || equalLettersIgnoringASCIICase(string, "unset") - || equalLettersIgnoringASCIICase(string, "revert"); -} - -static CSSParser::ParseResult parseKeywordValue(MutableStyleProperties* declaration, CSSPropertyID propertyId, const String& string, bool important, const CSSParserContext& parserContext, StyleSheetContents* styleSheetContents) +static bool parseKeywordValue(MutableStyleProperties* declaration, CSSPropertyID propertyId, const String& string, bool important, const CSSParserContext& parserContext) { ASSERT(!string.isEmpty()); if (!isKeywordPropertyID(propertyId)) { - if (!isUniversalKeyword(string)) - return CSSParser::ParseResult::Error; + // All properties accept the values of "initial" and "inherit". + String lowerCaseString = string.lower(); + if (lowerCaseString != "initial" && lowerCaseString != "inherit") + return false; - // Don't try to parse initial/inherit/unset/revert shorthands; return an error so the caller will use the full CSS parser. + // Parse initial/inherit shorthands using the CSSParser. if (shorthandForProperty(propertyId).length()) - return CSSParser::ParseResult::Error; + return false; } CSSParserString cssString; @@ -1209,29 +1179,25 @@ static CSSParser::ParseResult parseKeywordValue(MutableStyleProperties* declarat CSSValueID valueID = cssValueKeywordID(cssString); if (!valueID) - return CSSParser::ParseResult::Error; + return false; RefPtr<CSSValue> value; if (valueID == CSSValueInherit) - value = CSSValuePool::singleton().createInheritedValue(); + value = cssValuePool().createInheritedValue(); else if (valueID == CSSValueInitial) - value = CSSValuePool::singleton().createExplicitInitialValue(); - else if (valueID == CSSValueUnset) - value = CSSValuePool::singleton().createUnsetValue(); - else if (valueID == CSSValueRevert) - value = CSSValuePool::singleton().createRevertValue(); - else if (isValidKeywordPropertyAndValue(propertyId, valueID, parserContext, styleSheetContents)) - value = CSSValuePool::singleton().createIdentifierValue(valueID); + value = cssValuePool().createExplicitInitialValue(); + else if (isValidKeywordPropertyAndValue(propertyId, valueID, parserContext)) + value = cssValuePool().createIdentifierValue(valueID); else - return CSSParser::ParseResult::Error; + return false; - return declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged; + declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important)); + return true; } template <typename CharacterType> -static bool parseTransformTranslateArguments(WebKitCSSTransformValue& transformValue, CharacterType* characters, unsigned length, unsigned start, unsigned expectedCount) +static bool parseTransformArguments(WebKitCSSTransformValue* transformValue, CharacterType* characters, unsigned length, unsigned start, unsigned expectedCount) { - auto& cssValuePool = CSSValuePool::singleton(); while (expectedCount) { size_t end = WTF::find(characters, length, expectedCount == 1 ? ')' : ',', start); if (end == notFound || (expectedCount == 1 && end != length - 1)) @@ -1243,26 +1209,23 @@ static bool parseTransformTranslateArguments(WebKitCSSTransformValue& transformV return false; if (unit != CSSPrimitiveValue::CSS_PX && (number || unit != CSSPrimitiveValue::CSS_NUMBER)) return false; - transformValue.append(cssValuePool.createValue(number, CSSPrimitiveValue::CSS_PX)); + transformValue->append(cssValuePool().createValue(number, unit)); start = end + 1; --expectedCount; } return true; } -static CSSParser::ParseResult parseTranslateTransformValue(MutableStyleProperties* properties, CSSPropertyID propertyID, const String& string, bool important) +static bool parseTranslateTransformValue(MutableStyleProperties* properties, CSSPropertyID propertyID, const String& string, bool important) { - if (propertyID != CSSPropertyTransform) - return CSSParser::ParseResult::Error; - + if (propertyID != CSSPropertyWebkitTransform) + return false; static const unsigned shortestValidTransformStringLength = 12; static const unsigned likelyMultipartTransformStringLengthCutoff = 32; if (string.length() < shortestValidTransformStringLength || string.length() > likelyMultipartTransformStringLengthCutoff) - return CSSParser::ParseResult::Error; - + return false; if (!string.startsWith("translate", false)) - return CSSParser::ParseResult::Error; - + return false; UChar c9 = toASCIILower(string[9]); UChar c10 = toASCIILower(string[10]); @@ -1284,63 +1247,43 @@ static CSSParser::ParseResult parseTranslateTransformValue(MutableStylePropertie expectedArgumentCount = 3; argumentStart = 12; } else - return CSSParser::ParseResult::Error; + return false; RefPtr<WebKitCSSTransformValue> transformValue = WebKitCSSTransformValue::create(transformType); bool success; if (string.is8Bit()) - success = parseTransformTranslateArguments(*transformValue, string.characters8(), string.length(), argumentStart, expectedArgumentCount); + success = parseTransformArguments(transformValue.get(), string.characters8(), string.length(), argumentStart, expectedArgumentCount); else - success = parseTransformTranslateArguments(*transformValue, string.characters16(), string.length(), argumentStart, expectedArgumentCount); + success = parseTransformArguments(transformValue.get(), string.characters16(), string.length(), argumentStart, expectedArgumentCount); if (!success) - return CSSParser::ParseResult::Error; - + return false; RefPtr<CSSValueList> result = CSSValueList::createSpaceSeparated(); - result->append(transformValue.releaseNonNull()); - return properties->addParsedProperty(CSSProperty(CSSPropertyTransform, result.release(), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged; + result->append(transformValue.release()); + properties->addParsedProperty(CSSProperty(CSSPropertyWebkitTransform, result.release(), important)); + return true; } -RefPtr<CSSValueList> CSSParser::parseFontFaceValue(const AtomicString& string) +PassRefPtr<CSSValueList> CSSParser::parseFontFaceValue(const AtomicString& string) { if (string.isEmpty()) - return nullptr; - - Ref<CSSValueList> valueList = CSSValueList::createCommaSeparated(); - - Vector<String> familyNames; - string.string().split(',', true, familyNames); - - auto& cssValuePool = CSSValuePool::singleton(); - for (auto& familyName : familyNames) { - String stripped = stripLeadingAndTrailingHTMLSpaces(familyName); - if (stripped.isEmpty()) - return nullptr; - - RefPtr<CSSValue> value; - for (auto propertyID : { CSSValueSerif, CSSValueSansSerif, CSSValueCursive, CSSValueFantasy, CSSValueMonospace, CSSValueWebkitBody }) { - if (equalIgnoringASCIICase(stripped, getValueName(propertyID))) { - value = cssValuePool.createIdentifierValue(propertyID); - break; - } - } - if (!value) - value = cssValuePool.createFontFamilyValue(stripped); - valueList->append(value.releaseNonNull()); - } + return 0; + RefPtr<MutableStyleProperties> dummyStyle = MutableStyleProperties::create(); + if (!parseValue(dummyStyle.get(), CSSPropertyFontFamily, string, false, CSSQuirksMode, 0)) + return 0; - return WTFMove(valueList); + RefPtr<CSSValue> fontFamily = dummyStyle->getPropertyCSSValue(CSSPropertyFontFamily); + if (!fontFamily->isValueList()) + return 0; // FIXME: "initial" and "inherit" should be parsed as font names in the face attribute. + return static_pointer_cast<CSSValueList>(fontFamily.release()); } -CSSParser::ParseResult CSSParser::parseValue(MutableStyleProperties* declaration, CSSPropertyID propertyID, const String& string, bool important, CSSParserMode cssParserMode, StyleSheetContents* contextStyleSheet) +bool CSSParser::parseValue(MutableStyleProperties* declaration, CSSPropertyID propertyID, const String& string, bool important, CSSParserMode cssParserMode, StyleSheetContents* contextStyleSheet) { ASSERT(!string.isEmpty()); - CSSParser::ParseResult result = parseSimpleLengthValue(declaration, propertyID, string, important, cssParserMode); - if (result != ParseResult::Error) - return result; - - result = parseColorValue(declaration, propertyID, string, important, cssParserMode); - if (result != ParseResult::Error) - return result; + if (parseSimpleLengthValue(declaration, propertyID, string, important, cssParserMode)) + return true; + if (parseColorValue(declaration, propertyID, string, important, cssParserMode)) + return true; CSSParserContext context(cssParserMode); if (contextStyleSheet) { @@ -1348,32 +1291,16 @@ CSSParser::ParseResult CSSParser::parseValue(MutableStyleProperties* declaration context.mode = cssParserMode; } - result = parseKeywordValue(declaration, propertyID, string, important, context, contextStyleSheet); - if (result != ParseResult::Error) - return result; - - result = parseTranslateTransformValue(declaration, propertyID, string, important); - if (result != ParseResult::Error) - return result; + if (parseKeywordValue(declaration, propertyID, string, important, context)) + return true; + if (parseTranslateTransformValue(declaration, propertyID, string, important)) + return true; CSSParser parser(context); return parser.parseValue(declaration, propertyID, string, important, contextStyleSheet); } -CSSParser::ParseResult CSSParser::parseCustomPropertyValue(MutableStyleProperties* declaration, const AtomicString& propertyName, const String& string, bool important, CSSParserMode cssParserMode, StyleSheetContents* contextStyleSheet) -{ - CSSParserContext context(cssParserMode); - if (contextStyleSheet) { - context = contextStyleSheet->parserContext(); - context.mode = cssParserMode; - } - - CSSParser parser(context); - parser.setCustomPropertyName(propertyName); - return parser.parseValue(declaration, CSSPropertyCustom, string, important, contextStyleSheet); -} - -CSSParser::ParseResult CSSParser::parseValue(MutableStyleProperties* declaration, CSSPropertyID propertyID, const String& string, bool important, StyleSheetContents* contextStyleSheet) +bool CSSParser::parseValue(MutableStyleProperties* declaration, CSSPropertyID propertyID, const String& string, bool important, StyleSheetContents* contextStyleSheet) { setStyleSheet(contextStyleSheet); @@ -1384,25 +1311,24 @@ CSSParser::ParseResult CSSParser::parseValue(MutableStyleProperties* declaration cssyyparse(this); - m_rule = nullptr; - - ParseResult result = ParseResult::Error; + m_rule = 0; + bool ok = false; + if (m_hasFontFaceOnlyValues) + deleteFontFaceOnlyValues(); if (!m_parsedProperties.isEmpty()) { - result = declaration->addParsedProperties(m_parsedProperties) ? ParseResult::Changed : ParseResult::Unchanged; + ok = true; + declaration->addParsedProperties(m_parsedProperties); clearProperties(); } - return result; + return ok; } // The color will only be changed when string contains a valid CSS color, so callers // can set it to a default color and ignore the boolean result. bool CSSParser::parseColor(RGBA32& color, const String& string, bool strict) { - if (string.isEmpty()) - return false; - // First try creating a color specified by name, rgba(), rgb() or "#" syntax. if (fastParseColor(color, string, strict)) return true; @@ -1413,15 +1339,15 @@ bool CSSParser::parseColor(RGBA32& color, const String& string, bool strict) if (!parser.parseColor(string)) return false; - CSSValue& value = *parser.m_parsedProperties.first().value(); - if (!is<CSSPrimitiveValue>(value)) + CSSValue* value = parser.m_parsedProperties.first().value(); + if (!value->isPrimitiveValue()) return false; - CSSPrimitiveValue& primitiveValue = downcast<CSSPrimitiveValue>(value); - if (!primitiveValue.isRGBColor()) + CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); + if (!primitiveValue->isRGBColor()) return false; - color = primitiveValue.getRGBA32Value(); + color = primitiveValue->getRGBA32Value(); return true; } @@ -1429,7 +1355,7 @@ bool CSSParser::parseColor(const String& string) { setupParser("@-webkit-decls{color:", string, "} "); cssyyparse(this); - m_rule = nullptr; + m_rule = 0; return !m_parsedProperties.isEmpty() && m_parsedProperties.first().id() == CSSPropertyColor; } @@ -1442,14 +1368,10 @@ bool CSSParser::parseSystemColor(RGBA32& color, const String& string, Document* CSSParserString cssColor; cssColor.init(string); CSSValueID id = cssValueKeywordID(cssColor); - if (!validPrimitiveValueColor(id)) - return false; - - Color parsedColor = document->page()->theme().systemColor(id); - if (!parsedColor.isValid()) + if (id <= 0) return false; - color = parsedColor.rgb(); + color = document->page()->theme().systemColor(id).rgb(); return true; } @@ -1461,25 +1383,28 @@ void CSSParser::parseSelector(const String& string, CSSSelectorList& selectorLis cssyyparse(this); - m_selectorListForParseSelector = nullptr; + m_selectorListForParseSelector = 0; } -Ref<ImmutableStyleProperties> CSSParser::parseInlineStyleDeclaration(const String& string, Element* element) +PassRef<ImmutableStyleProperties> CSSParser::parseInlineStyleDeclaration(const String& string, Element* element) { CSSParserContext context = element->document().elementSheet().contents().parserContext(); context.mode = strictToCSSParserMode(element->isHTMLElement() && !element->document().inQuirksMode()); return CSSParser(context).parseDeclaration(string, &element->document().elementSheet().contents()); } -Ref<ImmutableStyleProperties> CSSParser::parseDeclaration(const String& string, StyleSheetContents* contextStyleSheet) +PassRef<ImmutableStyleProperties> CSSParser::parseDeclaration(const String& string, StyleSheetContents* contextStyleSheet) { setStyleSheet(contextStyleSheet); setupParser("@-webkit-decls{", string, "} "); cssyyparse(this); - m_rule = nullptr; + m_rule = 0; - Ref<ImmutableStyleProperties> style = createStyleProperties(); + if (m_hasFontFaceOnlyValues) + deleteFontFaceOnlyValues(); + + PassRef<ImmutableStyleProperties> style = createStyleProperties(); clearProperties(); return style; } @@ -1494,15 +1419,17 @@ bool CSSParser::parseDeclaration(MutableStyleProperties* declaration, const Stri RefPtr<CSSRuleSourceData> ruleSourceData = prpRuleSourceData; if (ruleSourceData) { - m_currentRuleDataStack = std::make_unique<RuleSourceDataList>(); + m_currentRuleDataStack = adoptPtr(new RuleSourceDataList()); m_currentRuleDataStack->append(ruleSourceData); } setupParser("@-webkit-decls{", string, "} "); cssyyparse(this); - m_rule = nullptr; + m_rule = 0; bool ok = false; + if (m_hasFontFaceOnlyValues) + deleteFontFaceOnlyValues(); if (!m_parsedProperties.isEmpty()) { ok = true; declaration->addParsedProperties(m_parsedProperties); @@ -1520,13 +1447,13 @@ bool CSSParser::parseDeclaration(MutableStyleProperties* declaration, const Stri } fixUnparsedPropertyRanges(ruleSourceData.get()); - m_currentRuleDataStack.reset(); + m_currentRuleDataStack.clear(); } return ok; } -std::unique_ptr<MediaQuery> CSSParser::parseMediaQuery(const String& string) +PassOwnPtr<MediaQuery> CSSParser::parseMediaQuery(const String& string) { if (string.isEmpty()) return nullptr; @@ -1538,97 +1465,33 @@ std::unique_ptr<MediaQuery> CSSParser::parseMediaQuery(const String& string) setupParser("@-webkit-mediaquery ", string, "} "); cssyyparse(this); - return WTFMove(m_mediaQuery); + return m_mediaQuery.release(); } -Vector<CSSParser::SourceSize> CSSParser::parseSizesAttribute(StringView string) -{ - Vector<SourceSize> result; - - if (string.isEmpty()) - return result; - - ASSERT(!m_sourceSizeList); - - setupParser("@-webkit-sizesattr ", string, "}"); - cssyyparse(this); - - if (!m_sourceSizeList) - return result; - - result = WTFMove(*m_sourceSizeList); - m_sourceSizeList = nullptr; - return result; -} - -// FIXME(141289): The following two constructors are only needed because of a bug in MSVC 2013 (and prior). -// We should remove this code as soon as a Visual Studio update that fixes this problem is released. -CSSParser::SourceSize::SourceSize(CSSParser::SourceSize&& original) - : expression(WTFMove(original.expression)) - , length(original.length) -{ -} - -CSSParser::SourceSize::SourceSize(std::unique_ptr<MediaQueryExp>&& origExp, RefPtr<CSSValue> value) - : expression(WTFMove(origExp)) - , length(value) -{ -} - -CSSParser::SourceSize CSSParser::sourceSize(std::unique_ptr<MediaQueryExp>&& expression, CSSParserValue& parserValue) -{ - RefPtr<CSSValue> value; - if (isCalculation(parserValue)) { - auto* args = parserValue.function->args.get(); - if (args && args->size()) - value = CSSCalcValue::create(parserValue.function->name, *args, CalculationRangeNonNegative); - } - if (!value) - value = parserValue.createCSSValue(); - destroy(parserValue); - // FIXME: Calling the constructor explicitly here to work around an MSVC bug. - // For other compilers, we did not need to define the constructors and we could use aggregate initialization syntax. - return SourceSize(WTFMove(expression), WTFMove(value)); -} - -static inline void filterProperties(bool important, const CSSParser::ParsedPropertyVector& input, Vector<CSSProperty, 256>& output, size_t& unusedEntries, std::bitset<numCSSProperties>& seenProperties, HashSet<AtomicString>& seenCustomProperties) +static inline void filterProperties(bool important, const CSSParser::ParsedPropertyVector& input, Vector<CSSProperty, 256>& output, size_t& unusedEntries, std::bitset<numCSSProperties>& seenProperties) { // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found. for (int i = input.size() - 1; i >= 0; --i) { const CSSProperty& property = input[i]; if (property.isImportant() != important) continue; - - if (property.id() == CSSPropertyCustom) { - if (property.value()) { - const AtomicString& name = downcast<CSSCustomPropertyValue>(*property.value()).name(); - if (seenCustomProperties.contains(name)) - continue; - seenCustomProperties.add(name); - output[--unusedEntries] = property; - } - continue; - } - const unsigned propertyIDIndex = property.id() - firstCSSProperty; - ASSERT(propertyIDIndex < seenProperties.size()); - if (seenProperties[propertyIDIndex]) + if (seenProperties.test(propertyIDIndex)) continue; seenProperties.set(propertyIDIndex); output[--unusedEntries] = property; } } -Ref<ImmutableStyleProperties> CSSParser::createStyleProperties() +PassRef<ImmutableStyleProperties> CSSParser::createStyleProperties() { std::bitset<numCSSProperties> seenProperties; size_t unusedEntries = m_parsedProperties.size(); Vector<CSSProperty, 256> results(unusedEntries); // Important properties have higher priority, so add them first. Duplicate definitions can then be ignored when found. - HashSet<AtomicString> seenCustomProperties; - filterProperties(true, m_parsedProperties, results, unusedEntries, seenProperties, seenCustomProperties); - filterProperties(false, m_parsedProperties, results, unusedEntries, seenProperties, seenCustomProperties); + filterProperties(true, m_parsedProperties, results, unusedEntries, seenProperties); + filterProperties(false, m_parsedProperties, results, unusedEntries, seenProperties); if (unusedEntries) results.remove(0, unusedEntries); @@ -1679,6 +1542,7 @@ void CSSParser::clearProperties() { m_parsedProperties.clear(); m_numParsedPropertiesBeforeMarginBox = INVALID_NUM_PARSED_PROPERTIES; + m_hasFontFaceOnlyValues = false; } URL CSSParser::completeURL(const CSSParserContext& context, const String& url) @@ -1695,86 +1559,71 @@ URL CSSParser::completeURL(const String& url) const return completeURL(m_context, url); } -bool CSSParser::validateCalculationUnit(ValueWithCalculation& valueWithCalculation, Units unitFlags) +bool CSSParser::validCalculationUnit(CSSParserValue* value, Units unitflags, ReleaseParsedCalcValueCondition releaseCalc) { - bool mustBeNonNegative = unitFlags & FNonNeg; + bool mustBeNonNegative = unitflags & FNonNeg; - RefPtr<CSSCalcValue> calculation; - if (valueWithCalculation.calculation()) { - // The calculation value was already parsed so we reuse it. However, we may need to update its range. - calculation = valueWithCalculation.calculation(); - calculation->setPermittedValueRange(mustBeNonNegative ? CalculationRangeNonNegative : CalculationRangeAll); - } else { - valueWithCalculation.setCalculation(parseCalculation(valueWithCalculation, mustBeNonNegative ? CalculationRangeNonNegative : CalculationRangeAll)); - calculation = valueWithCalculation.calculation(); - if (!calculation) - return false; - } + if (!parseCalculation(value, mustBeNonNegative ? CalculationRangeNonNegative : CalculationRangeAll)) + return false; - bool isValid = false; - switch (calculation->category()) { - case CalcNumber: - isValid = (unitFlags & FNumber); - if (!isValid && (unitFlags & FInteger) && calculation->isInt()) - isValid = true; - if (!isValid && (unitFlags & FPositiveInteger) && calculation->isInt() && calculation->isPositive()) - isValid = true; - break; + bool b = false; + switch (m_parsedCalculation->category()) { case CalcLength: - isValid = (unitFlags & FLength); + b = (unitflags & FLength); break; case CalcPercent: - isValid = (unitFlags & FPercent); + b = (unitflags & FPercent); + if (b && mustBeNonNegative && m_parsedCalculation->isNegative()) + b = false; + break; + case CalcNumber: + b = (unitflags & FNumber); + if (!b && (unitflags & FInteger) && m_parsedCalculation->isInt()) + b = true; + if (b && mustBeNonNegative && m_parsedCalculation->isNegative()) + b = false; break; case CalcPercentLength: - isValid = (unitFlags & FPercent) && (unitFlags & FLength); + b = (unitflags & FPercent) && (unitflags & FLength); break; case CalcPercentNumber: - isValid = (unitFlags & FPercent) && (unitFlags & FNumber); - break; - case CalcAngle: - isValid = (unitFlags & FAngle); - break; - case CalcTime: - isValid = (unitFlags & FTime); - break; - case CalcFrequency: - isValid = (unitFlags & FFrequency); + b = (unitflags & FPercent) && (unitflags & FNumber); break; case CalcOther: break; } - - return isValid; + if (!b || releaseCalc == ReleaseParsedCalcValue) + m_parsedCalculation.release(); + return b; } -inline bool CSSParser::shouldAcceptUnitLessValues(CSSParserValue& value, Units unitFlags, CSSParserMode cssParserMode) +inline bool CSSParser::shouldAcceptUnitLessValues(CSSParserValue* value, Units unitflags, CSSParserMode cssParserMode) { // Qirks mode and svg presentation attributes accept unit less values. - return (unitFlags & (FLength | FAngle | FTime)) && (!value.fValue || cssParserMode == CSSQuirksMode || cssParserMode == SVGAttributeMode); + return (unitflags & (FLength | FAngle | FTime)) && (!value->fValue || cssParserMode == CSSQuirksMode || cssParserMode == SVGAttributeMode); } -bool CSSParser::validateUnit(ValueWithCalculation& valueWithCalculation, Units unitFlags, CSSParserMode cssParserMode) +bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, CSSParserMode cssParserMode, ReleaseParsedCalcValueCondition releaseCalc) { - if (isCalculation(valueWithCalculation)) - return validateCalculationUnit(valueWithCalculation, unitFlags); + if (isCalculation(value)) + return validCalculationUnit(value, unitflags, releaseCalc); bool b = false; - switch (valueWithCalculation.value().unit) { + switch (value->unit) { case CSSPrimitiveValue::CSS_NUMBER: - b = (unitFlags & FNumber); - if (!b && shouldAcceptUnitLessValues(valueWithCalculation, unitFlags, cssParserMode)) { - valueWithCalculation.value().unit = (unitFlags & FLength) ? CSSPrimitiveValue::CSS_PX : - ((unitFlags & FAngle) ? CSSPrimitiveValue::CSS_DEG : CSSPrimitiveValue::CSS_MS); + b = (unitflags & FNumber); + if (!b && shouldAcceptUnitLessValues(value, unitflags, cssParserMode)) { + value->unit = (unitflags & FLength) ? CSSPrimitiveValue::CSS_PX : + ((unitflags & FAngle) ? CSSPrimitiveValue::CSS_DEG : CSSPrimitiveValue::CSS_MS); b = true; } - if (!b && (unitFlags & FInteger) && valueWithCalculation.value().isInt) + if (!b && (unitflags & FInteger) && value->isInt) b = true; - if (!b && (unitFlags & FPositiveInteger) && valueWithCalculation.value().isInt && valueWithCalculation.value().fValue > 0) + if (!b && (unitflags & FPositiveInteger) && value->isInt && value->fValue > 0) b = true; break; case CSSPrimitiveValue::CSS_PERCENTAGE: - b = (unitFlags & FPercent); + b = (unitflags & FPercent); break; case CSSParserValue::Q_EMS: case CSSPrimitiveValue::CSS_EMS: @@ -1791,23 +1640,23 @@ bool CSSParser::validateUnit(ValueWithCalculation& valueWithCalculation, Units u case CSSPrimitiveValue::CSS_VH: case CSSPrimitiveValue::CSS_VMIN: case CSSPrimitiveValue::CSS_VMAX: - b = (unitFlags & FLength); + b = (unitflags & FLength); break; case CSSPrimitiveValue::CSS_MS: case CSSPrimitiveValue::CSS_S: - b = (unitFlags & FTime); + b = (unitflags & FTime); break; case CSSPrimitiveValue::CSS_DEG: case CSSPrimitiveValue::CSS_RAD: case CSSPrimitiveValue::CSS_GRAD: case CSSPrimitiveValue::CSS_TURN: - b = (unitFlags & FAngle); + b = (unitflags & FAngle); break; #if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY) case CSSPrimitiveValue::CSS_DPPX: case CSSPrimitiveValue::CSS_DPI: case CSSPrimitiveValue::CSS_DPCM: - b = (unitFlags & FResolution); + b = (unitflags & FResolution); break; #endif case CSSPrimitiveValue::CSS_HZ: @@ -1816,36 +1665,35 @@ bool CSSParser::validateUnit(ValueWithCalculation& valueWithCalculation, Units u default: break; } - if (b && unitFlags & FNonNeg && valueWithCalculation.value().fValue < 0) - b = false; - if (b && std::isinf(valueWithCalculation.value().fValue)) + if (b && unitflags & FNonNeg && value->fValue < 0) b = false; return b; } -inline Ref<CSSPrimitiveValue> CSSParser::createPrimitiveNumericValue(ValueWithCalculation& valueWithCalculation) +inline PassRefPtr<CSSPrimitiveValue> CSSParser::createPrimitiveNumericValue(CSSParserValue* value) { - if (valueWithCalculation.calculation()) - return CSSPrimitiveValue::create(valueWithCalculation.calculation()); + if (m_parsedCalculation) { + ASSERT(isCalculation(value)); + return CSSPrimitiveValue::create(m_parsedCalculation.release()); + } - CSSParserValue& value = valueWithCalculation; #if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY) - ASSERT((value.unit >= CSSPrimitiveValue::CSS_NUMBER && value.unit <= CSSPrimitiveValue::CSS_KHZ) - || (value.unit >= CSSPrimitiveValue::CSS_TURN && value.unit <= CSSPrimitiveValue::CSS_CHS) - || (value.unit >= CSSPrimitiveValue::CSS_VW && value.unit <= CSSPrimitiveValue::CSS_VMAX) - || (value.unit >= CSSPrimitiveValue::CSS_DPPX && value.unit <= CSSPrimitiveValue::CSS_DPCM)); + ASSERT((value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ) + || (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_CHS) + || (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMAX) + || (value->unit >= CSSPrimitiveValue::CSS_DPPX && value->unit <= CSSPrimitiveValue::CSS_DPCM)); #else - ASSERT((value.unit >= CSSPrimitiveValue::CSS_NUMBER && value.unit <= CSSPrimitiveValue::CSS_KHZ) - || (value.unit >= CSSPrimitiveValue::CSS_TURN && value.unit <= CSSPrimitiveValue::CSS_CHS) - || (value.unit >= CSSPrimitiveValue::CSS_VW && value.unit <= CSSPrimitiveValue::CSS_VMAX)); + ASSERT((value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ) + || (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_CHS) + || (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMAX)); #endif - return CSSValuePool::singleton().createValue(value.fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value.unit)); + return cssValuePool().createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)); } -inline Ref<CSSPrimitiveValue> CSSParser::createPrimitiveStringValue(CSSParserValue& value) +inline PassRefPtr<CSSPrimitiveValue> CSSParser::createPrimitiveStringValue(CSSParserValue* value) { - ASSERT(value.unit == CSSPrimitiveValue::CSS_STRING || value.unit == CSSPrimitiveValue::CSS_IDENT); - return CSSValuePool::singleton().createValue(value.string, CSSPrimitiveValue::CSS_STRING); + ASSERT(value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT); + return cssValuePool().createValue(value->string, CSSPrimitiveValue::CSS_STRING); } static inline bool isComma(CSSParserValue* value) @@ -1853,42 +1701,51 @@ static inline bool isComma(CSSParserValue* value) return value && value->unit == CSSParserValue::Operator && value->iValue == ','; } -static inline bool isForwardSlashOperator(CSSParserValue& value) +static inline bool isForwardSlashOperator(CSSParserValue* value) { - return value.unit == CSSParserValue::Operator && value.iValue == '/'; + ASSERT(value); + return value->unit == CSSParserValue::Operator && value->iValue == '/'; } -bool CSSParser::isValidSize(ValueWithCalculation& valueWithCalculation) +bool CSSParser::validWidth(CSSParserValue* value) { - int id = valueWithCalculation.value().id; + int id = value->id; if (id == CSSValueIntrinsic || id == CSSValueMinIntrinsic || id == CSSValueWebkitMinContent || id == CSSValueWebkitMaxContent || id == CSSValueWebkitFillAvailable || id == CSSValueWebkitFitContent) return true; - return !id && validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg); + return !id && validUnit(value, FLength | FPercent | FNonNeg); +} + +// FIXME: Combine this with validWidth when we support fit-content, et al, for heights. +bool CSSParser::validHeight(CSSParserValue* value) +{ + int id = value->id; + if (id == CSSValueIntrinsic || id == CSSValueMinIntrinsic) + return true; + return !id && validUnit(value, FLength | FPercent | FNonNeg); } -inline RefPtr<CSSPrimitiveValue> CSSParser::parseValidPrimitive(CSSValueID identifier, ValueWithCalculation& valueWithCalculation) +inline PassRefPtr<CSSPrimitiveValue> CSSParser::parseValidPrimitive(CSSValueID identifier, CSSParserValue* value) { if (identifier) - return CSSValuePool::singleton().createIdentifierValue(identifier); - - if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_STRING) - return createPrimitiveStringValue(valueWithCalculation); - if (valueWithCalculation.value().unit >= CSSPrimitiveValue::CSS_NUMBER && valueWithCalculation.value().unit <= CSSPrimitiveValue::CSS_KHZ) - return createPrimitiveNumericValue(valueWithCalculation); - if (valueWithCalculation.value().unit >= CSSPrimitiveValue::CSS_TURN && valueWithCalculation.value().unit <= CSSPrimitiveValue::CSS_CHS) - return createPrimitiveNumericValue(valueWithCalculation); - if (valueWithCalculation.value().unit >= CSSPrimitiveValue::CSS_VW && valueWithCalculation.value().unit <= CSSPrimitiveValue::CSS_VMAX) - return createPrimitiveNumericValue(valueWithCalculation); + return cssValuePool().createIdentifierValue(identifier); + if (value->unit == CSSPrimitiveValue::CSS_STRING) + return createPrimitiveStringValue(value); + if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ) + return createPrimitiveNumericValue(value); + if (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_CHS) + return createPrimitiveNumericValue(value); + if (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMAX) + return createPrimitiveNumericValue(value); #if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY) - if (valueWithCalculation.value().unit >= CSSPrimitiveValue::CSS_DPPX && valueWithCalculation.value().unit <= CSSPrimitiveValue::CSS_DPCM) - return createPrimitiveNumericValue(valueWithCalculation); + if (value->unit >= CSSPrimitiveValue::CSS_DPPX && value->unit <= CSSPrimitiveValue::CSS_DPCM) + return createPrimitiveNumericValue(value); #endif - if (valueWithCalculation.value().unit >= CSSParserValue::Q_EMS) - return CSSPrimitiveValue::createAllowingMarginQuirk(valueWithCalculation.value().fValue, CSSPrimitiveValue::CSS_EMS); - if (valueWithCalculation.calculation()) - return CSSPrimitiveValue::create(valueWithCalculation.calculation()); + if (value->unit >= CSSParserValue::Q_EMS) + return CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS); + if (isCalculation(value)) + return CSSPrimitiveValue::create(m_parsedCalculation.release()); - return nullptr; + return 0; } void CSSParser::addExpandedPropertyForValue(CSSPropertyID propId, PassRefPtr<CSSValue> prpValue, bool important) @@ -1907,73 +1764,43 @@ void CSSParser::addExpandedPropertyForValue(CSSPropertyID propId, PassRefPtr<CSS addProperty(longhands[i], value, important); } -RefPtr<CSSValue> CSSParser::parseVariableDependentValue(CSSPropertyID propID, const CSSVariableDependentValue& dependentValue, const CustomPropertyValueMap& customProperties) -{ - m_valueList.reset(new CSSParserValueList()); - if (!dependentValue.valueList()->buildParserValueListSubstitutingVariables(m_valueList.get(), customProperties)) - return nullptr; - bool parsed = parseValue(dependentValue.propertyID(), false); - if (!parsed) - return nullptr; - for (size_t i = 0; i < m_parsedProperties.size(); ++i) { - if (m_parsedProperties[i].id() == propID) - return m_parsedProperties[i].value(); - } - return nullptr; -} - bool CSSParser::parseValue(CSSPropertyID propId, bool important) { - if (!m_valueList || !m_valueList->current()) + if (!m_valueList) return false; - - ValueWithCalculation valueWithCalculation(*m_valueList->current()); - CSSValueID id = valueWithCalculation.value().id; - - if (propId == CSSPropertyCustom) - return parseCustomPropertyDeclaration(important, id); - if (m_valueList->containsVariables()) { - RefPtr<CSSValueList> valueList = CSSValueList::createFromParserValueList(*m_valueList); - addExpandedPropertyForValue(propId, CSSVariableDependentValue::create(valueList, propId), important); - return true; - } + CSSParserValue* value = m_valueList->current(); + + if (!value) + return false; + + // Note: m_parsedCalculation is used to pass the calc value to validUnit and then cleared at the end of this function. + // FIXME: This is to avoid having to pass parsedCalc to all validUnit callers. + ASSERT(!m_parsedCalculation); + + CSSValueID id = value->id; - auto& cssValuePool = CSSValuePool::singleton(); unsigned num = inShorthand() ? 1 : m_valueList->size(); if (id == CSSValueInherit) { if (num != 1) return false; - addExpandedPropertyForValue(propId, cssValuePool.createInheritedValue(), important); + addExpandedPropertyForValue(propId, cssValuePool().createInheritedValue(), important); return true; } else if (id == CSSValueInitial) { if (num != 1) return false; - addExpandedPropertyForValue(propId, cssValuePool.createExplicitInitialValue(), important); - return true; - } else if (id == CSSValueUnset) { - if (num != 1) - return false; - addExpandedPropertyForValue(propId, cssValuePool.createUnsetValue(), important); - return true; - } else if (id == CSSValueRevert) { - if (num != 1) - return false; - addExpandedPropertyForValue(propId, cssValuePool.createRevertValue(), important); + addExpandedPropertyForValue(propId, cssValuePool().createExplicitInitialValue(), important); return true; } - - if (propId == CSSPropertyAll) - return false; // "all" doesn't allow you to specify anything other than inherit/initial/unset. if (isKeywordPropertyID(propId)) { - if (!isValidKeywordPropertyAndValue(propId, id, m_context, m_styleSheet)) + if (!isValidKeywordPropertyAndValue(propId, id, m_context)) return false; if (m_valueList->next() && !inShorthand()) return false; - addProperty(propId, cssValuePool.createIdentifierValue(id), important); + addProperty(propId, cssValuePool().createIdentifierValue(id), important); return true; } @@ -1990,7 +1817,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) return parseSize(propId, important); case CSSPropertyQuotes: // [<string> <string>]+ | none | inherit - if (id == CSSValueNone) + if (id) validPrimitive = true; else return parseQuotes(propId, important); @@ -2009,13 +1836,13 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) // close-quote | no-open-quote | no-close-quote ]+ | inherit return parseContent(propId, important); - case CSSPropertyAlt: // [ <string> | attr(X) ] + case CSSPropertyWebkitAlt: // [ <string> | attr(X) ] return parseAlt(propId, important); case CSSPropertyClip: // <shape> | auto | inherit if (id == CSSValueAuto) validPrimitive = true; - else if (valueWithCalculation.value().unit == CSSParserValue::Function) + else if (value->unit == CSSParserValue::Function) return parseClipShape(propId, important); break; @@ -2034,7 +1861,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) // pagination controls, it should default to hidden. If the overflow-y value is anything but // paged-x or paged-y, then overflow-x and overflow-y should have the same value. if (id == CSSValueWebkitPagedX || id == CSSValueWebkitPagedY) - overflowXValue = cssValuePool.createIdentifierValue(CSSValueAuto); + overflowXValue = cssValuePool().createIdentifierValue(CSSValueAuto); else overflowXValue = m_parsedProperties.last().value(); addProperty(CSSPropertyOverflowX, overflowXValue.release(), important); @@ -2054,10 +1881,6 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) return false; return parseFontWeight(important); } - - case CSSPropertyFontSynthesis: // none | [ weight || style ] - return parseFontSynthesis(important); - case CSSPropertyBorderSpacing: { if (num == 1) { ShorthandScope scope(this, CSSPropertyBorderSpacing); @@ -2077,7 +1900,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) } case CSSPropertyWebkitBorderHorizontalSpacing: case CSSPropertyWebkitBorderVerticalSpacing: - validPrimitive = validateUnit(valueWithCalculation, FLength | FNonNeg); + validPrimitive = validUnit(value, FLength | FNonNeg); break; case CSSPropertyOutlineColor: // <color> | invert | inherit // Outline color has "invert" as additional keyword. @@ -2100,7 +1923,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyTextLineThroughColor: // CSS3 text decoration colors case CSSPropertyTextUnderlineColor: case CSSPropertyTextOverlineColor: - case CSSPropertyColumnRuleColor: + case CSSPropertyWebkitColumnRuleColor: case CSSPropertyWebkitTextDecorationColor: case CSSPropertyWebkitTextEmphasisColor: case CSSPropertyWebkitTextFillColor: @@ -2110,8 +1933,8 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) // since we use this in our UA sheets. else if (id == CSSValueCurrentcolor) validPrimitive = true; - else if (isValidSystemColorValue(id) || id == CSSValueMenu - || (id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && inQuirksMode())) { + else if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || + (id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && inQuirksMode())) { validPrimitive = true; } else { parsedValue = parseColor(); @@ -2126,19 +1949,17 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) // [ auto | crosshair | default | pointer | progress | move | e-resize | ne-resize | // nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize | ew-resize | // ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | text | wait | help | - // vertical-text | cell | context-menu | alias | copy | no-drop | not-allowed | - // zoom-in | zoom-out | all-scroll | -webkit-grab | -webkit-grabbing | -webkit-zoom-in | - // -webkit-zoom-out ] ] | inherit + // vertical-text | cell | context-menu | alias | copy | no-drop | not-allowed | -webkit-zoom-in + // -webkit-zoom-out | all-scroll | -webkit-grab | -webkit-grabbing ] ] | inherit RefPtr<CSSValueList> list; - CSSParserValue* value = &valueWithCalculation.value(); while (value) { - RefPtr<CSSValue> image; + RefPtr<CSSValue> image = 0; if (value->unit == CSSPrimitiveValue::CSS_URI) { String uri = value->string; if (!uri.isNull()) image = CSSImageValue::create(completeURL(uri)); #if ENABLE(CSS_IMAGE_SET) && ENABLE(MOUSE_CURSOR_SCALE) - } else if (value->unit == CSSParserValue::Function && equalLettersIgnoringASCIICase(value->function->name, "-webkit-image-set(")) { + } else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "-webkit-image-set(")) { image = parseImageSet(); if (!image) break; @@ -2173,24 +1994,22 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) value = m_valueList->next(); // comma } if (list) { - if (!value) { - // no value after url list (MSIE 5 compatibility) + if (!value) { // no value after url list (MSIE 5 compatibility) if (list->length() != 1) return false; } else if (inQuirksMode() && value->id == CSSValueHand) // MSIE 5 compatibility :/ - list->append(cssValuePool.createIdentifierValue(CSSValuePointer)); - else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitZoomOut) || value->id == CSSValueCopy || value->id == CSSValueNone) - list->append(cssValuePool.createIdentifierValue(value->id)); + list->append(cssValuePool().createIdentifierValue(CSSValuePointer)); + else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone) + list->append(cssValuePool().createIdentifierValue(value->id)); m_valueList->next(); parsedValue = list.release(); break; } else if (value) { id = value->id; - if (inQuirksMode() && value->id == CSSValueHand) { - // MSIE 5 compatibility :/ + if (inQuirksMode() && value->id == CSSValueHand) { // MSIE 5 compatibility :/ id = CSSValuePointer; validPrimitive = true; - } else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitZoomOut) || value->id == CSSValueCopy || value->id == CSSValueNone) + } else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone) validPrimitive = true; } else { ASSERT_NOT_REACHED(); @@ -2207,7 +2026,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) #endif case CSSPropertyBackgroundAttachment: - case CSSPropertyBackgroundBlendMode: + case CSSPropertyWebkitBackgroundBlendMode: case CSSPropertyBackgroundClip: case CSSPropertyWebkitBackgroundClip: case CSSPropertyWebkitBackgroundComposite: @@ -2240,12 +2059,12 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) CSSPropertyID propId1, propId2; bool result = false; if (parseFillProperty(propId, propId1, propId2, val1, val2)) { - std::unique_ptr<ShorthandScope> shorthandScope; + OwnPtr<ShorthandScope> shorthandScope; if (propId == CSSPropertyBackgroundPosition || propId == CSSPropertyBackgroundRepeat || propId == CSSPropertyWebkitMaskPosition || propId == CSSPropertyWebkitMaskRepeat) { - shorthandScope = std::make_unique<ShorthandScope>(this, propId); + shorthandScope = adoptPtr(new ShorthandScope(this, propId)); } addProperty(propId1, val1.release(), important); if (val2) @@ -2259,19 +2078,19 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyBorderImageSource: case CSSPropertyWebkitMaskBoxImageSource: if (id == CSSValueNone) { - parsedValue = cssValuePool.createIdentifierValue(CSSValueNone); + parsedValue = cssValuePool().createIdentifierValue(CSSValueNone); m_valueList->next(); - } else if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_URI) { - parsedValue = CSSImageValue::create(completeURL(valueWithCalculation.value().string)); + } else if (value->unit == CSSPrimitiveValue::CSS_URI) { + parsedValue = CSSImageValue::create(completeURL(value->string)); m_valueList->next(); - } else if (isGeneratedImageValue(valueWithCalculation)) { - if (parseGeneratedImage(*m_valueList, parsedValue)) + } else if (isGeneratedImageValue(value)) { + if (parseGeneratedImage(m_valueList.get(), parsedValue)) m_valueList->next(); else return false; } #if ENABLE(CSS_IMAGE_SET) - else if (valueWithCalculation.value().unit == CSSParserValue::Function && equalLettersIgnoringASCIICase(valueWithCalculation.value().function->name, "-webkit-image-set(")) { + else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "-webkit-image-set(")) { parsedValue = parseImageSet(); if (!parsedValue) return false; @@ -2290,25 +2109,25 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyWebkitBorderEndWidth: case CSSPropertyWebkitBorderBeforeWidth: case CSSPropertyWebkitBorderAfterWidth: - case CSSPropertyColumnRuleWidth: + case CSSPropertyWebkitColumnRuleWidth: if (id == CSSValueThin || id == CSSValueMedium || id == CSSValueThick) validPrimitive = true; else - validPrimitive = validateUnit(valueWithCalculation, FLength | FNonNeg); + validPrimitive = validUnit(value, FLength | FNonNeg); break; case CSSPropertyLetterSpacing: // normal | <length> | inherit if (id == CSSValueNormal) validPrimitive = true; else - validPrimitive = validateUnit(valueWithCalculation, FLength); + validPrimitive = validUnit(value, FLength); break; case CSSPropertyWordSpacing: // normal | <length> | <percentage> | inherit if (id == CSSValueNormal) validPrimitive = true; else - validPrimitive = validateUnit(valueWithCalculation, FLength | FPercent); + validPrimitive = validUnit(value, FLength | FPercent); break; case CSSPropertyTextIndent: @@ -2323,33 +2142,45 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyWebkitPaddingEnd: case CSSPropertyWebkitPaddingBefore: case CSSPropertyWebkitPaddingAfter: - validPrimitive = (!id && validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg)); + validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg)); break; case CSSPropertyMaxWidth: case CSSPropertyWebkitMaxLogicalWidth: - case CSSPropertyMaxHeight: - case CSSPropertyWebkitMaxLogicalHeight: - validPrimitive = (id == CSSValueNone || isValidSize(valueWithCalculation)); + validPrimitive = (id == CSSValueNone || validWidth(value)); break; case CSSPropertyMinWidth: case CSSPropertyWebkitMinLogicalWidth: - case CSSPropertyMinHeight: - case CSSPropertyWebkitMinLogicalHeight: - validPrimitive = id == CSSValueAuto || isValidSize(valueWithCalculation); + validPrimitive = validWidth(value); break; case CSSPropertyWidth: case CSSPropertyWebkitLogicalWidth: + validPrimitive = (id == CSSValueAuto || validWidth(value)); + break; + + case CSSPropertyMaxHeight: + case CSSPropertyWebkitMaxLogicalHeight: + validPrimitive = (id == CSSValueNone || validHeight(value)); + break; + + case CSSPropertyMinHeight: + case CSSPropertyWebkitMinLogicalHeight: + validPrimitive = validHeight(value); + break; + case CSSPropertyHeight: case CSSPropertyWebkitLogicalHeight: - validPrimitive = (id == CSSValueAuto || isValidSize(valueWithCalculation)); + validPrimitive = (id == CSSValueAuto || validHeight(value)); break; case CSSPropertyFontSize: return parseFontSize(important); + case CSSPropertyFontVariant: // normal | small-caps | inherit + return parseFontVariant(important); + case CSSPropertyVerticalAlign: // baseline | sub | super | top | text-top | middle | bottom | text-bottom | // <percentage> | <length> | inherit @@ -2357,7 +2188,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) if (id >= CSSValueBaseline && id <= CSSValueWebkitBaselineMiddle) validPrimitive = true; else - validPrimitive = (!id && validateUnit(valueWithCalculation, FLength | FPercent)); + validPrimitive = (!id && validUnit(value, FLength | FPercent)); break; case CSSPropertyBottom: // <length> | <percentage> | auto | inherit @@ -2375,14 +2206,14 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) if (id == CSSValueAuto) validPrimitive = true; else - validPrimitive = (!id && validateUnit(valueWithCalculation, FLength | FPercent)); + validPrimitive = (!id && validUnit(value, FLength | FPercent)); break; case CSSPropertyZIndex: // auto | <integer> | inherit if (id == CSSValueAuto) validPrimitive = true; else - validPrimitive = (!id && validateUnit(valueWithCalculation, FInteger, CSSQuirksMode)); + validPrimitive = (!id && validUnit(value, FInteger, CSSQuirksMode)); break; case CSSPropertyOrphans: // <integer> | inherit | auto (We've added support for auto for backwards compatibility) @@ -2390,7 +2221,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) if (id == CSSValueAuto) validPrimitive = true; else - validPrimitive = (!id && validateUnit(valueWithCalculation, FPositiveInteger, CSSQuirksMode)); + validPrimitive = (!id && validUnit(value, FPositiveInteger, CSSQuirksMode)); break; case CSSPropertyLineHeight: @@ -2436,18 +2267,11 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) // auto | alphabetic | under return parseTextUnderlinePosition(important); - case CSSPropertyZoom: - // normal | reset | document | <number> | <percentage> | inherit + case CSSPropertyZoom: // normal | reset | document | <number> | <percentage> | inherit if (id == CSSValueNormal || id == CSSValueReset || id == CSSValueDocument) validPrimitive = true; else - validPrimitive = (!id && validateUnit(valueWithCalculation, FNumber | FPercent | FNonNeg, CSSStrictMode)); - break; - - case CSSPropertyWebkitTextZoom: - // normal | reset - if (id == CSSValueNormal || id == CSSValueReset) - validPrimitive = true; + validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg, CSSStrictMode)); break; case CSSPropertySrc: // Only used within @font-face and @-webkit-filter, so cannot use inherit | initial or be !important. This is a list of urls or local references. @@ -2513,17 +2337,17 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyBorderBottomRightRadius: { if (num != 1 && num != 2) return false; - validPrimitive = validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg); + validPrimitive = validUnit(value, FLength | FPercent | FNonNeg); if (!validPrimitive) return false; - RefPtr<CSSPrimitiveValue> parsedValue1 = createPrimitiveNumericValue(valueWithCalculation); + RefPtr<CSSPrimitiveValue> parsedValue1 = createPrimitiveNumericValue(value); RefPtr<CSSPrimitiveValue> parsedValue2; if (num == 2) { - ValueWithCalculation nextValueWithCalculation(*m_valueList->next()); - validPrimitive = validateUnit(nextValueWithCalculation, FLength | FPercent | FNonNeg); + value = m_valueList->next(); + validPrimitive = validUnit(value, FLength | FPercent | FNonNeg); if (!validPrimitive) return false; - parsedValue2 = createPrimitiveNumericValue(nextValueWithCalculation); + parsedValue2 = createPrimitiveNumericValue(value); } else parsedValue2 = parsedValue1; @@ -2531,7 +2355,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) return true; } case CSSPropertyTabSize: - validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg); + validPrimitive = validUnit(value, FInteger | FNonNeg); break; case CSSPropertyWebkitAspectRatio: return parseAspectRatio(important); @@ -2539,7 +2363,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyWebkitBorderRadius: return parseBorderRadius(propId, important); case CSSPropertyOutlineOffset: - validPrimitive = validateUnit(valueWithCalculation, FLength); + validPrimitive = validUnit(value, FLength); break; case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3 case CSSPropertyBoxShadow: @@ -2547,7 +2371,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) if (id == CSSValueNone) validPrimitive = true; else { - RefPtr<CSSValueList> shadowValueList = parseShadow(*m_valueList, propId); + RefPtr<CSSValueList> shadowValueList = parseShadow(m_valueList.get(), propId); if (shadowValueList) { addProperty(propId, shadowValueList.release(), important); m_valueList->next(); @@ -2556,30 +2380,6 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) return false; } break; - case CSSPropertyWebkitInitialLetter: { - if (id == CSSValueNormal) - validPrimitive = true; - else { - if (num != 1 && num != 2) - return false; - validPrimitive = validateUnit(valueWithCalculation, FPositiveInteger); - if (!validPrimitive) - return false; - RefPtr<CSSPrimitiveValue> height = createPrimitiveNumericValue(valueWithCalculation); - RefPtr<CSSPrimitiveValue> position; - if (num == 2) { - ValueWithCalculation nextValueWithCalculation(*m_valueList->next()); - validPrimitive = validateUnit(nextValueWithCalculation, FPositiveInteger); - if (!validPrimitive) - return false; - position = createPrimitiveNumericValue(nextValueWithCalculation); - } else - position = height; - addProperty(propId, createPrimitiveValuePair(position.release(), height.release()), important); - return true; - } - break; - } case CSSPropertyWebkitBoxReflect: if (id == CSSValueNone) validPrimitive = true; @@ -2587,67 +2387,62 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) return parseReflect(propId, important); break; case CSSPropertyOpacity: - validPrimitive = validateUnit(valueWithCalculation, FNumber); + validPrimitive = validUnit(value, FNumber); break; case CSSPropertyWebkitBoxFlex: - validPrimitive = validateUnit(valueWithCalculation, FNumber); + validPrimitive = validUnit(value, FNumber); break; case CSSPropertyWebkitBoxFlexGroup: - validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode); + validPrimitive = validUnit(value, FInteger | FNonNeg, CSSStrictMode); break; case CSSPropertyWebkitBoxOrdinalGroup: - validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode) && valueWithCalculation.value().fValue; + validPrimitive = validUnit(value, FInteger | FNonNeg, CSSStrictMode) && value->fValue; break; - case CSSPropertyFilter: -#if ENABLE(FILTERS_LEVEL_2) - case CSSPropertyWebkitBackdropFilter: -#endif +#if ENABLE(CSS_FILTERS) + case CSSPropertyWebkitFilter: if (id == CSSValueNone) validPrimitive = true; else { RefPtr<CSSValue> currValue; - if (!parseFilter(*m_valueList, currValue)) + if (!parseFilter(m_valueList.get(), currValue)) return false; + // m_valueList->next(); addProperty(propId, currValue, important); return true; } break; +#endif #if ENABLE(CSS_COMPOSITING) - case CSSPropertyMixBlendMode: - if (cssCompositingEnabled()) - validPrimitive = true; - break; - case CSSPropertyIsolation: + case CSSPropertyWebkitBlendMode: if (cssCompositingEnabled()) validPrimitive = true; break; #endif - case CSSPropertyFlex: { + case CSSPropertyWebkitFlex: { ShorthandScope scope(this, propId); if (id == CSSValueNone) { - addProperty(CSSPropertyFlexGrow, cssValuePool.createValue(0, CSSPrimitiveValue::CSS_NUMBER), important); - addProperty(CSSPropertyFlexShrink, cssValuePool.createValue(0, CSSPrimitiveValue::CSS_NUMBER), important); - addProperty(CSSPropertyFlexBasis, cssValuePool.createIdentifierValue(CSSValueAuto), important); + addProperty(CSSPropertyWebkitFlexGrow, cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER), important); + addProperty(CSSPropertyWebkitFlexShrink, cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER), important); + addProperty(CSSPropertyWebkitFlexBasis, cssValuePool().createIdentifierValue(CSSValueAuto), important); return true; } - return parseFlex(*m_valueList, important); + return parseFlex(m_valueList.get(), important); } - case CSSPropertyFlexBasis: + case CSSPropertyWebkitFlexBasis: // FIXME: Support intrinsic dimensions too. if (id == CSSValueAuto) validPrimitive = true; else - validPrimitive = (!id && validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg)); + validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg)); break; - case CSSPropertyFlexGrow: - case CSSPropertyFlexShrink: - validPrimitive = validateUnit(valueWithCalculation, FNumber | FNonNeg); + case CSSPropertyWebkitFlexGrow: + case CSSPropertyWebkitFlexShrink: + validPrimitive = validUnit(value, FNumber | FNonNeg); break; - case CSSPropertyOrder: - if (validateUnit(valueWithCalculation, FInteger, CSSStrictMode)) { + case CSSPropertyWebkitOrder: + if (validUnit(value, FInteger, CSSStrictMode)) { // We restrict the smallest value to int min + 2 because we use int min and int min + 1 as special values in a hash set. - double result = std::max<double>(std::numeric_limits<int>::min() + 2, parsedDouble(valueWithCalculation)); - parsedValue = cssValuePool.createValue(result, CSSPrimitiveValue::CSS_NUMBER); + parsedValue = cssValuePool().createValue(std::max<double>(std::numeric_limits<int>::min() + 2, value->fValue), static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)); m_valueList->next(); } break; @@ -2657,19 +2452,19 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) if (id == CSSValueSmall || id == CSSValueLarge || id == CSSValueMedium) validPrimitive = true; else - validPrimitive = validateUnit(valueWithCalculation, FLength | FPercent); + validPrimitive = validUnit(value, FLength | FPercent); break; case CSSPropertyWebkitMarqueeRepetition: if (id == CSSValueInfinite) validPrimitive = true; else - validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg); + validPrimitive = validUnit(value, FInteger | FNonNeg); break; case CSSPropertyWebkitMarqueeSpeed: if (id == CSSValueNormal || id == CSSValueSlow || id == CSSValueFast) validPrimitive = true; else - validPrimitive = validateUnit(valueWithCalculation, FTime | FInteger | FNonNeg); + validPrimitive = validUnit(value, FTime | FInteger | FNonNeg); break; #if ENABLE(CSS_REGIONS) case CSSPropertyWebkitFlowInto: @@ -2681,7 +2476,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) return false; return parseRegionThread(propId, important); #endif - case CSSPropertyTransform: + case CSSPropertyWebkitTransform: if (id == CSSValueNone) validPrimitive = true; else { @@ -2693,12 +2488,12 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) return false; } break; - case CSSPropertyTransformOrigin: - case CSSPropertyTransformOriginX: - case CSSPropertyTransformOriginY: - case CSSPropertyTransformOriginZ: { - RefPtr<CSSPrimitiveValue> val1; - RefPtr<CSSPrimitiveValue> val2; + case CSSPropertyWebkitTransformOrigin: + case CSSPropertyWebkitTransformOriginX: + case CSSPropertyWebkitTransformOriginY: + case CSSPropertyWebkitTransformOriginZ: { + RefPtr<CSSValue> val1; + RefPtr<CSSValue> val2; RefPtr<CSSValue> val3; CSSPropertyID propId1, propId2, propId3; if (parseTransformOrigin(propId, propId1, propId2, propId3, val1, val2, val3)) { @@ -2711,13 +2506,13 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) } return false; } - case CSSPropertyPerspective: + case CSSPropertyWebkitPerspective: if (id == CSSValueNone) validPrimitive = true; else { // Accepting valueless numbers is a quirk of the -webkit prefixed version of the property. - if (validateUnit(valueWithCalculation, FNumber | FLength | FNonNeg)) { - RefPtr<CSSValue> val = createPrimitiveNumericValue(valueWithCalculation); + if (validUnit(value, FNumber | FLength | FNonNeg)) { + RefPtr<CSSValue> val = createPrimitiveNumericValue(value); if (val) { addProperty(propId, val.release(), important); return true; @@ -2726,11 +2521,11 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) } } break; - case CSSPropertyPerspectiveOrigin: - case CSSPropertyPerspectiveOriginX: - case CSSPropertyPerspectiveOriginY: { - RefPtr<CSSPrimitiveValue> val1; - RefPtr<CSSPrimitiveValue> val2; + case CSSPropertyWebkitPerspectiveOrigin: + case CSSPropertyWebkitPerspectiveOriginX: + case CSSPropertyWebkitPerspectiveOriginY: { + RefPtr<CSSValue> val1; + RefPtr<CSSValue> val2; CSSPropertyID propId1, propId2; if (parsePerspectiveOrigin(propId, propId1, propId2, val1, val2)) { addProperty(propId1, val1.release(), important); @@ -2740,14 +2535,6 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) } return false; } - case CSSPropertyAnimationDelay: - case CSSPropertyAnimationDirection: - case CSSPropertyAnimationDuration: - case CSSPropertyAnimationFillMode: - case CSSPropertyAnimationName: - case CSSPropertyAnimationPlayState: - case CSSPropertyAnimationIterationCount: - case CSSPropertyAnimationTimingFunction: case CSSPropertyWebkitAnimationDelay: case CSSPropertyWebkitAnimationDirection: case CSSPropertyWebkitAnimationDuration: @@ -2756,9 +2543,6 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyWebkitAnimationPlayState: case CSSPropertyWebkitAnimationIterationCount: case CSSPropertyWebkitAnimationTimingFunction: -#if ENABLE(CSS_ANIMATIONS_LEVEL_2) - case CSSPropertyWebkitAnimationTrigger: -#endif case CSSPropertyTransitionDelay: case CSSPropertyTransitionDuration: case CSSPropertyTransitionTimingFunction: @@ -2775,63 +2559,50 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) } return false; } - case CSSPropertyJustifyContent: - parsedValue = parseContentDistributionOverflowPosition(); - break; - case CSSPropertyJustifySelf: - return parseItemPositionOverflowPosition(propId, important); - case CSSPropertyJustifyItems: - if (parseLegacyPosition(propId, important)) - return true; - m_valueList->setCurrentIndex(0); - return parseItemPositionOverflowPosition(propId, important); -#if ENABLE(CSS_GRID_LAYOUT) + case CSSPropertyWebkitGridAutoColumns: case CSSPropertyWebkitGridAutoRows: + if (!cssGridLayoutEnabled()) + return false; parsedValue = parseGridTrackSize(*m_valueList); break; - case CSSPropertyWebkitGridTemplateColumns: - case CSSPropertyWebkitGridTemplateRows: - parsedValue = parseGridTrackList(); - break; + case CSSPropertyWebkitGridDefinitionColumns: + case CSSPropertyWebkitGridDefinitionRows: + if (!cssGridLayoutEnabled()) + return false; + return parseGridTrackList(propId, important); case CSSPropertyWebkitGridColumnStart: case CSSPropertyWebkitGridColumnEnd: case CSSPropertyWebkitGridRowStart: case CSSPropertyWebkitGridRowEnd: - parsedValue = parseGridPosition(); - break; + if (!cssGridLayoutEnabled()) + return false; - case CSSPropertyWebkitGridColumnGap: - case CSSPropertyWebkitGridRowGap: - validPrimitive = validateUnit(valueWithCalculation, FLength | FNonNeg); + parsedValue = parseGridPosition(); break; - case CSSPropertyWebkitGridGap: - return parseGridGapShorthand(important); - case CSSPropertyWebkitGridColumn: case CSSPropertyWebkitGridRow: { + if (!cssGridLayoutEnabled()) + return false; + return parseGridItemPositionShorthand(propId, important); } - case CSSPropertyWebkitGridTemplate: - return parseGridTemplateShorthand(important); - - case CSSPropertyWebkitGrid: - return parseGridShorthand(important); - case CSSPropertyWebkitGridArea: + if (!cssGridLayoutEnabled()) + return false; return parseGridAreaShorthand(important); - case CSSPropertyWebkitGridTemplateAreas: - parsedValue = parseGridTemplateAreas(); - break; - case CSSPropertyWebkitGridAutoFlow: - parsedValue = parseGridAutoFlow(*m_valueList); + case CSSPropertyWebkitGridTemplate: + if (!cssGridLayoutEnabled()) + return false; + + parsedValue = parseGridTemplate(); break; -#endif /* ENABLE(CSS_GRID_LAYOUT) */ + case CSSPropertyWebkitMarginCollapse: { if (num == 1) { ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse); @@ -2856,51 +2627,48 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) id == CSSValueMedium || id == CSSValueThick) validPrimitive = true; else - validPrimitive = !id && validateUnit(valueWithCalculation, FNumber | FLength | FPercent); + validPrimitive = !id && validUnit(value, FNumber | FLength | FPercent); break; - case CSSPropertyColumnCount: - parsedValue = parseColumnCount(); + case CSSPropertyWebkitColumnCount: + if (id == CSSValueAuto) + validPrimitive = true; + else + validPrimitive = !id && validUnit(value, FPositiveInteger, CSSQuirksMode); break; - case CSSPropertyColumnGap: // normal | <length> + case CSSPropertyWebkitColumnGap: // normal | <length> if (id == CSSValueNormal) validPrimitive = true; else - validPrimitive = validateUnit(valueWithCalculation, FLength | FNonNeg); + validPrimitive = validUnit(value, FLength | FNonNeg); break; case CSSPropertyWebkitColumnAxis: if (id == CSSValueHorizontal || id == CSSValueVertical || id == CSSValueAuto) validPrimitive = true; break; - case CSSPropertyColumnProgression: + case CSSPropertyWebkitColumnProgression: if (id == CSSValueNormal || id == CSSValueReverse) validPrimitive = true; break; - case CSSPropertyColumnSpan: // none | all | 1 (will be dropped in the unprefixed property) + case CSSPropertyWebkitColumnSpan: // none | all | 1 (will be dropped in the unprefixed property) if (id == CSSValueAll || id == CSSValueNone) validPrimitive = true; - else if (validateUnit(valueWithCalculation, FNumber | FNonNeg) && parsedDouble(valueWithCalculation) == 1) { - addProperty(CSSPropertyColumnSpan, cssValuePool.createValue(1, CSSPrimitiveValue::CSS_NUMBER), important); - return true; - } - break; - case CSSPropertyColumnWidth: // auto | <length> - parsedValue = parseColumnWidth(); + else + validPrimitive = validUnit(value, FNumber | FNonNeg) && value->fValue == 1; break; - // End of CSS3 properties - - case CSSPropertyWillChange: // auto | [scroll-position | contents | <custom-ident>]# + case CSSPropertyWebkitColumnWidth: // auto | <length> if (id == CSSValueAuto) validPrimitive = true; - else - return parseWillChange(important); + else // Always parse this property in strict mode, since it would be ambiguous otherwise when used in the 'columns' shorthand property. + validPrimitive = validUnit(value, FLength | FNonNeg, CSSStrictMode) && value->fValue; break; + // End of CSS3 properties // Apple specific properties. These will never be standardized and are purely to // support custom WebKit-based Apple applications. case CSSPropertyWebkitLineClamp: // When specifying number of lines, don't allow 0 as a valid value // When specifying either type of unit, require non-negative integers - validPrimitive = (!id && (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_PERCENTAGE || valueWithCalculation.value().fValue) && validateUnit(valueWithCalculation, FInteger | FPercent | FNonNeg, CSSQuirksMode)); + validPrimitive = (!id && (value->unit == CSSPrimitiveValue::CSS_PERCENTAGE || value->fValue) && validUnit(value, FInteger | FPercent | FNonNeg, CSSQuirksMode)); break; #if ENABLE(IOS_TEXT_AUTOSIZING) case CSSPropertyWebkitTextSizeAdjust: @@ -2908,55 +2676,73 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) validPrimitive = true; else { // FIXME: Handle multilength case where we allow relative units. - validPrimitive = (!id && validateUnit(valueWithCalculation, FPercent | FNonNeg, CSSStrictMode)); + validPrimitive = (!id && validUnit(value, FPercent | FNonNeg, CSSStrictMode)); } break; #endif case CSSPropertyWebkitFontSizeDelta: // <length> - validPrimitive = validateUnit(valueWithCalculation, FLength); + validPrimitive = validUnit(value, FLength); + break; + + case CSSPropertyWebkitHighlight: + if (id == CSSValueNone || value->unit == CSSPrimitiveValue::CSS_STRING) + validPrimitive = true; break; case CSSPropertyWebkitHyphenateCharacter: - if (id == CSSValueAuto || valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_STRING) + if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING) validPrimitive = true; break; case CSSPropertyWebkitHyphenateLimitBefore: case CSSPropertyWebkitHyphenateLimitAfter: - if (id == CSSValueAuto || validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode)) + if (id == CSSValueAuto || validUnit(value, FInteger | FNonNeg, CSSStrictMode)) validPrimitive = true; break; case CSSPropertyWebkitHyphenateLimitLines: - if (id == CSSValueNoLimit || validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode)) + if (id == CSSValueNoLimit || validUnit(value, FInteger | FNonNeg, CSSStrictMode)) validPrimitive = true; break; case CSSPropertyWebkitLineGrid: if (id == CSSValueNone) validPrimitive = true; - else if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_IDENT) { - String lineGridValue = String(valueWithCalculation.value().string); + else if (value->unit == CSSPrimitiveValue::CSS_IDENT) { + String lineGridValue = String(value->string); if (!lineGridValue.isEmpty()) { - addProperty(propId, cssValuePool.createValue(lineGridValue, CSSPrimitiveValue::CSS_STRING), important); + addProperty(propId, cssValuePool().createValue(lineGridValue, CSSPrimitiveValue::CSS_STRING), important); return true; } } break; case CSSPropertyWebkitLocale: - if (id == CSSValueAuto || valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_STRING) + if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING) validPrimitive = true; break; #if ENABLE(DASHBOARD_SUPPORT) case CSSPropertyWebkitDashboardRegion: // <dashboard-region> | <dashboard-region> - if (valueWithCalculation.value().unit == CSSParserValue::Function || id == CSSValueNone) + if (value->unit == CSSParserValue::Function || id == CSSValueNone) return parseDashboardRegions(propId, important); break; #endif #if PLATFORM(IOS) + // FIXME: CSSPropertyWebkitCompositionFillColor shouldn't be iOS-specific. Once we fix up its usage in + // InlineTextBox::paintCompositionBackground() we should move it outside the PLATFORM(IOS)-guard. + // See <https://bugs.webkit.org/show_bug.cgi?id=126296>. + case CSSPropertyWebkitCompositionFillColor: + if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu + || (id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && inQuirksMode())) { + validPrimitive = true; + } else { + parsedValue = parseColor(); + if (parsedValue) + m_valueList->next(); + } + break; case CSSPropertyWebkitTouchCallout: if (id == CSSValueDefault || id == CSSValueNone) validPrimitive = true; @@ -2964,7 +2750,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) #endif #if ENABLE(TOUCH_EVENTS) case CSSPropertyWebkitTapHighlightColor: - if (isValidSystemColorValue(id) || id == CSSValueMenu + if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || (id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && inQuirksMode())) { validPrimitive = true; } else { @@ -2996,7 +2782,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) if (parseShorthand(propId, borderAbridgedShorthand(), important)) { // The CSS3 Borders and Backgrounds specification says that border also resets border-image. It's as // though a value of none was specified for the image. - addExpandedPropertyForValue(CSSPropertyBorderImage, cssValuePool.createImplicitInitialValue(), important); + addExpandedPropertyForValue(CSSPropertyBorderImage, cssValuePool().createImplicitInitialValue(), important); return true; } return false; @@ -3039,27 +2825,26 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyPadding: // <padding-width>{1,4} | inherit return parse4Values(propId, paddingShorthand().properties(), important); - case CSSPropertyFlexFlow: - return parseShorthand(propId, flexFlowShorthand(), important); + case CSSPropertyWebkitFlexFlow: + return parseShorthand(propId, webkitFlexFlowShorthand(), important); case CSSPropertyFont: // [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? // 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit - if (num == 1 && id >= CSSValueCaption && id <= CSSValueStatusBar) { - parseSystemFont(important); - return true; - } - return parseFont(important); + if (id >= CSSValueCaption && id <= CSSValueStatusBar) + validPrimitive = true; + else + return parseFont(important); + break; case CSSPropertyListStyle: return parseShorthand(propId, listStyleShorthand(), important); - case CSSPropertyColumns: - return parseColumnsShorthand(important); - case CSSPropertyColumnRule: - return parseShorthand(propId, columnRuleShorthand(), important); + case CSSPropertyWebkitColumns: + return parseShorthand(propId, webkitColumnsShorthand(), important); + case CSSPropertyWebkitColumnRule: + return parseShorthand(propId, webkitColumnRuleShorthand(), important); case CSSPropertyWebkitTextStroke: return parseShorthand(propId, webkitTextStrokeShorthand(), important); - case CSSPropertyAnimation: case CSSPropertyWebkitAnimation: - return parseAnimationShorthand(propId, important); + return parseAnimationShorthand(important); case CSSPropertyTransition: case CSSPropertyWebkitTransition: return parseTransitionShorthand(propId, important); @@ -3083,77 +2868,49 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) return parseTextEmphasisPosition(important); case CSSPropertyWebkitTextOrientation: - if (id == CSSValueSideways || id == CSSValueSidewaysRight || id == CSSValueVerticalRight || id == CSSValueMixed || id == CSSValueUpright) + // FIXME: For now just support sideways, sideways-right, upright and vertical-right. + if (id == CSSValueSideways || id == CSSValueSidewaysRight || id == CSSValueVerticalRight || id == CSSValueUpright) validPrimitive = true; break; - case CSSPropertyHangingPunctuation: - return parseHangingPunctuation(important); case CSSPropertyWebkitLineBoxContain: if (id == CSSValueNone) validPrimitive = true; else return parseLineBoxContain(important); break; - case CSSPropertyFontFeatureSettings: + case CSSPropertyWebkitFontFeatureSettings: if (id == CSSValueNormal) validPrimitive = true; else return parseFontFeatureSettings(important); break; - case CSSPropertyFontVariantLigatures: - if (id == CSSValueNormal || id == CSSValueNone) - validPrimitive = true; - else - return parseFontVariantLigatures(important, true, false); - break; - case CSSPropertyFontVariantNumeric: + + case CSSPropertyWebkitFontVariantLigatures: if (id == CSSValueNormal) validPrimitive = true; else - return parseFontVariantNumeric(important, true, false); + return parseFontVariantLigatures(important); break; - case CSSPropertyFontVariantEastAsian: - if (id == CSSValueNormal) - validPrimitive = true; - else - return parseFontVariantEastAsian(important, true, false); - break; - case CSSPropertyFontVariant: - if (id == CSSValueNormal) { - ShorthandScope scope(this, CSSPropertyFontVariant); - addProperty(CSSPropertyFontVariantLigatures, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true); - addProperty(CSSPropertyFontVariantPosition, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true); - addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true); - addProperty(CSSPropertyFontVariantNumeric, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true); - addProperty(CSSPropertyFontVariantAlternates, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true); - addProperty(CSSPropertyFontVariantEastAsian, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true); - return true; - } - if (id == CSSValueNone) { - ShorthandScope scope(this, CSSPropertyFontVariant); - addProperty(CSSPropertyFontVariantLigatures, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important, true); - return true; - } - return parseFontVariant(important); - case CSSPropertyWebkitClipPath: parsedValue = parseClipPath(); break; #if ENABLE(CSS_SHAPES) + case CSSPropertyWebkitShapeInside: case CSSPropertyWebkitShapeOutside: parsedValue = parseShapeProperty(propId); break; case CSSPropertyWebkitShapeMargin: - validPrimitive = (RuntimeEnabledFeatures::sharedFeatures().cssShapesEnabled() && !id && validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg)); + case CSSPropertyWebkitShapePadding: + validPrimitive = (RuntimeEnabledFeatures::sharedFeatures().cssShapesEnabled() && !id && validUnit(value, FLength | FNonNeg)); break; case CSSPropertyWebkitShapeImageThreshold: - validPrimitive = (RuntimeEnabledFeatures::sharedFeatures().cssShapesEnabled() && !id && validateUnit(valueWithCalculation, FNumber)); + validPrimitive = (RuntimeEnabledFeatures::sharedFeatures().cssShapesEnabled() && !id && validUnit(value, FNumber)); break; #endif #if ENABLE(CSS_IMAGE_ORIENTATION) case CSSPropertyImageOrientation: - validPrimitive = !id && validateUnit(valueWithCalculation, FAngle); + validPrimitive = !id && validUnit(value, FAngle); break; #endif #if ENABLE(CSS_IMAGE_RESOLUTION) @@ -3161,23 +2918,12 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) parsedValue = parseImageResolution(); break; #endif - case CSSPropertyAlignContent: - parsedValue = parseContentDistributionOverflowPosition(); - break; - case CSSPropertyAlignSelf: - return parseItemPositionOverflowPosition(propId, important); - - case CSSPropertyAlignItems: - return parseItemPositionOverflowPosition(propId, important); case CSSPropertyBorderBottomStyle: case CSSPropertyBorderCollapse: case CSSPropertyBorderLeftStyle: case CSSPropertyBorderRightStyle: case CSSPropertyBorderTopStyle: case CSSPropertyBoxSizing: - case CSSPropertyBreakAfter: - case CSSPropertyBreakBefore: - case CSSPropertyBreakInside: case CSSPropertyCaptionSide: case CSSPropertyClear: case CSSPropertyDirection: @@ -3226,16 +2972,22 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyWebkitBoxLines: case CSSPropertyWebkitBoxOrient: case CSSPropertyWebkitBoxPack: + case CSSPropertyWebkitColorCorrection: case CSSPropertyWebkitColumnBreakAfter: case CSSPropertyWebkitColumnBreakBefore: case CSSPropertyWebkitColumnBreakInside: - case CSSPropertyColumnFill: - case CSSPropertyColumnRuleStyle: - case CSSPropertyFlexDirection: - case CSSPropertyFlexWrap: + case CSSPropertyWebkitColumnFill: + case CSSPropertyWebkitColumnRuleStyle: + case CSSPropertyWebkitAlignContent: + case CSSPropertyWebkitAlignItems: + case CSSPropertyWebkitAlignSelf: + case CSSPropertyWebkitFlexDirection: + case CSSPropertyWebkitFlexWrap: + case CSSPropertyWebkitJustifyContent: case CSSPropertyWebkitFontKerning: case CSSPropertyWebkitFontSmoothing: case CSSPropertyWebkitHyphens: + case CSSPropertyWebkitGridAutoFlow: case CSSPropertyWebkitLineAlign: case CSSPropertyWebkitLineBreak: case CSSPropertyWebkitLineSnap: @@ -3266,24 +3018,18 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyWebkitTextJustify: #endif // CSS3_TEXT case CSSPropertyWebkitTextSecurity: - case CSSPropertyTransformStyle: case CSSPropertyWebkitTransformStyle: case CSSPropertyWebkitUserDrag: case CSSPropertyWebkitUserModify: case CSSPropertyWebkitUserSelect: +#if ENABLE(CSS_EXCLUSIONS) + case CSSPropertyWebkitWrapFlow: + case CSSPropertyWebkitWrapThrough: +#endif case CSSPropertyWebkitWritingMode: case CSSPropertyWhiteSpace: case CSSPropertyWordBreak: case CSSPropertyWordWrap: -#if ENABLE(TOUCH_EVENTS) - case CSSPropertyTouchAction: -#endif -#if ENABLE(CSS_SCROLL_SNAP) - case CSSPropertyWebkitScrollSnapType: -#endif -#if ENABLE(CSS_TRAILING_WORD) - case CSSPropertyAppleTrailingWord: -#endif // These properties should be handled before in isValidKeywordPropertyAndValue(). ASSERT_NOT_REACHED(); return false; @@ -3298,29 +3044,17 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) validPrimitive = false; break; #endif -#if ENABLE(CSS_SCROLL_SNAP) - case CSSPropertyWebkitScrollSnapPointsX: - case CSSPropertyWebkitScrollSnapPointsY: - if (id == CSSValueElements) { - validPrimitive = true; - break; - } - return parseNonElementSnapPoints(propId, important); - case CSSPropertyWebkitScrollSnapDestination: // <length>{2} - return parseScrollSnapDestination(propId, important); - case CSSPropertyWebkitScrollSnapCoordinate: - return parseScrollSnapCoordinate(propId, important); -#endif - +#if ENABLE(SVG) default: return parseSVGValue(propId, important); +#endif } if (validPrimitive) { - parsedValue = parseValidPrimitive(id, valueWithCalculation); + parsedValue = parseValidPrimitive(id, value); m_valueList->next(); } - + ASSERT(!m_parsedCalculation); if (parsedValue) { if (!m_valueList->current() || inShorthand()) { addProperty(propId, parsedValue.release(), important); @@ -3330,186 +3064,28 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) return false; } -void CSSParser::addFillValue(RefPtr<CSSValue>& lval, Ref<CSSValue>&& rval) -{ - if (!lval) { - lval = WTFMove(rval); - return; - } - - if (lval->isBaseValueList()) { - downcast<CSSValueList>(*lval).append(WTFMove(rval)); - return; - } - - auto list = CSSValueList::createCommaSeparated(); - list.get().append(lval.releaseNonNull()); - list.get().append(WTFMove(rval)); - lval = WTFMove(list); -} - -static bool isContentDistributionKeyword(CSSValueID id) -{ - return id == CSSValueSpaceBetween || id == CSSValueSpaceAround - || id == CSSValueSpaceEvenly || id == CSSValueStretch; -} - -static bool isContentPositionKeyword(CSSValueID id) -{ - return id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter - || id == CSSValueFlexStart || id == CSSValueFlexEnd - || id == CSSValueLeft || id == CSSValueRight; -} - -static inline bool isBaselinePositionKeyword(CSSValueID id) -{ - return id == CSSValueBaseline || id == CSSValueLastBaseline; -} - -static bool isAlignmentOverflowKeyword(CSSValueID id) +void CSSParser::addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval) { - return id == CSSValueUnsafe || id == CSSValueSafe; -} - -static bool isItemPositionKeyword(CSSValueID id) -{ - return id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter - || id == CSSValueSelfStart || id == CSSValueSelfEnd || id == CSSValueFlexStart - || id == CSSValueFlexEnd || id == CSSValueLeft || id == CSSValueRight; -} - -bool CSSParser::parseLegacyPosition(CSSPropertyID propId, bool important) -{ - // [ legacy && [ left | right | center ] - - CSSParserValue* value = m_valueList->current(); - if (!value) - return false; - - if (value->id == CSSValueLegacy) { - value = m_valueList->next(); - if (!value) - return false; - if (value->id != CSSValueCenter && value->id != CSSValueLeft && value->id != CSSValueRight) - return false; - } else if (value->id == CSSValueCenter || value->id == CSSValueLeft || value->id == CSSValueRight) { - if (!m_valueList->next() || m_valueList->current()->id != CSSValueLegacy) - return false; - } else - return false; - - auto& cssValuePool = CSSValuePool::singleton(); - addProperty(propId, createPrimitiveValuePair(cssValuePool.createIdentifierValue(CSSValueLegacy), cssValuePool.createIdentifierValue(value->id)), important); - return !m_valueList->next(); -} - -RefPtr<CSSValue> CSSParser::parseContentDistributionOverflowPosition() -{ - // auto | <baseline-position> | <content-distribution> || [ <overflow-position>? && <content-position> ] - // <baseline-position> = baseline | last-baseline; - // <content-distribution> = space-between | space-around | space-evenly | stretch; - // <content-position> = center | start | end | flex-start | flex-end | left | right; - // <overflow-position> = true | safe - - CSSParserValue* value = m_valueList->current(); - if (!value) - return nullptr; - - // auto | <baseline-position> - if (value->id == CSSValueAuto || isBaselinePositionKeyword(value->id)) { - m_valueList->next(); - return CSSContentDistributionValue::create(CSSValueInvalid, value->id, CSSValueInvalid); - } - - CSSValueID distribution = CSSValueInvalid; - CSSValueID position = CSSValueInvalid; - CSSValueID overflow = CSSValueInvalid; - while (value) { - if (isContentDistributionKeyword(value->id)) { - if (distribution != CSSValueInvalid) - return nullptr; - distribution = value->id; - } else if (isContentPositionKeyword(value->id)) { - if (position != CSSValueInvalid) - return nullptr; - position = value->id; - } else if (isAlignmentOverflowKeyword(value->id)) { - if (overflow != CSSValueInvalid) - return nullptr; - overflow = value->id; - } else - return nullptr; - value = m_valueList->next(); - } - - // The grammar states that we should have at least <content-distribution> or - // <content-position> ( <content-distribution> || <content-position> ). - if (position == CSSValueInvalid && distribution == CSSValueInvalid) - return nullptr; - - // The grammar states that <overflow-position> must be associated to <content-position>. - if (overflow != CSSValueInvalid && position == CSSValueInvalid) - return nullptr; - - return CSSContentDistributionValue::create(distribution, position, overflow); -} - -bool CSSParser::parseItemPositionOverflowPosition(CSSPropertyID propId, bool important) -{ - // auto | stretch | <baseline-position> | [<item-position> && <overflow-position>? ] - // <baseline-position> = baseline | last-baseline; - // <item-position> = center | start | end | self-start | self-end | flex-start | flex-end | left | right; - // <overflow-position> = true | safe - - CSSParserValue* value = m_valueList->current(); - if (!value) - return false; - - if (value->id == CSSValueAuto || value->id == CSSValueStretch || isBaselinePositionKeyword(value->id)) { - if (m_valueList->next()) - return false; - - addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value->id), important); - return true; - } - - RefPtr<CSSPrimitiveValue> position; - RefPtr<CSSPrimitiveValue> overflowAlignmentKeyword; - if (isItemPositionKeyword(value->id)) { - position = CSSValuePool::singleton().createIdentifierValue(value->id); - value = m_valueList->next(); - if (value) { - if (value->id != CSSValueUnsafe && value->id != CSSValueSafe) - return false; - overflowAlignmentKeyword = CSSValuePool::singleton().createIdentifierValue(value->id); + if (lval) { + if (lval->isBaseValueList()) + toCSSValueList(lval.get())->append(rval); + else { + PassRefPtr<CSSValue> oldlVal(lval.release()); + PassRefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + list->append(oldlVal); + list->append(rval); + lval = list; } - } else if (isAlignmentOverflowKeyword(value->id)) { - overflowAlignmentKeyword = CSSValuePool::singleton().createIdentifierValue(value->id); - value = m_valueList->next(); - if (value && isItemPositionKeyword(value->id)) - position = CSSValuePool::singleton().createIdentifierValue(value->id); - else - return false; - } else - return false; - - if (m_valueList->next()) - return false; - - ASSERT(position); - if (overflowAlignmentKeyword) - addProperty(propId, createPrimitiveValuePair(position.release(), overflowAlignmentKeyword.release()), important); + } else - addProperty(propId, position.release(), important); - - return true; + lval = rval; } -static bool parseBackgroundClip(CSSParserValue& parserValue, RefPtr<CSSValue>& cssValue) +static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtr<CSSValue>& cssValue) { - if (parserValue.id == CSSValueBorderBox || parserValue.id == CSSValuePaddingBox - || parserValue.id == CSSValueContentBox || parserValue.id == CSSValueWebkitText) { - cssValue = CSSValuePool::singleton().createIdentifierValue(parserValue.id); + if (parserValue->id == CSSValueBorderBox || parserValue->id == CSSValuePaddingBox + || parserValue->id == CSSValueContentBox || parserValue->id == CSSValueWebkitText) { + cssValue = cssValuePool().createIdentifierValue(parserValue->id); return true; } return false; @@ -3520,93 +3096,6 @@ bool CSSParser::useLegacyBackgroundSizeShorthandBehavior() const return m_context.useLegacyBackgroundSizeShorthandBehavior; } -#if ENABLE(CSS_SCROLL_SNAP) -bool CSSParser::parseNonElementSnapPoints(CSSPropertyID propId, bool important) -{ - RefPtr<CSSValueList> values = CSSValueList::createSpaceSeparated(); - while (CSSParserValue* value = m_valueList->current()) { - ValueWithCalculation valueWithCalculation(*value); - if (validateUnit(valueWithCalculation, FPercent | FLength)) - values->append(createPrimitiveNumericValue(valueWithCalculation)); - else if (value->unit == CSSParserValue::Function - && value->function->args - && value->function->args->size() == 1 - && equalLettersIgnoringASCIICase(value->function->name, "repeat(")) { - ValueWithCalculation argumentWithCalculation(*value->function->args.get()->current()); - if (validateUnit(argumentWithCalculation, FLength | FPercent | FNonNeg)) { - values->append(CSSValuePool::singleton().createValue(LengthRepeat::create(createPrimitiveNumericValue(argumentWithCalculation)))); - m_valueList->next(); - if (m_valueList->current()) - return false; - break; - } - } else - return false; - m_valueList->next(); - } - if (values->length()) { - addProperty(propId, values.release(), important); - m_valueList->next(); - return true; - } - return false; -} - -bool CSSParser::parseScrollSnapPositions(RefPtr<CSSValue>& cssValueX, RefPtr<CSSValue>& cssValueY) -{ - cssValueX = parsePositionX(*m_valueList); - if (!cssValueX) - return false; - - // Don't accept odd-length lists of positions (must always have an X and a Y): - if (!m_valueList->next()) - return false; - - cssValueY = parsePositionY(*m_valueList); - if (!cssValueY) - return false; - - return true; -} - -bool CSSParser::parseScrollSnapDestination(CSSPropertyID propId, bool important) -{ - RefPtr<CSSValueList> position = CSSValueList::createSpaceSeparated(); - if (m_valueList->size() != 2) - return false; - - RefPtr<CSSValue> cssValueX, cssValueY; - if (!parseScrollSnapPositions(cssValueX, cssValueY)) - return false; - - position->append(cssValueX.releaseNonNull()); - position->append(cssValueY.releaseNonNull()); - addProperty(propId, position, important); - m_valueList->next(); - return true; -} - -bool CSSParser::parseScrollSnapCoordinate(CSSPropertyID propId, bool important) -{ - RefPtr<CSSValueList> positions = CSSValueList::createSpaceSeparated(); - while (m_valueList->current()) { - RefPtr<CSSValue> cssValueX, cssValueY; - if (!parseScrollSnapPositions(cssValueX, cssValueY)) - return false; - - positions->append(cssValueX.releaseNonNull()); - positions->append(cssValueY.releaseNonNull()); - m_valueList->next(); - } - - if (positions->length()) { - addProperty(propId, positions.release(), important); - return true; - } - return false; -} -#endif - const int cMaxFillProperties = 9; bool CSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* properties, int numProperties, bool important) @@ -3626,10 +3115,9 @@ bool CSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* pr int i; bool foundPositionCSSProperty = false; - auto& cssValuePool = CSSValuePool::singleton(); while (m_valueList->current()) { - CSSParserValue& currentValue = *m_valueList->current(); - if (currentValue.unit == CSSParserValue::Operator && currentValue.iValue == ',') { + CSSParserValue* val = m_valueList->current(); + if (val->unit == CSSParserValue::Operator && val->iValue == ',') { // We hit the end. Fill in all remaining values with the initial value. m_valueList->next(); for (i = 0; i < numProperties; ++i) { @@ -3639,14 +3127,14 @@ bool CSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* pr return false; if (!parsedProperty[i] && properties[i] != CSSPropertyBackgroundColor) { - addFillValue(values[i], cssValuePool.createImplicitInitialValue()); + addFillValue(values[i], cssValuePool().createImplicitInitialValue()); if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition) - addFillValue(positionYValue, cssValuePool.createImplicitInitialValue()); + addFillValue(positionYValue, cssValuePool().createImplicitInitialValue()); if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat) - addFillValue(repeatYValue, cssValuePool.createImplicitInitialValue()); + addFillValue(repeatYValue, cssValuePool().createImplicitInitialValue()); if ((properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) && !parsedProperty[i]) { // If background-origin wasn't present, then reset background-clip also. - addFillValue(clipValue, cssValuePool.createImplicitInitialValue()); + addFillValue(clipValue, cssValuePool().createImplicitInitialValue()); } } parsedProperty[i] = false; @@ -3656,7 +3144,7 @@ bool CSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* pr } bool sizeCSSPropertyExpected = false; - if (isForwardSlashOperator(currentValue) && foundPositionCSSProperty) { + if (isForwardSlashOperator(val) && foundPositionCSSProperty) { sizeCSSPropertyExpected = true; m_valueList->next(); } @@ -3674,24 +3162,26 @@ bool CSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* pr RefPtr<CSSValue> val1; RefPtr<CSSValue> val2; CSSPropertyID propId1, propId2; - CSSParserValue& parserValue = *m_valueList->current(); - + CSSParserValue* parserValue = m_valueList->current(); if (parseFillProperty(properties[i], propId1, propId2, val1, val2)) { parsedProperty[i] = found = true; - addFillValue(values[i], val1.releaseNonNull()); + addFillValue(values[i], val1.release()); if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition) - addFillValue(positionYValue, val2.releaseNonNull()); + addFillValue(positionYValue, val2.release()); if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat) - addFillValue(repeatYValue, val2.releaseNonNull()); + 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)) - addFillValue(clipValue, val1.releaseNonNull()); // The property parsed successfully. + addFillValue(clipValue, val1.release()); // The property parsed successfully. else - addFillValue(clipValue, cssValuePool.createImplicitInitialValue()); // Some value was used for origin that is not supported by clip. Just reset clip instead. + addFillValue(clipValue, cssValuePool().createImplicitInitialValue()); // Some value was used for origin that is not supported by clip. Just reset clip instead. } - if (properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) + if (properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) { + // Update clipValue + addFillValue(clipValue, val1.release()); foundClip = true; + } if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition) foundPositionCSSProperty = true; } @@ -3705,17 +3195,17 @@ bool CSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* pr } // Now add all of the properties we found. - for (i = 0; i < numProperties; ++i) { + for (i = 0; i < numProperties; i++) { // Fill in any remaining properties with the initial value. if (!parsedProperty[i]) { - addFillValue(values[i], cssValuePool.createImplicitInitialValue()); + addFillValue(values[i], cssValuePool().createImplicitInitialValue()); if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition) - addFillValue(positionYValue, cssValuePool.createImplicitInitialValue()); + addFillValue(positionYValue, cssValuePool().createImplicitInitialValue()); if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat) - addFillValue(repeatYValue, cssValuePool.createImplicitInitialValue()); + addFillValue(repeatYValue, cssValuePool().createImplicitInitialValue()); if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) { // If background-origin wasn't present, then reset background-clip also. - addFillValue(clipValue, cssValuePool.createImplicitInitialValue()); + addFillValue(clipValue, cssValuePool().createImplicitInitialValue()); } } if (properties[i] == CSSPropertyBackgroundPosition) { @@ -3752,45 +3242,40 @@ bool CSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* pr return true; } -void CSSParser::addAnimationValue(RefPtr<CSSValue>& lval, Ref<CSSValue>&& rval) +void CSSParser::addAnimationValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval) { - if (!lval) { - lval = WTFMove(rval); - return; - } - - if (is<CSSValueList>(*lval)) { - downcast<CSSValueList>(*lval).append(WTFMove(rval)); - return; + if (lval) { + if (lval->isValueList()) + toCSSValueList(lval.get())->append(rval); + else { + PassRefPtr<CSSValue> oldVal(lval.release()); + PassRefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + list->append(oldVal); + list->append(rval); + lval = list; + } } - - auto list = CSSValueList::createCommaSeparated(); - list.get().append(lval.releaseNonNull()); - list.get().append(WTFMove(rval)); - lval = WTFMove(list); + else + lval = rval; } -bool CSSParser::parseAnimationShorthand(CSSPropertyID propId, bool important) +bool CSSParser::parseAnimationShorthand(bool important) { - ASSERT(propId == CSSPropertyAnimation || propId == CSSPropertyWebkitAnimation); - - const unsigned numProperties = 8; - const StylePropertyShorthand& shorthand = animationShorthandForParsing(propId); + const StylePropertyShorthand& animationProperties = webkitAnimationShorthandForParsing(); + const unsigned numProperties = 7; // The list of properties in the shorthand should be the same // length as the list with animation name in last position, even though they are // in a different order. - ASSERT(numProperties == shorthand.length()); - ASSERT(numProperties == animationShorthand().length()); + ASSERT(numProperties == webkitAnimationShorthandForParsing().length()); ASSERT(numProperties == webkitAnimationShorthand().length()); - ShorthandScope scope(this, propId); + ShorthandScope scope(this, CSSPropertyWebkitAnimation); bool parsedProperty[numProperties] = { false }; AnimationParseContext context; RefPtr<CSSValue> values[numProperties]; - auto& cssValuePool = CSSValuePool::singleton(); unsigned i; while (m_valueList->current()) { CSSParserValue* val = m_valueList->current(); @@ -3799,7 +3284,7 @@ bool CSSParser::parseAnimationShorthand(CSSPropertyID propId, bool important) m_valueList->next(); for (i = 0; i < numProperties; ++i) { if (!parsedProperty[i]) - addAnimationValue(values[i], cssValuePool.createImplicitInitialValue()); + addAnimationValue(values[i], cssValuePool().createImplicitInitialValue()); parsedProperty[i] = false; } if (!m_valueList->current()) @@ -3811,9 +3296,9 @@ bool CSSParser::parseAnimationShorthand(CSSPropertyID propId, bool important) for (i = 0; i < numProperties; ++i) { if (!parsedProperty[i]) { RefPtr<CSSValue> val; - if (parseAnimationProperty(shorthand.properties()[i], val, context)) { + if (parseAnimationProperty(animationProperties.properties()[i], val, context)) { parsedProperty[i] = found = true; - addAnimationValue(values[i], val.releaseNonNull()); + addAnimationValue(values[i], val.release()); break; } } @@ -3832,81 +3317,11 @@ bool CSSParser::parseAnimationShorthand(CSSPropertyID propId, bool important) for (i = 0; i < numProperties; ++i) { // If we didn't find the property, set an intial value. if (!parsedProperty[i]) - addAnimationValue(values[i], cssValuePool.createImplicitInitialValue()); - - addProperty(shorthand.properties()[i], values[i].release(), important); - } - - return true; -} - -RefPtr<CSSValue> CSSParser::parseColumnWidth() -{ - ValueWithCalculation valueWithCalculation(*m_valueList->current()); - CSSValueID id = valueWithCalculation.value().id; - // Always parse this property in strict mode, since it would be ambiguous otherwise when used in the 'columns' shorthand property. - if (id != CSSValueAuto && !(validateUnit(valueWithCalculation, FLength | FNonNeg, CSSStrictMode) && parsedDouble(valueWithCalculation))) - return nullptr; + addAnimationValue(values[i], cssValuePool().createImplicitInitialValue()); - RefPtr<CSSValue> parsedValue = parseValidPrimitive(id, valueWithCalculation); - m_valueList->next(); - return parsedValue; -} - -RefPtr<CSSValue> CSSParser::parseColumnCount() -{ - ValueWithCalculation valueWithCalculation(*m_valueList->current()); - CSSValueID id = valueWithCalculation.value().id; - - if (id != CSSValueAuto && !validateUnit(valueWithCalculation, FPositiveInteger, CSSQuirksMode)) - return nullptr; - - RefPtr<CSSValue> parsedValue = parseValidPrimitive(id, valueWithCalculation); - m_valueList->next(); - return parsedValue; -} - -bool CSSParser::parseColumnsShorthand(bool important) -{ - RefPtr<CSSValue> columnWidth; - RefPtr<CSSValue> columnCount; - bool hasPendingExplicitAuto = false; - - for (unsigned propertiesParsed = 0; CSSParserValue* value = m_valueList->current(); propertiesParsed++) { - if (propertiesParsed >= 2) - return false; // Too many values for this shorthand. Invalid declaration. - if (!propertiesParsed && value->id == CSSValueAuto) { - // 'auto' is a valid value for any of the two longhands, and at this point - // we don't know which one(s) it is meant for. We need to see if there are other values first. - m_valueList->next(); - hasPendingExplicitAuto = true; - } else { - if (!columnWidth) { - if ((columnWidth = parseColumnWidth())) - continue; - } - if (!columnCount) { - if ((columnCount = parseColumnCount())) - continue; - } - // If we didn't find at least one match, this is an invalid shorthand and we have to ignore it. - return false; - } - } - - // Any unassigned property at this point will become implicit 'auto'. - if (columnWidth) - addProperty(CSSPropertyColumnWidth, columnWidth, important); - else { - addProperty(CSSPropertyColumnWidth, CSSValuePool::singleton().createIdentifierValue(CSSValueAuto), important, !hasPendingExplicitAuto /* implicit */); - hasPendingExplicitAuto = false; + addProperty(animationProperties.properties()[i], values[i].release(), important); } - if (columnCount) - addProperty(CSSPropertyColumnCount, columnCount, important); - else - addProperty(CSSPropertyColumnCount, CSSValuePool::singleton().createIdentifierValue(CSSValueAuto), important, !hasPendingExplicitAuto /* implicit */); - return true; } @@ -3922,7 +3337,6 @@ bool CSSParser::parseTransitionShorthand(CSSPropertyID propId, bool important) AnimationParseContext context; RefPtr<CSSValue> values[numProperties]; - auto& cssValuePool = CSSValuePool::singleton(); unsigned i; while (m_valueList->current()) { CSSParserValue* val = m_valueList->current(); @@ -3931,7 +3345,7 @@ bool CSSParser::parseTransitionShorthand(CSSPropertyID propId, bool important) m_valueList->next(); for (i = 0; i < numProperties; ++i) { if (!parsedProperty[i]) - addAnimationValue(values[i], cssValuePool.createImplicitInitialValue()); + addAnimationValue(values[i], cssValuePool().createImplicitInitialValue()); parsedProperty[i] = false; } if (!m_valueList->current()) @@ -3945,7 +3359,7 @@ bool CSSParser::parseTransitionShorthand(CSSPropertyID propId, bool important) RefPtr<CSSValue> val; if (parseAnimationProperty(shorthand.properties()[i], val, context)) { parsedProperty[i] = found = true; - addAnimationValue(values[i], val.releaseNonNull()); + addAnimationValue(values[i], val.release()); } // There are more values to process but 'none' or 'all' were already defined as the animation property, the declaration becomes invalid. @@ -3963,11 +3377,11 @@ bool CSSParser::parseTransitionShorthand(CSSPropertyID propId, bool important) // Fill in any remaining properties with the initial value. for (i = 0; i < numProperties; ++i) { if (!parsedProperty[i]) - addAnimationValue(values[i], cssValuePool.createImplicitInitialValue()); + addAnimationValue(values[i], cssValuePool().createImplicitInitialValue()); } // Now add all of the properties we found. - for (i = 0; i < numProperties; ++i) + for (i = 0; i < numProperties; i++) addPropertyWithPrefixingVariant(shorthand.properties()[i], values[i].release(), important); return true; @@ -4003,8 +3417,7 @@ bool CSSParser::parseShorthand(CSSPropertyID propId, const StylePropertyShorthan return true; // Fill in any remaining properties with the initial value. - auto& cssValuePool = CSSValuePool::singleton(); - ImplicitScope implicitScope(*this, PropertyImplicit); + ImplicitScope implicitScope(this, PropertyImplicit); const StylePropertyShorthand* propertiesForInitialization = shorthand.propertiesForInitialization(); for (unsigned i = 0; i < shorthand.length(); ++i) { if (propertyFound[i]) @@ -4013,9 +3426,9 @@ bool CSSParser::parseShorthand(CSSPropertyID propId, const StylePropertyShorthan if (propertiesForInitialization) { const StylePropertyShorthand& initProperties = propertiesForInitialization[i]; for (unsigned propIndex = 0; propIndex < initProperties.length(); ++propIndex) - addProperty(initProperties.properties()[propIndex], cssValuePool.createImplicitInitialValue(), important); + addProperty(initProperties.properties()[propIndex], cssValuePool().createImplicitInitialValue(), important); } else - addProperty(shorthand.properties()[i], cssValuePool.createImplicitInitialValue(), important); + addProperty(shorthand.properties()[i], cssValuePool().createImplicitInitialValue(), important); } return true; @@ -4041,7 +3454,7 @@ bool CSSParser::parse4Values(CSSPropertyID propId, const CSSPropertyID *properti if (!parseValue(properties[0], important)) return false; CSSValue* value = m_parsedProperties.last().value(); - ImplicitScope implicitScope(*this, PropertyImplicit); + ImplicitScope implicitScope(this, PropertyImplicit); addProperty(properties[1], value, important); addProperty(properties[2], value, important); addProperty(properties[3], value, important); @@ -4051,7 +3464,7 @@ bool CSSParser::parse4Values(CSSPropertyID propId, const CSSPropertyID *properti if (!parseValue(properties[0], important) || !parseValue(properties[1], important)) return false; CSSValue* value = m_parsedProperties[m_parsedProperties.size() - 2].value(); - ImplicitScope implicitScope(*this, PropertyImplicit); + ImplicitScope implicitScope(this, PropertyImplicit); addProperty(properties[2], value, important); value = m_parsedProperties[m_parsedProperties.size() - 2].value(); addProperty(properties[3], value, important); @@ -4061,7 +3474,7 @@ bool CSSParser::parse4Values(CSSPropertyID propId, const CSSPropertyID *properti if (!parseValue(properties[0], important) || !parseValue(properties[1], important) || !parseValue(properties[2], important)) return false; CSSValue* value = m_parsedProperties[m_parsedProperties.size() - 2].value(); - ImplicitScope implicitScope(*this, PropertyImplicit); + ImplicitScope implicitScope(this, PropertyImplicit); addProperty(properties[3], value, important); break; } @@ -4092,10 +3505,10 @@ bool CSSParser::parsePage(CSSPropertyID propId, bool important) return false; if (value->id == CSSValueAuto) { - addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value->id), important); + addProperty(propId, cssValuePool().createIdentifierValue(value->id), important); return true; } else if (value->id == 0 && value->unit == CSSPrimitiveValue::CSS_IDENT) { - addProperty(propId, createPrimitiveStringValue(*value), important); + addProperty(propId, createPrimitiveStringValue(value), important); return true; } return false; @@ -4116,14 +3529,14 @@ bool CSSParser::parseSize(CSSPropertyID propId, bool important) RefPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated(); // First parameter. - SizeParameterType paramType = parseSizeParameter(*parsedValues, *value, None); + SizeParameterType paramType = parseSizeParameter(parsedValues.get(), value, None); if (paramType == None) return false; // Second parameter, if any. value = m_valueList->next(); if (value) { - paramType = parseSizeParameter(*parsedValues, *value, paramType); + paramType = parseSizeParameter(parsedValues.get(), value, paramType); if (paramType == None) return false; } @@ -4132,19 +3545,19 @@ bool CSSParser::parseSize(CSSPropertyID propId, bool important) return true; } -CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList& parsedValues, CSSParserValue& value, SizeParameterType prevParamType) +CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList* parsedValues, CSSParserValue* value, SizeParameterType prevParamType) { - switch (value.id) { + switch (value->id) { case CSSValueAuto: if (prevParamType == None) { - parsedValues.append(CSSValuePool::singleton().createIdentifierValue(value.id)); + parsedValues->append(cssValuePool().createIdentifierValue(value->id)); return Auto; } return None; case CSSValueLandscape: case CSSValuePortrait: if (prevParamType == None || prevParamType == PageSize) { - parsedValues.append(CSSValuePool::singleton().createIdentifierValue(value.id)); + parsedValues->append(cssValuePool().createIdentifierValue(value->id)); return Orientation; } return None; @@ -4159,18 +3572,16 @@ 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 (StyleResolver::applyPageSizeProperty). - parsedValues.prepend(CSSValuePool::singleton().createIdentifierValue(value.id)); + parsedValues->prepend(cssValuePool().createIdentifierValue(value->id)); return PageSize; } return None; - case CSSValueInvalid: { - ValueWithCalculation valueWithCalculation(value); - if (validateUnit(valueWithCalculation, FLength | FNonNeg) && (prevParamType == None || prevParamType == Length)) { - parsedValues.append(createPrimitiveNumericValue(valueWithCalculation)); + case 0: + if (validUnit(value, FLength | FNonNeg) && (prevParamType == None || prevParamType == Length)) { + parsedValues->append(createPrimitiveNumericValue(value)); return Length; } return None; - } default: return None; } @@ -4181,10 +3592,13 @@ CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList& parsedV bool CSSParser::parseQuotes(CSSPropertyID propId, bool important) { RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated(); - while (CSSParserValue* value = m_valueList->current()) { - if (value->unit != CSSPrimitiveValue::CSS_STRING) + 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(CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_STRING)); + values->append(parsedValue.release()); m_valueList->next(); } if (values->length()) { @@ -4197,17 +3611,17 @@ bool CSSParser::parseQuotes(CSSPropertyID propId, bool important) bool CSSParser::parseAlt(CSSPropertyID propID, bool important) { - CSSParserValue& currentValue = *m_valueList->current(); + CSSParserValue* val = m_valueList->current(); RefPtr<CSSValue> parsedValue; - if (currentValue.unit == CSSPrimitiveValue::CSS_STRING) - parsedValue = createPrimitiveStringValue(currentValue); - else if (currentValue.unit == CSSParserValue::Function) { - CSSParserValueList* args = currentValue.function->args.get(); + if (val->unit == CSSPrimitiveValue::CSS_STRING) + parsedValue = createPrimitiveStringValue(val); + else if (val->unit == CSSParserValue::Function) { + CSSParserValueList* args = val->function->args.get(); if (!args) return false; - if (equalLettersIgnoringASCIICase(currentValue.function->name, "attr(")) - parsedValue = parseAttr(*args); + if (equalIgnoringCase(val->function->name, "attr(")) + parsedValue = parseAttr(args); } if (parsedValue) { @@ -4218,34 +3632,7 @@ bool CSSParser::parseAlt(CSSPropertyID propID, bool important) return false; } - -bool CSSParser::parseCustomPropertyDeclaration(bool important, CSSValueID id) -{ - if (m_customPropertyName.isEmpty() || !m_valueList) - return false; - auto& cssValuePool = CSSValuePool::singleton(); - RefPtr<CSSValue> value; - if (id == CSSValueInherit) - value = cssValuePool.createInheritedValue(); - else if (id == CSSValueInitial) - value = cssValuePool.createExplicitInitialValue(); - else if (id == CSSValueUnset) - value = cssValuePool.createUnsetValue(); - else if (id == CSSValueRevert) - value = cssValuePool.createRevertValue(); - else { - RefPtr<CSSValueList> valueList = CSSValueList::createFromParserValueList(*m_valueList); - if (m_valueList->containsVariables()) - value = CSSVariableDependentValue::create(valueList, CSSPropertyCustom); - else - value = valueList; - } - - addProperty(CSSPropertyCustom, CSSCustomPropertyValue::create(m_customPropertyName, value), important, false); - return true; -} - // [ <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 @@ -4253,40 +3640,40 @@ bool CSSParser::parseContent(CSSPropertyID propId, bool important) { RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated(); - while (CSSParserValue* value = m_valueList->current()) { + while (CSSParserValue* val = m_valueList->current()) { RefPtr<CSSValue> parsedValue; - if (value->unit == CSSPrimitiveValue::CSS_URI) { + if (val->unit == CSSPrimitiveValue::CSS_URI) { // url - parsedValue = CSSImageValue::create(completeURL(value->string)); - } else if (value->unit == CSSParserValue::Function) { + parsedValue = CSSImageValue::create(completeURL(val->string)); + } else if (val->unit == CSSParserValue::Function) { // attr(X) | counter(X [,Y]) | counters(X, Y, [,Z]) | -webkit-gradient(...) - CSSParserValueList* args = value->function->args.get(); + CSSParserValueList* args = val->function->args.get(); if (!args) return false; - if (equalLettersIgnoringASCIICase(value->function->name, "attr(")) { - parsedValue = parseAttr(*args); + if (equalIgnoringCase(val->function->name, "attr(")) { + parsedValue = parseAttr(args); if (!parsedValue) return false; - } else if (equalLettersIgnoringASCIICase(value->function->name, "counter(")) { - parsedValue = parseCounterContent(*args, false); + } else if (equalIgnoringCase(val->function->name, "counter(")) { + parsedValue = parseCounterContent(args, false); if (!parsedValue) return false; - } else if (equalLettersIgnoringASCIICase(value->function->name, "counters(")) { - parsedValue = parseCounterContent(*args, true); + } else if (equalIgnoringCase(val->function->name, "counters(")) { + parsedValue = parseCounterContent(args, true); if (!parsedValue) return false; #if ENABLE(CSS_IMAGE_SET) - } else if (equalLettersIgnoringASCIICase(value->function->name, "-webkit-image-set(")) { + } else if (equalIgnoringCase(val->function->name, "-webkit-image-set(")) { parsedValue = parseImageSet(); if (!parsedValue) return false; #endif - } else if (isGeneratedImageValue(*value)) { - if (!parseGeneratedImage(*m_valueList, parsedValue)) + } else if (isGeneratedImageValue(val)) { + if (!parseGeneratedImage(m_valueList.get(), parsedValue)) return false; } else return false; - } else if (value->unit == CSSPrimitiveValue::CSS_IDENT) { + } else if (val->unit == CSSPrimitiveValue::CSS_IDENT) { // open-quote // close-quote // no-open-quote @@ -4295,24 +3682,24 @@ bool CSSParser::parseContent(CSSPropertyID propId, bool important) // FIXME: These are not yet implemented (http://bugs.webkit.org/show_bug.cgi?id=6503). // none // normal - switch (value->id) { + switch (val->id) { case CSSValueOpenQuote: case CSSValueCloseQuote: case CSSValueNoOpenQuote: case CSSValueNoCloseQuote: case CSSValueNone: case CSSValueNormal: - parsedValue = CSSValuePool::singleton().createIdentifierValue(value->id); + parsedValue = cssValuePool().createIdentifierValue(val->id); break; default: break; } - } else if (value->unit == CSSPrimitiveValue::CSS_STRING) { - parsedValue = createPrimitiveStringValue(*value); + } else if (val->unit == CSSPrimitiveValue::CSS_STRING) { + parsedValue = createPrimitiveStringValue(val); } if (!parsedValue) break; - values->append(parsedValue.releaseNonNull()); + values->append(parsedValue.release()); m_valueList->next(); } @@ -4325,56 +3712,54 @@ bool CSSParser::parseContent(CSSPropertyID propId, bool important) return false; } -RefPtr<CSSValue> CSSParser::parseAttr(CSSParserValueList& args) +PassRefPtr<CSSValue> CSSParser::parseAttr(CSSParserValueList* args) { - if (args.size() != 1) - return nullptr; - - CSSParserValue& argument = *args.current(); + if (args->size() != 1) + return 0; - if (argument.unit != CSSPrimitiveValue::CSS_IDENT) - return nullptr; + CSSParserValue* a = args->current(); - ASSERT(argument.string.length()); + if (a->unit != CSSPrimitiveValue::CSS_IDENT) + return 0; + String attrName = a->string; // CSS allows identifiers with "-" at the start, like "-webkit-mask-image". // But HTML attribute names can't have those characters, and we should not // even parse them inside attr(). - if (argument.string[0] == '-') - return nullptr; + if (attrName[0] == '-') + return 0; if (m_context.isHTMLDocument) - argument.string.convertToASCIILowercaseInPlace(); + attrName = attrName.lower(); - // FIXME: Is there some small benefit to creating an AtomicString here instead of a String? - return CSSValuePool::singleton().createValue(String(argument.string), CSSPrimitiveValue::CSS_ATTR); + return cssValuePool().createValue(attrName, CSSPrimitiveValue::CSS_ATTR); } -RefPtr<CSSValue> CSSParser::parseBackgroundColor() +PassRefPtr<CSSValue> CSSParser::parseBackgroundColor() { CSSValueID id = m_valueList->current()->id; - if (id == CSSValueWebkitText || isValidSystemColorValue(id) || id == CSSValueMenu || id == CSSValueCurrentcolor - || (id >= CSSValueGrey && id < CSSValueWebkitText && inQuirksMode())) - return CSSValuePool::singleton().createIdentifierValue(id); + if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor || + (id >= CSSValueGrey && id < CSSValueWebkitText && inQuirksMode())) + return cssValuePool().createIdentifierValue(id); return parseColor(); } -bool CSSParser::parseFillImage(CSSParserValueList& valueList, RefPtr<CSSValue>& value) +bool CSSParser::parseFillImage(CSSParserValueList* valueList, RefPtr<CSSValue>& value) { - if (valueList.current()->id == CSSValueNone) { - value = CSSValuePool::singleton().createIdentifierValue(CSSValueNone); + if (valueList->current()->id == CSSValueNone) { + value = cssValuePool().createIdentifierValue(CSSValueNone); return true; } - if (valueList.current()->unit == CSSPrimitiveValue::CSS_URI) { - value = CSSImageValue::create(completeURL(valueList.current()->string)); + if (valueList->current()->unit == CSSPrimitiveValue::CSS_URI) { + value = CSSImageValue::create(completeURL(valueList->current()->string)); return true; } - if (isGeneratedImageValue(*valueList.current())) + if (isGeneratedImageValue(valueList->current())) return parseGeneratedImage(valueList, value); #if ENABLE(CSS_IMAGE_SET) - if (valueList.current()->unit == CSSParserValue::Function && equalLettersIgnoringASCIICase(valueList.current()->function->name, "-webkit-image-set(")) { + if (valueList->current()->unit == CSSParserValue::Function && equalIgnoringCase(valueList->current()->function->name, "-webkit-image-set(")) { value = parseImageSet(); if (value) return true; @@ -4384,48 +3769,46 @@ bool CSSParser::parseFillImage(CSSParserValueList& valueList, RefPtr<CSSValue>& return false; } -RefPtr<CSSPrimitiveValue> CSSParser::parsePositionX(CSSParserValueList& valueList) +PassRefPtr<CSSValue> CSSParser::parseFillPositionX(CSSParserValueList* valueList) { - int id = valueList.current()->id; + 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 CSSValuePool::singleton().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE); + return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE); } - ValueWithCalculation valueWithCalculation(*valueList.current()); - if (validateUnit(valueWithCalculation, FPercent | FLength)) - return createPrimitiveNumericValue(valueWithCalculation); - return nullptr; + if (validUnit(valueList->current(), FPercent | FLength)) + return createPrimitiveNumericValue(valueList->current()); + return 0; } -RefPtr<CSSPrimitiveValue> CSSParser::parsePositionY(CSSParserValueList& valueList) +PassRefPtr<CSSValue> CSSParser::parseFillPositionY(CSSParserValueList* valueList) { - int id = valueList.current()->id; + 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 CSSValuePool::singleton().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE); + return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE); } - ValueWithCalculation valueWithCalculation(*valueList.current()); - if (validateUnit(valueWithCalculation, FPercent | FLength)) - return createPrimitiveNumericValue(valueWithCalculation); - return nullptr; + if (validUnit(valueList->current(), FPercent | FLength)) + return createPrimitiveNumericValue(valueList->current()); + return 0; } -RefPtr<CSSPrimitiveValue> CSSParser::parseFillPositionComponent(CSSParserValueList& valueList, unsigned& cumulativeFlags, FillPositionFlag& individualFlag, FillPositionParsingMode parsingMode) +PassRefPtr<CSSPrimitiveValue> CSSParser::parseFillPositionComponent(CSSParserValueList* valueList, unsigned& cumulativeFlags, FillPositionFlag& individualFlag, FillPositionParsingMode parsingMode) { - CSSValueID id = valueList.current()->id; + CSSValueID id = valueList->current()->id; if (id == CSSValueLeft || id == CSSValueTop || id == CSSValueRight || id == CSSValueBottom || id == CSSValueCenter) { int percent = 0; if (id == CSSValueLeft || id == CSSValueRight) { if (cumulativeFlags & XFillPosition) - return nullptr; + return 0; cumulativeFlags |= XFillPosition; individualFlag = XFillPosition; if (id == CSSValueRight) @@ -4433,7 +3816,7 @@ RefPtr<CSSPrimitiveValue> CSSParser::parseFillPositionComponent(CSSParserValueLi } else if (id == CSSValueTop || id == CSSValueBottom) { if (cumulativeFlags & YFillPosition) - return nullptr; + return 0; cumulativeFlags |= YFillPosition; individualFlag = YFillPosition; if (id == CSSValueBottom) @@ -4446,23 +3829,25 @@ RefPtr<CSSPrimitiveValue> CSSParser::parseFillPositionComponent(CSSParserValueLi } if (parsingMode == ResolveValuesAsKeyword) - return CSSValuePool::singleton().createIdentifierValue(id); + return cssValuePool().createIdentifierValue(id); - return CSSValuePool::singleton().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE); + return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE); } - ValueWithCalculation valueWithCalculation(*valueList.current()); - if (validateUnit(valueWithCalculation, FPercent | FLength)) { + if (validUnit(valueList->current(), FPercent | FLength)) { if (!cumulativeFlags) { cumulativeFlags |= XFillPosition; individualFlag = XFillPosition; } else if (cumulativeFlags & (XFillPosition | AmbiguousFillPosition)) { cumulativeFlags |= YFillPosition; individualFlag = YFillPosition; - } else - return nullptr; - return createPrimitiveNumericValue(valueWithCalculation); + } else { + if (m_parsedCalculation) + m_parsedCalculation.release(); + return 0; + } + return createPrimitiveNumericValue(valueList->current()); } - return nullptr; + return 0; } static bool isValueConflictingWithCurrentEdge(int value1, int value2) @@ -4481,7 +3866,7 @@ static bool isFillPositionKeyword(CSSValueID value) return value == CSSValueLeft || value == CSSValueTop || value == CSSValueBottom || value == CSSValueRight || value == CSSValueCenter; } -void CSSParser::parse4ValuesFillPosition(CSSParserValueList& valueList, RefPtr<CSSPrimitiveValue>& value1, RefPtr<CSSPrimitiveValue>& value2, RefPtr<CSSPrimitiveValue>&& parsedValue1, RefPtr<CSSPrimitiveValue>&& parsedValue2) +void CSSParser::parse4ValuesFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2, PassRefPtr<CSSPrimitiveValue> parsedValue1, PassRefPtr<CSSPrimitiveValue> parsedValue2) { // [ left | right ] [ <percentage] | <length> ] && [ top | bottom ] [ <percentage> | <length> ] // In the case of 4 values <position> requires the second value to be a length or a percentage. @@ -4509,7 +3894,7 @@ void CSSParser::parse4ValuesFillPosition(CSSParserValueList& valueList, RefPtr<C if (isValueConflictingWithCurrentEdge(ident1, ident3)) return; - valueList.next(); + valueList->next(); cumulativeFlags = 0; FillPositionFlag value4Flag = InvalidFillPosition; @@ -4521,15 +3906,15 @@ void CSSParser::parse4ValuesFillPosition(CSSParserValueList& valueList, RefPtr<C if (isFillPositionKeyword(value4->getValueID())) return; - value1 = createPrimitiveValuePair(WTFMove(parsedValue1), WTFMove(parsedValue2)); - value2 = createPrimitiveValuePair(value3.copyRef(), value4.copyRef()); + value1 = createPrimitiveValuePair(parsedValue1, parsedValue2); + value2 = createPrimitiveValuePair(value3, value4); if (ident1 == CSSValueTop || ident1 == CSSValueBottom) value1.swap(value2); - valueList.next(); + valueList->next(); } -void CSSParser::parse3ValuesFillPosition(CSSParserValueList& valueList, RefPtr<CSSPrimitiveValue>& value1, RefPtr<CSSPrimitiveValue>& value2, RefPtr<CSSPrimitiveValue>&& parsedValue1, RefPtr<CSSPrimitiveValue>&& parsedValue2) +void CSSParser::parse3ValuesFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2, PassRefPtr<CSSPrimitiveValue> parsedValue1, PassRefPtr<CSSPrimitiveValue> parsedValue2) { unsigned cumulativeFlags = 0; FillPositionFlag value3Flag = InvalidFillPosition; @@ -4539,7 +3924,7 @@ void CSSParser::parse3ValuesFillPosition(CSSParserValueList& valueList, RefPtr<C if (!value3) return; - valueList.next(); + valueList->next(); bool swapNeeded = false; CSSValueID ident1 = parsedValue1->getValueID(); @@ -4549,7 +3934,6 @@ void CSSParser::parse3ValuesFillPosition(CSSParserValueList& valueList, RefPtr<C CSSValueID firstPositionKeyword; CSSValueID secondPositionKeyword; - auto& cssValuePool = CSSValuePool::singleton(); if (ident1 == CSSValueCenter) { // <position> requires the first 'center' to be followed by a keyword. if (!isFillPositionKeyword(ident2)) @@ -4564,8 +3948,8 @@ void CSSParser::parse3ValuesFillPosition(CSSParserValueList& valueList, RefPtr<C firstPositionKeyword = CSSValueTop; swapNeeded = true; } - value1 = createPrimitiveValuePair(cssValuePool.createIdentifierValue(firstPositionKeyword), cssValuePool.createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE)); - value2 = createPrimitiveValuePair(WTFMove(parsedValue2), value3.copyRef()); + value1 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(firstPositionKeyword), cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE)); + value2 = createPrimitiveValuePair(parsedValue2, value3); } else if (ident3 == CSSValueCenter) { if (isFillPositionKeyword(ident2)) return; @@ -4575,8 +3959,8 @@ void CSSParser::parse3ValuesFillPosition(CSSParserValueList& valueList, RefPtr<C secondPositionKeyword = CSSValueLeft; swapNeeded = true; } - value1 = createPrimitiveValuePair(WTFMove(parsedValue1), parsedValue2.copyRef()); - value2 = createPrimitiveValuePair(cssValuePool.createIdentifierValue(secondPositionKeyword), cssValuePool.createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE)); + value1 = createPrimitiveValuePair(parsedValue1, parsedValue2); + value2 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(secondPositionKeyword), cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE)); } else { RefPtr<CSSPrimitiveValue> firstPositionValue; RefPtr<CSSPrimitiveValue> secondPositionValue; @@ -4590,7 +3974,7 @@ void CSSParser::parse3ValuesFillPosition(CSSParserValueList& valueList, RefPtr<C secondPositionValue = value3; secondPositionKeyword = ident2; - firstPositionValue = cssValuePool.createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE); + firstPositionValue = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE); } else { // Per CSS, we should only accept: [ right | left | top | bottom ] [ <percentage> | <length> ] [ center | left | right | bottom | top ]. if (!isFillPositionKeyword(ident3)) @@ -4598,43 +3982,40 @@ void CSSParser::parse3ValuesFillPosition(CSSParserValueList& valueList, RefPtr<C firstPositionValue = parsedValue2; secondPositionKeyword = ident3; - secondPositionValue = cssValuePool.createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE); + secondPositionValue = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE); } if (isValueConflictingWithCurrentEdge(ident1, secondPositionKeyword)) return; - value1 = createPrimitiveValuePair(WTFMove(parsedValue1), firstPositionValue.copyRef()); - value2 = createPrimitiveValuePair(cssValuePool.createIdentifierValue(secondPositionKeyword), secondPositionValue.copyRef()); + value1 = createPrimitiveValuePair(parsedValue1, firstPositionValue); + value2 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(secondPositionKeyword), secondPositionValue); } if (ident1 == CSSValueTop || ident1 == CSSValueBottom || swapNeeded) value1.swap(value2); #ifndef NDEBUG - CSSPrimitiveValue& first = *value1; - CSSPrimitiveValue& second = *value2; - ident1 = first.getPairValue()->first()->getValueID(); - ident2 = second.getPairValue()->first()->getValueID(); + CSSPrimitiveValue* first = toCSSPrimitiveValue(value1.get()); + CSSPrimitiveValue* second = toCSSPrimitiveValue(value2.get()); + ident1 = first->getPairValue()->first()->getValueID(); + ident2 = second->getPairValue()->first()->getValueID(); ASSERT(ident1 == CSSValueLeft || ident1 == CSSValueRight); ASSERT(ident2 == CSSValueBottom || ident2 == CSSValueTop); #endif } -inline bool CSSParser::isPotentialPositionValue(CSSParserValue& value) +inline bool CSSParser::isPotentialPositionValue(CSSParserValue* value) { - if (isFillPositionKeyword(value.id)) - return true; - ValueWithCalculation valueWithCalculation(value); - return validateUnit(valueWithCalculation, FPercent | FLength); + return isFillPositionKeyword(value->id) || validUnit(value, FPercent | FLength, ReleaseParsedCalcValue); } -void CSSParser::parseFillPosition(CSSParserValueList& valueList, RefPtr<CSSPrimitiveValue>& value1, RefPtr<CSSPrimitiveValue>& value2) +void CSSParser::parseFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2) { unsigned numberOfValues = 0; - for (unsigned i = valueList.currentIndex(); i < valueList.size(); ++i, ++numberOfValues) { - CSSParserValue* current = valueList.valueAt(i); - if (!current || isComma(current) || isForwardSlashOperator(*current) || !isPotentialPositionValue(*current)) + for (unsigned i = valueList->currentIndex(); i < valueList->size(); ++i, ++numberOfValues) { + CSSParserValue* current = valueList->valueAt(i); + if (isComma(current) || !current || isForwardSlashOperator(current) || !isPotentialPositionValue(current)) break; } @@ -4649,7 +4030,7 @@ void CSSParser::parseFillPosition(CSSParserValueList& valueList, RefPtr<CSSPrimi ASSERT(numberOfValues > 2 && numberOfValues <= 4); - CSSParserValue* value = valueList.current(); + CSSParserValue* value = valueList->current(); // <position> requires the first value to be a background keyword. if (!isFillPositionKeyword(value->id)) @@ -4663,38 +4044,38 @@ void CSSParser::parseFillPosition(CSSParserValueList& valueList, RefPtr<CSSPrimi if (!value1) return; - value = valueList.next(); + value = valueList->next(); // In case we are parsing more than two values, relax the check inside of parseFillPositionComponent. top 20px is // a valid start for <position>. cumulativeFlags = AmbiguousFillPosition; value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag, ResolveValuesAsKeyword); if (value2) - valueList.next(); + valueList->next(); else { - value1 = nullptr; + value1.clear(); return; } - RefPtr<CSSPrimitiveValue> parsedValue1 = value1; - RefPtr<CSSPrimitiveValue> parsedValue2 = value2; + RefPtr<CSSPrimitiveValue> parsedValue1 = toCSSPrimitiveValue(value1.get()); + RefPtr<CSSPrimitiveValue> parsedValue2 = toCSSPrimitiveValue(value2.get()); - value1 = nullptr; - value2 = nullptr; + value1.clear(); + value2.clear(); // Per CSS3 syntax, <position> can't have 'center' as its second keyword as we have more arguments to follow. if (parsedValue2->getValueID() == CSSValueCenter) return; if (numberOfValues == 3) - parse3ValuesFillPosition(valueList, value1, value2, WTFMove(parsedValue1), WTFMove(parsedValue2)); + parse3ValuesFillPosition(valueList, value1, value2, parsedValue1.release(), parsedValue2.release()); else - parse4ValuesFillPosition(valueList, value1, value2, WTFMove(parsedValue1), WTFMove(parsedValue2)); + parse4ValuesFillPosition(valueList, value1, value2, parsedValue1.release(), parsedValue2.release()); } -void CSSParser::parse2ValuesFillPosition(CSSParserValueList& valueList, RefPtr<CSSPrimitiveValue>& value1, RefPtr<CSSPrimitiveValue>& value2) +void CSSParser::parse2ValuesFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2) { - CSSParserValue* value = valueList.current(); + 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. unsigned cumulativeFlags = 0; @@ -4707,19 +4088,19 @@ void CSSParser::parse2ValuesFillPosition(CSSParserValueList& valueList, RefPtr<C // It only takes one value for background-position to be correctly parsed if it was specified in a shorthand (since we // can assume that any other values belong to the rest of the shorthand). If we're not parsing a shorthand, though, the // value was explicitly specified for our property. - value = valueList.next(); + value = valueList->next(); // First check for the comma. If so, we are finished parsing this value or value pair. if (isComma(value)) - value = nullptr; + value = 0; if (value) { value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag); if (value2) - valueList.next(); + valueList->next(); else { if (!inShorthand()) { - value1 = nullptr; + value1.clear(); return; } } @@ -4730,7 +4111,7 @@ void CSSParser::parse2ValuesFillPosition(CSSParserValueList& valueList, RefPtr<C // 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 = CSSValuePool::singleton().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE); + value2 = cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE); if (value1Flag == YFillPosition || value2Flag == XFillPosition) value1.swap(value2); @@ -4741,22 +4122,22 @@ void CSSParser::parseFillRepeat(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& valu CSSValueID id = m_valueList->current()->id; if (id == CSSValueRepeatX) { m_implicitShorthand = true; - value1 = CSSValuePool::singleton().createIdentifierValue(CSSValueRepeat); - value2 = CSSValuePool::singleton().createIdentifierValue(CSSValueNoRepeat); + value1 = cssValuePool().createIdentifierValue(CSSValueRepeat); + value2 = cssValuePool().createIdentifierValue(CSSValueNoRepeat); m_valueList->next(); return; } if (id == CSSValueRepeatY) { m_implicitShorthand = true; - value1 = CSSValuePool::singleton().createIdentifierValue(CSSValueNoRepeat); - value2 = CSSValuePool::singleton().createIdentifierValue(CSSValueRepeat); + value1 = cssValuePool().createIdentifierValue(CSSValueNoRepeat); + value2 = cssValuePool().createIdentifierValue(CSSValueRepeat); m_valueList->next(); return; } if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace) - value1 = CSSValuePool::singleton().createIdentifierValue(id); + value1 = cssValuePool().createIdentifierValue(id); else { - value1 = nullptr; + value1 = 0; return; } @@ -4766,7 +4147,7 @@ void CSSParser::parseFillRepeat(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& valu if (value && !isComma(value)) { id = value->id; if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace) { - value2 = CSSValuePool::singleton().createIdentifierValue(id); + value2 = cssValuePool().createIdentifierValue(id); m_valueList->next(); return; } @@ -4774,26 +4155,25 @@ void CSSParser::parseFillRepeat(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& valu // If only one value was specified, value2 is the same as value1. m_implicitShorthand = true; - value2 = CSSValuePool::singleton().createIdentifierValue(downcast<CSSPrimitiveValue>(*value1).getValueID()); + value2 = cssValuePool().createIdentifierValue(toCSSPrimitiveValue(value1.get())->getValueID()); } -RefPtr<CSSValue> CSSParser::parseFillSize(CSSPropertyID propId, bool& allowComma) +PassRefPtr<CSSValue> CSSParser::parseFillSize(CSSPropertyID propId, bool& allowComma) { allowComma = true; CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueContain || value->id == CSSValueCover) - return CSSValuePool::singleton().createIdentifierValue(value->id); + return cssValuePool().createIdentifierValue(value->id); RefPtr<CSSPrimitiveValue> parsedValue1; if (value->id == CSSValueAuto) - parsedValue1 = CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); + parsedValue1 = cssValuePool().createIdentifierValue(CSSValueAuto); else { - ValueWithCalculation valueWithCalculation(*value); - if (!validateUnit(valueWithCalculation, FLength | FPercent)) - return nullptr; - parsedValue1 = createPrimitiveNumericValue(valueWithCalculation); + if (!validUnit(value, FLength | FPercent)) + return 0; + parsedValue1 = createPrimitiveNumericValue(value); } RefPtr<CSSPrimitiveValue> parsedValue2; @@ -4801,14 +4181,13 @@ RefPtr<CSSValue> CSSParser::parseFillSize(CSSPropertyID propId, bool& allowComma if (value->unit == CSSParserValue::Operator && value->iValue == ',') allowComma = false; else if (value->id != CSSValueAuto) { - ValueWithCalculation valueWithCalculation(*value); - if (!validateUnit(valueWithCalculation, FLength | FPercent)) { + if (!validUnit(value, FLength | FPercent)) { if (!inShorthand()) - return nullptr; + return 0; // We need to rewind the value list, so that when it is advanced we'll end up back at this value. m_valueList->previous(); } else - parsedValue2 = createPrimitiveNumericValue(valueWithCalculation); + parsedValue2 = createPrimitiveNumericValue(value); } } else if (!parsedValue2 && propId == CSSPropertyWebkitBackgroundSize) { // For backwards compatibility we set the second value to the first if it is omitted. @@ -4819,7 +4198,7 @@ RefPtr<CSSValue> CSSParser::parseFillSize(CSSPropertyID propId, bool& allowComma if (!parsedValue2) return parsedValue1; - return createPrimitiveValuePair(WTFMove(parsedValue1), WTFMove(parsedValue2), propId == CSSPropertyWebkitBackgroundSize ? Pair::IdenticalValueEncoding::Coalesce : Pair::IdenticalValueEncoding::DoNotCoalesce); + return createPrimitiveValuePair(parsedValue1.release(), parsedValue2.release()); } bool CSSParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, @@ -4827,13 +4206,13 @@ bool CSSParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, { RefPtr<CSSValueList> values; RefPtr<CSSValueList> values2; - CSSParserValue* currentValue; + CSSParserValue* val; RefPtr<CSSValue> value; RefPtr<CSSValue> value2; bool allowComma = false; - retValue1 = retValue2 = nullptr; + retValue1 = retValue2 = 0; propId1 = propId; propId2 = propId; if (propId == CSSPropertyBackgroundPosition) { @@ -4850,12 +4229,12 @@ bool CSSParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, propId2 = CSSPropertyWebkitMaskRepeatY; } - while ((currentValue = m_valueList->current())) { + while ((val = m_valueList->current())) { RefPtr<CSSValue> currValue; RefPtr<CSSValue> currValue2; if (allowComma) { - if (!isComma(currentValue)) + if (!isComma(val)) return false; m_valueList->next(); allowComma = false; @@ -4868,14 +4247,14 @@ bool CSSParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, m_valueList->next(); break; case CSSPropertyBackgroundAttachment: - if (currentValue->id == CSSValueScroll || currentValue->id == CSSValueFixed || currentValue->id == CSSValueLocal) { - currValue = CSSValuePool::singleton().createIdentifierValue(currentValue->id); + if (val->id == CSSValueScroll || val->id == CSSValueFixed || val->id == CSSValueLocal) { + currValue = cssValuePool().createIdentifierValue(val->id); m_valueList->next(); } break; case CSSPropertyBackgroundImage: case CSSPropertyWebkitMaskImage: - if (parseFillImage(*m_valueList, currValue)) + if (parseFillImage(m_valueList.get(), currValue)) m_valueList->next(); break; case CSSPropertyWebkitBackgroundClip: @@ -4884,62 +4263,58 @@ bool CSSParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, case CSSPropertyWebkitMaskOrigin: // The first three values here are deprecated and do not apply to the version of the property that has // the -webkit- prefix removed. - if (currentValue->id == CSSValueBorder || currentValue->id == CSSValuePadding || currentValue->id == CSSValueContent - || currentValue->id == CSSValueBorderBox || currentValue->id == CSSValuePaddingBox || currentValue->id == CSSValueContentBox - || ((propId == CSSPropertyWebkitBackgroundClip || propId == CSSPropertyWebkitMaskClip) - && (currentValue->id == CSSValueText || currentValue->id == CSSValueWebkitText))) { - currValue = CSSValuePool::singleton().createIdentifierValue(currentValue->id); + if (val->id == CSSValueBorder || val->id == CSSValuePadding || val->id == CSSValueContent || + val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox || + ((propId == CSSPropertyWebkitBackgroundClip || propId == CSSPropertyWebkitMaskClip) && + (val->id == CSSValueText || val->id == CSSValueWebkitText))) { + currValue = cssValuePool().createIdentifierValue(val->id); m_valueList->next(); } break; case CSSPropertyBackgroundClip: - if (parseBackgroundClip(*currentValue, currValue)) + if (parseBackgroundClip(val, currValue)) m_valueList->next(); break; case CSSPropertyBackgroundOrigin: - if (currentValue->id == CSSValueBorderBox || currentValue->id == CSSValuePaddingBox || currentValue->id == CSSValueContentBox) { - currValue = CSSValuePool::singleton().createIdentifierValue(currentValue->id); + if (val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox) { + currValue = cssValuePool().createIdentifierValue(val->id); m_valueList->next(); } break; case CSSPropertyBackgroundPosition: - case CSSPropertyWebkitMaskPosition: { - RefPtr<CSSPrimitiveValue> value1; - RefPtr<CSSPrimitiveValue> value2; - parseFillPosition(*m_valueList, value1, value2); - currValue = value1; - currValue2 = value2; + case CSSPropertyWebkitMaskPosition: + parseFillPosition(m_valueList.get(), currValue, currValue2); // parseFillPosition advances the m_valueList pointer. break; - } case CSSPropertyBackgroundPositionX: case CSSPropertyWebkitMaskPositionX: { - currValue = parsePositionX(*m_valueList); + currValue = parseFillPositionX(m_valueList.get()); if (currValue) m_valueList->next(); break; } case CSSPropertyBackgroundPositionY: case CSSPropertyWebkitMaskPositionY: { - currValue = parsePositionY(*m_valueList); + currValue = parseFillPositionY(m_valueList.get()); if (currValue) m_valueList->next(); break; } case CSSPropertyWebkitBackgroundComposite: case CSSPropertyWebkitMaskComposite: - if (currentValue->id >= CSSValueClear && currentValue->id <= CSSValuePlusLighter) { - currValue = CSSValuePool::singleton().createIdentifierValue(currentValue->id); + if (val->id >= CSSValueClear && val->id <= CSSValuePlusLighter) { + currValue = cssValuePool().createIdentifierValue(val->id); m_valueList->next(); } break; - case CSSPropertyBackgroundBlendMode: - if (cssCompositingEnabled() && (currentValue->id == CSSValueNormal || currentValue->id == CSSValueMultiply - || currentValue->id == CSSValueScreen || currentValue->id == CSSValueOverlay || currentValue->id == CSSValueDarken - || currentValue->id == CSSValueLighten || currentValue->id == CSSValueColorDodge || currentValue->id == CSSValueColorBurn - || currentValue->id == CSSValueHardLight || currentValue->id == CSSValueSoftLight || currentValue->id == CSSValueDifference - || currentValue->id == CSSValueExclusion)) { - currValue = CSSValuePool::singleton().createIdentifierValue(currentValue->id); + case CSSPropertyWebkitBackgroundBlendMode: + if (cssCompositingEnabled() && (val->id == CSSValueNormal || val->id == CSSValueMultiply + || val->id == CSSValueScreen || val->id == CSSValueOverlay || val->id == CSSValueDarken + || val->id == CSSValueLighten || val->id == CSSValueColorDodge || val->id == CSSValueColorBurn + || val->id == CSSValueHardLight || val->id == CSSValueSoftLight || val->id == CSSValueDifference + || val->id == CSSValueExclusion || val->id == CSSValueHue || val->id == CSSValueSaturation + || val->id == CSSValueColor || val->id == CSSValueLuminosity)) { + currValue = cssValuePool().createIdentifierValue(val->id); m_valueList->next(); } break; @@ -4957,11 +4332,11 @@ bool CSSParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, break; } case CSSPropertyWebkitMaskSourceType: { - if (currentValue->id == CSSValueAuto || currentValue->id == CSSValueAlpha || currentValue->id == CSSValueLuminance) { - currValue = CSSValuePool::singleton().createIdentifierValue(currentValue->id); + if (val->id == CSSValueAuto || val->id == CSSValueAlpha || val->id == CSSValueLuminance) { + currValue = cssValuePool().createIdentifierValue(val->id); m_valueList->next(); } else - currValue = nullptr; + currValue = 0; break; } default: @@ -4972,21 +4347,21 @@ bool CSSParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, if (value && !values) { values = CSSValueList::createCommaSeparated(); - values->append(value.releaseNonNull()); + values->append(value.release()); } if (value2 && !values2) { values2 = CSSValueList::createCommaSeparated(); - values2->append(value2.releaseNonNull()); + values2->append(value2.release()); } if (values) - values->append(currValue.releaseNonNull()); + values->append(currValue.release()); else value = currValue.release(); if (currValue2) { if (values2) - values2->append(currValue2.releaseNonNull()); + values2->append(currValue2.release()); else value2 = currValue2.release(); } @@ -5012,268 +4387,190 @@ bool CSSParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, return false; } -RefPtr<CSSValue> CSSParser::parseAnimationDelay() +PassRefPtr<CSSValue> CSSParser::parseAnimationDelay() { - ValueWithCalculation valueWithCalculation(*m_valueList->current()); - if (validateUnit(valueWithCalculation, FTime)) - return createPrimitiveNumericValue(valueWithCalculation); - return nullptr; + CSSParserValue* value = m_valueList->current(); + if (validUnit(value, FTime)) + return createPrimitiveNumericValue(value); + return 0; } -RefPtr<CSSValue> CSSParser::parseAnimationDirection() +PassRefPtr<CSSValue> CSSParser::parseAnimationDirection() { CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueNormal || value->id == CSSValueAlternate || value->id == CSSValueReverse || value->id == CSSValueAlternateReverse) - return CSSValuePool::singleton().createIdentifierValue(value->id); - return nullptr; + return cssValuePool().createIdentifierValue(value->id); + return 0; } -RefPtr<CSSValue> CSSParser::parseAnimationDuration() +PassRefPtr<CSSValue> CSSParser::parseAnimationDuration() { - ValueWithCalculation valueWithCalculation(*m_valueList->current()); - if (validateUnit(valueWithCalculation, FTime | FNonNeg)) - return createPrimitiveNumericValue(valueWithCalculation); - return nullptr; + CSSParserValue* value = m_valueList->current(); + if (validUnit(value, FTime | FNonNeg)) + return createPrimitiveNumericValue(value); + return 0; } -RefPtr<CSSValue> CSSParser::parseAnimationFillMode() +PassRefPtr<CSSValue> CSSParser::parseAnimationFillMode() { CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueNone || value->id == CSSValueForwards || value->id == CSSValueBackwards || value->id == CSSValueBoth) - return CSSValuePool::singleton().createIdentifierValue(value->id); - return nullptr; + return cssValuePool().createIdentifierValue(value->id); + return 0; } -RefPtr<CSSValue> CSSParser::parseAnimationIterationCount() +PassRefPtr<CSSValue> CSSParser::parseAnimationIterationCount() { - CSSParserValue& value = *m_valueList->current(); - if (value.id == CSSValueInfinite) - return CSSValuePool::singleton().createIdentifierValue(value.id); - ValueWithCalculation valueWithCalculation(value); - if (validateUnit(valueWithCalculation, FNumber | FNonNeg)) - return createPrimitiveNumericValue(valueWithCalculation); - return nullptr; + CSSParserValue* value = m_valueList->current(); + if (value->id == CSSValueInfinite) + return cssValuePool().createIdentifierValue(value->id); + if (validUnit(value, FNumber | FNonNeg)) + return createPrimitiveNumericValue(value); + return 0; } -RefPtr<CSSValue> CSSParser::parseAnimationName() +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 && equalLettersIgnoringASCIICase(value, "none"))) { - return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); + 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, "none"))) { + return cssValuePool().createIdentifierValue(CSSValueNone); + } else { + return createPrimitiveStringValue(value); } - return createPrimitiveStringValue(value); } - return nullptr; -} - -RefPtr<CSSValue> CSSParser::parseAnimationPlayState() -{ - CSSParserValue& value = *m_valueList->current(); - if (value.id == CSSValueRunning || value.id == CSSValuePaused) - return CSSValuePool::singleton().createIdentifierValue(value.id); - return nullptr; + return 0; } -#if ENABLE(CSS_ANIMATIONS_LEVEL_2) -RefPtr<CSSValue> CSSParser::parseAnimationTrigger() +PassRefPtr<CSSValue> CSSParser::parseAnimationPlayState() { CSSParserValue* value = m_valueList->current(); - if (value->id == CSSValueAuto) - return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); - - if (value->unit != CSSParserValue::Function) - return nullptr; - - CSSParserValueList* args = value->function->args.get(); - - if (equalLettersIgnoringASCIICase(value->function->name, "container-scroll(")) { - if (!args || (args->size() != 1 && args->size() != 3)) - return nullptr; - - CSSParserValue* argument = args->current(); - ValueWithCalculation firstArgumentWithCalculation(*argument); - if (!validateUnit(firstArgumentWithCalculation, FLength)) - return nullptr; - - RefPtr<CSSValue> startValue = createPrimitiveNumericValue(firstArgumentWithCalculation); - - argument = args->next(); - - if (!argument) - return CSSAnimationTriggerScrollValue::create(startValue.release()); - - if (!isComma(argument)) - return nullptr; - - argument = args->next(); - ValueWithCalculation secondArgumentWithCalculation(*argument); - if (!validateUnit(secondArgumentWithCalculation, FLength)) - return nullptr; - - RefPtr<CSSValue> endValue = createPrimitiveNumericValue(secondArgumentWithCalculation); - - return CSSAnimationTriggerScrollValue::create(startValue.release(), endValue.release()); - } - - return nullptr; + if (value->id == CSSValueRunning || value->id == CSSValuePaused) + return cssValuePool().createIdentifierValue(value->id); + return 0; } -#endif -RefPtr<CSSValue> CSSParser::parseAnimationProperty(AnimationParseContext& context) +PassRefPtr<CSSValue> CSSParser::parseAnimationProperty(AnimationParseContext& context) { - CSSParserValue& value = *m_valueList->current(); - if (value.unit != CSSPrimitiveValue::CSS_IDENT) - return nullptr; - CSSPropertyID result = cssPropertyID(value.string); - if (result && result != CSSPropertyAll) // "all" value in animation is not equivalent to the all property. - return CSSValuePool::singleton().createIdentifierValue(result); - if (equalLettersIgnoringASCIICase(value, "all")) { + CSSParserValue* value = m_valueList->current(); + if (value->unit != CSSPrimitiveValue::CSS_IDENT) + return 0; + CSSPropertyID result = cssPropertyID(value->string); + if (result) + return cssValuePool().createIdentifierValue(result); + if (equalIgnoringCase(value, "all")) { context.sawAnimationPropertyKeyword(); - return CSSValuePool::singleton().createIdentifierValue(CSSValueAll); + return cssValuePool().createIdentifierValue(CSSValueAll); } - if (equalLettersIgnoringASCIICase(value, "none")) { + if (equalIgnoringCase(value, "none")) { context.commitAnimationPropertyKeyword(); context.sawAnimationPropertyKeyword(); - return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); - } - return nullptr; -} - -/* static */ -Vector<double> CSSParser::parseKeyframeSelector(const String& selector) { - Vector<double> keys; - Vector<String> strings; - selector.split(',', strings); - - for (size_t i = 0; i < strings.size(); ++i) { - double key = -1; - String cur = strings[i].stripWhiteSpace(); - - // For now the syntax MUST be 'xxx%' or 'from' or 'to', where xxx is a legal floating point number - if (equalLettersIgnoringASCIICase(cur, "from")) - key = 0; - else if (equalLettersIgnoringASCIICase(cur, "to")) - key = 1; - else if (cur.endsWith('%')) { - double k = cur.substring(0, cur.length() - 1).toDouble(); - if (k >= 0 && k <= 100) - key = k / 100; - } - if (key < 0) { - keys.clear(); - break; - } - keys.append(key); + return cssValuePool().createIdentifierValue(CSSValueNone); } - - return keys; + return 0; } -bool CSSParser::parseTransformOriginShorthand(RefPtr<CSSPrimitiveValue>& value1, RefPtr<CSSPrimitiveValue>& value2, RefPtr<CSSValue>& value3) +bool CSSParser::parseTransformOriginShorthand(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2, RefPtr<CSSValue>& value3) { - parse2ValuesFillPosition(*m_valueList, value1, value2); + parse2ValuesFillPosition(m_valueList.get(), value1, value2); // now get z if (m_valueList->current()) { - ValueWithCalculation valueWithCalculation(*m_valueList->current()); - if (validateUnit(valueWithCalculation, FLength)) { - value3 = createPrimitiveNumericValue(valueWithCalculation); + if (validUnit(m_valueList->current(), FLength)) { + value3 = createPrimitiveNumericValue(m_valueList->current()); m_valueList->next(); return true; } return false; } - value3 = CSSValuePool::singleton().createImplicitInitialValue(); + value3 = cssValuePool().createImplicitInitialValue(); return true; } -bool CSSParser::parseCubicBezierTimingFunctionValue(CSSParserValueList& args, double& result) +bool CSSParser::parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result) { - ValueWithCalculation argumentWithCalculation(*args.current()); - if (!validateUnit(argumentWithCalculation, FNumber)) + CSSParserValue* v = args->current(); + if (!validUnit(v, FNumber)) return false; - result = parsedDouble(argumentWithCalculation); - CSSParserValue* nextValue = args.next(); - if (!nextValue) { + result = v->fValue; + v = args->next(); + if (!v) // The last number in the function has no comma after it, so we're done. return true; - } - if (!isComma(nextValue)) + if (!isComma(v)) return false; - args.next(); + args->next(); return true; } -RefPtr<CSSValue> CSSParser::parseAnimationTimingFunction() +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 CSSValuePool::singleton().createIdentifierValue(value.id); + 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 cssValuePool().createIdentifierValue(value->id); // We must be a function. - if (value.unit != CSSParserValue::Function) - return nullptr; + if (value->unit != CSSParserValue::Function) + return 0; - CSSParserValueList* args = value.function->args.get(); + CSSParserValueList* args = value->function->args.get(); - if (equalLettersIgnoringASCIICase(value.function->name, "steps(")) { + if (equalIgnoringCase(value->function->name, "steps(")) { // For steps, 1 or 2 params must be specified (comma-separated) if (!args || (args->size() != 1 && args->size() != 3)) - return nullptr; + return 0; // There are two values. int numSteps; bool stepAtStart = false; - CSSParserValue* argument = args->current(); - ValueWithCalculation argumentWithCalculation(*argument); - if (!validateUnit(argumentWithCalculation, FInteger)) - return nullptr; - numSteps = clampToInteger(parsedDouble(argumentWithCalculation)); + CSSParserValue* v = args->current(); + if (!validUnit(v, FInteger)) + return 0; + numSteps = clampToInteger(v->fValue); if (numSteps < 1) - return nullptr; - argument = args->next(); + return 0; + v = args->next(); - if (argument) { + if (v) { // There is a comma so we need to parse the second value - if (!isComma(argument)) - return nullptr; - argument = args->next(); - if (argument->id != CSSValueStart && argument->id != CSSValueEnd) - return nullptr; - stepAtStart = argument->id == CSSValueStart; + if (!isComma(v)) + return 0; + v = args->next(); + if (v->id != CSSValueStart && v->id != CSSValueEnd) + return 0; + stepAtStart = v->id == CSSValueStart; } return CSSStepsTimingFunctionValue::create(numSteps, stepAtStart); } - if (equalLettersIgnoringASCIICase(value.function->name, "cubic-bezier(")) { + if (equalIgnoringCase(value->function->name, "cubic-bezier(")) { // For cubic bezier, 4 values must be specified. if (!args || args->size() != 7) - return nullptr; + return 0; // There are two points specified. The x values must be between 0 and 1 but the y values can exceed this range. double x1, y1, x2, y2; - if (!parseCubicBezierTimingFunctionValue(*args, x1)) - return nullptr; + if (!parseCubicBezierTimingFunctionValue(args, x1)) + return 0; if (x1 < 0 || x1 > 1) - return nullptr; - if (!parseCubicBezierTimingFunctionValue(*args, y1)) - return nullptr; - if (!parseCubicBezierTimingFunctionValue(*args, x2)) - return nullptr; + return 0; + if (!parseCubicBezierTimingFunctionValue(args, y1)) + return 0; + if (!parseCubicBezierTimingFunctionValue(args, x2)) + return 0; if (x2 < 0 || x2 > 1) - return nullptr; - if (!parseCubicBezierTimingFunctionValue(*args, y2)) - return nullptr; + return 0; + if (!parseCubicBezierTimingFunctionValue(args, y2)) + return 0; return CSSCubicBezierTimingFunctionValue::create(x1, y1, x2, y2); } - return nullptr; + return 0; } bool CSSParser::parseAnimationProperty(CSSPropertyID propId, RefPtr<CSSValue>& result, AnimationParseContext& context) @@ -5283,7 +4580,7 @@ bool CSSParser::parseAnimationProperty(CSSPropertyID propId, RefPtr<CSSValue>& r RefPtr<CSSValue> value; bool allowComma = false; - result = nullptr; + result = 0; while ((val = m_valueList->current())) { RefPtr<CSSValue> currValue; @@ -5295,78 +4592,63 @@ bool CSSParser::parseAnimationProperty(CSSPropertyID propId, RefPtr<CSSValue>& r } else { switch (propId) { - case CSSPropertyAnimationDelay: - case CSSPropertyWebkitAnimationDelay: - case CSSPropertyTransitionDelay: - case CSSPropertyWebkitTransitionDelay: - currValue = parseAnimationDelay(); - if (currValue) - m_valueList->next(); - break; - case CSSPropertyAnimationDirection: - case CSSPropertyWebkitAnimationDirection: - currValue = parseAnimationDirection(); - if (currValue) - m_valueList->next(); - break; - case CSSPropertyAnimationDuration: - case CSSPropertyWebkitAnimationDuration: - case CSSPropertyTransitionDuration: - case CSSPropertyWebkitTransitionDuration: - currValue = parseAnimationDuration(); - if (currValue) - m_valueList->next(); - break; - case CSSPropertyAnimationFillMode: - case CSSPropertyWebkitAnimationFillMode: - currValue = parseAnimationFillMode(); - if (currValue) - m_valueList->next(); - break; - case CSSPropertyAnimationIterationCount: - case CSSPropertyWebkitAnimationIterationCount: - currValue = parseAnimationIterationCount(); - if (currValue) - m_valueList->next(); - break; - case CSSPropertyAnimationName: - case CSSPropertyWebkitAnimationName: - currValue = parseAnimationName(); - if (currValue) - m_valueList->next(); - break; - case CSSPropertyAnimationPlayState: - case CSSPropertyWebkitAnimationPlayState: - currValue = parseAnimationPlayState(); - if (currValue) - m_valueList->next(); - break; - case CSSPropertyTransitionProperty: - case CSSPropertyWebkitTransitionProperty: - currValue = parseAnimationProperty(context); - if (value && !context.animationPropertyKeywordAllowed()) + case CSSPropertyWebkitAnimationDelay: + case CSSPropertyTransitionDelay: + case CSSPropertyWebkitTransitionDelay: + currValue = parseAnimationDelay(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyWebkitAnimationDirection: + currValue = parseAnimationDirection(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyWebkitAnimationDuration: + case CSSPropertyTransitionDuration: + case CSSPropertyWebkitTransitionDuration: + currValue = parseAnimationDuration(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyWebkitAnimationFillMode: + currValue = parseAnimationFillMode(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyWebkitAnimationIterationCount: + currValue = parseAnimationIterationCount(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyWebkitAnimationName: + currValue = parseAnimationName(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyWebkitAnimationPlayState: + currValue = parseAnimationPlayState(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyTransitionProperty: + case CSSPropertyWebkitTransitionProperty: + currValue = parseAnimationProperty(context); + if (value && !context.animationPropertyKeywordAllowed()) + return false; + if (currValue) + m_valueList->next(); + break; + case CSSPropertyWebkitAnimationTimingFunction: + case CSSPropertyTransitionTimingFunction: + case CSSPropertyWebkitTransitionTimingFunction: + currValue = parseAnimationTimingFunction(); + if (currValue) + m_valueList->next(); + break; + default: + ASSERT_NOT_REACHED(); return false; - if (currValue) - m_valueList->next(); - break; - case CSSPropertyAnimationTimingFunction: - case CSSPropertyWebkitAnimationTimingFunction: - case CSSPropertyTransitionTimingFunction: - case CSSPropertyWebkitTransitionTimingFunction: - currValue = parseAnimationTimingFunction(); - if (currValue) - m_valueList->next(); - break; -#if ENABLE(CSS_ANIMATIONS_LEVEL_2) - case CSSPropertyWebkitAnimationTrigger: - currValue = parseAnimationTrigger(); - if (currValue) - m_valueList->next(); - break; -#endif - default: - ASSERT_NOT_REACHED(); - return false; } if (!currValue) @@ -5374,11 +4656,11 @@ bool CSSParser::parseAnimationProperty(CSSPropertyID propId, RefPtr<CSSValue>& r if (value && !values) { values = CSSValueList::createCommaSeparated(); - values->append(value.releaseNonNull()); + values->append(value.release()); } if (values) - values->append(currValue.releaseNonNull()); + values->append(currValue.release()); else value = currValue.release(); @@ -5402,34 +4684,26 @@ bool CSSParser::parseAnimationProperty(CSSPropertyID propId, RefPtr<CSSValue>& r return false; } -#if ENABLE(CSS_GRID_LAYOUT) -static inline bool isValidGridPositionCustomIdent(const CSSParserValue& value) +// The function parses [ <integer> || <string> ] in <grid-line> (which can be stand alone or with 'span'). +bool CSSParser::parseIntegerOrStringFromGridPosition(RefPtr<CSSPrimitiveValue>& numericValue, RefPtr<CSSPrimitiveValue>& gridLineName) { - return value.unit == CSSPrimitiveValue::CSS_IDENT && value.id != CSSValueSpan && value.id != CSSValueAuto; -} - -// The function parses [ <integer> || <custom-ident> ] in <grid-line> (which can be stand alone or with 'span'). -bool CSSParser::parseIntegerOrCustomIdentFromGridPosition(RefPtr<CSSPrimitiveValue>& numericValue, RefPtr<CSSPrimitiveValue>& gridLineName) -{ - ValueWithCalculation valueWithCalculation(*m_valueList->current()); - if (validateUnit(valueWithCalculation, FInteger) && valueWithCalculation.value().fValue) { - numericValue = createPrimitiveNumericValue(valueWithCalculation); - CSSParserValue* nextValue = m_valueList->next(); - if (nextValue && isValidGridPositionCustomIdent(*nextValue)) { - gridLineName = createPrimitiveStringValue(*nextValue); + CSSParserValue* value = m_valueList->current(); + if (validUnit(value, FInteger) && value->fValue) { + numericValue = createPrimitiveNumericValue(value); + value = m_valueList->next(); + if (value && value->unit == CSSPrimitiveValue::CSS_STRING) { + gridLineName = createPrimitiveStringValue(m_valueList->current()); m_valueList->next(); } return true; } - if (isValidGridPositionCustomIdent(valueWithCalculation)) { - gridLineName = createPrimitiveStringValue(valueWithCalculation); - if (CSSParserValue* nextValue = m_valueList->next()) { - ValueWithCalculation nextValueWithCalculation(*nextValue); - if (validateUnit(nextValueWithCalculation, FInteger) && nextValueWithCalculation.value().fValue) { - numericValue = createPrimitiveNumericValue(nextValueWithCalculation); - m_valueList->next(); - } + if (value->unit == CSSPrimitiveValue::CSS_STRING) { + gridLineName = createPrimitiveStringValue(m_valueList->current()); + value = m_valueList->next(); + if (value && validUnit(value, FInteger) && value->fValue) { + numericValue = createPrimitiveNumericValue(value); + m_valueList->next(); } return true; } @@ -5437,66 +4711,65 @@ bool CSSParser::parseIntegerOrCustomIdentFromGridPosition(RefPtr<CSSPrimitiveVal return false; } -RefPtr<CSSValue> CSSParser::parseGridPosition() +PassRefPtr<CSSValue> CSSParser::parseGridPosition() { CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueAuto) { m_valueList->next(); - return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); + return cssValuePool().createIdentifierValue(CSSValueAuto); + } + + if (value->id != CSSValueSpan && value->unit == CSSPrimitiveValue::CSS_IDENT) { + m_valueList->next(); + return cssValuePool().createValue(value->string, CSSPrimitiveValue::CSS_STRING); } RefPtr<CSSPrimitiveValue> numericValue; RefPtr<CSSPrimitiveValue> gridLineName; bool hasSeenSpanKeyword = false; - if (value->id == CSSValueSpan) { - hasSeenSpanKeyword = true; - if (auto* nextValue = m_valueList->next()) { - if (!isForwardSlashOperator(*nextValue) && !parseIntegerOrCustomIdentFromGridPosition(numericValue, gridLineName)) - return nullptr; - } - } else if (parseIntegerOrCustomIdentFromGridPosition(numericValue, gridLineName)) { + if (parseIntegerOrStringFromGridPosition(numericValue, gridLineName)) { value = m_valueList->current(); if (value && value->id == CSSValueSpan) { hasSeenSpanKeyword = true; m_valueList->next(); } + } else if (value->id == CSSValueSpan) { + hasSeenSpanKeyword = true; + if (m_valueList->next()) + parseIntegerOrStringFromGridPosition(numericValue, gridLineName); } // Check that we have consumed all the value list. For shorthands, the parser will pass // the whole value list (including the opposite position). - if (m_valueList->current() && !isForwardSlashOperator(*m_valueList->current())) - return nullptr; + if (m_valueList->current() && !isForwardSlashOperator(m_valueList->current())) + return 0; // If we didn't parse anything, this is not a valid grid position. if (!hasSeenSpanKeyword && !gridLineName && !numericValue) - return nullptr; + return 0; // Negative numbers are not allowed for span (but are for <integer>). if (hasSeenSpanKeyword && numericValue && numericValue->getIntValue() < 0) - return nullptr; - - // For the <custom-ident> case. - if (gridLineName && !numericValue && !hasSeenSpanKeyword) - return CSSValuePool::singleton().createValue(gridLineName->getStringValue(), CSSPrimitiveValue::CSS_STRING); + return 0; RefPtr<CSSValueList> values = CSSValueList::createSpaceSeparated(); if (hasSeenSpanKeyword) - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSpan)); + values->append(cssValuePool().createIdentifierValue(CSSValueSpan)); if (numericValue) - values->append(numericValue.releaseNonNull()); + values->append(numericValue.release()); if (gridLineName) - values->append(gridLineName.releaseNonNull()); + values->append(gridLineName.release()); ASSERT(values->length()); - return values; + return values.release(); } -static RefPtr<CSSValue> gridMissingGridPositionValue(CSSValue& value) +static PassRefPtr<CSSValue> gridMissingGridPositionValue(CSSValue* value) { - if (is<CSSPrimitiveValue>(value) && downcast<CSSPrimitiveValue>(value).isString()) - return &value; + if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->isString()) + return value; - return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); + return cssValuePool().createIdentifierValue(CSSValueAuto); } bool CSSParser::parseGridItemPositionShorthand(CSSPropertyID shorthandId, bool important) @@ -5511,7 +4784,7 @@ bool CSSParser::parseGridItemPositionShorthand(CSSPropertyID shorthandId, bool i RefPtr<CSSValue> endValue; if (m_valueList->current()) { - if (!isForwardSlashOperator(*m_valueList->current())) + if (!isForwardSlashOperator(m_valueList->current())) return false; if (!m_valueList->next()) @@ -5521,219 +4794,17 @@ bool CSSParser::parseGridItemPositionShorthand(CSSPropertyID shorthandId, bool i if (!endValue || m_valueList->current()) return false; } else - endValue = gridMissingGridPositionValue(*startValue); + endValue = gridMissingGridPositionValue(startValue.get()); addProperty(shorthand.properties()[0], startValue, important); addProperty(shorthand.properties()[1], endValue, important); return true; } -bool CSSParser::parseGridGapShorthand(bool important) -{ - ShorthandScope scope(this, CSSPropertyWebkitGridGap); - ASSERT(shorthandForProperty(CSSPropertyWebkitGridGap).length() == 2); - - CSSParserValue* value = m_valueList->current(); - if (!value) - return false; - - ValueWithCalculation columnValueWithCalculation(*value); - if (!validateUnit(columnValueWithCalculation, FLength | FNonNeg)) - return false; - - RefPtr<CSSPrimitiveValue> columnGap = createPrimitiveNumericValue(columnValueWithCalculation); - - value = m_valueList->next(); - if (!value) { - addProperty(CSSPropertyWebkitGridColumnGap, columnGap, important); - addProperty(CSSPropertyWebkitGridRowGap, columnGap, important); - return true; - } - - ValueWithCalculation rowValueWithCalculation(*value); - if (!validateUnit(rowValueWithCalculation, FLength | FNonNeg)) - return false; - - if (m_valueList->next()) - return false; - - RefPtr<CSSPrimitiveValue> rowGap = createPrimitiveNumericValue(rowValueWithCalculation); - - addProperty(CSSPropertyWebkitGridColumnGap, columnGap, important); - addProperty(CSSPropertyWebkitGridRowGap, rowGap, important); - - return true; -} - -bool CSSParser::parseGridTemplateRowsAndAreas(PassRefPtr<CSSValue> templateColumns, bool important) -{ - // At least template-areas strings must be defined. - if (!m_valueList->current()) - return false; - - NamedGridAreaMap gridAreaMap; - unsigned rowCount = 0; - unsigned columnCount = 0; - bool trailingIdentWasAdded = false; - RefPtr<CSSValueList> templateRows = CSSValueList::createSpaceSeparated(); - - do { - // Handle leading <custom-ident>*. - if (m_valueList->current()->unit == CSSParserValue::ValueList) { - if (trailingIdentWasAdded) { - // A row's trailing ident must be concatenated with the next row's leading one. - parseGridLineNames(*m_valueList, *templateRows, downcast<CSSGridLineNamesValue>(templateRows->item(templateRows->length() - 1))); - } else - parseGridLineNames(*m_valueList, *templateRows); - } - - // Handle a template-area's row. - if (!parseGridTemplateAreasRow(gridAreaMap, rowCount, columnCount)) - return false; - ++rowCount; - - // Handle template-rows's track-size. - if (m_valueList->current() && m_valueList->current()->unit != CSSParserValue::ValueList && m_valueList->current()->unit != CSSPrimitiveValue::CSS_STRING) { - RefPtr<CSSValue> value = parseGridTrackSize(*m_valueList); - if (!value) - return false; - templateRows->append(value.releaseNonNull()); - } else - templateRows->append(CSSValuePool::singleton().createIdentifierValue(CSSValueAuto)); - - // This will handle the trailing/leading <custom-ident>* in the grammar. - trailingIdentWasAdded = false; - if (m_valueList->current() && m_valueList->current()->unit == CSSParserValue::ValueList) - trailingIdentWasAdded = parseGridLineNames(*m_valueList, *templateRows); - } while (m_valueList->current()); - - // [<track-list> /]? - if (templateColumns) - addProperty(CSSPropertyWebkitGridTemplateColumns, templateColumns, important); - else - addProperty(CSSPropertyWebkitGridTemplateColumns, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important); - - // [<line-names>? <string> [<track-size> <line-names>]? ]+ - RefPtr<CSSValue> templateAreas = CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount); - addProperty(CSSPropertyWebkitGridTemplateAreas, templateAreas.release(), important); - addProperty(CSSPropertyWebkitGridTemplateRows, templateRows.release(), important); - - return true; -} - -bool CSSParser::parseGridTemplateShorthand(bool important) -{ - ShorthandScope scope(this, CSSPropertyWebkitGridTemplate); - ASSERT(shorthandForProperty(CSSPropertyWebkitGridTemplate).length() == 3); - - // At least "none" must be defined. - if (!m_valueList->current()) - return false; - - bool firstValueIsNone = m_valueList->current()->id == CSSValueNone; - - // 1- 'none' case. - if (firstValueIsNone && !m_valueList->next()) { - addProperty(CSSPropertyWebkitGridTemplateColumns, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important); - addProperty(CSSPropertyWebkitGridTemplateRows, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important); - addProperty(CSSPropertyWebkitGridTemplateAreas, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important); - return true; - } - - unsigned index = 0; - RefPtr<CSSValue> columnsValue = firstValueIsNone ? CSSValuePool::singleton().createIdentifierValue(CSSValueNone) : parseGridTrackList(); - - // 2- <grid-template-columns> / <grid-template-columns> syntax. - if (columnsValue) { - if (!(m_valueList->current() && isForwardSlashOperator(*m_valueList->current()) && m_valueList->next())) - return false; - index = m_valueList->currentIndex(); - if (RefPtr<CSSValue> rowsValue = parseGridTrackList()) { - if (m_valueList->current()) - return false; - addProperty(CSSPropertyWebkitGridTemplateColumns, columnsValue.release(), important); - addProperty(CSSPropertyWebkitGridTemplateRows, rowsValue.release(), important); - addProperty(CSSPropertyWebkitGridTemplateAreas, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important); - return true; - } - } - - - // 3- [<track-list> /]? [<line-names>? <string> [<track-size> <line-names>]? ]+ syntax. - // The template-columns <track-list> can't be 'none'. - if (firstValueIsNone) - return false; - // It requires to rewind parsing due to previous syntax failures. - m_valueList->setCurrentIndex(index); - return parseGridTemplateRowsAndAreas(columnsValue, important); -} - -bool CSSParser::parseGridShorthand(bool important) -{ - ShorthandScope scope(this, CSSPropertyWebkitGrid); - ASSERT(shorthandForProperty(CSSPropertyWebkitGrid).length() == 8); - - // 1- <grid-template> - if (parseGridTemplateShorthand(important)) { - // It can only be specified the explicit or the implicit grid properties in a single grid declaration. - // The sub-properties not specified are set to their initial value, as normal for shorthands. - addProperty(CSSPropertyWebkitGridAutoFlow, CSSValuePool::singleton().createImplicitInitialValue(), important); - addProperty(CSSPropertyWebkitGridAutoColumns, CSSValuePool::singleton().createImplicitInitialValue(), important); - addProperty(CSSPropertyWebkitGridAutoRows, CSSValuePool::singleton().createImplicitInitialValue(), important); - addProperty(CSSPropertyWebkitGridColumnGap, CSSValuePool::singleton().createImplicitInitialValue(), important); - addProperty(CSSPropertyWebkitGridRowGap, CSSValuePool::singleton().createImplicitInitialValue(), important); - return true; - } - - // Need to rewind parsing to explore the alternative syntax of this shorthand. - m_valueList->setCurrentIndex(0); - - // 2- <grid-auto-flow> [ <grid-auto-columns> [ / <grid-auto-rows> ]? ] - if (!parseValue(CSSPropertyWebkitGridAutoFlow, important)) - return false; - - RefPtr<CSSValue> autoColumnsValue; - RefPtr<CSSValue> autoRowsValue; - - if (m_valueList->current()) { - autoColumnsValue = parseGridTrackSize(*m_valueList); - if (!autoColumnsValue) - return false; - if (m_valueList->current()) { - if (!isForwardSlashOperator(*m_valueList->current()) || !m_valueList->next()) - return false; - autoRowsValue = parseGridTrackSize(*m_valueList); - if (!autoRowsValue) - return false; - } - if (m_valueList->current()) - return false; - } else { - // Other omitted values are set to their initial values. - autoColumnsValue = CSSValuePool::singleton().createImplicitInitialValue(); - autoRowsValue = CSSValuePool::singleton().createImplicitInitialValue(); - } - - // if <grid-auto-rows> value is omitted, it is set to the value specified for grid-auto-columns. - if (!autoRowsValue) - autoRowsValue = autoColumnsValue; - - addProperty(CSSPropertyWebkitGridAutoColumns, autoColumnsValue.release(), important); - addProperty(CSSPropertyWebkitGridAutoRows, autoRowsValue.release(), important); - - // It can only be specified the explicit or the implicit grid properties in a single grid declaration. - // The sub-properties not specified are set to their initial value, as normal for shorthands. - addProperty(CSSPropertyWebkitGridTemplateColumns, CSSValuePool::singleton().createImplicitInitialValue(), important); - addProperty(CSSPropertyWebkitGridTemplateRows, CSSValuePool::singleton().createImplicitInitialValue(), important); - addProperty(CSSPropertyWebkitGridTemplateAreas, CSSValuePool::singleton().createImplicitInitialValue(), important); - addProperty(CSSPropertyWebkitGridColumnGap, CSSValuePool::singleton().createImplicitInitialValue(), important); - addProperty(CSSPropertyWebkitGridRowGap, CSSValuePool::singleton().createImplicitInitialValue(), important); - - return true; -} - bool CSSParser::parseGridAreaShorthand(bool important) { + ASSERT(cssGridLayoutEnabled()); + ShorthandScope scope(this, CSSPropertyWebkitGridArea); ASSERT(shorthandForProperty(CSSPropertyWebkitGridArea).length() == 4); @@ -5754,13 +4825,13 @@ bool CSSParser::parseGridAreaShorthand(bool important) return false; if (!columnStartValue) - columnStartValue = gridMissingGridPositionValue(*rowStartValue); + columnStartValue = gridMissingGridPositionValue(rowStartValue.get()); if (!rowEndValue) - rowEndValue = gridMissingGridPositionValue(*rowStartValue); + rowEndValue = gridMissingGridPositionValue(rowStartValue.get()); if (!columnEndValue) - columnEndValue = gridMissingGridPositionValue(*columnStartValue); + columnEndValue = gridMissingGridPositionValue(columnStartValue.get()); addProperty(CSSPropertyWebkitGridRowStart, rowStartValue, important); addProperty(CSSPropertyWebkitGridColumnStart, columnStartValue, important); @@ -5774,7 +4845,7 @@ bool CSSParser::parseSingleGridAreaLonghand(RefPtr<CSSValue>& property) if (!m_valueList->current()) return true; - if (!isForwardSlashOperator(*m_valueList->current())) + if (!isForwardSlashOperator(m_valueList->current())) return false; if (!m_valueList->next()) @@ -5784,238 +4855,141 @@ bool CSSParser::parseSingleGridAreaLonghand(RefPtr<CSSValue>& property) return true; } -bool CSSParser::parseGridLineNames(CSSParserValueList& inputList, CSSValueList& valueList, CSSGridLineNamesValue* previousNamedAreaTrailingLineNames) +void CSSParser::parseGridTrackNames(CSSParserValueList& parserValues, CSSValueList& values) { - ASSERT(inputList.current() && inputList.current()->unit == CSSParserValue::ValueList); - - CSSParserValueList& identList = *inputList.current()->valueList; - if (!identList.size()) { - inputList.next(); - return false; - } - - // Need to ensure the identList is at the heading index, since the parserList might have been rewound. - identList.setCurrentIndex(0); - RefPtr<CSSGridLineNamesValue> lineNames; - if (previousNamedAreaTrailingLineNames) - lineNames = previousNamedAreaTrailingLineNames; - else - lineNames = CSSGridLineNamesValue::create(); - while (CSSParserValue* identValue = identList.current()) { - ASSERT(identValue->unit == CSSPrimitiveValue::CSS_IDENT); - lineNames->append(createPrimitiveStringValue(*identValue)); - identList.next(); - } - if (!previousNamedAreaTrailingLineNames) - valueList.append(lineNames.releaseNonNull()); - - inputList.next(); - return true; + do { + RefPtr<CSSPrimitiveValue> name = createPrimitiveStringValue(parserValues.current()); + values.append(name.release()); + parserValues.next(); + } while (parserValues.current() && parserValues.current()->unit == CSSPrimitiveValue::CSS_STRING); } -RefPtr<CSSValue> CSSParser::parseGridTrackList() +bool CSSParser::parseGridTrackList(CSSPropertyID propId, bool important) { CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueNone) { - m_valueList->next(); - return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); + if (m_valueList->next()) + return false; + + addProperty(propId, cssValuePool().createIdentifierValue(value->id), important); + return true; } RefPtr<CSSValueList> values = CSSValueList::createSpaceSeparated(); - // Handle leading <custom-ident>*. - value = m_valueList->current(); - if (value && value->unit == CSSParserValue::ValueList) - parseGridLineNames(*m_valueList, *values); + // Handle leading track names + if (m_valueList->current() && m_valueList->current()->unit == CSSPrimitiveValue::CSS_STRING) + parseGridTrackNames(*m_valueList, *values); bool seenTrackSizeOrRepeatFunction = false; while (CSSParserValue* currentValue = m_valueList->current()) { - if (isForwardSlashOperator(*currentValue)) - break; - if (currentValue->unit == CSSParserValue::Function && equalLettersIgnoringASCIICase(currentValue->function->name, "repeat(")) { + if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase(currentValue->function->name, "repeat(")) { if (!parseGridTrackRepeatFunction(*values)) - return nullptr; + return false; } else { RefPtr<CSSValue> value = parseGridTrackSize(*m_valueList); if (!value) - return nullptr; - values->append(value.releaseNonNull()); + return false; + values->append(value.release()); } seenTrackSizeOrRepeatFunction = true; - // This will handle the trailing <custom-ident>* in the grammar. - value = m_valueList->current(); - if (value && value->unit == CSSParserValue::ValueList) - parseGridLineNames(*m_valueList, *values); + if (m_valueList->current() && m_valueList->current()->unit == CSSPrimitiveValue::CSS_STRING) + parseGridTrackNames(*m_valueList, *values); } if (!seenTrackSizeOrRepeatFunction) - return nullptr; + return false; - return values; + addProperty(propId, values.release(), important); + return true; } bool CSSParser::parseGridTrackRepeatFunction(CSSValueList& list) { CSSParserValueList* arguments = m_valueList->current()->function->args.get(); - if (!arguments || arguments->size() < 3) + if (!arguments || arguments->size() < 3 || !validUnit(arguments->valueAt(0), FPositiveInteger) || !isComma(arguments->valueAt(1))) return false; - ValueWithCalculation firstValueWithCalculation(*arguments->valueAt(0)); - if (!validateUnit(firstValueWithCalculation, FPositiveInteger) || !isComma(arguments->valueAt(1))) - return false; - - // If arguments->valueAt(0)->fValue > SIZE_MAX then repetitions becomes 0 during the type casting, that's why we - // clamp it down to kGridMaxTracks before the type casting. - unsigned repetitions = clampTo<unsigned>(parsedDouble(firstValueWithCalculation), 0, kGridMaxTracks); - + ASSERT_WITH_SECURITY_IMPLICATION(arguments->valueAt(0)->fValue > 0); + size_t repetitions = arguments->valueAt(0)->fValue; RefPtr<CSSValueList> repeatedValues = CSSValueList::createSpaceSeparated(); arguments->next(); // Skip the repetition count. arguments->next(); // Skip the comma. - // Handle leading <custom-ident>*. - CSSParserValue* currentValue = arguments->current(); - if (currentValue && currentValue->unit == CSSParserValue::ValueList) - parseGridLineNames(*arguments, *repeatedValues); - - unsigned numberOfTracks = 0; while (arguments->current()) { + if (arguments->current()->unit == CSSPrimitiveValue::CSS_STRING) + parseGridTrackNames(*arguments, *repeatedValues); + + if (!arguments->current()) + break; + RefPtr<CSSValue> trackSize = parseGridTrackSize(*arguments); if (!trackSize) return false; - repeatedValues->append(trackSize.releaseNonNull()); - ++numberOfTracks; - - // This takes care of any trailing <custom-ident>* in the grammar. - currentValue = arguments->current(); - if (currentValue && currentValue->unit == CSSParserValue::ValueList) - parseGridLineNames(*arguments, *repeatedValues); + repeatedValues->append(trackSize.release()); } - // We should have found at least one <track-size>, otherwise the declaration is invalid. - if (!numberOfTracks) - return false; - - // We clamp the number of repetitions to a multiple of the repeat() track list's size, while staying below the max - // grid size. - repetitions = std::min(repetitions, kGridMaxTracks / numberOfTracks); - for (size_t i = 0; i < repetitions; ++i) { for (size_t j = 0; j < repeatedValues->length(); ++j) - list.append(*repeatedValues->itemWithoutBoundsCheck(j)); + list.append(repeatedValues->itemWithoutBoundsCheck(j)); } m_valueList->next(); return true; } -RefPtr<CSSValue> CSSParser::parseGridTrackSize(CSSParserValueList& inputList) +PassRefPtr<CSSValue> CSSParser::parseGridTrackSize(CSSParserValueList& inputList) { - CSSParserValue& currentValue = *inputList.current(); + CSSParserValue* currentValue = inputList.current(); inputList.next(); - if (currentValue.id == CSSValueAuto) - return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); + if (currentValue->id == CSSValueAuto) + return cssValuePool().createIdentifierValue(CSSValueAuto); - if (currentValue.unit == CSSParserValue::Function && equalLettersIgnoringASCIICase(currentValue.function->name, "minmax(")) { + if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase(currentValue->function->name, "minmax(")) { // The spec defines the following grammar: minmax( <track-breadth> , <track-breadth> ) - CSSParserValueList* arguments = currentValue.function->args.get(); + CSSParserValueList* arguments = currentValue->function->args.get(); if (!arguments || arguments->size() != 3 || !isComma(arguments->valueAt(1))) - return nullptr; + return 0; - RefPtr<CSSPrimitiveValue> minTrackBreadth = parseGridBreadth(*arguments->valueAt(0)); + RefPtr<CSSPrimitiveValue> minTrackBreadth = parseGridBreadth(arguments->valueAt(0)); if (!minTrackBreadth) - return nullptr; + return 0; - RefPtr<CSSPrimitiveValue> maxTrackBreadth = parseGridBreadth(*arguments->valueAt(2)); + RefPtr<CSSPrimitiveValue> maxTrackBreadth = parseGridBreadth(arguments->valueAt(2)); if (!maxTrackBreadth) - return nullptr; + return 0; RefPtr<CSSValueList> parsedArguments = CSSValueList::createCommaSeparated(); - parsedArguments->append(minTrackBreadth.releaseNonNull()); - parsedArguments->append(maxTrackBreadth.releaseNonNull()); + parsedArguments->append(minTrackBreadth); + parsedArguments->append(maxTrackBreadth); return CSSFunctionValue::create("minmax(", parsedArguments); } return parseGridBreadth(currentValue); } -RefPtr<CSSPrimitiveValue> CSSParser::parseGridBreadth(CSSParserValue& value) +PassRefPtr<CSSPrimitiveValue> CSSParser::parseGridBreadth(CSSParserValue* currentValue) { - if (value.id == CSSValueWebkitMinContent || value.id == CSSValueWebkitMaxContent || value.id == CSSValueAuto) - return CSSValuePool::singleton().createIdentifierValue(value.id); + if (currentValue->id == CSSValueWebkitMinContent || currentValue->id == CSSValueWebkitMaxContent) + return cssValuePool().createIdentifierValue(currentValue->id); - if (value.unit == CSSPrimitiveValue::CSS_FR) { - double flexValue = value.fValue; + if (currentValue->unit == CSSPrimitiveValue::CSS_FR) { + double flexValue = currentValue->fValue; // Fractional unit is a non-negative dimension. if (flexValue <= 0) - return nullptr; - - return CSSValuePool::singleton().createValue(flexValue, CSSPrimitiveValue::CSS_FR); - } - - ValueWithCalculation valueWithCalculation(value); - if (!validateUnit(valueWithCalculation, FNonNeg | FLength | FPercent)) - return nullptr; - - return createPrimitiveNumericValue(valueWithCalculation); -} - -static inline bool isValidGridAutoFlowId(CSSValueID id) -{ - return (id == CSSValueRow || id == CSSValueColumn || id == CSSValueDense); -} - -RefPtr<CSSValue> CSSParser::parseGridAutoFlow(CSSParserValueList& inputList) -{ - // [ row | column ] || dense - CSSParserValue* value = inputList.current(); - if (!value) - return nullptr; - - RefPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated(); - - // First parameter. - CSSValueID firstId = value->id; - if (!isValidGridAutoFlowId(firstId)) - return nullptr; - - // Second parameter, if any. - // If second parameter is not valid we should process anyway the first one as we can be inside the "grid" shorthand. - value = inputList.next(); - if (!value || !isValidGridAutoFlowId(value->id)) { - if (firstId == CSSValueDense) - parsedValues->append(CSSValuePool::singleton().createIdentifierValue(CSSValueRow)); + return 0; - parsedValues->append(CSSValuePool::singleton().createIdentifierValue(firstId)); - return parsedValues; + return cssValuePool().createValue(flexValue, CSSPrimitiveValue::CSS_FR); } - switch (firstId) { - case CSSValueRow: - case CSSValueColumn: - parsedValues->append(CSSValuePool::singleton().createIdentifierValue(firstId)); - if (value->id == CSSValueDense) { - parsedValues->append(CSSValuePool::singleton().createIdentifierValue(value->id)); - inputList.next(); - } - break; - case CSSValueDense: - if (value->id == CSSValueRow || value->id == CSSValueColumn) { - parsedValues->append(CSSValuePool::singleton().createIdentifierValue(value->id)); - inputList.next(); - } - parsedValues->append(CSSValuePool::singleton().createIdentifierValue(firstId)); - break; - default: - ASSERT_NOT_REACHED(); - break; - } + if (!validUnit(currentValue, FNonNeg | FLength | FPercent)) + return 0; - return parsedValues; + return createPrimitiveNumericValue(currentValue); } -#endif /* ENABLE(CSS_GRID_LAYOUT) */ #if ENABLE(DASHBOARD_SUPPORT) @@ -6026,8 +5000,8 @@ static CSSParserValue* skipCommaInDashboardRegion(CSSParserValueList *args) { if (args->size() == (DASHBOARD_REGION_NUM_PARAMETERS*2-1) || args->size() == (DASHBOARD_REGION_SHORT_NUM_PARAMETERS*2-1)) { - CSSParserValue& current = *args->current(); - if (current.unit == CSSParserValue::Operator && current.iValue == ',') + CSSParserValue* current = args->current(); + if (current->unit == CSSParserValue::Operator && current->iValue == ',') return args->next(); } return args->current(); @@ -6042,20 +5016,20 @@ bool CSSParser::parseDashboardRegions(CSSPropertyID propId, bool important) if (value->id == CSSValueNone) { if (m_valueList->next()) return false; - addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value->id), important); + addProperty(propId, cssValuePool().createIdentifierValue(value->id), important); return valid; } - auto firstRegion = DashboardRegion::create(); - DashboardRegion* region = nullptr; + RefPtr<DashboardRegion> firstRegion = DashboardRegion::create(); + DashboardRegion* region = 0; while (value) { - if (!region) { - region = firstRegion.ptr(); + if (region == 0) { + region = firstRegion.get(); } else { - auto nextRegion = DashboardRegion::create(); - region->m_next = nextRegion.copyRef(); - region = nextRegion.ptr(); + RefPtr<DashboardRegion> nextRegion = DashboardRegion::create(); + region->m_next = nextRegion; + region = nextRegion.get(); } if (value->unit != CSSParserValue::Function) { @@ -6070,7 +5044,7 @@ bool CSSParser::parseDashboardRegions(CSSPropertyID propId, bool important) // dashboard-region(label, type) or dashboard-region(label type) // dashboard-region(label, type) or dashboard-region(label type) CSSParserValueList* args = value->function->args.get(); - if (!equalLettersIgnoringASCIICase(value->function->name, "dashboard-region(") || !args) { + if (!equalIgnoringCase(value->function->name, "dashboard-region(") || !args) { valid = false; break; } @@ -6099,9 +5073,9 @@ bool CSSParser::parseDashboardRegions(CSSPropertyID propId, bool important) break; } - if (equalLettersIgnoringASCIICase(*arg, "circle")) + if (equalIgnoringCase(arg, "circle")) region->m_isCircle = true; - else if (equalLettersIgnoringASCIICase(*arg, "rectangle")) + else if (equalIgnoringCase(arg, "rectangle")) region->m_isRectangle = true; else { valid = false; @@ -6112,7 +5086,7 @@ bool CSSParser::parseDashboardRegions(CSSPropertyID 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 = CSSValuePool::singleton().createIdentifierValue(CSSValueInvalid); + RefPtr<CSSPrimitiveValue> amount = cssValuePool().createIdentifierValue(CSSValueInvalid); region->setTop(amount); region->setRight(amount); @@ -6120,16 +5094,18 @@ bool CSSParser::parseDashboardRegions(CSSPropertyID propId, bool important) region->setLeft(amount); } else { // Next four arguments must be offset numbers - for (int i = 0; i < 4; ++i) { + int i; + for (i = 0; i < 4; i++) { arg = args->next(); arg = skipCommaInDashboardRegion(args); - ValueWithCalculation argWithCalculation(*arg); - valid = arg->id == CSSValueAuto || validateUnit(argWithCalculation, FLength); + valid = arg->id == CSSValueAuto || validUnit(arg, FLength); if (!valid) break; - RefPtr<CSSPrimitiveValue> amount = arg->id == CSSValueAuto ? CSSValuePool::singleton().createIdentifierValue(CSSValueAuto) : createPrimitiveNumericValue(argWithCalculation); + RefPtr<CSSPrimitiveValue> amount = arg->id == CSSValueAuto ? + cssValuePool().createIdentifierValue(CSSValueAuto) : + createPrimitiveNumericValue(arg); if (i == 0) region->setTop(amount); @@ -6149,202 +5125,162 @@ bool CSSParser::parseDashboardRegions(CSSPropertyID propId, bool important) } if (valid) - addProperty(propId, CSSValuePool::singleton().createValue(RefPtr<DashboardRegion>(WTFMove(firstRegion))), important); + addProperty(propId, cssValuePool().createValue(firstRegion.release()), important); return valid; } #endif /* ENABLE(DASHBOARD_SUPPORT) */ -#if ENABLE(CSS_GRID_LAYOUT) -static Vector<String> parseGridTemplateAreasColumnNames(const String& gridRowNames) +PassRefPtr<CSSValue> CSSParser::parseGridTemplate() { - ASSERT(!gridRowNames.isEmpty()); - Vector<String> columnNames; - // Using StringImpl to avoid checks and indirection in every call to String::operator[]. - StringImpl& text = *gridRowNames.impl(); - unsigned length = text.length(); - unsigned index = 0; - while (index < length) { - if (text[index] != ' ' && text[index] != '.') { - unsigned gridAreaStart = index; - while (index < length && text[index] != ' ' && text[index] != '.') - index++; - columnNames.append(text.substring(gridAreaStart, index - gridAreaStart)); - continue; - } - - if (text[index] == '.') { - while (index < length && text[index] == '.') - index++; - columnNames.append("."); - continue; - } - - index++; - } + NamedGridAreaMap gridAreaMap; + size_t rowCount = 0; + size_t columnCount = 0; - return columnNames; -} + while (CSSParserValue* currentValue = m_valueList->current()) { + if (currentValue->unit != CSSPrimitiveValue::CSS_STRING) + return 0; -bool CSSParser::parseGridTemplateAreasRow(NamedGridAreaMap& gridAreaMap, const unsigned rowCount, unsigned& columnCount) -{ - CSSParserValue* currentValue = m_valueList->current(); - if (!currentValue || currentValue->unit != CSSPrimitiveValue::CSS_STRING) - return false; + String gridRowNames = currentValue->string; + if (!gridRowNames.length()) + return 0; - String gridRowNames = currentValue->string; - if (gridRowNames.containsOnlyWhitespace()) - return false; + Vector<String> columnNames; + gridRowNames.split(' ', columnNames); - Vector<String> columnNames = parseGridTemplateAreasColumnNames(gridRowNames); - if (!columnCount) { - columnCount = columnNames.size(); - ASSERT(columnCount); - } else if (columnCount != columnNames.size()) { - // The declaration is invalid is all the rows don't have the number of columns. - return false; - } - - for (unsigned currentColumn = 0; currentColumn < columnCount; ++currentColumn) { - const String& gridAreaName = columnNames[currentColumn]; - - // Unamed areas are always valid (we consider them to be 1x1). - if (gridAreaName == ".") - continue; + if (columnCount && (columnCount != columnNames.size())) { + // The declaration is invalid if all the rows don't have the number of columns. + return 0; + } - // We handle several grid areas with the same name at once to simplify the validation code. - unsigned lookAheadColumn; - for (lookAheadColumn = currentColumn + 1; lookAheadColumn < columnCount; ++lookAheadColumn) { - if (columnNames[lookAheadColumn] != gridAreaName) - break; + if (!columnCount) { + columnCount = columnNames.size(); + ASSERT(columnCount); } - auto gridAreaIterator = gridAreaMap.find(gridAreaName); - if (gridAreaIterator == gridAreaMap.end()) - gridAreaMap.add(gridAreaName, GridCoordinate(GridSpan::definiteGridSpan(rowCount, rowCount + 1), GridSpan::definiteGridSpan(currentColumn, lookAheadColumn))); - else { - GridCoordinate& gridCoordinate = gridAreaIterator->value; + for (size_t currentColumn = 0; currentColumn < columnCount; ++currentColumn) { + const String& gridAreaName = columnNames[currentColumn]; - // The following checks test that the grid area is a single filled-in rectangle. - // 1. The new row is adjacent to the previously parsed row. - if (rowCount != gridCoordinate.rows.resolvedFinalPosition().toInt()) - return false; + // Unamed areas are always valid (we consider them to be 1x1). + if (gridAreaName == ".") + continue; - // 2. The new area starts at the same position as the previously parsed area. - if (currentColumn != gridCoordinate.columns.resolvedInitialPosition().toInt()) - return false; + // We handle several grid areas with the same name at once to simplify the validation code. + size_t lookAheadColumn; + for (lookAheadColumn = currentColumn; lookAheadColumn < (columnCount - 1); ++lookAheadColumn) { + if (columnNames[lookAheadColumn + 1] != gridAreaName) + break; + } - // 3. The new area ends at the same position as the previously parsed area. - if (lookAheadColumn != gridCoordinate.columns.resolvedFinalPosition().toInt()) - return false; + auto gridAreaIterator = gridAreaMap.find(gridAreaName); + if (gridAreaIterator == gridAreaMap.end()) + gridAreaMap.add(gridAreaName, GridCoordinate(GridSpan(rowCount, rowCount), GridSpan(currentColumn, lookAheadColumn))); + else { + GridCoordinate& gridCoordinate = gridAreaIterator->value; - gridCoordinate.rows = GridSpan::definiteGridSpan(gridCoordinate.rows.resolvedInitialPosition(), gridCoordinate.rows.resolvedFinalPosition().next()); - } - currentColumn = lookAheadColumn - 1; - } + // The following checks test that the grid area is a single filled-in rectangle. + // 1. The new row is adjacent to the previously parsed row. + if (rowCount != gridCoordinate.rows.initialPositionIndex + 1) + return 0; - m_valueList->next(); - return true; -} + // 2. The new area starts at the same position as the previously parsed area. + if (currentColumn != gridCoordinate.columns.initialPositionIndex) + return 0; -RefPtr<CSSValue> CSSParser::parseGridTemplateAreas() -{ - if (m_valueList->current() && m_valueList->current()->id == CSSValueNone) { - m_valueList->next(); - return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); - } + // 3. The new area ends at the same position as the previously parsed area. + if (lookAheadColumn != gridCoordinate.columns.finalPositionIndex) + return 0; - NamedGridAreaMap gridAreaMap; - unsigned rowCount = 0; - unsigned columnCount = 0; + ++gridCoordinate.rows.finalPositionIndex; + } + currentColumn = lookAheadColumn; + } - while (m_valueList->current()) { - if (!parseGridTemplateAreasRow(gridAreaMap, rowCount, columnCount)) - return nullptr; ++rowCount; + m_valueList->next(); } if (!rowCount || !columnCount) - return nullptr; + return 0; - return CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount); + return CSSGridTemplateValue::create(gridAreaMap, rowCount, columnCount); } -#endif /* ENABLE(CSS_GRID_LAYOUT) */ -RefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList& args, bool counters) +PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bool counters) { - unsigned numArgs = args.size(); + unsigned numArgs = args->size(); if (counters && numArgs != 3 && numArgs != 5) - return nullptr; + return 0; if (!counters && numArgs != 1 && numArgs != 3) - return nullptr; + return 0; - CSSParserValue* argument = args.current(); - if (argument->unit != CSSPrimitiveValue::CSS_IDENT) - return nullptr; - RefPtr<CSSPrimitiveValue> identifier = createPrimitiveStringValue(*argument); + CSSParserValue* i = args->current(); + if (i->unit != CSSPrimitiveValue::CSS_IDENT) + return 0; + RefPtr<CSSPrimitiveValue> identifier = createPrimitiveStringValue(i); RefPtr<CSSPrimitiveValue> separator; if (!counters) - separator = CSSValuePool::singleton().createValue(String(), CSSPrimitiveValue::CSS_STRING); + separator = cssValuePool().createValue(String(), CSSPrimitiveValue::CSS_STRING); else { - argument = args.next(); - if (argument->unit != CSSParserValue::Operator || argument->iValue != ',') - return nullptr; + i = args->next(); + if (i->unit != CSSParserValue::Operator || i->iValue != ',') + return 0; - argument = args.next(); - if (argument->unit != CSSPrimitiveValue::CSS_STRING) - return nullptr; + i = args->next(); + if (i->unit != CSSPrimitiveValue::CSS_STRING) + return 0; - separator = createPrimitiveStringValue(*argument); + separator = createPrimitiveStringValue(i); } RefPtr<CSSPrimitiveValue> listStyle; - argument = args.next(); - if (!argument) // Make the list style default decimal - listStyle = CSSValuePool::singleton().createIdentifierValue(CSSValueDecimal); + i = args->next(); + if (!i) // Make the list style default decimal + listStyle = cssValuePool().createIdentifierValue(CSSValueDecimal); else { - if (argument->unit != CSSParserValue::Operator || argument->iValue != ',') - return nullptr; + if (i->unit != CSSParserValue::Operator || i->iValue != ',') + return 0; - argument = args.next(); - if (argument->unit != CSSPrimitiveValue::CSS_IDENT) - return nullptr; + i = args->next(); + if (i->unit != CSSPrimitiveValue::CSS_IDENT) + return 0; CSSValueID listStyleID = CSSValueInvalid; - if (argument->id == CSSValueNone || (argument->id >= CSSValueDisc && argument->id <= CSSValueKatakanaIroha)) - listStyleID = argument->id; + if (i->id == CSSValueNone || (i->id >= CSSValueDisc && i->id <= CSSValueKatakanaIroha)) + listStyleID = i->id; else - return nullptr; + return 0; - listStyle = CSSValuePool::singleton().createIdentifierValue(listStyleID); + listStyle = cssValuePool().createIdentifierValue(listStyleID); } - return CSSValuePool::singleton().createValue(Counter::create(identifier.release(), listStyle.release(), separator.release())); + return cssValuePool().createValue(Counter::create(identifier.release(), listStyle.release(), separator.release())); } bool CSSParser::parseClipShape(CSSPropertyID propId, bool important) { - CSSParserValue& value = *m_valueList->current(); - CSSParserValueList* args = value.function->args.get(); + CSSParserValue* value = m_valueList->current(); + CSSParserValueList* args = value->function->args.get(); - if (!equalLettersIgnoringASCIICase(value.function->name, "rect(") || !args) + if (!equalIgnoringCase(value->function->name, "rect(") || !args) return false; // rect(t, r, b, l) || rect(t r b l) if (args->size() != 4 && args->size() != 7) return false; - auto rect = Rect::create(); + RefPtr<Rect> rect = Rect::create(); bool valid = true; int i = 0; - CSSParserValue* argument = args->current(); - while (argument) { - ValueWithCalculation argumentWithCalculation(*argument); - valid = argument->id == CSSValueAuto || validateUnit(argumentWithCalculation, FLength); + CSSParserValue* a = args->current(); + while (a) { + valid = a->id == CSSValueAuto || validUnit(a, FLength); if (!valid) break; - RefPtr<CSSPrimitiveValue> length = argument->id == CSSValueAuto ? CSSValuePool::singleton().createIdentifierValue(CSSValueAuto) : createPrimitiveNumericValue(argumentWithCalculation); + RefPtr<CSSPrimitiveValue> length = a->id == CSSValueAuto ? + cssValuePool().createIdentifierValue(CSSValueAuto) : + createPrimitiveNumericValue(a); if (i == 0) rect->setTop(length); else if (i == 1) @@ -6353,10 +5289,10 @@ bool CSSParser::parseClipShape(CSSPropertyID propId, bool important) rect->setBottom(length); else rect->setLeft(length); - argument = args->next(); - if (argument && args->size() == 7) { - if (argument->unit == CSSParserValue::Operator && argument->iValue == ',') { - argument = args->next(); + a = args->next(); + if (a && args->size() == 7) { + if (a->unit == CSSParserValue::Operator && a->iValue == ',') { + a = args->next(); } else { valid = false; break; @@ -6365,7 +5301,7 @@ bool CSSParser::parseClipShape(CSSPropertyID propId, bool important) i++; } if (valid) { - addProperty(propId, CSSValuePool::singleton().createValue(WTFMove(rect)), important); + addProperty(propId, cssValuePool().createValue(rect.release()), important); m_valueList->next(); return true; } @@ -6386,20 +5322,20 @@ static void completeBorderRadii(RefPtr<CSSPrimitiveValue> radii[4]) // FIXME: This should be refactored with CSSParser::parseBorderRadius. // CSSParser::parseBorderRadius contains support for some legacy radius construction. -RefPtr<CSSBasicShape> CSSParser::parseInsetRoundedCorners(PassRefPtr<CSSBasicShapeInset> shape, CSSParserValueList& args) +PassRefPtr<CSSBasicShape> CSSParser::parseInsetRoundedCorners(PassRefPtr<CSSBasicShapeInset> shape, CSSParserValueList* args) { - CSSParserValue* argument = args.next(); + CSSParserValue* argument = args->next(); if (!argument) return nullptr; - Vector<CSSParserValue*> radiusArguments; + std::unique_ptr<CSSParserValueList> radiusArguments(new CSSParserValueList); while (argument) { - radiusArguments.append(argument); - argument = args.next(); + radiusArguments->addValue(*argument); + argument = args->next(); } - unsigned num = radiusArguments.size(); + unsigned num = radiusArguments->size(); if (!num || num > 9) return nullptr; @@ -6407,9 +5343,9 @@ RefPtr<CSSBasicShape> CSSParser::parseInsetRoundedCorners(PassRefPtr<CSSBasicSha unsigned indexAfterSlash = 0; for (unsigned i = 0; i < num; ++i) { - CSSParserValue& value = *radiusArguments.at(i); - if (value.unit == CSSParserValue::Operator) { - if (value.iValue != '/') + CSSParserValue* value = radiusArguments->valueAt(i); + if (value->unit == CSSParserValue::Operator) { + if (value->iValue != '/') return nullptr; if (!i || indexAfterSlash || i + 1 == num || num > i + 5) @@ -6423,11 +5359,10 @@ RefPtr<CSSBasicShape> CSSParser::parseInsetRoundedCorners(PassRefPtr<CSSBasicSha if (i - indexAfterSlash >= 4) return nullptr; - ValueWithCalculation valueWithCalculation(value); - if (!validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg)) + if (!validUnit(value, FLength | FPercent | FNonNeg)) return nullptr; - RefPtr<CSSPrimitiveValue> radius = createPrimitiveNumericValue(valueWithCalculation); + RefPtr<CSSPrimitiveValue> radius = createPrimitiveNumericValue(value); if (!indexAfterSlash) radii[0][i] = radius; @@ -6450,43 +5385,56 @@ RefPtr<CSSBasicShape> CSSParser::parseInsetRoundedCorners(PassRefPtr<CSSBasicSha return shape; } -RefPtr<CSSBasicShape> CSSParser::parseBasicShapeInset(CSSParserValueList& args) +PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeInset(CSSParserValueList* args) { + ASSERT(args); + RefPtr<CSSBasicShapeInset> shape = CSSBasicShapeInset::create(); - CSSParserValue* argument = args.current(); + CSSParserValue* argument = args->current(); Vector<RefPtr<CSSPrimitiveValue> > widthArguments; bool hasRoundedInset = false; while (argument) { - if (argument->unit == CSSPrimitiveValue::CSS_IDENT && equalLettersIgnoringASCIICase(argument->string, "round")) { + if (argument->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(argument->string, "round")) { hasRoundedInset = true; break; } Units unitFlags = FLength | FPercent; - ValueWithCalculation argumentWithCalculation(*argument); - if (!validateUnit(argumentWithCalculation, unitFlags) || widthArguments.size() > 4) + if (!validUnit(argument, unitFlags) || widthArguments.size() > 4) return nullptr; - widthArguments.append(createPrimitiveNumericValue(argumentWithCalculation)); - argument = args.next(); + widthArguments.append(createPrimitiveNumericValue(argument)); + argument = args->next(); } switch (widthArguments.size()) { case 1: { - shape->updateShapeSize1Value(widthArguments[0].get()); + shape->setTop(widthArguments[0]); + shape->setRight(widthArguments[0]); + shape->setBottom(widthArguments[0]); + shape->setLeft(widthArguments[0]); break; } case 2: { - shape->updateShapeSize2Values(widthArguments[0].get(), widthArguments[1].get()); + shape->setTop(widthArguments[0]); + shape->setRight(widthArguments[1]); + shape->setBottom(widthArguments[0]); + shape->setLeft(widthArguments[1]); break; } case 3: { - shape->updateShapeSize3Values(widthArguments[0].get(), widthArguments[1].get(), widthArguments[2].get()); + shape->setTop(widthArguments[0]); + shape->setRight(widthArguments[1]); + shape->setBottom(widthArguments[2]); + shape->setLeft(widthArguments[1]); break; } case 4: { - shape->updateShapeSize4Values(widthArguments[0].get(), widthArguments[1].get(), widthArguments[2].get(), widthArguments[3].get()); + shape->setTop(widthArguments[0]); + shape->setRight(widthArguments[1]); + shape->setBottom(widthArguments[2]); + shape->setLeft(widthArguments[3]); break; } default: @@ -6498,77 +5446,245 @@ RefPtr<CSSBasicShape> CSSParser::parseBasicShapeInset(CSSParserValueList& args) return shape; } -RefPtr<CSSPrimitiveValue> CSSParser::parseShapeRadius(CSSParserValue& value) +PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeRectangle(CSSParserValueList* args) { - if (value.id == CSSValueClosestSide || value.id == CSSValueFarthestSide) - return CSSValuePool::singleton().createIdentifierValue(value.id); + ASSERT(args); - ValueWithCalculation valueWithCalculation(value); - if (!validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg)) - return nullptr; + // rect(x, y, width, height, [[rx], ry]) + if (args->size() != 7 && args->size() != 9 && args->size() != 11) + return 0; + + RefPtr<CSSBasicShapeRectangle> shape = CSSBasicShapeRectangle::create(); + + unsigned argumentNumber = 0; + CSSParserValue* argument = args->current(); + while (argument) { + Units unitFlags = FLength | FPercent; + if (argumentNumber > 1) { + // Arguments width, height, rx, and ry cannot be negative. + unitFlags = unitFlags | FNonNeg; + } + if (!validUnit(argument, unitFlags)) + return 0; + + RefPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument); + ASSERT(argumentNumber < 6); + switch (argumentNumber) { + case 0: + shape->setX(length); + break; + case 1: + shape->setY(length); + break; + case 2: + shape->setWidth(length); + break; + case 3: + shape->setHeight(length); + break; + case 4: + shape->setRadiusX(length); + break; + case 5: + shape->setRadiusY(length); + break; + } + argument = args->next(); + if (argument) { + if (!isComma(argument)) + return 0; + + argument = args->next(); + } + argumentNumber++; + } + + if (argumentNumber < 4) + return 0; + return shape; +} + +PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeInsetRectangle(CSSParserValueList* args) +{ + ASSERT(args); + + // inset-rectangle(top, right, bottom, left, [[rx], ry]) + if (args->size() != 7 && args->size() != 9 && args->size() != 11) + return 0; + + RefPtr<CSSBasicShapeInsetRectangle> shape = CSSBasicShapeInsetRectangle::create(); + + unsigned argumentNumber = 0; + CSSParserValue* argument = args->current(); + while (argument) { + Units unitFlags = FLength | FPercent | FNonNeg; + if (!validUnit(argument, unitFlags)) + return 0; + + RefPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument); + ASSERT(argumentNumber < 6); + switch (argumentNumber) { + case 0: + shape->setTop(length); + break; + case 1: + shape->setRight(length); + break; + case 2: + shape->setBottom(length); + break; + case 3: + shape->setLeft(length); + break; + case 4: + shape->setRadiusX(length); + break; + case 5: + shape->setRadiusY(length); + break; + } + argument = args->next(); + if (argument) { + if (!isComma(argument)) + return 0; - return createPrimitiveNumericValue(valueWithCalculation); + argument = args->next(); + } + argumentNumber++; + } + + if (argumentNumber < 4) + return 0; + return shape; +} + +PassRefPtr<CSSPrimitiveValue> CSSParser::parseShapeRadius(CSSParserValue* value) +{ + if (value->id == CSSValueClosestSide || value->id == CSSValueFarthestSide) + return cssValuePool().createIdentifierValue(value->id); + + if (!validUnit(value, FLength | FPercent | FNonNeg)) + return 0; + + return createPrimitiveNumericValue(value); } -RefPtr<CSSBasicShape> CSSParser::parseBasicShapeCircle(CSSParserValueList& args) +PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeCircle(CSSParserValueList* args) { + ASSERT(args); + // circle(radius) - // circle(radius at <position>) + // circle(radius at <position> // circle(at <position>) // where position defines centerX and centerY using a CSS <position> data type. RefPtr<CSSBasicShapeCircle> shape = CSSBasicShapeCircle::create(); - for (CSSParserValue* argument = args.current(); argument; argument = args.next()) { + for (CSSParserValue* argument = args->current(); argument; argument = args->next()) { // The call to parseFillPosition below should consume all of the // arguments except the first two. Thus, and index greater than one // indicates an invalid production. - if (args.currentIndex() > 1) - return nullptr; + if (args->currentIndex() > 1) + return 0; - if (!args.currentIndex() && argument->id != CSSValueAt) { - if (RefPtr<CSSPrimitiveValue> radius = parseShapeRadius(*argument)) { + if (!args->currentIndex() && argument->id != CSSValueAt) { + if (RefPtr<CSSPrimitiveValue> radius = parseShapeRadius(argument)) { shape->setRadius(radius); continue; } - return nullptr; + return 0; } - if (argument->id == CSSValueAt && args.next()) { - RefPtr<CSSPrimitiveValue> centerX; - RefPtr<CSSPrimitiveValue> centerY; + if (argument->id == CSSValueAt) { + RefPtr<CSSValue> centerX; + RefPtr<CSSValue> centerY; + args->next(); // set list to start of position center parseFillPosition(args, centerX, centerY); - if (centerX && centerY && !args.current()) { - shape->setCenterX(centerX); - shape->setCenterY(centerY); + if (centerX && centerY) { + ASSERT(centerX->isPrimitiveValue()); + ASSERT(centerY->isPrimitiveValue()); + shape->setCenterX(toCSSPrimitiveValue(centerX.get())); + shape->setCenterY(toCSSPrimitiveValue(centerY.get())); } else - return nullptr; + return 0; } else - return nullptr; + return 0; } return shape; } -RefPtr<CSSBasicShape> CSSParser::parseBasicShapeEllipse(CSSParserValueList& args) +PassRefPtr<CSSBasicShape> CSSParser::parseDeprecatedBasicShapeCircle(CSSParserValueList* args) { + ASSERT(args); + + // circle(centerX, centerY, radius) + if (args->size() != 5) + return 0; + + RefPtr<CSSDeprecatedBasicShapeCircle> shape = CSSDeprecatedBasicShapeCircle::create(); + + unsigned argumentNumber = 0; + CSSParserValue* argument = args->current(); + while (argument) { + Units unitFlags = FLength | FPercent; + if (argumentNumber == 2) { + // Argument radius cannot be negative. + unitFlags = unitFlags | FNonNeg; + } + + if (!validUnit(argument, unitFlags)) + return 0; + + RefPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument); + ASSERT(argumentNumber < 3); + switch (argumentNumber) { + case 0: + shape->setCenterX(length); + break; + case 1: + shape->setCenterY(length); + break; + case 2: + shape->setRadius(length); + break; + } + + argument = args->next(); + if (argument) { + if (!isComma(argument)) + return 0; + argument = args->next(); + } + argumentNumber++; + } + + if (argumentNumber < 3) + return 0; + return shape; +} + +PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeEllipse(CSSParserValueList* args) +{ + ASSERT(args); + // ellipse(radiusX) - // ellipse(radiusX at <position>) + // ellipse(radiusX at <position> // ellipse(radiusX radiusY) - // ellipse(radiusX radiusY at <position>) + // ellipse(radiusX radiusY at <position> // ellipse(at <position>) // where position defines centerX and centerY using a CSS <position> data type. RefPtr<CSSBasicShapeEllipse> shape = CSSBasicShapeEllipse::create(); - for (CSSParserValue* argument = args.current(); argument; argument = args.next()) { + for (CSSParserValue* argument = args->current(); argument; argument = args->next()) { // The call to parseFillPosition below should consume all of the // arguments except the first three. Thus, an index greater than two // indicates an invalid production. - if (args.currentIndex() > 2) - return nullptr; + if (args->currentIndex() > 2) + return 0; - if (args.currentIndex() < 2 && argument->id != CSSValueAt) { - if (RefPtr<CSSPrimitiveValue> radius = parseShapeRadius(*argument)) { + if (args->currentIndex() < 2 && argument->id != CSSValueAt) { + if (RefPtr<CSSPrimitiveValue> radius = parseShapeRadius(argument)) { if (!shape->radiusX()) shape->setRadiusX(radius); else @@ -6576,106 +5692,126 @@ RefPtr<CSSBasicShape> CSSParser::parseBasicShapeEllipse(CSSParserValueList& args continue; } - return nullptr; + return 0; } - if (argument->id != CSSValueAt || !args.next()) // expecting ellipse(.. at <position>) - return nullptr; - - RefPtr<CSSPrimitiveValue> centerX; - RefPtr<CSSPrimitiveValue> centerY; + if (argument->id != CSSValueAt) + return 0; + RefPtr<CSSValue> centerX; + RefPtr<CSSValue> centerY; + args->next(); // set list to start of position center parseFillPosition(args, centerX, centerY); - if (!centerX || !centerY || args.current()) - return nullptr; + if (!centerX || !centerY) + return 0; + + ASSERT(centerX->isPrimitiveValue()); + ASSERT(centerY->isPrimitiveValue()); + shape->setCenterX(toCSSPrimitiveValue(centerX.get())); + shape->setCenterY(toCSSPrimitiveValue(centerY.get())); + } + + return shape; +} + +PassRefPtr<CSSBasicShape> CSSParser::parseDeprecatedBasicShapeEllipse(CSSParserValueList* args) +{ + ASSERT(args); + + // ellipse(centerX, centerY, radiusX, radiusY) + if (args->size() != 7) + return 0; + + RefPtr<CSSDeprecatedBasicShapeEllipse> shape = CSSDeprecatedBasicShapeEllipse::create(); + unsigned argumentNumber = 0; + CSSParserValue* argument = args->current(); + while (argument) { + Units unitFlags = FLength | FPercent; + if (argumentNumber > 1) { + // Arguments radiusX and radiusY cannot be negative. + unitFlags = unitFlags | FNonNeg; + } + if (!validUnit(argument, unitFlags)) + return 0; + + RefPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument); + ASSERT(argumentNumber < 4); + switch (argumentNumber) { + case 0: + shape->setCenterX(length); + break; + case 1: + shape->setCenterY(length); + break; + case 2: + shape->setRadiusX(length); + break; + case 3: + shape->setRadiusY(length); + break; + } - shape->setCenterX(centerX); - shape->setCenterY(centerY); + argument = args->next(); + if (argument) { + if (!isComma(argument)) + return 0; + argument = args->next(); + } + argumentNumber++; } + if (argumentNumber < 4) + return 0; return shape; } -RefPtr<CSSBasicShape> CSSParser::parseBasicShapePolygon(CSSParserValueList& args) +PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapePolygon(CSSParserValueList* args) { - unsigned size = args.size(); + ASSERT(args); + + unsigned size = args->size(); if (!size) - return nullptr; + return 0; RefPtr<CSSBasicShapePolygon> shape = CSSBasicShapePolygon::create(); - CSSParserValue* argument = args.current(); + CSSParserValue* argument = args->current(); if (argument->id == CSSValueEvenodd || argument->id == CSSValueNonzero) { shape->setWindRule(argument->id == CSSValueEvenodd ? RULE_EVENODD : RULE_NONZERO); - if (!isComma(args.next())) - return nullptr; + if (!isComma(args->next())) + return 0; - argument = args.next(); + argument = args->next(); size -= 2; } // <length> <length>, ... <length> <length> -> each pair has 3 elements except the last one if (!size || (size % 3) - 2) - return nullptr; + return 0; CSSParserValue* argumentX = argument; while (argumentX) { + if (!validUnit(argumentX, FLength | FPercent)) + return 0; - ValueWithCalculation argumentXWithCalculation(*argumentX); - if (!validateUnit(argumentXWithCalculation, FLength | FPercent)) - return nullptr; - RefPtr<CSSPrimitiveValue> xLength = createPrimitiveNumericValue(argumentXWithCalculation); + CSSParserValue* argumentY = args->next(); + if (!argumentY || !validUnit(argumentY, FLength | FPercent)) + return 0; - CSSParserValue* argumentY = args.next(); - if (!argumentY) - return nullptr; - ValueWithCalculation argumentYWithCalculation(*argumentY); - if (!validateUnit(argumentYWithCalculation, FLength | FPercent)) - return nullptr; - RefPtr<CSSPrimitiveValue> yLength = createPrimitiveNumericValue(argumentYWithCalculation); + RefPtr<CSSPrimitiveValue> xLength = createPrimitiveNumericValue(argumentX); + RefPtr<CSSPrimitiveValue> yLength = createPrimitiveNumericValue(argumentY); shape->appendPoint(xLength.release(), yLength.release()); - CSSParserValue* commaOrNull = args.next(); + CSSParserValue* commaOrNull = args->next(); if (!commaOrNull) - argumentX = nullptr; + argumentX = 0; else if (!isComma(commaOrNull)) - return nullptr; + return 0; else - argumentX = args.next(); - } - - return shape; -} - -RefPtr<CSSBasicShape> CSSParser::parseBasicShapePath(CSSParserValueList& args) -{ - unsigned size = args.size(); - if (size != 1 && size != 3) - return nullptr; - - WindRule windRule = RULE_NONZERO; - - CSSParserValue* argument = args.current(); - if (argument->id == CSSValueEvenodd || argument->id == CSSValueNonzero) { - windRule = argument->id == CSSValueEvenodd ? RULE_EVENODD : RULE_NONZERO; - - if (!isComma(args.next())) - return nullptr; - argument = args.next(); + argumentX = args->next(); } - if (argument->unit != CSSPrimitiveValue::CSS_STRING) - return nullptr; - - auto byteStream = std::make_unique<SVGPathByteStream>(); - if (!buildSVGPathByteStreamFromString(argument->string, *byteStream, UnalteredParsing)) - return nullptr; - - RefPtr<CSSBasicShapePath> shape = CSSBasicShapePath::create(WTFMove(byteStream)); - shape->setWindRule(windRule); - - args.next(); return shape; } @@ -6687,9 +5823,7 @@ static bool isBoxValue(CSSValueID valueId, CSSPropertyID propId) case CSSValueBorderBox: case CSSValueMarginBox: return true; - case CSSValueFill: - case CSSValueStroke: - case CSSValueViewBox: + case CSSValueBoundingBox: return propId == CSSPropertyWebkitClipPath; default: break; } @@ -6697,7 +5831,7 @@ static bool isBoxValue(CSSValueID valueId, CSSPropertyID propId) return false; } -RefPtr<CSSValue> CSSParser::parseBasicShapeAndOrBox(CSSPropertyID propId) +PassRefPtr<CSSValue> CSSParser::parseBasicShapeAndOrBox(CSSPropertyID propId) { CSSParserValue* value = m_valueList->current(); @@ -6715,11 +5849,10 @@ RefPtr<CSSValue> CSSParser::parseBasicShapeAndOrBox(CSSPropertyID propId) RefPtr<CSSPrimitiveValue> shapeValue = parseBasicShape(); if (!shapeValue) return nullptr; - list->append(shapeValue.releaseNonNull()); + list->append(shapeValue.release()); shapeFound = true; } else if (isBoxValue(valueId, propId) && !boxFound) { - RefPtr<CSSPrimitiveValue> parsedValue = CSSValuePool::singleton().createIdentifierValue(valueId); - list->append(parsedValue.releaseNonNull()); + list->append(parseValidPrimitive(valueId, value)); boxFound = true; m_valueList->next(); } else @@ -6729,76 +5862,104 @@ RefPtr<CSSValue> CSSParser::parseBasicShapeAndOrBox(CSSPropertyID propId) if (m_valueList->current()) return nullptr; - return list; + return list.release(); } #if ENABLE(CSS_SHAPES) -RefPtr<CSSValue> CSSParser::parseShapeProperty(CSSPropertyID propId) +PassRefPtr<CSSValue> CSSParser::parseShapeProperty(CSSPropertyID propId) { if (!RuntimeEnabledFeatures::sharedFeatures().cssShapesEnabled()) return nullptr; - CSSParserValue& value = *m_valueList->current(); - CSSValueID valueId = value.id; + CSSParserValue* value = m_valueList->current(); + CSSValueID valueId = value->id; + RefPtr<CSSPrimitiveValue> keywordValue; + RefPtr<CSSPrimitiveValue> shapeValue; - if (valueId == CSSValueNone) { + if (valueId == CSSValueNone + || (valueId == CSSValueOutsideShape && propId == CSSPropertyWebkitShapeInside)) { + keywordValue = parseValidPrimitive(valueId, value); m_valueList->next(); - return CSSValuePool::singleton().createIdentifierValue(valueId); + return keywordValue.release(); } RefPtr<CSSValue> imageValue; - if (valueId != CSSValueNone && parseFillImage(*m_valueList, imageValue)) { + if (valueId != CSSValueNone && parseFillImage(m_valueList.get(), imageValue)) { m_valueList->next(); - return imageValue; + return imageValue.release(); } return parseBasicShapeAndOrBox(propId); } #endif -RefPtr<CSSValue> CSSParser::parseClipPath() +PassRefPtr<CSSValue> CSSParser::parseClipPath() { - CSSParserValue& value = *m_valueList->current(); - CSSValueID valueId = value.id; + CSSParserValue* value = m_valueList->current(); + CSSValueID valueId = value->id; if (valueId == CSSValueNone) { m_valueList->next(); - return CSSValuePool::singleton().createIdentifierValue(valueId); + return parseValidPrimitive(valueId, value); } - if (value.unit == CSSPrimitiveValue::CSS_URI) { +#if ENABLE(SVG) + if (value->unit == CSSPrimitiveValue::CSS_URI) { m_valueList->next(); - return CSSPrimitiveValue::create(value.string, CSSPrimitiveValue::CSS_URI); + return CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_URI); } +#endif return parseBasicShapeAndOrBox(CSSPropertyWebkitClipPath); } -RefPtr<CSSPrimitiveValue> CSSParser::parseBasicShape() +// FIXME This function is temporary to allow for an orderly transition between +// the new CSS Shapes circle and ellipse syntax. It will be removed when the +// old syntax is removed. +static bool isDeprecatedBasicShape(CSSParserValueList* args) { - CSSParserValue& value = *m_valueList->current(); - ASSERT(value.unit == CSSParserValue::Function); - CSSParserValueList* args = value.function->args.get(); + for (unsigned i = args->currentIndex(); i < args->size(); ++i) { + CSSParserValue* value = args->valueAt(i); + if (isComma(value)) + return true; + } + + return false; +} + +PassRefPtr<CSSPrimitiveValue> CSSParser::parseBasicShape() +{ + CSSParserValue* value = m_valueList->current(); + ASSERT(value->unit == CSSParserValue::Function); + CSSParserValueList* args = value->function->args.get(); if (!args) return nullptr; RefPtr<CSSBasicShape> shape; - if (equalLettersIgnoringASCIICase(value.function->name, "circle(")) - shape = parseBasicShapeCircle(*args); - else if (equalLettersIgnoringASCIICase(value.function->name, "ellipse(")) - shape = parseBasicShapeEllipse(*args); - else if (equalLettersIgnoringASCIICase(value.function->name, "polygon(")) - shape = parseBasicShapePolygon(*args); - else if (equalLettersIgnoringASCIICase(value.function->name, "path(")) - shape = parseBasicShapePath(*args); - else if (equalLettersIgnoringASCIICase(value.function->name, "inset(")) - shape = parseBasicShapeInset(*args); + if (equalIgnoringCase(value->function->name, "rectangle(")) + shape = parseBasicShapeRectangle(args); + else if (equalIgnoringCase(value->function->name, "circle(")) + if (isDeprecatedBasicShape(args)) + shape = parseDeprecatedBasicShapeCircle(args); + else + shape = parseBasicShapeCircle(args); + else if (equalIgnoringCase(value->function->name, "ellipse(")) + if (isDeprecatedBasicShape(args)) + shape = parseDeprecatedBasicShapeEllipse(args); + else + shape = parseBasicShapeEllipse(args); + else if (equalIgnoringCase(value->function->name, "polygon(")) + shape = parseBasicShapePolygon(args); + else if (equalIgnoringCase(value->function->name, "inset-rectangle(")) + shape = parseBasicShapeInsetRectangle(args); + else if (equalIgnoringCase(value->function->name, "inset(")) + shape = parseBasicShapeInset(args); if (!shape) return nullptr; m_valueList->next(); - return CSSValuePool::singleton().createValue(shape.releaseNonNull()); + return cssValuePool().createValue(shape.release()); } // [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? 'font-family' @@ -6817,12 +5978,12 @@ bool CSSParser::parseFont(bool important) bool fontWeightParsed = false; CSSParserValue* value; while ((value = m_valueList->current())) { - if (!fontStyleParsed && isValidKeywordPropertyAndValue(CSSPropertyFontStyle, value->id, m_context, m_styleSheet)) { - addProperty(CSSPropertyFontStyle, CSSValuePool::singleton().createIdentifierValue(value->id), important); + if (!fontStyleParsed && isValidKeywordPropertyAndValue(CSSPropertyFontStyle, value->id, m_context)) { + addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(value->id), important); fontStyleParsed = true; } else if (!fontVariantParsed && (value->id == CSSValueNormal || value->id == CSSValueSmallCaps)) { // Font variant in the shorthand is particular, it only accepts normal or small-caps. - addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(value->id), important); + addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue(value->id), important); fontVariantParsed = true; } else if (!fontWeightParsed && parseFontWeight(important)) fontWeightParsed = true; @@ -6835,11 +5996,11 @@ bool CSSParser::parseFont(bool important) return false; if (!fontStyleParsed) - addProperty(CSSPropertyFontStyle, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true); + addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(CSSValueNormal), important, true); if (!fontVariantParsed) - addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true); + addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue(CSSValueNormal), important, true); if (!fontWeightParsed) - addProperty(CSSPropertyFontWeight, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true); + addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(CSSValueNormal), important, true); // Now a font size _must_ come. // <absolute-size> | <relative-size> | <length> | <percentage> | inherit @@ -6850,7 +6011,7 @@ bool CSSParser::parseFont(bool important) if (!value) return false; - if (isForwardSlashOperator(*value)) { + if (isForwardSlashOperator(value)) { // The line-height property. value = m_valueList->next(); if (!value) @@ -6858,7 +6019,7 @@ bool CSSParser::parseFont(bool important) if (!parseLineHeight(important)) return false; } else - addProperty(CSSPropertyLineHeight, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true); + addProperty(CSSPropertyLineHeight, cssValuePool().createIdentifierValue(CSSValueNormal), important, true); // Font family must come now. RefPtr<CSSValue> parsedFamilyValue = parseFontFamily(); @@ -6876,33 +6037,9 @@ bool CSSParser::parseFont(bool important) return true; } -void CSSParser::parseSystemFont(bool important) -{ - ASSERT(m_valueList->size() == 1); - CSSValueID systemFontID = m_valueList->valueAt(0)->id; - ASSERT(systemFontID >= CSSValueCaption && systemFontID <= CSSValueStatusBar); - m_valueList->next(); - - FontCascadeDescription fontDescription; - RenderTheme::defaultTheme()->systemFont(systemFontID, fontDescription); - if (!fontDescription.isAbsoluteSize()) - return; - - // We must set font's constituent properties, even for system fonts, so the cascade functions correctly. - ShorthandScope scope(this, CSSPropertyFont); - addProperty(CSSPropertyFontStyle, CSSValuePool::singleton().createIdentifierValue(fontDescription.italic() == FontItalicOn ? CSSValueItalic : CSSValueNormal), important); - addProperty(CSSPropertyFontWeight, CSSValuePool::singleton().createValue(fontDescription.weight()), important); - addProperty(CSSPropertyFontSize, CSSValuePool::singleton().createValue(fontDescription.specifiedSize(), CSSPrimitiveValue::CSS_PX), important); - Ref<CSSValueList> fontFamilyList = CSSValueList::createCommaSeparated(); - fontFamilyList->append(CSSValuePool::singleton().createFontFamilyValue(fontDescription.familyAt(0), FromSystemFontID::Yes)); - addProperty(CSSPropertyFontFamily, WTFMove(fontFamilyList), important); - addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important); - addProperty(CSSPropertyLineHeight, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important); -} - class FontFamilyValueBuilder { public: - FontFamilyValueBuilder(CSSValueList& list) + FontFamilyValueBuilder(CSSValueList* list) : m_list(list) { } @@ -6924,27 +6061,21 @@ public: { if (m_builder.isEmpty()) return; - m_list.append(CSSValuePool::singleton().createFontFamilyValue(m_builder.toString())); + m_list->append(cssValuePool().createFontFamilyValue(m_builder.toString())); m_builder.clear(); } private: StringBuilder m_builder; - CSSValueList& m_list; + CSSValueList* m_list; }; -static bool valueIsCSSKeyword(const CSSParserValue& value) -{ - // FIXME: when we add "unset", we should handle it here. - return value.id == CSSValueInitial || value.id == CSSValueInherit || value.id == CSSValueDefault; -} - -RefPtr<CSSValueList> CSSParser::parseFontFamily() +PassRefPtr<CSSValueList> CSSParser::parseFontFamily() { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); CSSParserValue* value = m_valueList->current(); - FontFamilyValueBuilder familyBuilder(*list); + FontFamilyValueBuilder familyBuilder(list.get()); bool inFamily = false; while (value) { @@ -6955,7 +6086,7 @@ RefPtr<CSSValueList> CSSParser::parseFontFamily() ((nextValue->id >= CSSValueSerif && nextValue->id <= CSSValueWebkitBody) || (nextValue->unit == CSSPrimitiveValue::CSS_STRING || nextValue->unit == CSSPrimitiveValue::CSS_IDENT)); - bool valueIsKeyword = valueIsCSSKeyword(*value); + bool valueIsKeyword = value->id == CSSValueInitial || value->id == CSSValueInherit || value->id == CSSValueDefault; if (valueIsKeyword && !inFamily) { if (nextValBreaksFont) value = m_valueList->next(); @@ -6968,7 +6099,7 @@ RefPtr<CSSValueList> CSSParser::parseFontFamily() if (inFamily) familyBuilder.add(value->string); else if (nextValBreaksFont || !nextValIsFontName) - list->append(CSSValuePool::singleton().createIdentifierValue(value->id)); + list->append(cssValuePool().createIdentifierValue(value->id)); else { familyBuilder.commit(); familyBuilder.add(value->string); @@ -6978,12 +6109,12 @@ RefPtr<CSSValueList> CSSParser::parseFontFamily() // Strings never share in a family name. inFamily = false; familyBuilder.commit(); - list->append(CSSValuePool::singleton().createFontFamilyValue(value->string)); + list->append(cssValuePool().createFontFamilyValue(value->string)); } else if (value->unit == CSSPrimitiveValue::CSS_IDENT) { if (inFamily) familyBuilder.add(value->string); else if (nextValBreaksFont || !nextValIsFontName) - list->append(CSSValuePool::singleton().createFontFamilyValue(value->string)); + list->append(cssValuePool().createFontFamilyValue(value->string)); else { familyBuilder.commit(); familyBuilder.add(value->string); @@ -7009,40 +6140,87 @@ RefPtr<CSSValueList> CSSParser::parseFontFamily() familyBuilder.commit(); if (!list->length()) - list = nullptr; - return list; + list = 0; + return list.release(); } bool CSSParser::parseLineHeight(bool important) { - ValueWithCalculation valueWithCalculation(*m_valueList->current()); - CSSValueID id = valueWithCalculation.value().id; + CSSParserValue* value = m_valueList->current(); + CSSValueID id = value->id; bool validPrimitive = false; // normal | <number> | <length> | <percentage> | inherit if (id == CSSValueNormal) validPrimitive = true; else - validPrimitive = (!id && validateUnit(valueWithCalculation, FNumber | FLength | FPercent | FNonNeg)); + validPrimitive = (!id && validUnit(value, FNumber | FLength | FPercent | FNonNeg)); if (validPrimitive && (!m_valueList->next() || inShorthand())) - addProperty(CSSPropertyLineHeight, parseValidPrimitive(id, valueWithCalculation), important); + addProperty(CSSPropertyLineHeight, parseValidPrimitive(id, value), important); return validPrimitive; } bool CSSParser::parseFontSize(bool important) { - ValueWithCalculation valueWithCalculation(*m_valueList->current()); - CSSValueID id = valueWithCalculation.value().id; + CSSParserValue* value = m_valueList->current(); + CSSValueID id = value->id; bool validPrimitive = false; // <absolute-size> | <relative-size> | <length> | <percentage> | inherit if (id >= CSSValueXxSmall && id <= CSSValueLarger) validPrimitive = true; else - validPrimitive = validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg); + validPrimitive = validUnit(value, FLength | FPercent | FNonNeg); if (validPrimitive && (!m_valueList->next() || inShorthand())) - addProperty(CSSPropertyFontSize, parseValidPrimitive(id, valueWithCalculation), important); + addProperty(CSSPropertyFontSize, parseValidPrimitive(id, value), important); return validPrimitive; } +bool CSSParser::parseFontVariant(bool important) +{ + RefPtr<CSSValueList> values; + if (m_valueList->size() > 1) + values = CSSValueList::createCommaSeparated(); + CSSParserValue* val; + bool expectComma = false; + while ((val = m_valueList->current())) { + RefPtr<CSSPrimitiveValue> parsedValue; + if (!expectComma) { + expectComma = true; + if (val->id == CSSValueNormal || val->id == CSSValueSmallCaps) + parsedValue = cssValuePool().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 = cssValuePool().createIdentifierValue(val->id); + } + } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') { + expectComma = false; + m_valueList->next(); + continue; + } + + if (!parsedValue) + return false; + + m_valueList->next(); + + if (values) + values->append(parsedValue.release()); + else { + addProperty(CSSPropertyFontVariant, parsedValue.release(), important); + return true; + } + } + + if (values && values->length()) { + m_hasFontFaceOnlyValues = true; + addProperty(CSSPropertyFontVariant, values.release(), important); + return true; + } + + return false; +} + static CSSValueID createFontWeightValueKeyword(int weight) { ASSERT(!(weight % 100) && weight >= 100 && weight <= 900); @@ -7053,73 +6231,37 @@ static CSSValueID createFontWeightValueKeyword(int weight) bool CSSParser::parseFontWeight(bool important) { - CSSParserValue& value = *m_valueList->current(); - if ((value.id >= CSSValueNormal) && (value.id <= CSSValue900)) { - addProperty(CSSPropertyFontWeight, CSSValuePool::singleton().createIdentifierValue(value.id), important); + CSSParserValue* value = m_valueList->current(); + if ((value->id >= CSSValueNormal) && (value->id <= CSSValue900)) { + addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(value->id), important); return true; } - ValueWithCalculation valueWithCalculation(value); - if (validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSQuirksMode)) { - int weight = static_cast<int>(parsedDouble(valueWithCalculation)); + if (validUnit(value, FInteger | FNonNeg, CSSQuirksMode)) { + int weight = static_cast<int>(value->fValue); if (!(weight % 100) && weight >= 100 && weight <= 900) { - addProperty(CSSPropertyFontWeight, CSSValuePool::singleton().createIdentifierValue(createFontWeightValueKeyword(weight)), important); + addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(createFontWeightValueKeyword(weight)), important); return true; } } return false; } -bool CSSParser::parseFontSynthesis(bool important) -{ - // none | [ weight || style ] - CSSParserValue* value = m_valueList->current(); - if (value && value->id == CSSValueNone) { - addProperty(CSSPropertyFontSynthesis, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important); - m_valueList->next(); - return true; - } - - bool encounteredWeight = false; - bool encounteredStyle = false; - while (value) { - switch (value->id) { - case CSSValueWeight: - encounteredWeight = true; - break; - case CSSValueStyle: - encounteredStyle = true; - break; - default: - return false; - } - value = m_valueList->next(); - } - - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - if (encounteredWeight) - list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight)); - if (encounteredStyle) - list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle)); - addProperty(CSSPropertyFontSynthesis, list.release(), important); - return true; -} - -bool CSSParser::parseFontFaceSrcURI(CSSValueList& valueList) +bool CSSParser::parseFontFaceSrcURI(CSSValueList* valueList) { RefPtr<CSSFontFaceSrcValue> uriValue(CSSFontFaceSrcValue::create(completeURL(m_valueList->current()->string))); CSSParserValue* value = m_valueList->next(); if (!value) { - valueList.append(uriValue.releaseNonNull()); + valueList->append(uriValue.releaseNonNull()); return true; } if (value->unit == CSSParserValue::Operator && value->iValue == ',') { m_valueList->next(); - valueList.append(uriValue.releaseNonNull()); + valueList->append(uriValue.releaseNonNull()); return true; } - if (value->unit != CSSParserValue::Function || !equalLettersIgnoringASCIICase(value->function->name, "format(")) + if (value->unit != CSSParserValue::Function || !equalIgnoringCase(value->function->name, "format(")) return false; // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20111004/ says that format() contains a comma-separated list of strings, @@ -7128,21 +6270,21 @@ bool CSSParser::parseFontFaceSrcURI(CSSValueList& valueList) if (!args || args->size() != 1 || (args->current()->unit != CSSPrimitiveValue::CSS_STRING && args->current()->unit != CSSPrimitiveValue::CSS_IDENT)) return false; uriValue->setFormat(args->current()->string); - valueList.append(uriValue.releaseNonNull()); + valueList->append(uriValue.releaseNonNull()); value = m_valueList->next(); if (value && value->unit == CSSParserValue::Operator && value->iValue == ',') m_valueList->next(); return true; } -bool CSSParser::parseFontFaceSrcLocal(CSSValueList& valueList) +bool CSSParser::parseFontFaceSrcLocal(CSSValueList* valueList) { CSSParserValueList* args = m_valueList->current()->function->args.get(); if (!args || !args->size()) return false; if (args->size() == 1 && args->current()->unit == CSSPrimitiveValue::CSS_STRING) - valueList.append(CSSFontFaceSrcValue::createLocal(args->current()->string)); + valueList->append(CSSFontFaceSrcValue::createLocal(args->current()->string)); else if (args->current()->unit == CSSPrimitiveValue::CSS_IDENT) { StringBuilder builder; for (CSSParserValue* localValue = args->current(); localValue; localValue = args->next()) { @@ -7152,7 +6294,7 @@ bool CSSParser::parseFontFaceSrcLocal(CSSValueList& valueList) builder.append(' '); builder.append(localValue->string); } - valueList.append(CSSFontFaceSrcValue::createLocal(builder.toString())); + valueList->append(CSSFontFaceSrcValue::createLocal(builder.toString())); } else return false; @@ -7169,10 +6311,10 @@ bool CSSParser::parseFontFaceSrc() while (CSSParserValue* value = m_valueList->current()) { if (value->unit == CSSPrimitiveValue::CSS_URI) { - if (!parseFontFaceSrcURI(*values)) + if (!parseFontFaceSrcURI(values.get())) return false; - } else if (value->unit == CSSParserValue::Function && equalLettersIgnoringASCIICase(value->function->name, "local(")) { - if (!parseFontFaceSrcLocal(*values)) + } else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "local(")) { + if (!parseFontFaceSrcLocal(values.get())) return false; } else return false; @@ -7590,78 +6732,83 @@ bool CSSParser::fastParseColor(RGBA32& rgb, const StringType& name, bool strict) return false; } -inline double CSSParser::parsedDouble(ValueWithCalculation& valueWithCalculation) +inline double CSSParser::parsedDouble(CSSParserValue *v, ReleaseParsedCalcValueCondition releaseCalc) { - return valueWithCalculation.calculation() ? valueWithCalculation.calculation()->doubleValue() : valueWithCalculation.value().fValue; + const double result = m_parsedCalculation ? m_parsedCalculation->doubleValue() : v->fValue; + if (releaseCalc == ReleaseParsedCalcValue) + m_parsedCalculation.release(); + return result; } -bool CSSParser::isCalculation(CSSParserValue& value) +bool CSSParser::isCalculation(CSSParserValue* value) { - return value.unit == CSSParserValue::Function - && (equalLettersIgnoringASCIICase(value.function->name, "calc(") - || equalLettersIgnoringASCIICase(value.function->name, "-webkit-calc(")); + return (value->unit == CSSParserValue::Function) + && (equalIgnoringCase(value->function->name, "calc(") + || equalIgnoringCase(value->function->name, "-webkit-calc(") + || equalIgnoringCase(value->function->name, "-webkit-min(") + || equalIgnoringCase(value->function->name, "-webkit-max(")); } -inline int CSSParser::colorIntFromValue(ValueWithCalculation& valueWithCalculation) +inline int CSSParser::colorIntFromValue(CSSParserValue* v) { bool isPercent; - if (valueWithCalculation.calculation()) - isPercent = valueWithCalculation.calculation()->category() == CalcPercent; + if (m_parsedCalculation) + isPercent = m_parsedCalculation->category() == CalcPercent; else - isPercent = valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_PERCENTAGE; + isPercent = v->unit == CSSPrimitiveValue::CSS_PERCENTAGE; - const double doubleValue = parsedDouble(valueWithCalculation); + const double value = parsedDouble(v, ReleaseParsedCalcValue); - if (doubleValue <= 0.0) + if (value <= 0.0) return 0; if (isPercent) { - if (doubleValue >= 100.0) + if (value >= 100.0) return 255; - return static_cast<int>(doubleValue * 256.0 / 100.0); + return static_cast<int>(value * 256.0 / 100.0); } - if (doubleValue >= 255.0) + if (value >= 255.0) return 255; - return static_cast<int>(doubleValue); + return static_cast<int>(value); } -bool CSSParser::parseColorParameters(CSSParserValue& value, int* colorArray, bool parseAlpha) +bool CSSParser::parseColorParameters(CSSParserValue* value, int* colorArray, bool parseAlpha) { - CSSParserValueList* args = value.function->args.get(); - ValueWithCalculation firstArgumentWithCalculation(*args->current()); + CSSParserValueList* args = value->function->args.get(); + CSSParserValue* v = args->current(); Units unitType = FUnknown; // Get the first value and its type - if (validateUnit(firstArgumentWithCalculation, FInteger, CSSStrictMode)) + if (validUnit(v, FInteger, CSSStrictMode)) unitType = FInteger; - else if (validateUnit(firstArgumentWithCalculation, FPercent, CSSStrictMode)) + else if (validUnit(v, FPercent, CSSStrictMode)) unitType = FPercent; else return false; - colorArray[0] = colorIntFromValue(firstArgumentWithCalculation); + colorArray[0] = colorIntFromValue(v); for (int i = 1; i < 3; i++) { - CSSParserValue& operatorArgument = *args->next(); - if (operatorArgument.unit != CSSParserValue::Operator && operatorArgument.iValue != ',') + v = args->next(); + if (v->unit != CSSParserValue::Operator && v->iValue != ',') return false; - ValueWithCalculation argumentWithCalculation(*args->next()); - if (!validateUnit(argumentWithCalculation, unitType, CSSStrictMode)) + v = args->next(); + if (!validUnit(v, unitType, CSSStrictMode)) return false; - colorArray[i] = colorIntFromValue(argumentWithCalculation); + colorArray[i] = colorIntFromValue(v); } if (parseAlpha) { - CSSParserValue& operatorArgument = *args->next(); - if (operatorArgument.unit != CSSParserValue::Operator && operatorArgument.iValue != ',') + v = args->next(); + if (v->unit != CSSParserValue::Operator && v->iValue != ',') return false; - ValueWithCalculation argumentWithCalculation(*args->next()); - if (!validateUnit(argumentWithCalculation, FNumber, CSSStrictMode)) + v = args->next(); + if (!validUnit(v, FNumber, CSSStrictMode)) return false; - double doubleValue = parsedDouble(argumentWithCalculation); + const double value = parsedDouble(v, ReleaseParsedCalcValue); // Convert the floating pointer number of alpha to an integer in the range [0, 256), // with an equal distribution across all 256 values. - colorArray[3] = static_cast<int>(std::max<double>(0, std::min<double>(1, doubleValue)) * nextafter(256.0, 0.0)); + colorArray[3] = static_cast<int>(std::max<double>(0, std::min<double>(1, value)) * nextafter(256.0, 0.0)); } return true; } @@ -7671,86 +6818,86 @@ bool CSSParser::parseColorParameters(CSSParserValue& value, int* colorArray, boo // and with alpha, the format is // hsla(<number>, <percent>, <percent>, <number>) // The first value, HUE, is in an angle with a value between 0 and 360 -bool CSSParser::parseHSLParameters(CSSParserValue& value, double* colorArray, bool parseAlpha) +bool CSSParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bool parseAlpha) { - CSSParserValueList* args = value.function->args.get(); - ValueWithCalculation firstArgumentWithCalculation(*args->current()); + CSSParserValueList* args = value->function->args.get(); + CSSParserValue* v = args->current(); // Get the first value - if (!validateUnit(firstArgumentWithCalculation, FNumber, CSSStrictMode)) + if (!validUnit(v, FNumber, CSSStrictMode)) return false; // normalize the Hue value and change it to be between 0 and 1.0 - colorArray[0] = (((static_cast<int>(parsedDouble(firstArgumentWithCalculation)) % 360) + 360) % 360) / 360.0; - for (int i = 1; i < 3; ++i) { - CSSParserValue& operatorArgument = *args->next(); - if (operatorArgument.unit != CSSParserValue::Operator && operatorArgument.iValue != ',') + colorArray[0] = (((static_cast<int>(parsedDouble(v, ReleaseParsedCalcValue)) % 360) + 360) % 360) / 360.0; + for (int i = 1; i < 3; i++) { + v = args->next(); + if (v->unit != CSSParserValue::Operator && v->iValue != ',') return false; - ValueWithCalculation argumentWithCalculation(*args->next()); - if (!validateUnit(argumentWithCalculation, FPercent, CSSStrictMode)) + v = args->next(); + if (!validUnit(v, FPercent, CSSStrictMode)) return false; - colorArray[i] = std::max<double>(0, std::min<double>(100, parsedDouble(argumentWithCalculation))) / 100.0; // needs to be value between 0 and 1.0 + colorArray[i] = std::max<double>(0, std::min<double>(100, parsedDouble(v, ReleaseParsedCalcValue))) / 100.0; // needs to be value between 0 and 1.0 } if (parseAlpha) { - CSSParserValue& operatorArgument = *args->next(); - if (operatorArgument.unit != CSSParserValue::Operator && operatorArgument.iValue != ',') + v = args->next(); + if (v->unit != CSSParserValue::Operator && v->iValue != ',') return false; - ValueWithCalculation argumentWithCalculation(*args->next()); - if (!validateUnit(argumentWithCalculation, FNumber, CSSStrictMode)) + v = args->next(); + if (!validUnit(v, FNumber, CSSStrictMode)) return false; - colorArray[3] = std::max<double>(0, std::min<double>(1, parsedDouble(argumentWithCalculation))); + colorArray[3] = std::max<double>(0, std::min<double>(1, parsedDouble(v, ReleaseParsedCalcValue))); } return true; } -RefPtr<CSSPrimitiveValue> CSSParser::parseColor(CSSParserValue* value) +PassRefPtr<CSSPrimitiveValue> CSSParser::parseColor(CSSParserValue* value) { RGBA32 c = Color::transparent; - if (!parseColorFromValue(value ? *value : *m_valueList->current(), c)) - return nullptr; - return CSSValuePool::singleton().createColorValue(c); + if (!parseColorFromValue(value ? value : m_valueList->current(), c)) + return 0; + return cssValuePool().createColorValue(c); } -bool CSSParser::parseColorFromValue(CSSParserValue& value, RGBA32& c) +bool CSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c) { - if (inQuirksMode() && value.unit == CSSPrimitiveValue::CSS_NUMBER - && value.fValue >= 0. && value.fValue < 1000000.) { - String str = String::format("%06d", static_cast<int>((value.fValue+.5))); + if (inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_NUMBER + && value->fValue >= 0. && value->fValue < 1000000.) { + String str = String::format("%06d", static_cast<int>((value->fValue+.5))); // FIXME: This should be strict parsing for SVG as well. if (!fastParseColor(c, str, inStrictMode())) return false; - } else if (value.unit == CSSPrimitiveValue::CSS_PARSER_HEXCOLOR - || value.unit == CSSPrimitiveValue::CSS_IDENT - || (inQuirksMode() && value.unit == CSSPrimitiveValue::CSS_DIMENSION)) { - if (!fastParseColor(c, value.string, inStrictMode() && value.unit == CSSPrimitiveValue::CSS_IDENT)) + } else if (value->unit == CSSPrimitiveValue::CSS_PARSER_HEXCOLOR || + value->unit == CSSPrimitiveValue::CSS_IDENT || + (inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_DIMENSION)) { + if (!fastParseColor(c, value->string, inStrictMode() && value->unit == CSSPrimitiveValue::CSS_IDENT)) return false; - } else if (value.unit == CSSParserValue::Function - && value.function->args - && value.function->args->size() == 5 /* rgb + two commas */ - && equalLettersIgnoringASCIICase(value.function->name, "rgb(")) { + } else if (value->unit == CSSParserValue::Function && + value->function->args != 0 && + value->function->args->size() == 5 /* rgb + two commas */ && + equalIgnoringCase(value->function->name, "rgb(")) { int colorValues[3]; if (!parseColorParameters(value, colorValues, false)) return false; c = makeRGB(colorValues[0], colorValues[1], colorValues[2]); } else { - if (value.unit == CSSParserValue::Function - && value.function->args - && value.function->args->size() == 7 /* rgba + three commas */ - && equalLettersIgnoringASCIICase(value.function->name, "rgba(")) { + if (value->unit == CSSParserValue::Function && + value->function->args != 0 && + value->function->args->size() == 7 /* rgba + three commas */ && + equalIgnoringCase(value->function->name, "rgba(")) { int colorValues[4]; if (!parseColorParameters(value, colorValues, true)) return false; c = makeRGBA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]); - } else if (value.unit == CSSParserValue::Function - && value.function->args - && value.function->args->size() == 5 /* hsl + two commas */ - && equalLettersIgnoringASCIICase(value.function->name, "hsl(")) { + } else if (value->unit == CSSParserValue::Function && + value->function->args != 0 && + value->function->args->size() == 5 /* hsl + two commas */ && + equalIgnoringCase(value->function->name, "hsl(")) { double colorValues[3]; if (!parseHSLParameters(value, colorValues, false)) return false; c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], 1.0); - } else if (value.unit == CSSParserValue::Function - && value.function->args - && value.function->args->size() == 7 /* hsla + three commas */ - && equalLettersIgnoringASCIICase(value.function->name, "hsla(")) { + } else if (value->unit == CSSParserValue::Function && + value->function->args != 0 && + value->function->args->size() == 7 /* hsla + three commas */ && + equalIgnoringCase(value->function->name, "hsla(")) { double colorValues[4]; if (!parseHSLParameters(value, colorValues, true)) return false; @@ -7765,7 +6912,7 @@ 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, CSSParser& parser) + ShadowParseContext(CSSPropertyID prop, CSSParser* parser) : property(prop) , m_parser(parser) , allowX(true) @@ -7792,12 +6939,12 @@ struct ShadowParseContext { } // Now reset for the next shadow value. - x = nullptr; - y = nullptr; - blur = nullptr; - spread = nullptr; - style = nullptr; - color = nullptr; + x = 0; + y = 0; + blur = 0; + spread = 0; + style = 0; + color = 0; allowX = true; allowColor = true; @@ -7808,30 +6955,30 @@ struct ShadowParseContext { allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow; } - void commitLength(CSSParser::ValueWithCalculation& valueWithCalculation) + void commitLength(CSSParserValue* v) { - RefPtr<CSSPrimitiveValue> primitiveValue = m_parser.createPrimitiveNumericValue(valueWithCalculation); + RefPtr<CSSPrimitiveValue> val = m_parser->createPrimitiveNumericValue(v); if (allowX) { - x = primitiveValue.release(); + x = val.release(); allowX = false; allowY = true; allowColor = false; allowStyle = false; allowBreak = false; } else if (allowY) { - y = primitiveValue.release(); + y = val.release(); allowY = false; allowBlur = true; allowColor = true; allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow; allowBreak = true; } else if (allowBlur) { - blur = primitiveValue.release(); + blur = val.release(); allowBlur = false; allowSpread = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow; } else if (allowSpread) { - spread = primitiveValue.release(); + spread = val.release(); allowSpread = false; } } @@ -7850,9 +6997,9 @@ struct ShadowParseContext { } } - void commitStyle(CSSParserValue& value) + void commitStyle(CSSParserValue* v) { - style = CSSValuePool::singleton().createIdentifierValue(value.id); + style = cssValuePool().createIdentifierValue(v->id); allowStyle = false; if (allowX) allowBreak = false; @@ -7864,7 +7011,7 @@ struct ShadowParseContext { } CSSPropertyID property; - CSSParser& m_parser; + CSSParser* m_parser; RefPtr<CSSValueList> values; RefPtr<CSSPrimitiveValue> x; @@ -7883,64 +7030,64 @@ struct ShadowParseContext { bool allowBreak; }; -RefPtr<CSSValueList> CSSParser::parseShadow(CSSParserValueList& valueList, CSSPropertyID propId) +PassRefPtr<CSSValueList> CSSParser::parseShadow(CSSParserValueList* valueList, CSSPropertyID propId) { - ShadowParseContext context(propId, *this); - CSSParserValue* value; - while ((value = valueList.current())) { - ValueWithCalculation valueWithCalculation(*value); + ShadowParseContext context(propId, this); + CSSParserValue* val; + while ((val = valueList->current())) { // Check for a comma break first. - if (value->unit == CSSParserValue::Operator) { - if (value->iValue != ',' || !context.allowBreak) { + if (val->unit == CSSParserValue::Operator) { + if (val->iValue != ',' || !context.allowBreak) // Other operators aren't legal or we aren't done with the current shadow // value. Treat as invalid. - return nullptr; - } + return 0; +#if ENABLE(SVG) // -webkit-svg-shadow does not support multiple values. if (propId == CSSPropertyWebkitSvgShadow) - return nullptr; + return 0; +#endif // The value is good. Commit it. context.commitValue(); - } else if (validateUnit(valueWithCalculation, FLength, CSSStrictMode)) { + } else if (validUnit(val, FLength, CSSStrictMode)) { // We required a length and didn't get one. Invalid. if (!context.allowLength()) - return nullptr; + return 0; // Blur radius must be non-negative. - if (context.allowBlur && !validateUnit(valueWithCalculation, FLength | FNonNeg, CSSStrictMode)) - return nullptr; + if (context.allowBlur && !validUnit(val, FLength | FNonNeg, CSSStrictMode)) + return 0; // A length is allowed here. Construct the value and add it. - context.commitLength(valueWithCalculation); - } else if (value->id == CSSValueInset) { + context.commitLength(val); + } else if (val->id == CSSValueInset) { if (!context.allowStyle) - return nullptr; + return 0; - context.commitStyle(valueWithCalculation); + context.commitStyle(val); } else { // The only other type of value that's ok is a color value. RefPtr<CSSPrimitiveValue> parsedColor; - bool isColor = (isValidSystemColorValue(value->id) || value->id == CSSValueMenu - || (value->id >= CSSValueWebkitFocusRingColor && value->id <= CSSValueWebkitText && inQuirksMode()) - || value->id == CSSValueCurrentcolor); + bool isColor = ((val->id >= CSSValueAqua && val->id <= CSSValueWindowtext) || val->id == CSSValueMenu + || (val->id >= CSSValueWebkitFocusRingColor && val->id <= CSSValueWebkitText && inQuirksMode()) + || val->id == CSSValueCurrentcolor); if (isColor) { if (!context.allowColor) - return nullptr; - parsedColor = CSSValuePool::singleton().createIdentifierValue(value->id); + return 0; + parsedColor = cssValuePool().createIdentifierValue(val->id); } if (!parsedColor) // It's not built-in. Try to parse it as a color. - parsedColor = parseColor(value); + parsedColor = parseColor(val); if (!parsedColor || !context.allowColor) - return nullptr; // This value is not a color or length and is invalid or + return 0; // This value is not a color or length and is invalid or // it is a color, but a color isn't allowed at this point. context.commitColor(parsedColor.release()); } - valueList.next(); + valueList->next(); } if (context.allowBreak) { @@ -7949,7 +7096,7 @@ RefPtr<CSSValueList> CSSParser::parseShadow(CSSParserValueList& valueList, CSSPr return context.values.release(); } - return nullptr; + return 0; } bool CSSParser::parseReflect(CSSPropertyID propId, bool important) @@ -7957,35 +7104,34 @@ bool CSSParser::parseReflect(CSSPropertyID propId, bool important) // box-reflect: <direction> <offset> <mask> // Direction comes first. - CSSParserValue* value = m_valueList->current(); + CSSParserValue* val = m_valueList->current(); RefPtr<CSSPrimitiveValue> direction; - switch (value->id) { + switch (val->id) { case CSSValueAbove: case CSSValueBelow: case CSSValueLeft: case CSSValueRight: - direction = CSSValuePool::singleton().createIdentifierValue(value->id); + direction = cssValuePool().createIdentifierValue(val->id); break; default: return false; } // The offset comes next. - value = m_valueList->next(); + val = m_valueList->next(); RefPtr<CSSPrimitiveValue> offset; - if (!value) - offset = CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_PX); + if (!val) + offset = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX); else { - ValueWithCalculation valueWithCalculation(*value); - if (!validateUnit(valueWithCalculation, FLength | FPercent)) + if (!validUnit(val, FLength | FPercent)) return false; - offset = createPrimitiveNumericValue(valueWithCalculation); + offset = createPrimitiveNumericValue(val); } // Now for the mask. RefPtr<CSSValue> mask; - value = m_valueList->next(); - if (value) { + val = m_valueList->next(); + if (val) { if (!parseBorderImage(propId, mask)) return false; } @@ -7995,36 +7141,35 @@ bool CSSParser::parseReflect(CSSPropertyID propId, bool important) return true; } -bool CSSParser::parseFlex(CSSParserValueList& args, bool important) +bool CSSParser::parseFlex(CSSParserValueList* args, bool important) { - if (!args.size() || args.size() > 3) + if (!args || !args->size() || args->size() > 3) return false; static const double unsetValue = -1; double flexGrow = unsetValue; double flexShrink = unsetValue; RefPtr<CSSPrimitiveValue> flexBasis; - while (CSSParserValue* argument = args.current()) { - ValueWithCalculation argumentWithCalculation(*argument); - if (validateUnit(argumentWithCalculation, FNumber | FNonNeg)) { + while (CSSParserValue* arg = args->current()) { + if (validUnit(arg, FNumber | FNonNeg)) { if (flexGrow == unsetValue) - flexGrow = parsedDouble(argumentWithCalculation); + flexGrow = arg->fValue; else if (flexShrink == unsetValue) - flexShrink = parsedDouble(argumentWithCalculation); - else if (!parsedDouble(argumentWithCalculation)) { + flexShrink = arg->fValue; + else if (!arg->fValue) { // flex only allows a basis of 0 (sans units) if flex-grow and flex-shrink values have already been set. - flexBasis = CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_PX); + flexBasis = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX); } else { // We only allow 3 numbers without units if the last value is 0. E.g., flex:1 1 1 is invalid. return false; } - } else if (!flexBasis && (argumentWithCalculation.value().id == CSSValueAuto || validateUnit(argumentWithCalculation, FLength | FPercent | FNonNeg))) - flexBasis = parseValidPrimitive(argumentWithCalculation.value().id, argumentWithCalculation); + } else if (!flexBasis && (arg->id == CSSValueAuto || validUnit(arg, FLength | FPercent | FNonNeg))) + flexBasis = parseValidPrimitive(arg->id, arg); else { // Not a valid arg for flex. return false; } - args.next(); + args->next(); } if (flexGrow == unsetValue) @@ -8032,11 +7177,11 @@ bool CSSParser::parseFlex(CSSParserValueList& args, bool important) if (flexShrink == unsetValue) flexShrink = 1; if (!flexBasis) - flexBasis = CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_PX); + flexBasis = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX); - addProperty(CSSPropertyFlexGrow, CSSValuePool::singleton().createValue(clampToFloat(flexGrow), CSSPrimitiveValue::CSS_NUMBER), important); - addProperty(CSSPropertyFlexShrink, CSSValuePool::singleton().createValue(clampToFloat(flexShrink), CSSPrimitiveValue::CSS_NUMBER), important); - addProperty(CSSPropertyFlexBasis, flexBasis, important); + addProperty(CSSPropertyWebkitFlexGrow, cssValuePool().createValue(clampToFloat(flexGrow), CSSPrimitiveValue::CSS_NUMBER), important); + addProperty(CSSPropertyWebkitFlexShrink, cssValuePool().createValue(clampToFloat(flexShrink), CSSPrimitiveValue::CSS_NUMBER), important); + addProperty(CSSPropertyWebkitFlexBasis, flexBasis, important); return true; } @@ -8127,7 +7272,7 @@ struct BorderImageParseContext { return createBorderImageValue(m_image, m_imageSlice, m_borderSlice, m_outset, m_repeat); } - void commitBorderImage(CSSParser& parser, bool important) + void commitBorderImage(CSSParser* parser, bool important) { commitBorderImageProperty(CSSPropertyBorderImageSource, parser, m_image, important); commitBorderImageProperty(CSSPropertyBorderImageSlice, parser, m_imageSlice, important); @@ -8136,12 +7281,12 @@ struct BorderImageParseContext { commitBorderImageProperty(CSSPropertyBorderImageRepeat, parser, m_repeat, important); } - void commitBorderImageProperty(CSSPropertyID propId, CSSParser& parser, PassRefPtr<CSSValue> value, bool important) + void commitBorderImageProperty(CSSPropertyID propId, CSSParser* parser, PassRefPtr<CSSValue> value, bool important) { if (value) - parser.addProperty(propId, value, important); + parser->addProperty(propId, value, important); else - parser.addProperty(propId, CSSValuePool::singleton().createImplicitInitialValue(), important, true); + parser->addProperty(propId, cssValuePool().createImplicitInitialValue(), important, true); } bool m_canAdvance; @@ -8167,31 +7312,31 @@ bool CSSParser::parseBorderImage(CSSPropertyID propId, RefPtr<CSSValue>& result, { ShorthandScope scope(this, propId); BorderImageParseContext context; - while (CSSParserValue* currentValue = m_valueList->current()) { + while (CSSParserValue* val = m_valueList->current()) { context.setCanAdvance(false); - if (!context.canAdvance() && context.allowForwardSlashOperator() && isForwardSlashOperator(*currentValue)) + if (!context.canAdvance() && context.allowForwardSlashOperator() && isForwardSlashOperator(val)) context.commitForwardSlashOperator(); if (!context.canAdvance() && context.allowImage()) { - if (currentValue->unit == CSSPrimitiveValue::CSS_URI) - context.commitImage(CSSImageValue::create(completeURL(currentValue->string))); - else if (isGeneratedImageValue(*currentValue)) { + if (val->unit == CSSPrimitiveValue::CSS_URI) + context.commitImage(CSSImageValue::create(completeURL(val->string))); + else if (isGeneratedImageValue(val)) { RefPtr<CSSValue> value; - if (parseGeneratedImage(*m_valueList, value)) + if (parseGeneratedImage(m_valueList.get(), value)) context.commitImage(value.release()); else return false; #if ENABLE(CSS_IMAGE_SET) - } else if (currentValue->unit == CSSParserValue::Function && equalLettersIgnoringASCIICase(currentValue->function->name, "-webkit-image-set(")) { + } else if (val->unit == CSSParserValue::Function && equalIgnoringCase(val->function->name, "-webkit-image-set(")) { RefPtr<CSSValue> value = parseImageSet(); if (value) context.commitImage(value.release()); else return false; #endif - } else if (currentValue->id == CSSValueNone) - context.commitImage(CSSValuePool::singleton().createIdentifierValue(CSSValueNone)); + } else if (val->id == CSSValueNone) + context.commitImage(cssValuePool().createIdentifierValue(CSSValueNone)); } if (!context.canAdvance() && context.allowImageSlice()) { @@ -8226,7 +7371,7 @@ bool CSSParser::parseBorderImage(CSSPropertyID propId, RefPtr<CSSValue>& result, if (context.allowCommit()) { if (propId == CSSPropertyBorderImage) - context.commitBorderImage(*this, important); + context.commitBorderImage(this, important); else // Need to fully commit as a single value. result = context.commitWebKitBorderImage(); @@ -8249,14 +7394,14 @@ bool CSSParser::parseBorderImageRepeat(RefPtr<CSSValue>& result) if (!val) return false; if (isBorderImageRepeatKeyword(val->id)) - firstValue = CSSValuePool::singleton().createIdentifierValue(val->id); + firstValue = cssValuePool().createIdentifierValue(val->id); else return false; val = m_valueList->next(); if (val) { if (isBorderImageRepeatKeyword(val->id)) - secondValue = CSSValuePool::singleton().createIdentifierValue(val->id); + secondValue = cssValuePool().createIdentifierValue(val->id); else if (!inShorthand()) { // If we're not parsing a shorthand then we are invalid. return false; @@ -8269,13 +7414,13 @@ bool CSSParser::parseBorderImageRepeat(RefPtr<CSSValue>& result) } else secondValue = firstValue; - result = createPrimitiveValuePair(WTFMove(firstValue), WTFMove(secondValue)); + result = createPrimitiveValuePair(firstValue, secondValue); return true; } class BorderImageSliceParseContext { public: - BorderImageSliceParseContext(CSSParser& parser) + BorderImageSliceParseContext(CSSParser* parser) : m_parser(parser) , m_allowNumber(true) , m_allowFill(true) @@ -8288,18 +7433,18 @@ public: bool allowFinalCommit() const { return m_allowFinalCommit; } CSSPrimitiveValue* top() const { return m_top.get(); } - void commitNumber(CSSParser::ValueWithCalculation& valueWithCalculation) + void commitNumber(CSSParserValue* v) { - RefPtr<CSSPrimitiveValue> primitiveValue = m_parser.createPrimitiveNumericValue(valueWithCalculation); + RefPtr<CSSPrimitiveValue> val = m_parser->createPrimitiveNumericValue(v); if (!m_top) - m_top = primitiveValue.release(); + m_top = val; else if (!m_right) - m_right = primitiveValue.release(); + m_right = val; else if (!m_bottom) - m_bottom = primitiveValue.release(); + m_bottom = val; else { ASSERT(!m_left); - m_left = primitiveValue.release(); + m_left = val; } m_allowNumber = !m_left; @@ -8325,18 +7470,18 @@ public: m_left = m_right; // Now build a rect value to hold all four of our primitive values. - auto quad = Quad::create(); + RefPtr<Quad> quad = Quad::create(); quad->setTop(m_top); quad->setRight(m_right); quad->setBottom(m_bottom); quad->setLeft(m_left); // Make our new border image value now. - return CSSBorderImageSliceValue::create(CSSValuePool::singleton().createValue(WTFMove(quad)), m_fill); + return CSSBorderImageSliceValue::create(cssValuePool().createValue(quad.release()), m_fill); } private: - CSSParser& m_parser; + CSSParser* m_parser; bool m_allowNumber; bool m_allowFill; @@ -8352,14 +7497,13 @@ private: bool CSSParser::parseBorderImageSlice(CSSPropertyID propId, RefPtr<CSSBorderImageSliceValue>& result) { - BorderImageSliceParseContext context(*this); - CSSParserValue* value; - while ((value = m_valueList->current())) { - ValueWithCalculation valueWithCalculation(*value); + BorderImageSliceParseContext context(this); + CSSParserValue* val; + while ((val = m_valueList->current())) { // FIXME calc() http://webkit.org/b/16662 : calc is parsed but values are not created yet. - if (context.allowNumber() && !isCalculation(valueWithCalculation) && validateUnit(valueWithCalculation, FInteger | FNonNeg | FPercent, CSSStrictMode)) { - context.commitNumber(valueWithCalculation); - } else if (context.allowFill() && value->id == CSSValueFill) + if (context.allowNumber() && !isCalculation(val) && validUnit(val, FInteger | FNonNeg | FPercent, CSSStrictMode)) { + context.commitNumber(val); + } else if (context.allowFill() && val->id == CSSValueFill) context.commitFill(); else if (!inShorthand()) { // If we're not parsing a shorthand then we are invalid. @@ -8390,7 +7534,7 @@ bool CSSParser::parseBorderImageSlice(CSSPropertyID propId, RefPtr<CSSBorderImag class BorderImageQuadParseContext { public: - BorderImageQuadParseContext(CSSParser& parser) + BorderImageQuadParseContext(CSSParser* parser) : m_parser(parser) , m_allowNumber(true) , m_allowFinalCommit(false) @@ -8400,23 +7544,23 @@ public: bool allowFinalCommit() const { return m_allowFinalCommit; } CSSPrimitiveValue* top() const { return m_top.get(); } - void commitNumber(CSSParser::ValueWithCalculation& valueWithCalculation) + void commitNumber(CSSParserValue* v) { - RefPtr<CSSPrimitiveValue> primitiveValue; - if (valueWithCalculation.value().id == CSSValueAuto) - primitiveValue = CSSValuePool::singleton().createIdentifierValue(valueWithCalculation.value().id); + RefPtr<CSSPrimitiveValue> val; + if (v->id == CSSValueAuto) + val = cssValuePool().createIdentifierValue(v->id); else - primitiveValue = m_parser.createPrimitiveNumericValue(valueWithCalculation); + val = m_parser->createPrimitiveNumericValue(v); if (!m_top) - m_top = primitiveValue.release(); + m_top = val; else if (!m_right) - m_right = primitiveValue.release(); + m_right = val; else if (!m_bottom) - m_bottom = primitiveValue.release(); + m_bottom = val; else { ASSERT(!m_left); - m_left = primitiveValue.release(); + m_left = val; } m_allowNumber = !m_left; @@ -8443,18 +7587,18 @@ public: m_left = m_right; // Now build a quad value to hold all four of our primitive values. - auto quad = Quad::create(); + RefPtr<Quad> quad = Quad::create(); quad->setTop(m_top); quad->setRight(m_right); quad->setBottom(m_bottom); quad->setLeft(m_left); // Make our new value now. - return CSSValuePool::singleton().createValue(WTFMove(quad)); + return cssValuePool().createValue(quad.release()); } private: - CSSParser& m_parser; + CSSParser* m_parser; bool m_allowNumber; bool m_allowFinalCommit; @@ -8467,12 +7611,11 @@ private: bool CSSParser::parseBorderImageQuad(Units validUnits, RefPtr<CSSPrimitiveValue>& result) { - BorderImageQuadParseContext context(*this); - CSSParserValue* value; - while ((value = m_valueList->current())) { - ValueWithCalculation valueWithCalculation(*value); - if (context.allowNumber() && (validateUnit(valueWithCalculation, validUnits, CSSStrictMode) || value->id == CSSValueAuto)) { - context.commitNumber(valueWithCalculation); + BorderImageQuadParseContext context(this); + CSSParserValue* val; + while ((val = m_valueList->current())) { + if (context.allowNumber() && (validUnit(val, validUnits, CSSStrictMode) || val->id == CSSValueAuto)) { + context.commitNumber(val); } else if (!inShorthand()) { // If we're not parsing a shorthand then we are invalid. return false; @@ -8513,9 +7656,9 @@ bool CSSParser::parseBorderRadius(CSSPropertyID propId, bool important) unsigned indexAfterSlash = 0; for (unsigned i = 0; i < num; ++i) { - CSSParserValue& value = *m_valueList->valueAt(i); - if (value.unit == CSSParserValue::Operator) { - if (value.iValue != '/') + CSSParserValue* value = m_valueList->valueAt(i); + if (value->unit == CSSParserValue::Operator) { + if (value->iValue != '/') return false; if (!i || indexAfterSlash || i + 1 == num || num > i + 5) @@ -8529,11 +7672,10 @@ bool CSSParser::parseBorderRadius(CSSPropertyID propId, bool important) if (i - indexAfterSlash >= 4) return false; - ValueWithCalculation valueWithCalculation(value); - if (!validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg)) + if (!validUnit(value, FLength | FPercent | FNonNeg)) return false; - RefPtr<CSSPrimitiveValue> radius = createPrimitiveNumericValue(valueWithCalculation); + RefPtr<CSSPrimitiveValue> radius = createPrimitiveNumericValue(value); if (!indexAfterSlash) { radii[0][i] = radius; @@ -8554,7 +7696,7 @@ bool CSSParser::parseBorderRadius(CSSPropertyID propId, bool important) } else completeBorderRadii(radii[1]); - ImplicitScope implicitScope(*this, PropertyImplicit); + ImplicitScope implicitScope(this, PropertyImplicit); addProperty(CSSPropertyBorderTopLeftRadius, createPrimitiveValuePair(radii[0][0].release(), radii[1][0].release()), important); addProperty(CSSPropertyBorderTopRightRadius, createPrimitiveValuePair(radii[0][1].release(), radii[1][1].release()), important); addProperty(CSSPropertyBorderBottomRightRadius, createPrimitiveValuePair(radii[0][2].release(), radii[1][2].release()), important); @@ -8565,32 +7707,28 @@ bool CSSParser::parseBorderRadius(CSSPropertyID propId, bool important) bool CSSParser::parseAspectRatio(bool important) { unsigned num = m_valueList->size(); - if (num == 1) { - CSSValueID valueId = m_valueList->valueAt(0)->id; - if (valueId == CSSValueAuto || valueId == CSSValueFromDimensions || valueId == CSSValueFromIntrinsic) { - addProperty(CSSPropertyWebkitAspectRatio, CSSValuePool::singleton().createIdentifierValue(valueId), important); - return true; - } + if (num == 1 && m_valueList->valueAt(0)->id == CSSValueNone) { + addProperty(CSSPropertyWebkitAspectRatio, cssValuePool().createIdentifierValue(CSSValueNone), important); + return true; } if (num != 3) return false; - CSSParserValue& op = *m_valueList->valueAt(1); + CSSParserValue* lvalue = m_valueList->valueAt(0); + CSSParserValue* op = m_valueList->valueAt(1); + CSSParserValue* rvalue = m_valueList->valueAt(2); if (!isForwardSlashOperator(op)) return false; - ValueWithCalculation lvalueWithCalculation(*m_valueList->valueAt(0)); - ValueWithCalculation rvalueWithCalculation(*m_valueList->valueAt(2)); - if (!validateUnit(lvalueWithCalculation, FNumber | FNonNeg) || !validateUnit(rvalueWithCalculation, FNumber | FNonNeg)) + if (!validUnit(lvalue, FNumber | FNonNeg) || !validUnit(rvalue, FNumber | FNonNeg)) return false; - // FIXME: This doesn't handle calculated values. - if (!lvalueWithCalculation.value().fValue || !rvalueWithCalculation.value().fValue) + if (!lvalue->fValue || !rvalue->fValue) return false; - addProperty(CSSPropertyWebkitAspectRatio, CSSAspectRatioValue::create(narrowPrecisionToFloat(lvalueWithCalculation.value().fValue), narrowPrecisionToFloat(rvalueWithCalculation.value().fValue)), important); + addProperty(CSSPropertyWebkitAspectRatio, CSSAspectRatioValue::create(narrowPrecisionToFloat(lvalue->fValue), narrowPrecisionToFloat(rvalue->fValue)), important); return true; } @@ -8603,11 +7741,11 @@ bool CSSParser::parseCounter(CSSPropertyID propId, int defaultValue, bool import RefPtr<CSSPrimitiveValue> counterName; while (true) { - CSSParserValue* value = m_valueList->current(); + CSSParserValue* val = m_valueList->current(); switch (state) { case ID: - if (value && value->unit == CSSPrimitiveValue::CSS_IDENT) { - counterName = createPrimitiveStringValue(*value); + if (val && val->unit == CSSPrimitiveValue::CSS_IDENT) { + counterName = createPrimitiveStringValue(val); state = VAL; m_valueList->next(); continue; @@ -8615,13 +7753,13 @@ bool CSSParser::parseCounter(CSSPropertyID propId, int defaultValue, bool import break; case VAL: { int i = defaultValue; - if (value && value->unit == CSSPrimitiveValue::CSS_NUMBER) { - i = clampToInteger(value->fValue); + if (val && val->unit == CSSPrimitiveValue::CSS_NUMBER) { + i = clampToInteger(val->fValue); m_valueList->next(); } list->append(createPrimitiveValuePair(counterName.release(), - CSSValuePool::singleton().createValue(i, CSSPrimitiveValue::CSS_NUMBER))); + cssValuePool().createValue(i, CSSPrimitiveValue::CSS_NUMBER))); state = ID; continue; } @@ -8638,67 +7776,67 @@ bool CSSParser::parseCounter(CSSPropertyID propId, int defaultValue, bool import } // This should go away once we drop support for -webkit-gradient -static PassRefPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue& value, bool horizontal) +static PassRefPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue* a, bool horizontal) { RefPtr<CSSPrimitiveValue> result; - if (value.unit == CSSPrimitiveValue::CSS_IDENT) { - if ((equalLettersIgnoringASCIICase(value, "left") && horizontal) - || (equalLettersIgnoringASCIICase(value, "top") && !horizontal)) - result = CSSValuePool::singleton().createValue(0., CSSPrimitiveValue::CSS_PERCENTAGE); - else if ((equalLettersIgnoringASCIICase(value, "right") && horizontal) - || (equalLettersIgnoringASCIICase(value, "bottom") && !horizontal)) - result = CSSValuePool::singleton().createValue(100., CSSPrimitiveValue::CSS_PERCENTAGE); - else if (equalLettersIgnoringASCIICase(value, "center")) - result = CSSValuePool::singleton().createValue(50., CSSPrimitiveValue::CSS_PERCENTAGE); - } else if (value.unit == CSSPrimitiveValue::CSS_NUMBER || value.unit == CSSPrimitiveValue::CSS_PERCENTAGE) - result = CSSValuePool::singleton().createValue(value.fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value.unit)); + if (a->unit == CSSPrimitiveValue::CSS_IDENT) { + if ((equalIgnoringCase(a, "left") && horizontal) + || (equalIgnoringCase(a, "top") && !horizontal)) + result = cssValuePool().createValue(0., CSSPrimitiveValue::CSS_PERCENTAGE); + else if ((equalIgnoringCase(a, "right") && horizontal) + || (equalIgnoringCase(a, "bottom") && !horizontal)) + result = cssValuePool().createValue(100., CSSPrimitiveValue::CSS_PERCENTAGE); + else if (equalIgnoringCase(a, "center")) + result = cssValuePool().createValue(50., CSSPrimitiveValue::CSS_PERCENTAGE); + } else if (a->unit == CSSPrimitiveValue::CSS_NUMBER || a->unit == CSSPrimitiveValue::CSS_PERCENTAGE) + result = cssValuePool().createValue(a->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(a->unit)); return result; } -static bool parseDeprecatedGradientColorStop(CSSParser& parser, CSSParserValue& value, CSSGradientColorStop& stop) +static bool parseDeprecatedGradientColorStop(CSSParser* p, CSSParserValue* a, CSSGradientColorStop& stop) { - if (value.unit != CSSParserValue::Function) + if (a->unit != CSSParserValue::Function) return false; - if (!equalLettersIgnoringASCIICase(value.function->name, "from(") - && !equalLettersIgnoringASCIICase(value.function->name, "to(") - && !equalLettersIgnoringASCIICase(value.function->name, "color-stop(")) + if (!equalIgnoringCase(a->function->name, "from(") && + !equalIgnoringCase(a->function->name, "to(") && + !equalIgnoringCase(a->function->name, "color-stop(")) return false; - CSSParserValueList* args = value.function->args.get(); + CSSParserValueList* args = a->function->args.get(); if (!args) return false; - if (equalLettersIgnoringASCIICase(value.function->name, "from(") - || equalLettersIgnoringASCIICase(value.function->name, "to(")) { + if (equalIgnoringCase(a->function->name, "from(") + || equalIgnoringCase(a->function->name, "to(")) { // The "from" and "to" stops expect 1 argument. if (args->size() != 1) return false; - if (equalLettersIgnoringASCIICase(value.function->name, "from(")) - stop.m_position = CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_NUMBER); + if (equalIgnoringCase(a->function->name, "from(")) + stop.m_position = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER); else - stop.m_position = CSSValuePool::singleton().createValue(1, CSSPrimitiveValue::CSS_NUMBER); + stop.m_position = cssValuePool().createValue(1, CSSPrimitiveValue::CSS_NUMBER); CSSValueID id = args->current()->id; - if (id == CSSValueWebkitText || CSSParser::isValidSystemColorValue(id) || id == CSSValueMenu) - stop.m_color = CSSValuePool::singleton().createIdentifierValue(id); + if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu) + stop.m_color = cssValuePool().createIdentifierValue(id); else - stop.m_color = parser.parseColor(args->current()); + stop.m_color = p->parseColor(args->current()); if (!stop.m_color) return false; } // The "color-stop" function expects 3 arguments. - if (equalLettersIgnoringASCIICase(value.function->name, "color-stop(")) { + if (equalIgnoringCase(a->function->name, "color-stop(")) { if (args->size() != 3) return false; CSSParserValue* stopArg = args->current(); if (stopArg->unit == CSSPrimitiveValue::CSS_PERCENTAGE) - stop.m_position = CSSValuePool::singleton().createValue(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER); + stop.m_position = cssValuePool().createValue(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER); else if (stopArg->unit == CSSPrimitiveValue::CSS_NUMBER) - stop.m_position = CSSValuePool::singleton().createValue(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER); + stop.m_position = cssValuePool().createValue(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER); else return false; @@ -8708,10 +7846,10 @@ static bool parseDeprecatedGradientColorStop(CSSParser& parser, CSSParserValue& stopArg = args->next(); CSSValueID id = stopArg->id; - if (id == CSSValueWebkitText || CSSParser::isValidSystemColorValue(id) || id == CSSValueMenu) - stop.m_color = CSSValuePool::singleton().createIdentifierValue(id); + if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu) + stop.m_color = cssValuePool().createIdentifierValue(id); else - stop.m_color = parser.parseColor(stopArg); + stop.m_color = p->parseColor(stopArg); if (!stop.m_color) return false; } @@ -8719,21 +7857,21 @@ static bool parseDeprecatedGradientColorStop(CSSParser& parser, CSSParserValue& return true; } -bool CSSParser::parseDeprecatedGradient(CSSParserValueList& valueList, RefPtr<CSSValue>& gradient) +bool CSSParser::parseDeprecatedGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient) { // Walk the arguments. - CSSParserValueList* args = valueList.current()->function->args.get(); + CSSParserValueList* args = valueList->current()->function->args.get(); if (!args || args->size() == 0) return false; // The first argument is the gradient type. It is an identifier. CSSGradientType gradientType; - CSSParserValue* argument = args->current(); - if (!argument || argument->unit != CSSPrimitiveValue::CSS_IDENT) + CSSParserValue* a = args->current(); + if (!a || a->unit != CSSPrimitiveValue::CSS_IDENT) return false; - if (equalLettersIgnoringASCIICase(*argument, "linear")) + if (equalIgnoringCase(a, "linear")) gradientType = CSSDeprecatedLinearGradient; - else if (equalLettersIgnoringASCIICase(*argument, "radial")) + else if (equalIgnoringCase(a, "radial")) gradientType = CSSDeprecatedRadialGradient; else return false; @@ -8752,65 +7890,63 @@ bool CSSParser::parseDeprecatedGradient(CSSParserValueList& valueList, RefPtr<CS } // Comma. - argument = args->next(); - if (!isComma(argument)) + a = args->next(); + if (!isComma(a)) return false; // Next comes the starting point for the gradient as an x y pair. There is no // comma between the x and the y values. // First X. It can be left, right, number or percent. - argument = args->next(); - if (!argument) + a = args->next(); + if (!a) return false; - RefPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(*argument, true); + RefPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(a, true); if (!point) return false; result->setFirstX(point.release()); // First Y. It can be top, bottom, number or percent. - argument = args->next(); - if (!argument) + a = args->next(); + if (!a) return false; - point = parseDeprecatedGradientPoint(*argument, false); + point = parseDeprecatedGradientPoint(a, false); if (!point) return false; result->setFirstY(point.release()); // Comma after the first point. - argument = args->next(); - if (!isComma(argument)) + a = args->next(); + if (!isComma(a)) return false; // For radial gradients only, we now expect a numeric radius. if (gradientType == CSSDeprecatedRadialGradient) { - argument = args->next(); - // FIXME: This does not handle calculation values. - if (!argument || argument->unit != CSSPrimitiveValue::CSS_NUMBER) + a = args->next(); + if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER) return false; - ValueWithCalculation argumentWithCalculation(*argument); - downcast<CSSRadialGradientValue>(*result).setFirstRadius(createPrimitiveNumericValue(argumentWithCalculation)); + toCSSRadialGradientValue(result.get())->setFirstRadius(createPrimitiveNumericValue(a)); // Comma after the first radius. - argument = args->next(); - if (!isComma(argument)) + a = args->next(); + if (!isComma(a)) return false; } // Next is the ending point for the gradient as an x, y pair. // Second X. It can be left, right, number or percent. - argument = args->next(); - if (!argument) + a = args->next(); + if (!a) return false; - point = parseDeprecatedGradientPoint(*argument, true); + point = parseDeprecatedGradientPoint(a, true); if (!point) return false; result->setSecondX(point.release()); // Second Y. It can be top, bottom, number or percent. - argument = args->next(); - if (!argument) + a = args->next(); + if (!a) return false; - point = parseDeprecatedGradientPoint(*argument, false); + point = parseDeprecatedGradientPoint(a, false); if (!point) return false; result->setSecondY(point.release()); @@ -8818,50 +7954,48 @@ bool CSSParser::parseDeprecatedGradient(CSSParserValueList& valueList, RefPtr<CS // For radial gradients only, we now expect the second radius. if (gradientType == CSSDeprecatedRadialGradient) { // Comma after the second point. - argument = args->next(); - if (!isComma(argument)) + a = args->next(); + if (!isComma(a)) return false; - argument = args->next(); - // FIXME: This does not handle calculation values. - if (!argument || argument->unit != CSSPrimitiveValue::CSS_NUMBER) + a = args->next(); + if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER) return false; - ValueWithCalculation argumentWithCalculation(*argument); - downcast<CSSRadialGradientValue>(*result).setSecondRadius(createPrimitiveNumericValue(argumentWithCalculation)); + toCSSRadialGradientValue(result.get())->setSecondRadius(createPrimitiveNumericValue(a)); } // We now will accept any number of stops (0 or more). - argument = args->next(); - while (argument) { + a = args->next(); + while (a) { // Look for the comma before the next stop. - if (!isComma(argument)) + if (!isComma(a)) return false; // Now examine the stop itself. - argument = args->next(); - if (!argument) + a = args->next(); + if (!a) return false; // The function name needs to be one of "from", "to", or "color-stop." CSSGradientColorStop stop; - if (!parseDeprecatedGradientColorStop(*this, *argument, stop)) + if (!parseDeprecatedGradientColorStop(this, a, stop)) return false; result->addStop(stop); // Advance - argument = args->next(); + a = args->next(); } gradient = result.release(); return true; } -static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue& value, bool& isHorizontal) +static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, bool& isHorizontal) { - if (value.unit != CSSPrimitiveValue::CSS_IDENT) - return nullptr; + if (a->unit != CSSPrimitiveValue::CSS_IDENT) + return 0; - switch (value.id) { + switch (a->id) { case CSSValueLeft: case CSSValueRight: isHorizontal = true; @@ -8871,38 +8005,37 @@ static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue& value, isHorizontal = false; break; default: - return nullptr; + return 0; } - return CSSValuePool::singleton().createIdentifierValue(value.id); + return cssValuePool().createIdentifierValue(a->id); } -static PassRefPtr<CSSPrimitiveValue> parseGradientColorOrKeyword(CSSParser& parser, CSSParserValue& value) +static PassRefPtr<CSSPrimitiveValue> parseGradientColorOrKeyword(CSSParser* p, CSSParserValue* value) { - CSSValueID id = value.id; - if (id == CSSValueWebkitText || CSSParser::isValidSystemColorValue(id) || id == CSSValueMenu || id == CSSValueCurrentcolor) - return CSSValuePool::singleton().createIdentifierValue(id); + CSSValueID id = value->id; + if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor) + return cssValuePool().createIdentifierValue(id); - return parser.parseColor(&value); + return p->parseColor(value); } -bool CSSParser::parseDeprecatedLinearGradient(CSSParserValueList& valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating) +bool CSSParser::parseDeprecatedLinearGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating) { RefPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating, CSSPrefixedLinearGradient); // Walk the arguments. - CSSParserValueList* args = valueList.current()->function->args.get(); + CSSParserValueList* args = valueList->current()->function->args.get(); if (!args || !args->size()) return false; - CSSParserValue* argument = args->current(); - if (!argument) + CSSParserValue* a = args->current(); + if (!a) return false; - ValueWithCalculation argumentWithCalculation(*argument); bool expectComma = false; // Look for angle. - if (validateUnit(argumentWithCalculation, FAngle, CSSStrictMode)) { - result->setAngle(createPrimitiveNumericValue(argumentWithCalculation)); + if (validUnit(a, FAngle, CSSStrictMode)) { + result->setAngle(createPrimitiveNumericValue(a)); args->next(); expectComma = true; @@ -8912,14 +8045,14 @@ bool CSSParser::parseDeprecatedLinearGradient(CSSParserValueList& valueList, Ref RefPtr<CSSPrimitiveValue> location; bool isHorizontal = false; - if ((location = valueFromSideKeyword(*argument, isHorizontal))) { + if ((location = valueFromSideKeyword(a, isHorizontal))) { if (isHorizontal) startX = location; else startY = location; - if ((argument = args->next())) { - if ((location = valueFromSideKeyword(*argument, isHorizontal))) { + if ((a = args->next())) { + if ((location = valueFromSideKeyword(a, isHorizontal))) { if (isHorizontal) { if (startX) return false; @@ -8938,13 +8071,13 @@ bool CSSParser::parseDeprecatedLinearGradient(CSSParserValueList& valueList, Ref } if (!startX && !startY) - startY = CSSValuePool::singleton().createIdentifierValue(CSSValueTop); + startY = cssValuePool().createIdentifierValue(CSSValueTop); result->setFirstX(startX.release()); result->setFirstY(startY.release()); } - if (!parseGradientColorStops(*args, *result, expectComma)) + if (!parseGradientColorStops(args, result.get(), expectComma)) return false; if (!result->stopCount()) @@ -8954,59 +8087,62 @@ bool CSSParser::parseDeprecatedLinearGradient(CSSParserValueList& valueList, Ref return true; } -bool CSSParser::parseDeprecatedRadialGradient(CSSParserValueList& valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating) +bool CSSParser::parseDeprecatedRadialGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating) { RefPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating, CSSPrefixedRadialGradient); // Walk the arguments. - CSSParserValueList* args = valueList.current()->function->args.get(); + CSSParserValueList* args = valueList->current()->function->args.get(); if (!args || !args->size()) return false; - CSSParserValue* argument = args->current(); - if (!argument) + CSSParserValue* a = args->current(); + if (!a) return false; bool expectComma = false; // Optional background-position - RefPtr<CSSPrimitiveValue> centerX; - RefPtr<CSSPrimitiveValue> centerY; + RefPtr<CSSValue> centerX; + RefPtr<CSSValue> centerY; // parse2ValuesFillPosition advances the args next pointer. - parse2ValuesFillPosition(*args, centerX, centerY); - argument = args->current(); - if (!argument) + parse2ValuesFillPosition(args, centerX, centerY); + a = args->current(); + if (!a) return false; if (centerX || centerY) { // Comma - if (!isComma(argument)) + if (!isComma(a)) return false; - argument = args->next(); - if (!argument) + a = args->next(); + if (!a) return false; } - result->setFirstX(centerX); - result->setSecondX(centerX); + ASSERT(!centerX || centerX->isPrimitiveValue()); + ASSERT(!centerY || centerY->isPrimitiveValue()); + + result->setFirstX(toCSSPrimitiveValue(centerX.get())); + result->setSecondX(toCSSPrimitiveValue(centerX.get())); // CSS3 radial gradients always share the same start and end point. - result->setFirstY(centerY); - result->setSecondY(centerY); + result->setFirstY(toCSSPrimitiveValue(centerY.get())); + result->setSecondY(toCSSPrimitiveValue(centerY.get())); RefPtr<CSSPrimitiveValue> shapeValue; RefPtr<CSSPrimitiveValue> sizeValue; // Optional shape and/or size in any order. for (int i = 0; i < 2; ++i) { - if (argument->unit != CSSPrimitiveValue::CSS_IDENT) + if (a->unit != CSSPrimitiveValue::CSS_IDENT) break; bool foundValue = false; - switch (argument->id) { + switch (a->id) { case CSSValueCircle: case CSSValueEllipse: - shapeValue = CSSValuePool::singleton().createIdentifierValue(argument->id); + shapeValue = cssValuePool().createIdentifierValue(a->id); foundValue = true; break; case CSSValueClosestSide: @@ -9015,7 +8151,7 @@ bool CSSParser::parseDeprecatedRadialGradient(CSSParserValueList& valueList, Ref case CSSValueFarthestCorner: case CSSValueContain: case CSSValueCover: - sizeValue = CSSValuePool::singleton().createIdentifierValue(argument->id); + sizeValue = cssValuePool().createIdentifierValue(a->id); foundValue = true; break; default: @@ -9023,8 +8159,8 @@ bool CSSParser::parseDeprecatedRadialGradient(CSSParserValueList& valueList, Ref } if (foundValue) { - argument = args->next(); - if (!argument) + a = args->next(); + if (!a) return false; expectComma = true; @@ -9039,22 +8175,20 @@ bool CSSParser::parseDeprecatedRadialGradient(CSSParserValueList& valueList, Ref RefPtr<CSSPrimitiveValue> verticalSize; if (!shapeValue && !sizeValue) { - ValueWithCalculation hSizeWithCalculation(*argument); - if (validateUnit(hSizeWithCalculation, FLength | FPercent)) { - horizontalSize = createPrimitiveNumericValue(hSizeWithCalculation); - argument = args->next(); - if (!argument) + if (validUnit(a, FLength | FPercent)) { + horizontalSize = createPrimitiveNumericValue(a); + a = args->next(); + if (!a) return false; expectComma = true; } - ValueWithCalculation vSizeWithCalculation(*argument); - if (validateUnit(vSizeWithCalculation, FLength | FPercent)) { - verticalSize = createPrimitiveNumericValue(vSizeWithCalculation); + if (validUnit(a, FLength | FPercent)) { + verticalSize = createPrimitiveNumericValue(a); - argument = args->next(); - if (!argument) + a = args->next(); + if (!a) return false; expectComma = true; } @@ -9067,44 +8201,43 @@ bool CSSParser::parseDeprecatedRadialGradient(CSSParserValueList& valueList, Ref result->setEndHorizontalSize(horizontalSize); result->setEndVerticalSize(verticalSize); - if (!parseGradientColorStops(*args, *result, expectComma)) + if (!parseGradientColorStops(args, result.get(), expectComma)) return false; gradient = result.release(); return true; } -bool CSSParser::parseLinearGradient(CSSParserValueList& valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating) +bool CSSParser::parseLinearGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating) { RefPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating, CSSLinearGradient); - CSSParserValueList* args = valueList.current()->function->args.get(); + CSSParserValueList* args = valueList->current()->function->args.get(); if (!args || !args->size()) return false; - if (!args->current()) + CSSParserValue* a = args->current(); + if (!a) return false; - ValueWithCalculation firstArgumentWithCalculation(*args->current()); - bool expectComma = false; // Look for angle. - if (validateUnit(firstArgumentWithCalculation, FAngle, CSSStrictMode)) { - result->setAngle(createPrimitiveNumericValue(firstArgumentWithCalculation)); + if (validUnit(a, FAngle, CSSStrictMode)) { + result->setAngle(createPrimitiveNumericValue(a)); args->next(); expectComma = true; - } else if (firstArgumentWithCalculation.value().unit == CSSPrimitiveValue::CSS_IDENT && equalLettersIgnoringASCIICase(firstArgumentWithCalculation, "to")) { + } else if (a->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(a, "to")) { // to [ [left | right] || [top | bottom] ] - CSSParserValue* nextArgument = args->next(); - if (!nextArgument) + a = args->next(); + if (!a) return false; RefPtr<CSSPrimitiveValue> endX, endY; RefPtr<CSSPrimitiveValue> location; bool isHorizontal = false; - location = valueFromSideKeyword(*nextArgument, isHorizontal); + location = valueFromSideKeyword(a, isHorizontal); if (!location) return false; @@ -9113,11 +8246,11 @@ bool CSSParser::parseLinearGradient(CSSParserValueList& valueList, RefPtr<CSSVal else endY = location; - nextArgument = args->next(); - if (!nextArgument) + a = args->next(); + if (!a) return false; - location = valueFromSideKeyword(*nextArgument, isHorizontal); + location = valueFromSideKeyword(a, isHorizontal); if (location) { if (isHorizontal) { if (endX) @@ -9137,7 +8270,7 @@ bool CSSParser::parseLinearGradient(CSSParserValueList& valueList, RefPtr<CSSVal result->setFirstY(endY.release()); } - if (!parseGradientColorStops(*args, *result, expectComma)) + if (!parseGradientColorStops(args, result.get(), expectComma)) return false; if (!result->stopCount()) @@ -9147,16 +8280,16 @@ bool CSSParser::parseLinearGradient(CSSParserValueList& valueList, RefPtr<CSSVal return true; } -bool CSSParser::parseRadialGradient(CSSParserValueList& valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating) +bool CSSParser::parseRadialGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating) { RefPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating, CSSRadialGradient); - CSSParserValueList* args = valueList.current()->function->args.get(); + CSSParserValueList* args = valueList->current()->function->args.get(); if (!args || !args->size()) return false; - CSSParserValue* argument = args->current(); - if (!argument) + CSSParserValue* a = args->current(); + if (!a) return false; bool expectComma = false; @@ -9171,15 +8304,14 @@ bool CSSParser::parseRadialGradient(CSSParserValueList& valueList, RefPtr<CSSVal // [ ellipse || [ <length> | <percentage> ]{2} ] | // [ [ circle | ellipse] || <size-keyword> ] for (int i = 0; i < 3; ++i) { - ValueWithCalculation argumentWithCalculation(*argument); - if (argument->unit == CSSPrimitiveValue::CSS_IDENT) { + if (a->unit == CSSPrimitiveValue::CSS_IDENT) { bool badIdent = false; - switch (argument->id) { + switch (a->id) { case CSSValueCircle: case CSSValueEllipse: if (shapeValue) return false; - shapeValue = CSSValuePool::singleton().createIdentifierValue(argument->id); + shapeValue = cssValuePool().createIdentifierValue(a->id); break; case CSSValueClosestSide: case CSSValueClosestCorner: @@ -9187,7 +8319,7 @@ bool CSSParser::parseRadialGradient(CSSParserValueList& valueList, RefPtr<CSSVal case CSSValueFarthestCorner: if (sizeValue || horizontalSize) return false; - sizeValue = CSSValuePool::singleton().createIdentifierValue(argument->id); + sizeValue = cssValuePool().createIdentifierValue(a->id); break; default: badIdent = true; @@ -9196,25 +8328,24 @@ bool CSSParser::parseRadialGradient(CSSParserValueList& valueList, RefPtr<CSSVal if (badIdent) break; - argument = args->next(); - if (!argument) + a = args->next(); + if (!a) return false; - } else if (validateUnit(argumentWithCalculation, FLength | FPercent)) { + } else if (validUnit(a, FLength | FPercent)) { if (sizeValue || horizontalSize) return false; - horizontalSize = createPrimitiveNumericValue(argumentWithCalculation); + horizontalSize = createPrimitiveNumericValue(a); - argument = args->next(); - if (!argument) + a = args->next(); + if (!a) return false; - ValueWithCalculation vSizeWithCalculation(*argument); - if (validateUnit(vSizeWithCalculation, FLength | FPercent)) { - verticalSize = createPrimitiveNumericValue(vSizeWithCalculation); + if (validUnit(a, FLength | FPercent)) { + verticalSize = createPrimitiveNumericValue(a); ++i; - argument = args->next(); - if (!argument) + a = args->next(); + if (!a) return false; } } else @@ -9241,165 +8372,152 @@ bool CSSParser::parseRadialGradient(CSSParserValueList& valueList, RefPtr<CSSVal // Second part of grammar, the center-position clause: // at <position> - RefPtr<CSSPrimitiveValue> centerX; - RefPtr<CSSPrimitiveValue> centerY; - if (argument->unit == CSSPrimitiveValue::CSS_IDENT && equalLettersIgnoringASCIICase(*argument, "at")) { - argument = args->next(); - if (!argument) + RefPtr<CSSValue> centerX; + RefPtr<CSSValue> centerY; + if (a->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(a, "at")) { + a = args->next(); + if (!a) return false; - parseFillPosition(*args, centerX, centerY); + parseFillPosition(args, centerX, centerY); if (!(centerX && centerY)) return false; - argument = args->current(); - if (!argument) + a = args->current(); + if (!a) return false; - result->setFirstX(centerX); - result->setFirstY(centerY); + ASSERT(centerX->isPrimitiveValue()); + ASSERT(centerY->isPrimitiveValue()); + result->setFirstX(toCSSPrimitiveValue(centerX.get())); + result->setFirstY(toCSSPrimitiveValue(centerY.get())); // Right now, CSS radial gradients have the same start and end centers. - result->setSecondX(centerX); - result->setSecondY(centerY); + result->setSecondX(toCSSPrimitiveValue(centerX.get())); + result->setSecondY(toCSSPrimitiveValue(centerY.get())); } if (shapeValue || sizeValue || horizontalSize || centerX || centerY) expectComma = true; - if (!parseGradientColorStops(*args, *result, expectComma)) + if (!parseGradientColorStops(args, result.get(), expectComma)) return false; gradient = result.release(); return true; } -bool CSSParser::parseGradientColorStops(CSSParserValueList& valueList, CSSGradientValue& gradient, bool expectComma) +bool CSSParser::parseGradientColorStops(CSSParserValueList* valueList, CSSGradientValue* gradient, bool expectComma) { - CSSParserValue* value = valueList.current(); - bool previousStopWasMidpoint = true; + CSSParserValue* a = valueList->current(); // Now look for color stops. - while (value) { + while (a) { // Look for the comma before the next stop. if (expectComma) { - if (!isComma(value)) + if (!isComma(a)) return false; - value = valueList.next(); - if (!value) + a = valueList->next(); + if (!a) return false; } // <color-stop> = <color> [ <percentage> | <length> ]? CSSGradientColorStop stop; - stop.m_color = parseGradientColorOrKeyword(*this, *value); - if (!stop.m_color) { - if (previousStopWasMidpoint) // 2 midpoints in a row is not allowed. This also catches starting with a midpoint. - return false; - - stop.isMidpoint = true; - } else - value = valueList.next(); - - previousStopWasMidpoint = stop.isMidpoint; + stop.m_color = parseGradientColorOrKeyword(this, a); + if (!stop.m_color) + return false; - if (value) { - ValueWithCalculation valueWithCalculation(*value); - if (validateUnit(valueWithCalculation, FLength | FPercent)) { - stop.m_position = createPrimitiveNumericValue(valueWithCalculation); - value = valueList.next(); - } else if (stop.isMidpoint) - return false; + a = valueList->next(); + if (a) { + if (validUnit(a, FLength | FPercent)) { + stop.m_position = createPrimitiveNumericValue(a); + a = valueList->next(); + } } - gradient.addStop(stop); + gradient->addStop(stop); expectComma = true; } - // We can't end on a midpoint. - if (previousStopWasMidpoint) - return false; - // Must have 2 or more stops to be valid. - return gradient.stopCount() >= 2; + return gradient->stopCount() >= 2; } -bool CSSParser::isGeneratedImageValue(CSSParserValue& value) const +bool CSSParser::isGeneratedImageValue(CSSParserValue* val) const { - if (value.unit != CSSParserValue::Function) + if (val->unit != CSSParserValue::Function) return false; - return equalLettersIgnoringASCIICase(value.function->name, "-webkit-gradient(") - || equalLettersIgnoringASCIICase(value.function->name, "-webkit-linear-gradient(") - || equalLettersIgnoringASCIICase(value.function->name, "linear-gradient(") - || equalLettersIgnoringASCIICase(value.function->name, "-webkit-repeating-linear-gradient(") - || equalLettersIgnoringASCIICase(value.function->name, "repeating-linear-gradient(") - || equalLettersIgnoringASCIICase(value.function->name, "-webkit-radial-gradient(") - || equalLettersIgnoringASCIICase(value.function->name, "radial-gradient(") - || equalLettersIgnoringASCIICase(value.function->name, "-webkit-repeating-radial-gradient(") - || equalLettersIgnoringASCIICase(value.function->name, "repeating-radial-gradient(") - || equalLettersIgnoringASCIICase(value.function->name, "-webkit-canvas(") - || equalLettersIgnoringASCIICase(value.function->name, "-webkit-cross-fade(") - || equalLettersIgnoringASCIICase(value.function->name, "filter(") - || equalLettersIgnoringASCIICase(value.function->name, "-webkit-filter(") - || equalLettersIgnoringASCIICase(value.function->name, "-webkit-named-image("); + return equalIgnoringCase(val->function->name, "-webkit-gradient(") + || equalIgnoringCase(val->function->name, "-webkit-linear-gradient(") + || equalIgnoringCase(val->function->name, "linear-gradient(") + || equalIgnoringCase(val->function->name, "-webkit-repeating-linear-gradient(") + || equalIgnoringCase(val->function->name, "repeating-linear-gradient(") + || equalIgnoringCase(val->function->name, "-webkit-radial-gradient(") + || equalIgnoringCase(val->function->name, "radial-gradient(") + || equalIgnoringCase(val->function->name, "-webkit-repeating-radial-gradient(") + || equalIgnoringCase(val->function->name, "repeating-radial-gradient(") + || equalIgnoringCase(val->function->name, "-webkit-canvas(") + || equalIgnoringCase(val->function->name, "-webkit-cross-fade(") + || equalIgnoringCase(val->function->name, "-webkit-filter("); } -bool CSSParser::parseGeneratedImage(CSSParserValueList& valueList, RefPtr<CSSValue>& value) +bool CSSParser::parseGeneratedImage(CSSParserValueList* valueList, RefPtr<CSSValue>& value) { - CSSParserValue& parserValue = *valueList.current(); + CSSParserValue* val = valueList->current(); - if (parserValue.unit != CSSParserValue::Function) + if (val->unit != CSSParserValue::Function) return false; - if (equalLettersIgnoringASCIICase(parserValue.function->name, "-webkit-gradient(")) + if (equalIgnoringCase(val->function->name, "-webkit-gradient(")) return parseDeprecatedGradient(valueList, value); - if (equalLettersIgnoringASCIICase(parserValue.function->name, "-webkit-linear-gradient(")) + if (equalIgnoringCase(val->function->name, "-webkit-linear-gradient(")) return parseDeprecatedLinearGradient(valueList, value, NonRepeating); - if (equalLettersIgnoringASCIICase(parserValue.function->name, "linear-gradient(")) + if (equalIgnoringCase(val->function->name, "linear-gradient(")) return parseLinearGradient(valueList, value, NonRepeating); - if (equalLettersIgnoringASCIICase(parserValue.function->name, "-webkit-repeating-linear-gradient(")) + if (equalIgnoringCase(val->function->name, "-webkit-repeating-linear-gradient(")) return parseDeprecatedLinearGradient(valueList, value, Repeating); - if (equalLettersIgnoringASCIICase(parserValue.function->name, "repeating-linear-gradient(")) + if (equalIgnoringCase(val->function->name, "repeating-linear-gradient(")) return parseLinearGradient(valueList, value, Repeating); - if (equalLettersIgnoringASCIICase(parserValue.function->name, "-webkit-radial-gradient(")) + if (equalIgnoringCase(val->function->name, "-webkit-radial-gradient(")) return parseDeprecatedRadialGradient(valueList, value, NonRepeating); - if (equalLettersIgnoringASCIICase(parserValue.function->name, "radial-gradient(")) + if (equalIgnoringCase(val->function->name, "radial-gradient(")) return parseRadialGradient(valueList, value, NonRepeating); - if (equalLettersIgnoringASCIICase(parserValue.function->name, "-webkit-repeating-radial-gradient(")) + if (equalIgnoringCase(val->function->name, "-webkit-repeating-radial-gradient(")) return parseDeprecatedRadialGradient(valueList, value, Repeating); - if (equalLettersIgnoringASCIICase(parserValue.function->name, "repeating-radial-gradient(")) + if (equalIgnoringCase(val->function->name, "repeating-radial-gradient(")) return parseRadialGradient(valueList, value, Repeating); - if (equalLettersIgnoringASCIICase(parserValue.function->name, "-webkit-canvas(")) + if (equalIgnoringCase(val->function->name, "-webkit-canvas(")) return parseCanvas(valueList, value); - if (equalLettersIgnoringASCIICase(parserValue.function->name, "-webkit-cross-fade(")) + if (equalIgnoringCase(val->function->name, "-webkit-cross-fade(")) return parseCrossfade(valueList, value); - if (equalLettersIgnoringASCIICase(parserValue.function->name, "filter(") || equalLettersIgnoringASCIICase(parserValue.function->name, "-webkit-filter(")) +#if ENABLE(CSS_FILTERS) + if (equalIgnoringCase(val->function->name, "-webkit-filter(")) return parseFilterImage(valueList, value); - - if (equalLettersIgnoringASCIICase(parserValue.function->name, "-webkit-named-image(")) - return parseNamedImage(valueList, value); +#endif return false; } -bool CSSParser::parseFilterImage(CSSParserValueList& valueList, RefPtr<CSSValue>& filter) +#if ENABLE(CSS_FILTERS) +bool CSSParser::parseFilterImage(CSSParserValueList* valueList, RefPtr<CSSValue>& filter) { RefPtr<CSSFilterImageValue> result; // Walk the arguments. - CSSParserValueList* args = valueList.current()->function->args.get(); + CSSParserValueList* args = valueList->current()->function->args.get(); if (!args) return false; CSSParserValue* value = args->current(); @@ -9410,7 +8528,7 @@ bool CSSParser::parseFilterImage(CSSParserValueList& valueList, RefPtr<CSSValue> return false; // The first argument is the image. It is a fill image. - if (!parseFillImage(*args, imageValue)) { + if (!parseFillImage(args, imageValue)) { if (value->unit == CSSPrimitiveValue::CSS_STRING) imageValue = CSSImageValue::create(completeURL(value->string)); else @@ -9424,7 +8542,7 @@ bool CSSParser::parseFilterImage(CSSParserValueList& valueList, RefPtr<CSSValue> return false; value = args->next(); - if (!value || !parseFilter(*args, filterValue)) + if (!value || !parseFilter(args, filterValue)) return false; value = args->next(); @@ -9434,48 +8552,49 @@ bool CSSParser::parseFilterImage(CSSParserValueList& valueList, RefPtr<CSSValue> return true; } +#endif -bool CSSParser::parseCrossfade(CSSParserValueList& valueList, RefPtr<CSSValue>& crossfade) +bool CSSParser::parseCrossfade(CSSParserValueList* valueList, RefPtr<CSSValue>& crossfade) { RefPtr<CSSCrossfadeValue> result; // Walk the arguments. - CSSParserValueList* args = valueList.current()->function->args.get(); + CSSParserValueList* args = valueList->current()->function->args.get(); if (!args || args->size() != 5) return false; - CSSParserValue* argument = args->current(); + CSSParserValue* a = args->current(); RefPtr<CSSValue> fromImageValue; RefPtr<CSSValue> toImageValue; // The first argument is the "from" image. It is a fill image. - if (!argument || !parseFillImage(*args, fromImageValue)) + if (!a || !parseFillImage(args, fromImageValue)) return false; - argument = args->next(); + a = args->next(); // Skip a comma - if (!isComma(argument)) + if (!isComma(a)) return false; - argument = args->next(); + a = args->next(); // The second argument is the "to" image. It is a fill image. - if (!argument || !parseFillImage(*args, toImageValue)) + if (!a || !parseFillImage(args, toImageValue)) return false; - argument = args->next(); + a = args->next(); // Skip a comma - if (!isComma(argument)) + if (!isComma(a)) return false; - argument = args->next(); + a = args->next(); // The third argument is the crossfade value. It is a percentage or a fractional number. RefPtr<CSSPrimitiveValue> percentage; - if (!argument) + if (!a) return false; - if (argument->unit == CSSPrimitiveValue::CSS_PERCENTAGE) - percentage = CSSValuePool::singleton().createValue(clampTo<double>(argument->fValue / 100, 0, 1), CSSPrimitiveValue::CSS_NUMBER); - else if (argument->unit == CSSPrimitiveValue::CSS_NUMBER) - percentage = CSSValuePool::singleton().createValue(clampTo<double>(argument->fValue, 0, 1), CSSPrimitiveValue::CSS_NUMBER); + if (a->unit == CSSPrimitiveValue::CSS_PERCENTAGE) + percentage = cssValuePool().createValue(clampTo<double>(a->fValue / 100, 0, 1), CSSPrimitiveValue::CSS_NUMBER); + else if (a->unit == CSSPrimitiveValue::CSS_NUMBER) + percentage = cssValuePool().createValue(clampTo<double>(a->fValue, 0, 1), CSSPrimitiveValue::CSS_NUMBER); else return false; @@ -9487,10 +8606,10 @@ bool CSSParser::parseCrossfade(CSSParserValueList& valueList, RefPtr<CSSValue>& return true; } -bool CSSParser::parseCanvas(CSSParserValueList& valueList, RefPtr<CSSValue>& canvas) +bool CSSParser::parseCanvas(CSSParserValueList* valueList, RefPtr<CSSValue>& canvas) { // Walk the arguments. - CSSParserValueList* args = valueList.current()->function->args.get(); + CSSParserValueList* args = valueList->current()->function->args.get(); if (!args || args->size() != 1) return false; @@ -9503,23 +8622,8 @@ bool CSSParser::parseCanvas(CSSParserValueList& valueList, RefPtr<CSSValue>& can return true; } -bool CSSParser::parseNamedImage(CSSParserValueList& valueList, RefPtr<CSSValue>& namedImage) -{ - CSSParserValueList* args = valueList.current()->function->args.get(); - if (!args || args->size() != 1) - return false; - - // The only argument is the image name. - CSSParserValue* value = args->current(); - if (!value || value->unit != CSSPrimitiveValue::CSS_IDENT) - return false; - - namedImage = CSSNamedImageValue::create(value->string); - return true; -} - #if ENABLE(CSS_IMAGE_RESOLUTION) -RefPtr<CSSValue> CSSParser::parseImageResolution() +PassRefPtr<CSSValue> CSSParser::parseImageResolution() { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); bool haveResolution = false; @@ -9528,54 +8632,53 @@ RefPtr<CSSValue> CSSParser::parseImageResolution() CSSParserValue* value = m_valueList->current(); while (value) { - ValueWithCalculation valueWithCalculation(*value); if (!haveFromImage && value->id == CSSValueFromImage) { - list->append(CSSValuePool::singleton().createIdentifierValue(value->id)); + list->append(cssValuePool().createIdentifierValue(value->id)); haveFromImage = true; } else if (!haveSnap && value->id == CSSValueSnap) { - list->append(CSSValuePool::singleton().createIdentifierValue(value->id)); + list->append(cssValuePool().createIdentifierValue(value->id)); haveSnap = true; - } else if (!haveResolution && validateUnit(valueWithCalculation, FResolution | FNonNeg) && value->fValue > 0) { - list->append(createPrimitiveNumericValue(valueWithCalculation)); + } else if (!haveResolution && validUnit(value, FResolution | FNonNeg) && value->fValue > 0) { + list->append(createPrimitiveNumericValue(value)); haveResolution = true; } else - return nullptr; + return 0; value = m_valueList->next(); } if (!list->length()) - return nullptr; + return 0; if (!haveFromImage && !haveResolution) - return nullptr; - return list; + return 0; + return list.release(); } #endif #if ENABLE(CSS_IMAGE_SET) -RefPtr<CSSValue> CSSParser::parseImageSet() +PassRefPtr<CSSValue> CSSParser::parseImageSet() { - CSSParserValue& value = *m_valueList->current(); - ASSERT(value.unit == CSSParserValue::Function); + CSSParserValue* value = m_valueList->current(); + ASSERT(value->unit == CSSParserValue::Function); - CSSParserValueList* functionArgs = value.function->args.get(); + CSSParserValueList* functionArgs = value->function->args.get(); if (!functionArgs || !functionArgs->size() || !functionArgs->current()) - return nullptr; + return 0; RefPtr<CSSImageSetValue> imageSet = CSSImageSetValue::create(); CSSParserValue* arg = functionArgs->current(); while (arg) { if (arg->unit != CSSPrimitiveValue::CSS_URI) - return nullptr; + return 0; imageSet->append(CSSImageValue::create(completeURL(arg->string))); arg = functionArgs->next(); if (!arg || arg->unit != CSSPrimitiveValue::CSS_DIMENSION) - return nullptr; + return 0; double imageScaleFactor = 0; const String& string = arg->string; unsigned length = string.length(); if (!length) - return nullptr; + return 0; if (string.is8Bit()) { const LChar* start = string.characters8(); parseDouble(start, start + length, 'x', imageScaleFactor); @@ -9584,8 +8687,8 @@ RefPtr<CSSValue> CSSParser::parseImageSet() parseDouble(start, start + length, 'x', imageScaleFactor); } if (imageScaleFactor <= 0) - return nullptr; - imageSet->append(CSSValuePool::singleton().createValue(imageScaleFactor, CSSPrimitiveValue::CSS_NUMBER)); + return 0; + imageSet->append(cssValuePool().createValue(imageScaleFactor, CSSPrimitiveValue::CSS_NUMBER)); // If there are no more arguments, we're done. arg = functionArgs->next(); @@ -9594,13 +8697,13 @@ RefPtr<CSSValue> CSSParser::parseImageSet() // If there are more arguments, they should be after a comma. if (!isComma(arg)) - return nullptr; + return 0; // Skip the comma and move on to the next argument. arg = functionArgs->next(); } - return imageSet; + return imageSet.release(); } #endif @@ -9863,40 +8966,40 @@ private: CSSParser::Units m_unit; }; -RefPtr<CSSValueList> CSSParser::parseTransform() +PassRefPtr<CSSValueList> CSSParser::parseTransform() { if (!m_valueList) - return nullptr; + return 0; RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) { - RefPtr<CSSValue> parsedTransformValue = parseTransformValue(*value); + RefPtr<CSSValue> parsedTransformValue = parseTransformValue(value); if (!parsedTransformValue) - return nullptr; + return 0; - list->append(parsedTransformValue.releaseNonNull()); + list->append(parsedTransformValue.release()); } - return list; + return list.release(); } -RefPtr<CSSValue> CSSParser::parseTransformValue(CSSParserValue& value) +PassRefPtr<CSSValue> CSSParser::parseTransformValue(CSSParserValue *value) { - if (value.unit != CSSParserValue::Function || !value.function) - return nullptr; + if (value->unit != CSSParserValue::Function || !value->function) + return 0; // Every primitive requires at least one argument. - CSSParserValueList* args = value.function->args.get(); + CSSParserValueList* args = value->function->args.get(); if (!args) - return nullptr; + return 0; // See if the specified primitive is one we understand. - TransformOperationInfo info(value.function->name); + TransformOperationInfo info(value->function->name); if (info.unknown()) - return nullptr; + return 0; if (!info.hasCorrectArgCount(args->size())) - return nullptr; + return 0; // The transform is a list of functional primitives that specify transform operations. // We collect a list of WebKitCSSTransformValues, where each value specifies a single operation. @@ -9905,42 +9008,41 @@ RefPtr<CSSValue> CSSParser::parseTransformValue(CSSParserValue& value) RefPtr<WebKitCSSTransformValue> transformValue = WebKitCSSTransformValue::create(info.type()); // Snag our values. - CSSParserValue* argument = args->current(); + CSSParserValue* a = args->current(); unsigned argNumber = 0; - while (argument) { - ValueWithCalculation argumentWithCalculation(*argument); + while (a) { CSSParser::Units unit = info.unit(); if (info.type() == WebKitCSSTransformValue::Rotate3DTransformOperation && argNumber == 3) { // 4th param of rotate3d() is an angle rather than a bare number, validate it as such - if (!validateUnit(argumentWithCalculation, FAngle, CSSStrictMode)) - return nullptr; + if (!validUnit(a, FAngle, CSSStrictMode)) + return 0; } else if (info.type() == WebKitCSSTransformValue::Translate3DTransformOperation && argNumber == 2) { // 3rd param of translate3d() cannot be a percentage - if (!validateUnit(argumentWithCalculation, FLength, CSSStrictMode)) - return nullptr; + if (!validUnit(a, FLength, CSSStrictMode)) + return 0; } else if (info.type() == WebKitCSSTransformValue::TranslateZTransformOperation && !argNumber) { // 1st param of translateZ() cannot be a percentage - if (!validateUnit(argumentWithCalculation, FLength, CSSStrictMode)) - return nullptr; + if (!validUnit(a, FLength, CSSStrictMode)) + return 0; } else if (info.type() == WebKitCSSTransformValue::PerspectiveTransformOperation && !argNumber) { // 1st param of perspective() must be a non-negative number (deprecated) or length. - if (!validateUnit(argumentWithCalculation, FNumber | FLength | FNonNeg, CSSStrictMode)) - return nullptr; - } else if (!validateUnit(argumentWithCalculation, unit, CSSStrictMode)) - return nullptr; + if (!validUnit(a, FNumber | FLength | FNonNeg, CSSStrictMode)) + return 0; + } else if (!validUnit(a, unit, CSSStrictMode)) + return 0; // Add the value to the current transform operation. - transformValue->append(createPrimitiveNumericValue(argumentWithCalculation)); + transformValue->append(createPrimitiveNumericValue(a)); - argument = args->next(); - if (!argument) + a = args->next(); + if (!a) break; - if (argument->unit != CSSParserValue::Operator || argument->iValue != ',') - return nullptr; - argument = args->next(); + if (a->unit != CSSParserValue::Operator || a->iValue != ',') + return 0; + a = args->next(); - ++argNumber; + argNumber++; } return transformValue.release(); @@ -9959,35 +9061,38 @@ bool CSSParser::isCompositeOperator(CSSValueID valueID) return valueID >= CSSValueClear && valueID <= CSSValueXor; } +#if ENABLE(CSS_FILTERS) + static void filterInfoForName(const CSSParserString& name, WebKitCSSFilterValue::FilterOperationType& filterType, unsigned& maximumArgumentCount) { - if (equalLettersIgnoringASCIICase(name, "grayscale(")) + if (equalIgnoringCase(name, "grayscale(")) filterType = WebKitCSSFilterValue::GrayscaleFilterOperation; - else if (equalLettersIgnoringASCIICase(name, "sepia(")) + else if (equalIgnoringCase(name, "sepia(")) filterType = WebKitCSSFilterValue::SepiaFilterOperation; - else if (equalLettersIgnoringASCIICase(name, "saturate(")) + else if (equalIgnoringCase(name, "saturate(")) filterType = WebKitCSSFilterValue::SaturateFilterOperation; - else if (equalLettersIgnoringASCIICase(name, "hue-rotate(")) + else if (equalIgnoringCase(name, "hue-rotate(")) filterType = WebKitCSSFilterValue::HueRotateFilterOperation; - else if (equalLettersIgnoringASCIICase(name, "invert(")) + else if (equalIgnoringCase(name, "invert(")) filterType = WebKitCSSFilterValue::InvertFilterOperation; - else if (equalLettersIgnoringASCIICase(name, "opacity(")) + else if (equalIgnoringCase(name, "opacity(")) filterType = WebKitCSSFilterValue::OpacityFilterOperation; - else if (equalLettersIgnoringASCIICase(name, "brightness(")) + else if (equalIgnoringCase(name, "brightness(")) filterType = WebKitCSSFilterValue::BrightnessFilterOperation; - else if (equalLettersIgnoringASCIICase(name, "contrast(")) + else if (equalIgnoringCase(name, "contrast(")) filterType = WebKitCSSFilterValue::ContrastFilterOperation; - else if (equalLettersIgnoringASCIICase(name, "blur(")) + else if (equalIgnoringCase(name, "blur(")) filterType = WebKitCSSFilterValue::BlurFilterOperation; - else if (equalLettersIgnoringASCIICase(name, "drop-shadow(")) { + else if (equalIgnoringCase(name, "drop-shadow(")) { filterType = WebKitCSSFilterValue::DropShadowFilterOperation; maximumArgumentCount = 4; // x-offset, y-offset, blur-radius, color -- spread and inset style not allowed. } } -RefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParserValueList& args, WebKitCSSFilterValue::FilterOperationType filterType) +PassRefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParserValueList* args, WebKitCSSFilterValue::FilterOperationType filterType) { RefPtr<WebKitCSSFilterValue> filterValue = WebKitCSSFilterValue::create(filterType); + ASSERT(args); switch (filterType) { case WebKitCSSFilterValue::GrayscaleFilterOperation: @@ -9997,77 +9102,77 @@ RefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParserVal case WebKitCSSFilterValue::OpacityFilterOperation: case WebKitCSSFilterValue::ContrastFilterOperation: { // One optional argument, 0-1 or 0%-100%, if missing use 100%. - if (args.size() > 1) - return nullptr; - - if (args.size()) { - ValueWithCalculation argumentWithCalculation(*args.current()); - if (!validateUnit(argumentWithCalculation, FNumber | FPercent | FNonNeg, CSSStrictMode)) - return nullptr; - - auto primitiveValue = createPrimitiveNumericValue(argumentWithCalculation); + if (args->size() > 1) + return 0; + if (args->size()) { + CSSParserValue* value = args->current(); + if (!validUnit(value, FNumber | FPercent | FNonNeg, CSSStrictMode)) + return 0; + + double amount = value->fValue; + // Saturate and Contrast allow values over 100%. if (filterType != WebKitCSSFilterValue::SaturateFilterOperation && filterType != WebKitCSSFilterValue::ContrastFilterOperation) { - double maxAllowed = primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE ? 100.0 : 1.0; - if (primitiveValue->getDoubleValue() > maxAllowed) - return nullptr; + double maxAllowed = value->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 100.0 : 1.0; + if (amount > maxAllowed) + return 0; } - filterValue->append(WTFMove(primitiveValue)); + filterValue->append(cssValuePool().createValue(amount, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit))); } break; } case WebKitCSSFilterValue::BrightnessFilterOperation: { // One optional argument, if missing use 100%. - if (args.size() > 1) - return nullptr; + if (args->size() > 1) + return 0; - if (args.size()) { - ValueWithCalculation argumentWithCalculation(*args.current()); - if (!validateUnit(argumentWithCalculation, FNumber | FPercent, CSSStrictMode)) - return nullptr; + if (args->size()) { + CSSParserValue* value = args->current(); + if (!validUnit(value, FNumber | FPercent, CSSStrictMode)) + return 0; - filterValue->append(createPrimitiveNumericValue(argumentWithCalculation)); + filterValue->append(cssValuePool().createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit))); } break; } case WebKitCSSFilterValue::HueRotateFilterOperation: { // hue-rotate() takes one optional angle. - if (args.size() > 1) - return nullptr; + if (args->size() > 1) + return 0; - if (args.size()) { - ValueWithCalculation argumentWithCalculation(*args.current()); - if (!validateUnit(argumentWithCalculation, FAngle, CSSStrictMode)) - return nullptr; + if (args->size()) { + CSSParserValue* argument = args->current(); + if (!validUnit(argument, FAngle, CSSStrictMode)) + return 0; - filterValue->append(createPrimitiveNumericValue(argumentWithCalculation)); + filterValue->append(createPrimitiveNumericValue(argument)); } break; } case WebKitCSSFilterValue::BlurFilterOperation: { // Blur takes a single length. Zero parameters are allowed. - if (args.size() > 1) - return nullptr; + if (args->size() > 1) + return 0; - if (args.size()) { - ValueWithCalculation argumentWithCalculation(*args.current()); - if (!validateUnit(argumentWithCalculation, FLength | FNonNeg, CSSStrictMode)) - return nullptr; + if (args->size()) { + CSSParserValue* argument = args->current(); + if (!validUnit(argument, FLength | FNonNeg, CSSStrictMode)) + return 0; - filterValue->append(createPrimitiveNumericValue(argumentWithCalculation)); + filterValue->append(createPrimitiveNumericValue(argument)); } break; } case WebKitCSSFilterValue::DropShadowFilterOperation: { // drop-shadow() takes a single shadow. - RefPtr<CSSValueList> shadowValueList = parseShadow(args, CSSPropertyFilter); + RefPtr<CSSValueList> shadowValueList = parseShadow(args, CSSPropertyWebkitFilter); if (!shadowValueList || shadowValueList->length() != 1) - return nullptr; + return 0; - filterValue->append(*shadowValueList->itemWithoutBoundsCheck(0)); + filterValue->append((shadowValueList.release())->itemWithoutBoundsCheck(0)); break; } default: @@ -10076,11 +9181,14 @@ RefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParserVal return filterValue.release(); } -bool CSSParser::parseFilter(CSSParserValueList& valueList, RefPtr<CSSValue>& result) +bool CSSParser::parseFilter(CSSParserValueList* valueList, RefPtr<CSSValue>& result) { + if (!valueList) + return false; + // The filter is a list of functional primitives that specify individual operations. RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - for (auto* value = valueList.current(); value; value = valueList.next()) { + for (auto value = valueList->current(); value; value = valueList->next()) { if (value->unit != CSSPrimitiveValue::CSS_URI && (value->unit != CSSParserValue::Function || !value->function)) return false; @@ -10088,9 +9196,11 @@ bool CSSParser::parseFilter(CSSParserValueList& valueList, RefPtr<CSSValue>& res // See if the specified primitive is one we understand. if (value->unit == CSSPrimitiveValue::CSS_URI) { +#if ENABLE(SVG) RefPtr<WebKitCSSFilterValue> referenceFilterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ReferenceFilterOperation); referenceFilterValue->append(CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_URI)); - list->append(referenceFilterValue.releaseNonNull()); + list->append(referenceFilterValue.release()); +#endif } else { const CSSParserString name = value->function->name; unsigned maximumArgumentCount = 1; @@ -10104,11 +9214,11 @@ bool CSSParser::parseFilter(CSSParserValueList& valueList, RefPtr<CSSValue>& res if (!args) return false; - RefPtr<WebKitCSSFilterValue> filterValue = parseBuiltinFilterArguments(*args, filterType); + RefPtr<WebKitCSSFilterValue> filterValue = parseBuiltinFilterArguments(args, filterType); if (!filterValue) return false; - list->append(filterValue.releaseNonNull()); + list->append(filterValue.release()); } } @@ -10116,15 +9226,16 @@ bool CSSParser::parseFilter(CSSParserValueList& valueList, RefPtr<CSSValue>& res return true; } +#endif #if ENABLE(CSS_REGIONS) static bool validFlowName(const String& flowName) { - return !(equalLettersIgnoringASCIICase(flowName, "auto") - || equalLettersIgnoringASCIICase(flowName, "default") - || equalLettersIgnoringASCIICase(flowName, "inherit") - || equalLettersIgnoringASCIICase(flowName, "initial") - || equalLettersIgnoringASCIICase(flowName, "none")); + return !(equalIgnoringCase(flowName, "auto") + || equalIgnoringCase(flowName, "default") + || equalIgnoringCase(flowName, "inherit") + || equalIgnoringCase(flowName, "initial") + || equalIgnoringCase(flowName, "none")); } #endif @@ -10138,6 +9249,11 @@ bool CSSParser::cssCompositingEnabled() const return m_context.isCSSCompositingEnabled; } +bool CSSParser::cssGridLayoutEnabled() const +{ + return m_context.isCSSGridLayoutEnabled; +} + #if ENABLE(CSS_REGIONS) // none | <ident> @@ -10157,7 +9273,7 @@ bool CSSParser::parseFlowThread(CSSPropertyID propId, bool important) return false; if (value->id == CSSValueNone) { - addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value->id), important); + addProperty(propId, cssValuePool().createIdentifierValue(value->id), important); return true; } @@ -10165,9 +9281,9 @@ bool CSSParser::parseFlowThread(CSSPropertyID propId, bool important) if (!inputProperty.isEmpty()) { if (!validFlowName(inputProperty)) return false; - addProperty(propId, CSSValuePool::singleton().createValue(inputProperty, CSSPrimitiveValue::CSS_STRING), important); + addProperty(propId, cssValuePool().createValue(inputProperty, CSSPrimitiveValue::CSS_STRING), important); } else - addProperty(propId, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important); + addProperty(propId, cssValuePool().createIdentifierValue(CSSValueNone), important); return true; } @@ -10189,96 +9305,95 @@ bool CSSParser::parseRegionThread(CSSPropertyID propId, bool important) return false; if (value->id == CSSValueNone) - addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value->id), important); + addProperty(propId, cssValuePool().createIdentifierValue(value->id), important); else { String inputProperty = String(value->string); if (!inputProperty.isEmpty()) { if (!validFlowName(inputProperty)) return false; - addProperty(propId, CSSValuePool::singleton().createValue(inputProperty, CSSPrimitiveValue::CSS_STRING), important); + addProperty(propId, cssValuePool().createValue(inputProperty, CSSPrimitiveValue::CSS_STRING), important); } else - addProperty(propId, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important); + addProperty(propId, cssValuePool().createIdentifierValue(CSSValueNone), important); } return true; } #endif -bool CSSParser::parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtr<CSSPrimitiveValue>& value, RefPtr<CSSPrimitiveValue>& value2, RefPtr<CSSValue>& value3) +bool CSSParser::parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2, RefPtr<CSSValue>& value3) { propId1 = propId; propId2 = propId; propId3 = propId; - if (propId == CSSPropertyTransformOrigin) { - propId1 = CSSPropertyTransformOriginX; - propId2 = CSSPropertyTransformOriginY; - propId3 = CSSPropertyTransformOriginZ; + if (propId == CSSPropertyWebkitTransformOrigin) { + propId1 = CSSPropertyWebkitTransformOriginX; + propId2 = CSSPropertyWebkitTransformOriginY; + propId3 = CSSPropertyWebkitTransformOriginZ; } switch (propId) { - case CSSPropertyTransformOrigin: - if (!parseTransformOriginShorthand(value, value2, value3)) + case CSSPropertyWebkitTransformOrigin: + if (!parseTransformOriginShorthand(value, value2, value3)) + return false; + // parseTransformOriginShorthand advances the m_valueList pointer + break; + case CSSPropertyWebkitTransformOriginX: { + value = parseFillPositionX(m_valueList.get()); + if (value) + m_valueList->next(); + break; + } + case CSSPropertyWebkitTransformOriginY: { + value = parseFillPositionY(m_valueList.get()); + if (value) + m_valueList->next(); + break; + } + case CSSPropertyWebkitTransformOriginZ: { + if (validUnit(m_valueList->current(), FLength)) + value = createPrimitiveNumericValue(m_valueList->current()); + if (value) + m_valueList->next(); + break; + } + default: + ASSERT_NOT_REACHED(); return false; - // parseTransformOriginShorthand advances the m_valueList pointer - break; - case CSSPropertyTransformOriginX: { - value = parsePositionX(*m_valueList); - if (value) - m_valueList->next(); - break; - } - case CSSPropertyTransformOriginY: { - value = parsePositionY(*m_valueList); - if (value) - m_valueList->next(); - break; - } - case CSSPropertyTransformOriginZ: { - ValueWithCalculation valueWithCalculation(*m_valueList->current()); - if (validateUnit(valueWithCalculation, FLength)) - value = createPrimitiveNumericValue(valueWithCalculation); - if (value) - m_valueList->next(); - break; - } - default: - ASSERT_NOT_REACHED(); - return false; } return value; } -bool CSSParser::parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtr<CSSPrimitiveValue>& value, RefPtr<CSSPrimitiveValue>& value2) +bool CSSParser::parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2) { propId1 = propId; propId2 = propId; - if (propId == CSSPropertyPerspectiveOrigin) { - propId1 = CSSPropertyPerspectiveOriginX; - propId2 = CSSPropertyPerspectiveOriginY; + if (propId == CSSPropertyWebkitPerspectiveOrigin) { + propId1 = CSSPropertyWebkitPerspectiveOriginX; + propId2 = CSSPropertyWebkitPerspectiveOriginY; } switch (propId) { - case CSSPropertyPerspectiveOrigin: - if (m_valueList->size() > 2) + case CSSPropertyWebkitPerspectiveOrigin: + if (m_valueList->size() > 2) + return false; + parse2ValuesFillPosition(m_valueList.get(), value, value2); + break; + case CSSPropertyWebkitPerspectiveOriginX: { + value = parseFillPositionX(m_valueList.get()); + if (value) + m_valueList->next(); + break; + } + case CSSPropertyWebkitPerspectiveOriginY: { + value = parseFillPositionY(m_valueList.get()); + if (value) + m_valueList->next(); + break; + } + default: + ASSERT_NOT_REACHED(); return false; - parse2ValuesFillPosition(*m_valueList, value, value2); - break; - case CSSPropertyPerspectiveOriginX: { - value = parsePositionX(*m_valueList); - if (value) - m_valueList->next(); - break; - } - case CSSPropertyPerspectiveOriginY: { - value = parsePositionY(*m_valueList); - if (value) - m_valueList->next(); - break; - } - default: - ASSERT_NOT_REACHED(); - return false; } return value; @@ -10300,7 +9415,7 @@ bool CSSParser::parseTextDecoration(CSSPropertyID propId, bool important) { CSSParserValue* value = m_valueList->current(); if (value && value->id == CSSValueNone) { - addTextDecorationProperty(propId, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important); + addTextDecorationProperty(propId, cssValuePool().createIdentifierValue(CSSValueNone), important); m_valueList->next(); return true; } @@ -10316,7 +9431,7 @@ bool CSSParser::parseTextDecoration(CSSPropertyID propId, bool important) #if ENABLE(LETTERPRESS) case CSSValueWebkitLetterpress: #endif - list->append(CSSValuePool::singleton().createIdentifierValue(value->id)); + list->append(cssValuePool().createIdentifierValue(value->id)); break; default: isValid = false; @@ -10343,10 +9458,8 @@ bool CSSParser::parseTextDecorationSkip(bool important) do { switch (value->id) { case CSSValueNone: - case CSSValueAuto: case CSSValueInk: - case CSSValueObjects: - addProperty(CSSPropertyWebkitTextDecorationSkip, CSSValuePool::singleton().createIdentifierValue(value->id), important); + addProperty(CSSPropertyWebkitTextDecorationSkip, cssValuePool().createIdentifierValue(value->id), important); return true; default: break; @@ -10360,15 +9473,15 @@ bool CSSParser::parseTextUnderlinePosition(bool important) // The text-underline-position property has sintax "auto | alphabetic | [ under || [ left | right ] ]". // However, values 'left' and 'right' are not implemented yet, so we will parse sintax // "auto | alphabetic | under" for now. - CSSParserValue& value = *m_valueList->current(); - switch (value.id) { + CSSParserValue* value = m_valueList->current(); + switch (value->id) { case CSSValueAuto: case CSSValueAlphabetic: case CSSValueUnder: if (m_valueList->next()) return false; - addProperty(CSSPropertyWebkitTextUnderlinePosition, CSSValuePool::singleton().createIdentifierValue(value.id), important); + addProperty(CSSPropertyWebkitTextUnderlinePosition, cssValuePool().createIdentifierValue(value->id), important); return true; default: break; @@ -10387,7 +9500,7 @@ bool CSSParser::parseTextEmphasisStyle(bool important) if (value->unit == CSSPrimitiveValue::CSS_STRING) { if (fill || shape || (valueListSize != 1 && !inShorthand())) return false; - addProperty(CSSPropertyWebkitTextEmphasisStyle, createPrimitiveStringValue(*value), important); + addProperty(CSSPropertyWebkitTextEmphasisStyle, createPrimitiveStringValue(value), important); m_valueList->next(); return true; } @@ -10395,7 +9508,7 @@ bool CSSParser::parseTextEmphasisStyle(bool important) if (value->id == CSSValueNone) { if (fill || shape || (valueListSize != 1 && !inShorthand())) return false; - addProperty(CSSPropertyWebkitTextEmphasisStyle, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important); + addProperty(CSSPropertyWebkitTextEmphasisStyle, cssValuePool().createIdentifierValue(CSSValueNone), important); m_valueList->next(); return true; } @@ -10403,11 +9516,11 @@ bool CSSParser::parseTextEmphasisStyle(bool important) if (value->id == CSSValueOpen || value->id == CSSValueFilled) { if (fill) return false; - fill = CSSValuePool::singleton().createIdentifierValue(value->id); + fill = cssValuePool().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 = CSSValuePool::singleton().createIdentifierValue(value->id); + shape = cssValuePool().createIdentifierValue(value->id); } else if (!inShorthand()) return false; else @@ -10416,8 +9529,8 @@ bool CSSParser::parseTextEmphasisStyle(bool important) if (fill && shape) { RefPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated(); - parsedValues->append(fill.releaseNonNull()); - parsedValues->append(shape.releaseNonNull()); + parsedValues->append(fill.release()); + parsedValues->append(shape.release()); addProperty(CSSPropertyWebkitTextEmphasisStyle, parsedValues.release(), important); return true; } @@ -10472,14 +9585,14 @@ bool CSSParser::parseTextEmphasisPosition(bool important) if (!foundOverOrUnder) return false; RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(CSSValuePool::singleton().createIdentifierValue(overUnderValueID)); + list->append(cssValuePool().createIdentifierValue(overUnderValueID)); if (foundLeftOrRight) - list->append(CSSValuePool::singleton().createIdentifierValue(leftRightValueID)); + list->append(cssValuePool().createIdentifierValue(leftRightValueID)); addProperty(CSSPropertyWebkitTextEmphasisPosition, list, important); return true; } -RefPtr<CSSValue> CSSParser::parseTextIndent() +PassRefPtr<CSSValue> CSSParser::parseTextIndent() { // <length> | <percentage> | inherit when CSS3_TEXT is disabled. // [ <length> | <percentage> ] && [ -webkit-hanging || -webkit-each-line ]? | inherit when CSS3_TEXT is enabled. @@ -10492,76 +9605,31 @@ RefPtr<CSSValue> CSSParser::parseTextIndent() CSSParserValue* value = m_valueList->current(); while (value) { - ValueWithCalculation valueWithCalculation(*value); - if (!hasLengthOrPercentage && validateUnit(valueWithCalculation, FLength | FPercent)) { - list->append(createPrimitiveNumericValue(valueWithCalculation)); + if (!hasLengthOrPercentage && validUnit(value, FLength | FPercent)) { + list->append(createPrimitiveNumericValue(value)); hasLengthOrPercentage = true; } #if ENABLE(CSS3_TEXT) else if (!hasEachLine && value->id == CSSValueWebkitEachLine) { - list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueWebkitEachLine)); + list->append(cssValuePool().createIdentifierValue(CSSValueWebkitEachLine)); hasEachLine = true; } else if (!hasHanging && value->id == CSSValueWebkitHanging) { - list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueWebkitHanging)); + list->append(cssValuePool().createIdentifierValue(CSSValueWebkitHanging)); hasHanging = true; } #endif else - return nullptr; + return 0; value = m_valueList->next(); } if (!hasLengthOrPercentage) - return nullptr; + return 0; return list.release(); } -bool CSSParser::parseHangingPunctuation(bool important) -{ - CSSParserValue* value = m_valueList->current(); - if (value && value->id == CSSValueNone) { - addProperty(CSSPropertyHangingPunctuation, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important); - m_valueList->next(); - return true; - } - - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - bool isValid = true; - std::bitset<numCSSValueKeywords> seenValues; - while (isValid && value) { - if (seenValues[value->id] - || (value->id == CSSValueAllowEnd && seenValues[CSSValueForceEnd]) - || (value->id == CSSValueForceEnd && seenValues[CSSValueAllowEnd])) { - isValid = false; - break; - } - switch (value->id) { - case CSSValueAllowEnd: - case CSSValueFirst: - case CSSValueForceEnd: - case CSSValueLast: - list->append(CSSValuePool::singleton().createIdentifierValue(value->id)); - seenValues.set(value->id); - break; - default: - isValid = false; - break; - } - if (isValid) - value = m_valueList->next(); - } - - // Values are either valid or in shorthand scope. - if (list->length() && isValid) { - addProperty(CSSPropertyHangingPunctuation, list.release(), important); - return true; - } - - return false; -} - bool CSSParser::parseLineBoxContain(bool important) { LineBoxContain lineBoxContain = LineBoxContainNone; @@ -10591,10 +9659,6 @@ bool CSSParser::parseLineBoxContain(bool important) if (lineBoxContain & LineBoxContainInlineBox) return false; lineBoxContain |= LineBoxContainInlineBox; - } else if (value->id == CSSValueInitialLetter) { - if (lineBoxContain & LineBoxContainInitialLetter) - return false; - lineBoxContain |= LineBoxContainInitialLetter; } else return false; } @@ -10606,23 +9670,25 @@ bool CSSParser::parseLineBoxContain(bool important) return true; } -bool CSSParser::parseFontFeatureTag(CSSValueList& settings) +bool CSSParser::parseFontFeatureTag(CSSValueList* settings) { + // Feature tag name consists of 4-letter characters. + static const unsigned tagNameLength = 4; + CSSParserValue* value = m_valueList->current(); // Feature tag name comes first if (value->unit != CSSPrimitiveValue::CSS_STRING) return false; - FontFeatureTag tag; - if (value->string.length() != tag.size()) + if (value->string.length() != tagNameLength) return false; - for (unsigned i = 0; i < tag.size(); ++i) { + for (unsigned i = 0; i < tagNameLength; ++i) { // Limits the range of characters to 0x20-0x7E, following the tag name rules defiend in the OpenType specification. UChar character = value->string[i]; if (character < 0x20 || character > 0x7E) return false; - tag[i] = toASCIILower(character); } + String tag = value->string; int tagValue = 1; // Feature tag values could follow: <integer> | on | off value = m_valueList->next(); @@ -10637,22 +9703,22 @@ bool CSSParser::parseFontFeatureTag(CSSValueList& settings) m_valueList->next(); } } - settings.append(CSSFontFeatureValue::create(WTFMove(tag), tagValue)); + settings->append(CSSFontFeatureValue::create(tag, tagValue)); return true; } bool CSSParser::parseFontFeatureSettings(bool important) { if (m_valueList->size() == 1 && m_valueList->current()->id == CSSValueNormal) { - RefPtr<CSSPrimitiveValue> normalValue = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal); + RefPtr<CSSPrimitiveValue> normalValue = cssValuePool().createIdentifierValue(CSSValueNormal); m_valueList->next(); - addProperty(CSSPropertyFontFeatureSettings, normalValue.release(), important); + addProperty(CSSPropertyWebkitFontFeatureSettings, normalValue.release(), important); return true; } RefPtr<CSSValueList> settings = CSSValueList::createCommaSeparated(); for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) { - if (!parseFontFeatureTag(*settings)) + if (!parseFontFeatureTag(settings.get())) return false; // If the list isn't parsed fully, the current value should be comma. @@ -10661,19 +9727,18 @@ bool CSSParser::parseFontFeatureSettings(bool important) return false; } if (settings->length()) { - addProperty(CSSPropertyFontFeatureSettings, settings.release(), important); + addProperty(CSSPropertyWebkitFontFeatureSettings, settings.release(), important); return true; } return false; } -bool CSSParser::parseFontVariantLigatures(bool important, bool unknownIsFailure, bool implicit) +bool CSSParser::parseFontVariantLigatures(bool important) { - auto values = CSSValueList::createSpaceSeparated(); - FontVariantLigatures commonLigatures = FontVariantLigatures::Normal; - FontVariantLigatures discretionaryLigatures = FontVariantLigatures::Normal; - FontVariantLigatures historicalLigatures = FontVariantLigatures::Normal; - FontVariantLigatures contextualAlternates = FontVariantLigatures::Normal; + RefPtr<CSSValueList> ligatureValues = CSSValueList::createSpaceSeparated(); + bool sawCommonLigaturesValue = false; + bool sawDiscretionaryLigaturesValue = false; + bool sawHistoricalLigaturesValue = false; for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) { if (value->unit != CSSPrimitiveValue::CSS_IDENT) @@ -10681,469 +9746,53 @@ bool CSSParser::parseFontVariantLigatures(bool important, bool unknownIsFailure, switch (value->id) { case CSSValueNoCommonLigatures: - commonLigatures = FontVariantLigatures::No; - break; case CSSValueCommonLigatures: - commonLigatures = FontVariantLigatures::Yes; + if (sawCommonLigaturesValue) + return false; + sawCommonLigaturesValue = true; + ligatureValues->append(cssValuePool().createIdentifierValue(value->id)); break; case CSSValueNoDiscretionaryLigatures: - discretionaryLigatures = FontVariantLigatures::No; - break; case CSSValueDiscretionaryLigatures: - discretionaryLigatures = FontVariantLigatures::Yes; - break; - case CSSValueNoHistoricalLigatures: - historicalLigatures = FontVariantLigatures::No; - break; - case CSSValueHistoricalLigatures: - historicalLigatures = FontVariantLigatures::Yes; - break; - case CSSValueContextual: - contextualAlternates = FontVariantLigatures::Yes; - break; - case CSSValueNoContextual: - contextualAlternates = FontVariantLigatures::No; - break; - default: - if (unknownIsFailure) + if (sawDiscretionaryLigaturesValue) return false; - continue; - } - } - - switch (commonLigatures) { - case FontVariantLigatures::Normal: - break; - case FontVariantLigatures::Yes: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueCommonLigatures)); - break; - case FontVariantLigatures::No: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoCommonLigatures)); - break; - } - - switch (discretionaryLigatures) { - case FontVariantLigatures::Normal: - break; - case FontVariantLigatures::Yes: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiscretionaryLigatures)); - break; - case FontVariantLigatures::No: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoDiscretionaryLigatures)); - break; - } - - switch (historicalLigatures) { - case FontVariantLigatures::Normal: - break; - case FontVariantLigatures::Yes: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalLigatures)); - break; - case FontVariantLigatures::No: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoHistoricalLigatures)); - break; - } - - switch (contextualAlternates) { - case FontVariantLigatures::Normal: - break; - case FontVariantLigatures::Yes: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueContextual)); - break; - case FontVariantLigatures::No: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoContextual)); - break; - } - - if (!values->length()) - return !unknownIsFailure; - - addProperty(CSSPropertyFontVariantLigatures, WTFMove(values), important, implicit); - return true; -} - -bool CSSParser::parseFontVariantNumeric(bool important, bool unknownIsFailure, bool implicit) -{ - auto values = CSSValueList::createSpaceSeparated(); - FontVariantNumericFigure figure = FontVariantNumericFigure::Normal; - FontVariantNumericSpacing spacing = FontVariantNumericSpacing::Normal; - FontVariantNumericFraction fraction = FontVariantNumericFraction::Normal; - FontVariantNumericOrdinal ordinal = FontVariantNumericOrdinal::Normal; - FontVariantNumericSlashedZero slashedZero = FontVariantNumericSlashedZero::Normal; - - for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) { - if (value->unit != CSSPrimitiveValue::CSS_IDENT) - return false; - - switch (value->id) { - case CSSValueLiningNums: - figure = FontVariantNumericFigure::LiningNumbers; - break; - case CSSValueOldstyleNums: - figure = FontVariantNumericFigure::OldStyleNumbers; - break; - case CSSValueProportionalNums: - spacing = FontVariantNumericSpacing::ProportionalNumbers; - break; - case CSSValueTabularNums: - spacing = FontVariantNumericSpacing::TabularNumbers; - break; - case CSSValueDiagonalFractions: - fraction = FontVariantNumericFraction::DiagonalFractions; - break; - case CSSValueStackedFractions: - fraction = FontVariantNumericFraction::StackedFractions; - break; - case CSSValueOrdinal: - ordinal = FontVariantNumericOrdinal::Yes; - break; - case CSSValueSlashedZero: - slashedZero = FontVariantNumericSlashedZero::Yes; - break; - default: - if (unknownIsFailure) - return false; - continue; - } - } - - switch (figure) { - case FontVariantNumericFigure::Normal: - break; - case FontVariantNumericFigure::LiningNumbers: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueLiningNums)); - break; - case FontVariantNumericFigure::OldStyleNumbers: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueOldstyleNums)); - break; - } - - switch (spacing) { - case FontVariantNumericSpacing::Normal: - break; - case FontVariantNumericSpacing::ProportionalNumbers: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalNums)); - break; - case FontVariantNumericSpacing::TabularNumbers: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueTabularNums)); - break; - } - - switch (fraction) { - case FontVariantNumericFraction::Normal: - break; - case FontVariantNumericFraction::DiagonalFractions: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiagonalFractions)); - break; - case FontVariantNumericFraction::StackedFractions: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueStackedFractions)); - break; - } - - switch (ordinal) { - case FontVariantNumericOrdinal::Normal: - break; - case FontVariantNumericOrdinal::Yes: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueOrdinal)); - break; - } - - switch (slashedZero) { - case FontVariantNumericSlashedZero::Normal: - break; - case FontVariantNumericSlashedZero::Yes: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSlashedZero)); - break; - } - - if (!values->length()) - return !unknownIsFailure; - - addProperty(CSSPropertyFontVariantNumeric, WTFMove(values), important, implicit); - return true; -} - -bool CSSParser::parseFontVariantEastAsian(bool important, bool unknownIsFailure, bool implicit) -{ - auto values = CSSValueList::createSpaceSeparated(); - FontVariantEastAsianVariant variant = FontVariantEastAsianVariant::Normal; - FontVariantEastAsianWidth width = FontVariantEastAsianWidth::Normal; - FontVariantEastAsianRuby ruby = FontVariantEastAsianRuby::Normal; - - for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) { - if (value->unit != CSSPrimitiveValue::CSS_IDENT) - return false; - - switch (value->id) { - case CSSValueJis78: - variant = FontVariantEastAsianVariant::Jis78; - break; - case CSSValueJis83: - variant = FontVariantEastAsianVariant::Jis83; - break; - case CSSValueJis90: - variant = FontVariantEastAsianVariant::Jis90; - break; - case CSSValueJis04: - variant = FontVariantEastAsianVariant::Jis04; - break; - case CSSValueSimplified: - variant = FontVariantEastAsianVariant::Simplified; - break; - case CSSValueTraditional: - variant = FontVariantEastAsianVariant::Traditional; - break; - case CSSValueFullWidth: - width = FontVariantEastAsianWidth::Full; + sawDiscretionaryLigaturesValue = true; + ligatureValues->append(cssValuePool().createIdentifierValue(value->id)); break; - case CSSValueProportionalWidth: - width = FontVariantEastAsianWidth::Proportional; - break; - case CSSValueRuby: - ruby = FontVariantEastAsianRuby::Yes; - break; - default: - if (unknownIsFailure) - return false; - continue; - } - } - - switch (variant) { - case FontVariantEastAsianVariant::Normal: - break; - case FontVariantEastAsianVariant::Jis78: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis78)); - break; - case FontVariantEastAsianVariant::Jis83: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis83)); - break; - case FontVariantEastAsianVariant::Jis90: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis90)); - break; - case FontVariantEastAsianVariant::Jis04: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis04)); - break; - case FontVariantEastAsianVariant::Simplified: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSimplified)); - break; - case FontVariantEastAsianVariant::Traditional: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueTraditional)); - break; - } - - switch (width) { - case FontVariantEastAsianWidth::Normal: - break; - case FontVariantEastAsianWidth::Full: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueFullWidth)); - break; - case FontVariantEastAsianWidth::Proportional: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalWidth)); - break; - } - - switch (ruby) { - case FontVariantEastAsianRuby::Normal: - break; - case FontVariantEastAsianRuby::Yes: - values->append(CSSValuePool::singleton().createIdentifierValue(CSSValueRuby)); - } - - if (!values->length()) - return !unknownIsFailure; - - addProperty(CSSPropertyFontVariantEastAsian, WTFMove(values), important, implicit); - return true; -} - -bool CSSParser::parseFontVariant(bool important) -{ - ShorthandScope scope(this, CSSPropertyFontVariant); - if (!parseFontVariantLigatures(important, false, false)) - return false; - m_valueList->setCurrentIndex(0); - if (!parseFontVariantNumeric(important, false, false)) - return false; - m_valueList->setCurrentIndex(0); - if (!parseFontVariantEastAsian(important, false, false)) - return false; - m_valueList->setCurrentIndex(0); - - FontVariantPosition position = FontVariantPosition::Normal; - FontVariantCaps caps = FontVariantCaps::Normal; - FontVariantAlternates alternates = FontVariantAlternates::Normal; - - for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) { - if (value->unit != CSSPrimitiveValue::CSS_IDENT) - return false; - - switch (value->id) { - case CSSValueNoCommonLigatures: - case CSSValueCommonLigatures: - case CSSValueNoDiscretionaryLigatures: - case CSSValueDiscretionaryLigatures: case CSSValueNoHistoricalLigatures: case CSSValueHistoricalLigatures: - case CSSValueContextual: - case CSSValueNoContextual: - case CSSValueLiningNums: - case CSSValueOldstyleNums: - case CSSValueProportionalNums: - case CSSValueTabularNums: - case CSSValueDiagonalFractions: - case CSSValueStackedFractions: - case CSSValueOrdinal: - case CSSValueSlashedZero: - case CSSValueJis78: - case CSSValueJis83: - case CSSValueJis90: - case CSSValueJis04: - case CSSValueSimplified: - case CSSValueTraditional: - case CSSValueFullWidth: - case CSSValueProportionalWidth: - case CSSValueRuby: - break; - case CSSValueSub: - position = FontVariantPosition::Subscript; - break; - case CSSValueSuper: - position = FontVariantPosition::Superscript; - break; - case CSSValueSmallCaps: - caps = FontVariantCaps::Small; - break; - case CSSValueAllSmallCaps: - caps = FontVariantCaps::AllSmall; - break; - case CSSValuePetiteCaps: - caps = FontVariantCaps::Petite; - break; - case CSSValueAllPetiteCaps: - caps = FontVariantCaps::AllPetite; - break; - case CSSValueUnicase: - caps = FontVariantCaps::Unicase; - break; - case CSSValueTitlingCaps: - caps = FontVariantCaps::Titling; - break; - case CSSValueHistoricalForms: - alternates = FontVariantAlternates::HistoricalForms; + if (sawHistoricalLigaturesValue) + return false; + sawHistoricalLigaturesValue = true; + ligatureValues->append(cssValuePool().createIdentifierValue(value->id)); break; default: return false; } } - switch (position) { - case FontVariantPosition::Normal: - break; - case FontVariantPosition::Subscript: - addProperty(CSSPropertyFontVariantPosition, CSSValuePool::singleton().createIdentifierValue(CSSValueSub), important, false); - break; - case FontVariantPosition::Superscript: - addProperty(CSSPropertyFontVariantPosition, CSSValuePool::singleton().createIdentifierValue(CSSValueSuper), important, false); - break; - } - - switch (caps) { - case FontVariantCaps::Normal: - break; - case FontVariantCaps::Small: - addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps), important, false); - break; - case FontVariantCaps::AllSmall: - addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueAllSmallCaps), important, false); - break; - case FontVariantCaps::Petite: - addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValuePetiteCaps), important, false); - break; - case FontVariantCaps::AllPetite: - addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueAllPetiteCaps), important, false); - break; - case FontVariantCaps::Unicase: - addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueUnicase), important, false); - break; - case FontVariantCaps::Titling: - addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueTitlingCaps), important, false); - break; - } - - switch (alternates) { - case FontVariantAlternates::Normal: - break; - case FontVariantAlternates::HistoricalForms: - addProperty(CSSPropertyFontVariantAlternates, CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalForms), important, false); - break; - } - - return true; -} - -static inline bool isValidWillChangeAnimatableFeature(const CSSParserValue& value) -{ - if (value.id == CSSValueNone || value.id == CSSValueAuto || value.id == CSSValueAll) + if (!ligatureValues->length()) return false; - if (valueIsCSSKeyword(value)) - return false; - - if (cssPropertyID(value.string) == CSSPropertyWillChange) - return false; - - return true; -} - -bool CSSParser::parseWillChange(bool important) -{ - RefPtr<CSSValueList> willChangePropertyValues = CSSValueList::createCommaSeparated(); - - bool expectComma = false; - for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) { - if (expectComma) { - if (!isComma(value)) - return false; - - expectComma = false; - continue; - } - - if (value->unit != CSSPrimitiveValue::CSS_IDENT) - return false; - - if (!isValidWillChangeAnimatableFeature(*value)) - return false; - - RefPtr<CSSValue> cssValue; - if (value->id == CSSValueScrollPosition || value->id == CSSValueContents) - cssValue = CSSValuePool::singleton().createIdentifierValue(value->id); - else { - CSSPropertyID propertyID = cssPropertyID(value->string); - if (propertyID != CSSPropertyInvalid) - cssValue = CSSValuePool::singleton().createIdentifierValue(propertyID); - else // This might be a property we don't support. - cssValue = createPrimitiveStringValue(*value); - } - - willChangePropertyValues->append(cssValue.releaseNonNull()); - expectComma = true; - } - - addProperty(CSSPropertyWillChange, willChangePropertyValues.release(), important); + addProperty(CSSPropertyWebkitFontVariantLigatures, ligatureValues.release(), important); return true; } -RefPtr<CSSCalcValue> CSSParser::parseCalculation(CSSParserValue& value, CalculationPermittedValueRange range) +bool CSSParser::parseCalculation(CSSParserValue* value, CalculationPermittedValueRange range) { ASSERT(isCalculation(value)); - CSSParserValueList* args = value.function->args.get(); + CSSParserValueList* args = value->function->args.get(); if (!args || !args->size()) - return nullptr; + return false; - return CSSCalcValue::create(value.function->name, *args, range); + ASSERT(!m_parsedCalculation); + m_parsedCalculation = CSSCalcValue::create(value->function->name, args, range); + + if (!m_parsedCalculation) + return false; + + return true; } #define END_TOKEN 0 @@ -11163,7 +9812,7 @@ enum CharacterType { CharacterOther, CharacterNull, CharacterWhiteSpace, - CharacterEndConditionQuery, + CharacterEndMediaQuery, CharacterEndNthChild, CharacterQuote, CharacterExclamationMark, @@ -11242,7 +9891,7 @@ static const CharacterType typesOfASCIICharacters[128] = { /* 56 - 8 */ CharacterNumber, /* 57 - 9 */ CharacterNumber, /* 58 - : */ CharacterOther, -/* 59 - ; */ CharacterEndConditionQuery, +/* 59 - ; */ CharacterEndMediaQuery, /* 60 - < */ CharacterLess, /* 61 - = */ CharacterOther, /* 62 - > */ CharacterOther, @@ -11306,7 +9955,7 @@ static const CharacterType typesOfASCIICharacters[128] = { /* 120 - x */ CharacterIdentifierStart, /* 121 - y */ CharacterIdentifierStart, /* 122 - z */ CharacterIdentifierStart, -/* 123 - { */ CharacterEndConditionQuery, +/* 123 - { */ CharacterEndMediaQuery, /* 124 - | */ CharacterVerticalBar, /* 125 - } */ CharacterOther, /* 126 - ~ */ CharacterTilde, @@ -11341,13 +9990,6 @@ static inline bool isIdentifierStartAfterDash(CharacterType* currentCharacter) } template <typename CharacterType> -static inline bool isCustomPropertyIdentifier(CharacterType* currentCharacter) -{ - return isASCIIAlpha(currentCharacter[0]) || currentCharacter[0] == '_' || currentCharacter[0] >= 128 - || (currentCharacter[0] == '\\' && isCSSEscape(currentCharacter[1])); -} - -template <typename CharacterType> static inline bool isEqualToCSSIdentifier(CharacterType* cssString, const char* constantString) { // Compare an character memory data with a zero terminated string. @@ -11381,7 +10023,7 @@ static CharacterType* checkAndSkipEscape(CharacterType* currentCharacter) ++currentCharacter; if (!isCSSEscape(*currentCharacter)) - return nullptr; + return 0; if (isASCIIHexDigit(*currentCharacter)) { int length = 6; @@ -11452,19 +10094,10 @@ CSSParser::Location CSSParser::currentLocation() { Location location; location.lineNumber = m_tokenStartLineNumber; - location.columnNumber = m_tokenStartColumnNumber; - - ASSERT(location.lineNumber >= 0); - ASSERT(location.columnNumber >= 0); - - if (location.lineNumber == m_sheetStartLineNumber) - location.columnNumber += m_sheetStartColumnNumber; - if (is8BitSource()) location.token.init(tokenStart<LChar>(), currentCharacter<LChar>() - tokenStart<LChar>()); else location.token.init(tokenStart<UChar>(), currentCharacter<UChar>() - tokenStart<UChar>()); - return location; } @@ -11493,7 +10126,7 @@ static inline CharacterType* checkAndSkipString(CharacterType* currentCharacter, } if (UNLIKELY(*currentCharacter <= '\r' && (*currentCharacter == '\n' || (*currentCharacter | 0x1) == '\r'))) { // String parsing is failed for character '\n', '\f' or '\r'. - return nullptr; + return 0; } if (LIKELY(currentCharacter[0] != '\\')) @@ -11505,7 +10138,7 @@ static inline CharacterType* checkAndSkipString(CharacterType* currentCharacter, else { currentCharacter = checkAndSkipEscape(currentCharacter); if (!currentCharacter) - return nullptr; + return 0; } } } @@ -11526,8 +10159,9 @@ unsigned CSSParser::parseEscape(CharacterType*& src) unicode = (unicode << 4) + toASCIIHexValue(*src++); } while (--length && isASCIIHexDigit(*src)); - if (unicode > UCHAR_MAX_VALUE) - unicode = replacementCharacter; + // Characters above 0x10ffff are not handled. + if (unicode > 0x10ffff) + unicode = 0xfffd; // Optional space after the escape sequence. if (isHTMLSpace(*src)) @@ -11586,6 +10220,10 @@ inline bool CSSParser::parseIdentifierInternal(SrcCharacterType*& src, DestChara template <typename CharacterType> inline void CSSParser::parseIdentifier(CharacterType*& result, CSSParserString& resultString, bool& hasEscape) { + // If a valid identifier start is found, we can safely + // parse the identifier until the next invalid character. + ASSERT(isIdentifierStart<CharacterType>()); + CharacterType* start = currentCharacter<CharacterType>(); if (UNLIKELY(!parseIdentifierInternal(currentCharacter<CharacterType>(), result, hasEscape))) { // Found an escape we couldn't handle with 8 bits, copy what has been recognized and continue @@ -11593,14 +10231,13 @@ inline void CSSParser::parseIdentifier(CharacterType*& result, CSSParserString& UChar*& result16 = currentCharacter16(); UChar* start16 = result16; int i = 0; - for (; i < result - start; ++i) + for (; i < result - start; i++) result16[i] = start[i]; result16 += i; parseIdentifierInternal(currentCharacter<CharacterType>(), result16, hasEscape); - result += result16 - start16; resultString.init(start16, result16 - start16); return; @@ -11655,7 +10292,7 @@ inline void CSSParser::parseString(CharacterType*& result, CSSParserString& resu UChar*& result16 = currentCharacter16(); UChar* start16 = result16; int i = 0; - for (; i < result - start; ++i) + for (; i < result - start; i++) result16[i] = start[i]; result16 += i; @@ -11837,22 +10474,12 @@ inline bool CSSParser::detectFunctionTypeToken(int length) m_token = URI; return true; } - if (isASCIIAlphaCaselessEqual(name[0], 'v') && isASCIIAlphaCaselessEqual(name[1], 'a') && isASCIIAlphaCaselessEqual(name[2], 'r')) { - m_token = VARFUNCTION; - return true; - } #if ENABLE(VIDEO_TRACK) if (isASCIIAlphaCaselessEqual(name[0], 'c') && isASCIIAlphaCaselessEqual(name[1], 'u') && isASCIIAlphaCaselessEqual(name[2], 'e')) { m_token = CUEFUNCTION; return true; } #endif -#if ENABLE(CSS_SELECTORS_LEVEL4) - if (isASCIIAlphaCaselessEqual(name[0], 'd') && isASCIIAlphaCaselessEqual(name[1], 'i') && isASCIIAlphaCaselessEqual(name[2], 'r')) { - m_token = DIRFUNCTION; - return true; - } -#endif return false; case 4: @@ -11860,28 +10487,10 @@ inline bool CSSParser::detectFunctionTypeToken(int length) m_token = CALCFUNCTION; return true; } - if (isEqualToCSSIdentifier(name, "lang")) { - m_token = LANGFUNCTION; - return true; - } -#if ENABLE(CSS_SELECTORS_LEVEL4) - if (isEqualToCSSIdentifier(name, "role")) { - m_token = ROLEFUNCTION; - return true; - } -#endif - return false; - - case 7: - if (isEqualToCSSIdentifier(name, "matches")) { - m_token = MATCHESFUNCTION; - return true; - } return false; case 9: if (isEqualToCSSIdentifier(name, "nth-child")) { - m_token = NTHCHILDFUNCTIONS; m_parsingMode = NthChildMode; return true; } @@ -11896,7 +10505,6 @@ inline bool CSSParser::detectFunctionTypeToken(int length) case 14: if (isEqualToCSSIdentifier(name, "nth-last-child")) { - m_token = NTHCHILDFUNCTIONS; m_parsingMode = NthChildMode; return true; } @@ -12072,6 +10680,10 @@ inline void CSSParser::detectDashToken(int length) m_token = MAXFUNCTION; } else if (length == 12 && isEqualToCSSIdentifier(name + 1, "webkit-calc")) m_token = CALCFUNCTION; +#if ENABLE(SHADOW_DOM) + else if (length == 19 && isEqualToCSSIdentifier(name + 1, "webkit-distributed")) + m_token = DISTRIBUTEDFUNCTION; +#endif } template <typename CharacterType> @@ -12125,6 +10737,13 @@ inline void CSSParser::detectAtToken(int length, bool hasEscape) m_token = FONT_FACE_SYM; return; +#if ENABLE(SHADOW_DOM) + case 'h': + if (length == 5 && isEqualToCSSIdentifier(name + 2, "ost")) + m_token = HOST_SYM; + return; +#endif + case 'i': if (length == 7 && isEqualToCSSIdentifier(name + 2, "mport")) { m_parsingMode = MediaQueryMode; @@ -12132,13 +10751,6 @@ inline void CSSParser::detectAtToken(int length, bool hasEscape) } return; - case 'k': - if (length == 10 && isEqualToCSSIdentifier(name + 2, "eyframes")) - m_token = KEYFRAMES_SYM; - else if (length == 14 && !hasEscape && isEqualToCSSIdentifier(name + 2, "eyframe-rule")) - m_token = KEYFRAME_RULE_SYM; - return; - case 'l': if (hasEscape) return; @@ -12188,12 +10800,14 @@ inline void CSSParser::detectAtToken(int length, bool hasEscape) } return; +#if ENABLE(CSS3_CONDITIONAL_RULES) case 's': if (length == 9 && isEqualToCSSIdentifier(name + 2, "upports")) { m_parsingMode = SupportsMode; m_token = SUPPORTS_SYM; } return; +#endif case 't': if (hasEscape) @@ -12269,9 +10883,7 @@ inline void CSSParser::detectAtToken(int length, bool hasEscape) case 18: if (isEqualToCSSIdentifier(name + 2, "webkit-keyframes")) - m_token = KEYFRAMES_SYM; - else if (isEqualToCSSIdentifier(name + 2, "webkit-sizesattr")) - m_token = WEBKIT_SIZESATTR_SYM; + m_token = WEBKIT_KEYFRAMES_SYM; return; case 19: @@ -12283,19 +10895,22 @@ inline void CSSParser::detectAtToken(int length, bool hasEscape) case 22: if (!hasEscape && isEqualToCSSIdentifier(name + 2, "webkit-keyframe-rule")) - m_token = KEYFRAME_RULE_SYM; + m_token = WEBKIT_KEYFRAME_RULE_SYM; return; case 27: +#if ENABLE(CSS3_CONDITIONAL_RULES) if (isEqualToCSSIdentifier(name + 2, "webkit-supports-condition")) { m_parsingMode = SupportsMode; m_token = WEBKIT_SUPPORTS_CONDITION_SYM; } +#endif return; } } } +#if ENABLE(CSS3_CONDITIONAL_RULES) template <typename CharacterType> inline void CSSParser::detectSupportsToken(int length) { @@ -12312,6 +10927,7 @@ inline void CSSParser::detectSupportsToken(int length) m_token = SUPPORTS_NOT; } } +#endif template <typename SrcCharacterType> int CSSParser::realLex(void* yylvalWithoutType) @@ -12333,7 +10949,6 @@ restartAfterComment: result = currentCharacter<SrcCharacterType>(); setTokenStart(result); m_tokenStartLineNumber = m_lineNumber; - m_tokenStartColumnNumber = tokenStartOffset() - m_columnOffsetForLine; m_token = *currentCharacter<SrcCharacterType>(); ++currentCharacter<SrcCharacterType>(); @@ -12354,11 +10969,13 @@ restartAfterComment: m_token = IDENT; if (UNLIKELY(*currentCharacter<SrcCharacterType>() == '(')) { +#if ENABLE(CSS3_CONDITIONAL_RULES) if (m_parsingMode == SupportsMode && !hasEscape) { detectSupportsToken<SrcCharacterType>(result - tokenStart<SrcCharacterType>()); if (m_token != IDENT) break; } +#endif m_token = FUNCTION; bool shouldSkipParenthesis = true; if (!hasEscape) { @@ -12388,8 +11005,10 @@ restartAfterComment: } else if (UNLIKELY(m_parsingMode != NormalMode) && !hasEscape) { if (m_parsingMode == MediaQueryMode) detectMediaQueryToken<SrcCharacterType>(result - tokenStart<SrcCharacterType>()); +#if ENABLE(CSS3_CONDITIONAL_RULES) else if (m_parsingMode == SupportsMode) detectSupportsToken<SrcCharacterType>(result - tokenStart<SrcCharacterType>()); +#endif else if (m_parsingMode == NthChildMode && isASCIIAlphaCaselessEqual(tokenStart<SrcCharacterType>()[0], 'n')) { if (result - tokenStart<SrcCharacterType>() == 1) { // String "n" is IDENT but "n+1" is NTH. @@ -12412,10 +11031,6 @@ restartAfterComment: } } } - if (m_parsingMode == NthChildMode && m_token == IDENT && yylval->string.length() == 2 && equalLettersIgnoringASCIICase(yylval->string, "of")) { - m_parsingMode = NormalMode; - m_token = NTHCHILDSELECTORSEPARATOR; - } break; case CharacterDot: @@ -12446,6 +11061,7 @@ restartAfterComment: break; } +#if ENABLE(SVG) // Use SVG parser for numbers on SVG presentation attributes. if (m_context.mode == SVGAttributeMode) { // We need to take care of units like 'em' or 'ex'. @@ -12465,6 +11081,7 @@ restartAfterComment: if (!parseSVGNumber(tokenStart<SrcCharacterType>(), character - tokenStart<SrcCharacterType>(), yylval->number)) break; } else +#endif yylval->number = charactersToDouble(tokenStart<SrcCharacterType>(), currentCharacter<SrcCharacterType>() - tokenStart<SrcCharacterType>()); // Type of the function. @@ -12532,11 +11149,6 @@ restartAfterComment: } else if (currentCharacter<SrcCharacterType>()[0] == '-' && currentCharacter<SrcCharacterType>()[1] == '>') { currentCharacter<SrcCharacterType>() += 2; m_token = SGML_CD; - } else if (currentCharacter<SrcCharacterType>()[0] == '-') { - --currentCharacter<SrcCharacterType>(); - parseIdentifier(result, resultString, hasEscape); - m_token = CUSTOM_PROPERTY; - yylval->string = resultString; } else if (UNLIKELY(m_parsingMode == NthChildMode)) { // "-[0-9]+n" is always an NthChild. if (parseNthChild<SrcCharacterType>()) { @@ -12561,20 +11173,16 @@ restartAfterComment: // Might start with a '\n'. --currentCharacter<SrcCharacterType>(); do { - if (*currentCharacter<SrcCharacterType>() == '\n') { + if (*currentCharacter<SrcCharacterType>() == '\n') ++m_lineNumber; - m_columnOffsetForLine = currentCharacterOffset() + 1; - } ++currentCharacter<SrcCharacterType>(); } while (*currentCharacter<SrcCharacterType>() <= ' ' && (typesOfASCIICharacters[*currentCharacter<SrcCharacterType>()] == CharacterWhiteSpace)); break; - case CharacterEndConditionQuery: { - bool isParsingCondition = m_parsingMode == MediaQueryMode || m_parsingMode == SupportsMode; - if (isParsingCondition) + case CharacterEndMediaQuery: + if (m_parsingMode == MediaQueryMode) m_parsingMode = NormalMode; break; - } case CharacterEndNthChild: if (m_parsingMode == NthChildMode) @@ -12633,10 +11241,9 @@ restartAfterComment: if (*currentCharacter<SrcCharacterType>() == '*') { ++currentCharacter<SrcCharacterType>(); while (currentCharacter<SrcCharacterType>()[0] != '*' || currentCharacter<SrcCharacterType>()[1] != '/') { - if (*currentCharacter<SrcCharacterType>() == '\n') { + if (*currentCharacter<SrcCharacterType>() == '\n') ++m_lineNumber; - m_columnOffsetForLine = currentCharacterOffset() + 1; - } else if (*currentCharacter<SrcCharacterType>() == '\0') { + if (*currentCharacter<SrcCharacterType>() == '\0') { // Unterminated comments are simply ignored. currentCharacter<SrcCharacterType>() -= 2; break; @@ -12695,10 +11302,6 @@ restartAfterComment: parseIdentifier(result, yylval->string, hasEscape); m_token = IDENT; } - if (m_parsingMode == NthChildMode && m_token == IDENT && yylval->string.length() == 2 && equalLettersIgnoringASCIICase(yylval->string, "of")) { - m_parsingMode = NormalMode; - m_token = NTHCHILDSELECTORSEPARATOR; - } break; case CharacterXor: @@ -12730,18 +11333,18 @@ restartAfterComment: return token(); } -RefPtr<StyleRuleBase> CSSParser::createImportRule(const CSSParserString& url, PassRefPtr<MediaQuerySet> media) +PassRefPtr<StyleRuleBase> CSSParser::createImportRule(const CSSParserString& url, PassRefPtr<MediaQuerySet> media) { if (!media || !m_allowImportRules) { popRuleData(); - return nullptr; + return 0; } RefPtr<StyleRuleImport> rule = StyleRuleImport::create(url, media); processAndAddNewRuleToSourceTreeIfNeeded(); - return rule; + return rule.release(); } -RefPtr<StyleRuleBase> CSSParser::createMediaRule(PassRefPtr<MediaQuerySet> media, RuleList* rules) +PassRefPtr<StyleRuleBase> CSSParser::createMediaRule(PassRefPtr<MediaQuerySet> media, RuleList* rules) { m_allowImportRules = m_allowNamespaceDeclarations = false; RefPtr<StyleRuleMedia> rule; @@ -12753,15 +11356,16 @@ RefPtr<StyleRuleBase> CSSParser::createMediaRule(PassRefPtr<MediaQuerySet> media } else rule = StyleRuleMedia::create(media, rules ? *rules : emptyRules); processAndAddNewRuleToSourceTreeIfNeeded(); - return rule; + return rule.release(); } -RefPtr<StyleRuleBase> CSSParser::createEmptyMediaRule(RuleList* rules) +PassRefPtr<StyleRuleBase> CSSParser::createEmptyMediaRule(RuleList* rules) { return createMediaRule(MediaQuerySet::create(), rules); } -RefPtr<StyleRuleBase> CSSParser::createSupportsRule(bool conditionIsSupported, RuleList* rules) +#if ENABLE(CSS3_CONDITIONAL_RULES) +PassRefPtr<StyleRuleBase> CSSParser::createSupportsRule(bool conditionIsSupported, RuleList* rules) { m_allowImportRules = m_allowNamespaceDeclarations = false; @@ -12785,13 +11389,13 @@ RefPtr<StyleRuleBase> CSSParser::createSupportsRule(bool conditionIsSupported, R processAndAddNewRuleToSourceTreeIfNeeded(); - return rule; + return rule.release(); } void CSSParser::markSupportsRuleHeaderStart() { if (!m_supportsRuleDataStack) - m_supportsRuleDataStack = std::make_unique<RuleSourceDataList>(); + m_supportsRuleDataStack = adoptPtr(new RuleSourceDataList()); RefPtr<CSSRuleSourceData> data = CSSRuleSourceData::create(CSSRuleSourceData::SUPPORTS_RULE); data->ruleHeaderRange.start = tokenStartOffset(); @@ -12808,14 +11412,16 @@ void CSSParser::markSupportsRuleHeaderEnd() m_supportsRuleDataStack->last()->ruleHeaderRange.end = tokenStart<UChar>() - m_dataStart16.get(); } -RefPtr<CSSRuleSourceData> CSSParser::popSupportsRuleData() +PassRefPtr<CSSRuleSourceData> CSSParser::popSupportsRuleData() { ASSERT(m_supportsRuleDataStack && !m_supportsRuleDataStack->isEmpty()); RefPtr<CSSRuleSourceData> data = m_supportsRuleDataStack->last(); m_supportsRuleDataStack->removeLast(); - return data; + return data.release(); } +#endif + void CSSParser::processAndAddNewRuleToSourceTreeIfNeeded() { if (!isExtractingSourceData()) @@ -12840,10 +11446,10 @@ void CSSParser::addNewRuleToSourceTree(PassRefPtr<CSSRuleSourceData> rule) PassRefPtr<CSSRuleSourceData> CSSParser::popRuleData() { if (!m_ruleSourceDataResult) - return nullptr; + return 0; ASSERT(!m_currentRuleDataStack->isEmpty()); - m_currentRuleData = nullptr; + m_currentRuleData.clear(); RefPtr<CSSRuleSourceData> data = m_currentRuleDataStack->last(); m_currentRuleDataStack->removeLast(); return data.release(); @@ -12853,15 +11459,14 @@ void CSSParser::syntaxError(const Location& location, SyntaxErrorType error) { if (!isLoggingErrors()) return; - StringBuilder builder; switch (error) { case PropertyDeclarationError: builder.appendLiteral("Invalid CSS property declaration at: "); break; + default: builder.appendLiteral("Unexpected CSS token: "); - break; } if (location.token.is8Bit()) @@ -12869,7 +11474,7 @@ void CSSParser::syntaxError(const Location& location, SyntaxErrorType error) else builder.append(location.token.characters16(), location.token.length()); - logError(builder.toString(), location.lineNumber, location.columnNumber); + logError(builder.toString(), location.lineNumber); m_ignoreErrorsInDeclaration = true; } @@ -12879,59 +11484,80 @@ bool CSSParser::isLoggingErrors() return m_logErrors && !m_ignoreErrorsInDeclaration; } -void CSSParser::logError(const String& message, int lineNumber, int columnNumber) +void CSSParser::logError(const String& message, int lineNumber) { - PageConsoleClient& console = m_styleSheet->singleOwnerDocument()->page()->console(); - console.addMessage(MessageSource::CSS, MessageLevel::Warning, message, m_styleSheet->baseURL().string(), lineNumber + 1, columnNumber + 1); + // FIXME: <http://webkit.org/b/114313> CSS parser console message errors should include column numbers. + PageConsole& console = m_styleSheet->singleOwnerDocument()->page()->console(); + console.addMessage(CSSMessageSource, WarningMessageLevel, message, m_styleSheet->baseURL().string(), lineNumber + 1, 0); } -RefPtr<StyleRuleKeyframes> CSSParser::createKeyframesRule(const String& name, std::unique_ptr<Vector<RefPtr<StyleKeyframe>>> popKeyframes) +PassRefPtr<StyleRuleKeyframes> CSSParser::createKeyframesRule(const String& name, PassOwnPtr<Vector<RefPtr<StyleKeyframe>>> popKeyframes) { - std::unique_ptr<Vector<RefPtr<StyleKeyframe>>> keyframes = WTFMove(popKeyframes); + OwnPtr<Vector<RefPtr<StyleKeyframe>>> keyframes = popKeyframes; m_allowImportRules = m_allowNamespaceDeclarations = false; RefPtr<StyleRuleKeyframes> rule = StyleRuleKeyframes::create(); for (size_t i = 0; i < keyframes->size(); ++i) rule->parserAppendKeyframe(keyframes->at(i)); rule->setName(name); processAndAddNewRuleToSourceTreeIfNeeded(); - return rule; + return rule.release(); } -RefPtr<StyleRuleBase> CSSParser::createStyleRule(Vector<std::unique_ptr<CSSParserSelector>>* selectors) +PassRefPtr<StyleRuleBase> CSSParser::createStyleRule(Vector<OwnPtr<CSSParserSelector>>* selectors) { RefPtr<StyleRule> rule; if (selectors) { m_allowImportRules = false; m_allowNamespaceDeclarations = false; + if (m_hasFontFaceOnlyValues) + deleteFontFaceOnlyValues(); rule = StyleRule::create(m_lastSelectorLineNumber, createStyleProperties()); rule->parserAdoptSelectorVector(*selectors); processAndAddNewRuleToSourceTreeIfNeeded(); } else popRuleData(); clearProperties(); - return rule; + return rule.release(); } -RefPtr<StyleRuleBase> CSSParser::createFontFaceRule() +PassRefPtr<StyleRuleBase> CSSParser::createFontFaceRule() { m_allowImportRules = m_allowNamespaceDeclarations = false; for (unsigned i = 0; i < m_parsedProperties.size(); ++i) { CSSProperty& property = m_parsedProperties[i]; - if (property.id() == CSSPropertyFontFamily && (!is<CSSValueList>(*property.value()) || downcast<CSSValueList>(*property.value()).length() != 1)) { + if (property.id() == CSSPropertyFontVariant && property.value()->isPrimitiveValue()) + property.wrapValueInCommaSeparatedList(); + else if (property.id() == CSSPropertyFontFamily && (!property.value()->isValueList() || toCSSValueList(property.value())->length() != 1)) { // Unlike font-family property, font-family descriptor in @font-face rule // has to be a value list with exactly one family name. It cannot have a // have 'initial' value and cannot 'inherit' from parent. // See http://dev.w3.org/csswg/css3-fonts/#font-family-desc clearProperties(); popRuleData(); - return nullptr; + return 0; } } RefPtr<StyleRuleFontFace> rule = StyleRuleFontFace::create(createStyleProperties()); clearProperties(); processAndAddNewRuleToSourceTreeIfNeeded(); - return rule; + return rule.release(); +} + +#if ENABLE(SHADOW_DOM) +PassRefPtr<StyleRuleBase> CSSParser::createHostRule(RuleList* rules) +{ + m_allowImportRules = m_allowNamespaceDeclarations = false; + RefPtr<StyleRuleHost> rule; + if (rules) + rule = StyleRuleHost::create(*rules); + else { + RuleList emptyRules; + rule = StyleRuleHost::create(emptyRules); + } + processAndAddNewRuleToSourceTreeIfNeeded(); + return rule.release(); } +#endif void CSSParser::addNamespace(const AtomicString& prefix, const AtomicString& uri) { @@ -12964,7 +11590,9 @@ void CSSParser::rewriteSpecifiersWithElementName(const AtomicString& namespacePr if (!specifiers.isCustomPseudoElement()) { if (tag == anyQName()) return; - if (!specifiers.isPseudoElementCueFunction()) +#if ENABLE(VIDEO_TRACK) + if (specifiers.pseudoType() != CSSSelector::PseudoCue) +#endif specifiers.prependTagSelector(tag, tagIsForNamespaceRule); return; } @@ -12985,63 +11613,67 @@ void CSSParser::rewriteSpecifiersWithElementName(const AtomicString& namespacePr // For shadow-ID pseudo-elements to be correctly matched, the ShadowDescendant combinator has to be used. // We therefore create a new Selector with that combinator here in any case, even if matching any (host) element in any namespace (i.e. '*'). - lastShadowDescendant->setTagHistory(std::make_unique<CSSParserSelector>(tag)); + lastShadowDescendant->setTagHistory(adoptPtr(new CSSParserSelector(tag))); lastShadowDescendant->setRelation(CSSSelector::ShadowDescendant); } -std::unique_ptr<CSSParserSelector> CSSParser::rewriteSpecifiers(std::unique_ptr<CSSParserSelector> specifiers, std::unique_ptr<CSSParserSelector> newSpecifier) +OwnPtr<CSSParserSelector> CSSParser::rewriteSpecifiers(OwnPtr<CSSParserSelector> specifiers, OwnPtr<CSSParserSelector> newSpecifier) { - if (newSpecifier->isCustomPseudoElement() || newSpecifier->isPseudoElementCueFunction()) { +#if ENABLE(VIDEO_TRACK) + if (newSpecifier->isCustomPseudoElement() || newSpecifier->pseudoType() == CSSSelector::PseudoCue) { +#else + if (newSpecifier->isCustomPseudoElement()) { +#endif // Unknown pseudo element always goes at the top of selector chain. - newSpecifier->appendTagHistory(CSSSelector::ShadowDescendant, WTFMove(specifiers)); + newSpecifier->appendTagHistory(CSSSelector::ShadowDescendant, specifiers.release()); return newSpecifier; } if (specifiers->isCustomPseudoElement()) { // Specifiers for unknown pseudo element go right behind it in the chain. - specifiers->insertTagHistory(CSSSelector::SubSelector, WTFMove(newSpecifier), CSSSelector::ShadowDescendant); + specifiers->insertTagHistory(CSSSelector::SubSelector, newSpecifier.release(), CSSSelector::ShadowDescendant); return specifiers; } - specifiers->appendTagHistory(CSSSelector::SubSelector, WTFMove(newSpecifier)); + specifiers->appendTagHistory(CSSSelector::SubSelector, newSpecifier.release()); return specifiers; } -RefPtr<StyleRuleBase> CSSParser::createPageRule(std::unique_ptr<CSSParserSelector> pageSelector) +PassRefPtr<StyleRuleBase> CSSParser::createPageRule(PassOwnPtr<CSSParserSelector> pageSelector) { // FIXME: Margin at-rules are ignored. m_allowImportRules = m_allowNamespaceDeclarations = false; RefPtr<StyleRulePage> rule; if (pageSelector) { rule = StyleRulePage::create(createStyleProperties()); - Vector<std::unique_ptr<CSSParserSelector>> selectorVector; - selectorVector.append(WTFMove(pageSelector)); + Vector<OwnPtr<CSSParserSelector>> selectorVector; + selectorVector.append(pageSelector); rule->parserAdoptSelectorVector(selectorVector); processAndAddNewRuleToSourceTreeIfNeeded(); } else popRuleData(); clearProperties(); - return rule; + return rule.release(); } -std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>> CSSParser::createSelectorVector() +OwnPtr<Vector<OwnPtr<CSSParserSelector>>> CSSParser::createSelectorVector() { if (m_recycledSelectorVector) { m_recycledSelectorVector->shrink(0); - return WTFMove(m_recycledSelectorVector); + return std::move(m_recycledSelectorVector); } - return std::make_unique<Vector<std::unique_ptr<CSSParserSelector>>>(); + return adoptPtr(new Vector<OwnPtr<CSSParserSelector>>); } -void CSSParser::recycleSelectorVector(std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>> vector) +void CSSParser::recycleSelectorVector(OwnPtr<Vector<OwnPtr<CSSParserSelector>>> vector) { if (vector && !m_recycledSelectorVector) - m_recycledSelectorVector = WTFMove(vector); + m_recycledSelectorVector = std::move(vector); } -RefPtr<StyleRuleBase> CSSParser::createRegionRule(Vector<std::unique_ptr<CSSParserSelector>>* regionSelector, RuleList* rules) +PassRefPtr<StyleRuleBase> CSSParser::createRegionRule(Vector<OwnPtr<CSSParserSelector>>* regionSelector, RuleList* rules) { if (!cssRegionsEnabled() || !regionSelector || !rules) { popRuleData(); - return nullptr; + return 0; } m_allowImportRules = m_allowNamespaceDeclarations = false; @@ -13051,7 +11683,7 @@ RefPtr<StyleRuleBase> CSSParser::createRegionRule(Vector<std::unique_ptr<CSSPars if (isExtractingSourceData()) addNewRuleToSourceTree(CSSRuleSourceData::createUnknown()); - return regionRule; + return regionRule.release(); } void CSSParser::createMarginAtRule(CSSSelector::MarginBoxType /* marginBox */) @@ -13075,7 +11707,20 @@ void CSSParser::endDeclarationsForMarginBox() m_numParsedPropertiesBeforeMarginBox = INVALID_NUM_PARSED_PROPERTIES; } -RefPtr<StyleKeyframe> CSSParser::createKeyframe(CSSParserValueList& keys) +void CSSParser::deleteFontFaceOnlyValues() +{ + ASSERT(m_hasFontFaceOnlyValues); + for (unsigned i = 0; i < m_parsedProperties.size();) { + CSSProperty& property = m_parsedProperties[i]; + if (property.id() == CSSPropertyFontVariant && property.value()->isValueList()) { + m_parsedProperties.remove(i); + continue; + } + ++i; + } +} + +PassRefPtr<StyleKeyframe> CSSParser::createKeyframe(CSSParserValueList& keys) { // Create a key string from the passed keys StringBuilder keyString; @@ -13085,7 +11730,7 @@ RefPtr<StyleKeyframe> CSSParser::createKeyframe(CSSParserValueList& keys) // marked as CSSPrimitiveValue::CSS_UNKNOWN during parsing. if (keys.valueAt(i)->unit == CSSPrimitiveValue::CSS_UNKNOWN) { clearProperties(); - return nullptr; + return 0; } ASSERT(keys.valueAt(i)->unit == CSSPrimitiveValue::CSS_NUMBER); @@ -13095,7 +11740,7 @@ RefPtr<StyleKeyframe> CSSParser::createKeyframe(CSSParserValueList& keys) // "If a keyframe selector specifies negative percentage values // or values higher than 100%, then the keyframe will be ignored." clearProperties(); - return nullptr; + return 0; } if (i != 0) keyString.append(','); @@ -13108,7 +11753,7 @@ RefPtr<StyleKeyframe> CSSParser::createKeyframe(CSSParserValueList& keys) clearProperties(); - return keyframe; + return keyframe.release(); } void CSSParser::invalidBlockHit() @@ -13228,7 +11873,7 @@ void CSSParser::markRuleHeaderEnd() void CSSParser::markSelectorStart() { - if (!isExtractingSourceData() || m_nestedSelectorLevel) + if (!isExtractingSourceData()) return; ASSERT(!m_selectorRange.end); @@ -13237,7 +11882,7 @@ void CSSParser::markSelectorStart() void CSSParser::markSelectorEnd() { - if (!isExtractingSourceData() || m_nestedSelectorLevel) + if (!isExtractingSourceData()) return; ASSERT(!m_selectorRange.end); ASSERT(m_currentRuleDataStack->size()); @@ -13252,7 +11897,7 @@ void CSSParser::markRuleBodyStart() { if (!isExtractingSourceData()) return; - m_currentRuleData = nullptr; + m_currentRuleData.clear(); unsigned offset = tokenStartOffset(); if (tokenStartChar() == '{') ++offset; // Skip the rule body opening brace. @@ -13330,12 +11975,11 @@ PassRefPtr<StyleRuleBase> CSSParser::createViewportRule() bool CSSParser::parseViewportProperty(CSSPropertyID propId, bool important) { - if (!m_valueList->current()) + CSSParserValue* value = m_valueList->current(); + if (!value) return false; - ValueWithCalculation valueWithCalculation(*m_valueList->current()); - - CSSValueID id = valueWithCalculation.value().id; + CSSValueID id = value->id; bool validPrimitive = false; switch (propId) { @@ -13346,7 +11990,7 @@ bool CSSParser::parseViewportProperty(CSSPropertyID propId, bool important) if (id == CSSValueAuto || id == CSSValueDeviceWidth || id == CSSValueDeviceHeight) validPrimitive = true; else - validPrimitive = (!id && validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg)); + validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg)); break; case CSSPropertyWidth: // shorthand return parseViewportShorthand(propId, CSSPropertyMinWidth, CSSPropertyMaxWidth, important); @@ -13358,7 +12002,7 @@ bool CSSParser::parseViewportProperty(CSSPropertyID propId, bool important) if (id == CSSValueAuto) validPrimitive = true; else - validPrimitive = (!id && validateUnit(valueWithCalculation, FNumber | FPercent | FNonNeg)); + validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg)); break; case CSSPropertyUserZoom: // zoom | fixed if (id == CSSValueZoom || id == CSSValueFixed) @@ -13373,7 +12017,7 @@ bool CSSParser::parseViewportProperty(CSSPropertyID propId, bool important) RefPtr<CSSValue> parsedValue; if (validPrimitive) { - parsedValue = parseValidPrimitive(id, valueWithCalculation); + parsedValue = parseValidPrimitive(id, value); m_valueList->next(); } @@ -13439,7 +12083,16 @@ static CSSPropertyID cssPropertyID(const CharacterType* propertyName, unsigned l } const Property* hashTableEntry = findProperty(name, length); - return hashTableEntry ? static_cast<CSSPropertyID>(hashTableEntry->id) : CSSPropertyInvalid; + const CSSPropertyID propertyID = hashTableEntry ? static_cast<CSSPropertyID>(hashTableEntry->id) : CSSPropertyInvalid; + + static const int cssPropertyHistogramSize = numCSSProperties; + if (hasPrefix(buffer, length, "-webkit-") && propertyID != CSSPropertyInvalid) { + int histogramValue = propertyID - firstCSSProperty; + ASSERT(0 <= histogramValue && histogramValue < cssPropertyHistogramSize); + HistogramSupport::histogramEnumeration("CSS.PrefixUsage", histogramValue, cssPropertyHistogramSize); + } + + return propertyID; } CSSPropertyID cssPropertyID(const String& string) @@ -13478,17 +12131,6 @@ void cssPropertyNameIOSAliasing(const char* propertyName, const char*& propertyN } #endif -static bool isAppleLegacyCssValueKeyword(const char* valueKeyword, unsigned length) -{ - static const char* applePrefix = "-apple-"; - static const char* appleSystemPrefix = "-apple-system"; - static const char* appleWirelessPlaybackTargetActive = getValueName(CSSValueAppleWirelessPlaybackTargetActive); - - return hasPrefix(valueKeyword, length, applePrefix) - && !hasPrefix(valueKeyword, length, appleSystemPrefix) - && !WTF::equal(reinterpret_cast<const LChar*>(valueKeyword), reinterpret_cast<const LChar*>(appleWirelessPlaybackTargetActive), length); -} - template <typename CharacterType> static CSSValueID cssValueKeywordID(const CharacterType* valueKeyword, unsigned length) { @@ -13506,8 +12148,7 @@ static CSSValueID cssValueKeywordID(const CharacterType* valueKeyword, unsigned // If the prefix is -apple- or -khtml-, change it to -webkit-. // This makes the string one character longer. // On iOS we don't want to change values starting with -apple-system to -webkit-system. - // FIXME: Remove this mangling without breaking the web. - if (isAppleLegacyCssValueKeyword(buffer, length) || hasPrefix(buffer, length, "-khtml-")) { + if ((hasPrefix(buffer, length, "-apple-") && !hasPrefix(buffer, length, "-apple-system")) || hasPrefix(buffer, length, "-khtml-")) { memmove(buffer + 7, buffer + 6, length + 1 - 6); memcpy(buffer, "-webkit", 7); ++length; @@ -13690,10 +12331,8 @@ bool isValidNthToken(const CSSParserString& token) // However, since the {ident} rule precedes the {nth} rule, some of those // tokens are identified as string literal. Furthermore we need to accept // "odd" and "even" which does not match to an+b. - return equalLettersIgnoringASCIICase(token, "odd") - || equalLettersIgnoringASCIICase(token, "even") - || equalLettersIgnoringASCIICase(token, "n") - || equalLettersIgnoringASCIICase(token, "-n"); + return equalIgnoringCase(token, "odd") || equalIgnoringCase(token, "even") + || equalIgnoringCase(token, "n") || equalIgnoringCase(token, "-n"); } } |