Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / parser / BisonCSSParser-in.cpp
index adff837..c5d3995 100644 (file)
@@ -74,8 +74,8 @@
 #include "core/css/StyleSheetContents.h"
 #include "core/css/parser/CSSParserIdioms.h"
 #include "core/dom/Document.h"
+#include "core/frame/FrameConsole.h"
 #include "core/frame/FrameHost.h"
-#include "core/frame/PageConsole.h"
 #include "core/frame/Settings.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/inspector/InspectorInstrumentation.h"
@@ -109,7 +109,7 @@ BisonCSSParser::BisonCSSParser(const CSSParserContext& context)
     : m_context(context)
     , m_important(false)
     , m_id(CSSPropertyInvalid)
-    , m_styleSheet(0)
+    , m_styleSheet(nullptr)
     , m_supportsCondition(false)
     , m_selectorListForParseSelector(0)
     , m_numParsedPropertiesBeforeMarginBox(INVALID_NUM_PARSED_PROPERTIES)
@@ -129,7 +129,6 @@ BisonCSSParser::BisonCSSParser(const CSSParserContext& context)
 #if YYDEBUG > 0
     cssyydebug = 1;
 #endif
-    CSSPropertySourceData::init();
 }
 
 BisonCSSParser::~BisonCSSParser()
@@ -287,7 +286,6 @@ static inline bool isSimpleLengthPropertyID(CSSPropertyID propertyId, bool& acce
         acceptsNegativeNumbers = false;
         return true;
     case CSSPropertyShapeMargin:
-    case CSSPropertyShapePadding:
         acceptsNegativeNumbers = false;
         return RuntimeEnabledFeatures::cssShapesEnabled();
     case CSSPropertyBottom:
@@ -331,7 +329,7 @@ static inline bool parseSimpleLength(const CharacterType* characters, unsigned l
 static bool parseSimpleLengthValue(MutableStylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode)
 {
     ASSERT(!string.isEmpty());
-    bool acceptsNegativeNumbers;
+    bool acceptsNegativeNumbers = false;
 
     // In @viewport, width and height are shorthands, not simple length values.
     if (isCSSViewportParsingEnabledForMode(cssParserMode) || !isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers))
@@ -369,6 +367,11 @@ bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int valueID, const
         return false;
 
     switch (propertyId) {
+    case CSSPropertyBackgroundRepeatX: // repeat | no-repeat | inherit
+    case CSSPropertyBackgroundRepeatY: // repeat | no-repeat | inherit
+        if (valueID == CSSValueRepeat || valueID == CSSValueNoRepeat)
+            return true;
+        break;
     case CSSPropertyBorderCollapse: // collapse | separate | inherit
         if (valueID == CSSValueCollapse || valueID == CSSValueSeparate)
             return true;
@@ -551,6 +554,7 @@ bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int valueID, const
         if ((valueID >= CSSValueCheckbox && valueID <= CSSValueTextarea) || valueID == CSSValueNone)
             return true;
         break;
+    case CSSPropertyBackfaceVisibility:
     case CSSPropertyWebkitBackfaceVisibility:
         if (valueID == CSSValueVisible || valueID == CSSValueHidden)
             return true;
@@ -740,6 +744,8 @@ bool isKeywordPropertyID(CSSPropertyID propertyId)
     switch (propertyId) {
     case CSSPropertyMixBlendMode:
     case CSSPropertyIsolation:
+    case CSSPropertyBackgroundRepeatX:
+    case CSSPropertyBackgroundRepeatY:
     case CSSPropertyBorderBottomStyle:
     case CSSPropertyBorderCollapse:
     case CSSPropertyBorderLeftStyle:
@@ -784,6 +790,7 @@ bool isKeywordPropertyID(CSSPropertyID propertyId)
     case CSSPropertyTouchActionDelay:
     case CSSPropertyVisibility:
     case CSSPropertyWebkitAppearance:
+    case CSSPropertyBackfaceVisibility:
     case CSSPropertyWebkitBackfaceVisibility:
     case CSSPropertyWebkitBorderAfterStyle:
     case CSSPropertyWebkitBorderBeforeStyle:
@@ -900,60 +907,117 @@ static bool parseTransformTranslateArguments(CharType*& pos, CharType* end, unsi
 }
 
 template <typename CharType>
-static PassRefPtrWillBeRawPtr<CSSTransformValue> parseTranslateTransformValue(CharType*& pos, CharType* end)
+static bool parseTransformNumberArguments(CharType*& pos, CharType* end, unsigned expectedCount, CSSTransformValue* transformValue)
+{
+    while (expectedCount) {
+        size_t delimiter = WTF::find(pos, end - pos, expectedCount == 1 ? ')' : ',');
+        if (delimiter == kNotFound)
+            return false;
+        unsigned argumentLength = static_cast<unsigned>(delimiter);
+        bool ok;
+        double number = charactersToDouble(pos, argumentLength, &ok);
+        if (!ok)
+            return false;
+        transformValue->append(cssValuePool().createValue(number, CSSPrimitiveValue::CSS_NUMBER));
+        pos += argumentLength + 1;
+        --expectedCount;
+    }
+    return true;
+}
+
+template <typename CharType>
+static PassRefPtrWillBeRawPtr<CSSTransformValue> parseSimpleTransformValue(CharType*& pos, CharType* end)
 {
     static const int shortestValidTransformStringLength = 12;
 
     if (end - pos < shortestValidTransformStringLength)
         return nullptr;
 
-    if ((pos[0] != 't' && pos[0] != 'T')
-        || (pos[1] != 'r' && pos[1] != 'R')
-        || (pos[2] != 'a' && pos[2] != 'A')
-        || (pos[3] != 'n' && pos[3] != 'N')
-        || (pos[4] != 's' && pos[4] != 'S')
-        || (pos[5] != 'l' && pos[5] != 'L')
-        || (pos[6] != 'a' && pos[6] != 'A')
-        || (pos[7] != 't' && pos[7] != 'T')
-        || (pos[8] != 'e' && pos[8] != 'E'))
-        return nullptr;
+    const bool isTranslate = toASCIILower(pos[0]) == 't'
+        && toASCIILower(pos[1]) == 'r'
+        && toASCIILower(pos[2]) == 'a'
+        && toASCIILower(pos[3]) == 'n'
+        && toASCIILower(pos[4]) == 's'
+        && toASCIILower(pos[5]) == 'l'
+        && toASCIILower(pos[6]) == 'a'
+        && toASCIILower(pos[7]) == 't'
+        && toASCIILower(pos[8]) == 'e';
+
+    if (isTranslate) {
+        CSSTransformValue::TransformOperationType transformType;
+        unsigned expectedArgumentCount = 1;
+        unsigned argumentStart = 11;
+        CharType c9 = toASCIILower(pos[9]);
+        if (c9 == 'x' && pos[10] == '(') {
+            transformType = CSSTransformValue::TranslateXTransformOperation;
+        } else if (c9 == 'y' && pos[10] == '(') {
+            transformType = CSSTransformValue::TranslateYTransformOperation;
+        } else if (c9 == 'z' && pos[10] == '(') {
+            transformType = CSSTransformValue::TranslateZTransformOperation;
+        } else if (c9 == '(') {
+            transformType = CSSTransformValue::TranslateTransformOperation;
+            expectedArgumentCount = 2;
+            argumentStart = 10;
+        } else if (c9 == '3' && toASCIILower(pos[10]) == 'd' && pos[11] == '(') {
+            transformType = CSSTransformValue::Translate3DTransformOperation;
+            expectedArgumentCount = 3;
+            argumentStart = 12;
+        } else {
+            return nullptr;
+        }
+        pos += argumentStart;
+        RefPtrWillBeRawPtr<CSSTransformValue> transformValue = CSSTransformValue::create(transformType);
+        if (!parseTransformTranslateArguments(pos, end, expectedArgumentCount, transformValue.get()))
+            return nullptr;
+        return transformValue.release();
+    }
 
-    CSSTransformValue::TransformOperationType transformType;
-    unsigned expectedArgumentCount = 1;
-    unsigned argumentStart = 11;
-    if ((pos[9] == 'x' || pos[9] == 'X') && pos[10] == '(') {
-        transformType = CSSTransformValue::TranslateXTransformOperation;
-    } else if ((pos[9] == 'y' || pos[9] == 'Y') && pos[10] == '(') {
-        transformType = CSSTransformValue::TranslateYTransformOperation;
-    } else if ((pos[9] == 'z' || pos[9] == 'Z') && pos[10] == '(') {
-        transformType = CSSTransformValue::TranslateZTransformOperation;
-    } else if (pos[9] == '(') {
-        transformType = CSSTransformValue::TranslateTransformOperation;
-        expectedArgumentCount = 2;
-        argumentStart = 10;
-    } else if (pos[9] == '3' && (pos[10] == 'd' || pos[10] == 'D') && pos[11] == '(') {
-        transformType = CSSTransformValue::Translate3DTransformOperation;
-        expectedArgumentCount = 3;
-        argumentStart = 12;
-    } else {
-        return nullptr;
+    const bool isMatrix3d = toASCIILower(pos[0]) == 'm'
+        && toASCIILower(pos[1]) == 'a'
+        && toASCIILower(pos[2]) == 't'
+        && toASCIILower(pos[3]) == 'r'
+        && toASCIILower(pos[4]) == 'i'
+        && toASCIILower(pos[5]) == 'x'
+        && pos[6] == '3'
+        && toASCIILower(pos[7]) == 'd'
+        && pos[8] == '(';
+
+    if (isMatrix3d) {
+        pos += 9;
+        RefPtrWillBeRawPtr<CSSTransformValue> transformValue = CSSTransformValue::create(CSSTransformValue::Matrix3DTransformOperation);
+        if (!parseTransformNumberArguments(pos, end, 16, transformValue.get()))
+            return nullptr;
+        return transformValue.release();
     }
-    pos += argumentStart;
 
-    RefPtrWillBeRawPtr<CSSTransformValue> transformValue = CSSTransformValue::create(transformType);
-    if (!parseTransformTranslateArguments(pos, end, expectedArgumentCount, transformValue.get()))
-        return nullptr;
-    return transformValue.release();
+    const bool isScale3d = toASCIILower(pos[0]) == 's'
+        && toASCIILower(pos[1]) == 'c'
+        && toASCIILower(pos[2]) == 'a'
+        && toASCIILower(pos[3]) == 'l'
+        && toASCIILower(pos[4]) == 'e'
+        && pos[5] == '3'
+        && toASCIILower(pos[6]) == 'd'
+        && pos[7] == '(';
+
+    if (isScale3d) {
+        pos += 8;
+        RefPtrWillBeRawPtr<CSSTransformValue> transformValue = CSSTransformValue::create(CSSTransformValue::Scale3DTransformOperation);
+        if (!parseTransformNumberArguments(pos, end, 3, transformValue.get()))
+            return nullptr;
+        return transformValue.release();
+    }
+
+    return nullptr;
 }
 
 template <typename CharType>
-static PassRefPtrWillBeRawPtr<CSSValueList> parseTranslateTransformList(CharType*& pos, CharType* end)
+static PassRefPtrWillBeRawPtr<CSSValueList> parseSimpleTransformList(CharType*& pos, CharType* end)
 {
     RefPtrWillBeRawPtr<CSSValueList> transformList = nullptr;
     while (pos < end) {
         while (pos < end && isCSSSpace(*pos))
             ++pos;
-        RefPtrWillBeRawPtr<CSSTransformValue> transformValue = parseTranslateTransformValue(pos, end);
+        RefPtrWillBeRawPtr<CSSTransformValue> transformValue = parseSimpleTransformValue(pos, end);
         if (!transformValue)
             return nullptr;
         if (!transformList)
@@ -967,9 +1031,9 @@ static PassRefPtrWillBeRawPtr<CSSValueList> parseTranslateTransformList(CharType
     return transformList.release();
 }
 
-static bool parseTranslateTransform(MutableStylePropertySet* properties, CSSPropertyID propertyID, const String& string, bool important)
+static bool parseSimpleTransform(MutableStylePropertySet* properties, CSSPropertyID propertyID, const String& string, bool important)
 {
-    if (propertyID != CSSPropertyWebkitTransform)
+    if (propertyID != CSSPropertyTransform && propertyID != CSSPropertyWebkitTransform)
         return false;
     if (string.isEmpty())
         return false;
@@ -977,17 +1041,17 @@ static bool parseTranslateTransform(MutableStylePropertySet* properties, CSSProp
     if (string.is8Bit()) {
         const LChar* pos = string.characters8();
         const LChar* end = pos + string.length();
-        transformList = parseTranslateTransformList(pos, end);
+        transformList = parseSimpleTransformList(pos, end);
         if (!transformList)
             return false;
     } else {
         const UChar* pos = string.characters16();
         const UChar* end = pos + string.length();
-        transformList = parseTranslateTransformList(pos, end);
+        transformList = parseSimpleTransformList(pos, end);
         if (!transformList)
             return false;
     }
-    properties->addParsedProperty(CSSProperty(CSSPropertyWebkitTransform, transformList.release(), important));
+    properties->addParsedProperty(CSSProperty(propertyID, transformList.release(), important));
     return true;
 }
 
@@ -1011,10 +1075,10 @@ PassRefPtrWillBeRawPtr<CSSValue> BisonCSSParser::parseAnimationTimingFunctionVal
     if (string.isEmpty())
         return nullptr;
     RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
-    if (!parseValue(style.get(), CSSPropertyAnimationTimingFunction, string, false, HTMLStandardMode, 0))
+    if (!parseValue(style.get(), CSSPropertyTransitionTimingFunction, string, false, HTMLStandardMode, 0))
         return nullptr;
 
-    return style->getPropertyCSSValue(CSSPropertyAnimationTimingFunction);
+    return style->getPropertyCSSValue(CSSPropertyTransitionTimingFunction);
 }
 
 bool BisonCSSParser::parseValue(MutableStylePropertySet* declaration, CSSPropertyID propertyID, const String& string, bool important, const Document& document)
@@ -1050,7 +1114,7 @@ bool BisonCSSParser::parseValue(MutableStylePropertySet* declaration, CSSPropert
 
     if (parseKeywordValue(declaration, propertyID, string, important, context))
         return true;
-    if (parseTranslateTransform(declaration, propertyID, string, important))
+    if (parseSimpleTransform(declaration, propertyID, string, important))
         return true;
 
     BisonCSSParser parser(context);
@@ -1416,14 +1480,14 @@ private:
     CSSPropertyParser::Units m_unit;
 };
 
-PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseTransform()
+PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseTransform(CSSPropertyID propId)
 {
     if (!m_valueList)
         return nullptr;
 
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
     for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
-        RefPtrWillBeRawPtr<CSSValue> parsedTransformValue = parseTransformValue(value);
+        RefPtrWillBeRawPtr<CSSValue> parsedTransformValue = parseTransformValue(propId, value);
         if (!parsedTransformValue)
             return nullptr;
 
@@ -1433,7 +1497,7 @@ PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseTransform()
     return list.release();
 }
 
-PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseTransformValue(CSSParserValue *value)
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseTransformValue(CSSPropertyID propId, CSSParserValue *value)
 {
     if (value->unit != CSSParserValue::Function || !value->function)
         return nullptr;
@@ -1477,7 +1541,8 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseTransformValue(CSSParse
                 return nullptr;
         } else if (info.type() == CSSTransformValue::PerspectiveTransformOperation && !argNumber) {
             // 1st param of perspective() must be a non-negative number (deprecated) or length.
-            if (!validUnit(a, FNumber | FLength | FNonNeg, HTMLStandardMode))
+            if ((propId == CSSPropertyWebkitTransform && !validUnit(a, FNumber | FLength | FNonNeg, HTMLStandardMode))
+                || (propId == CSSPropertyTransform && !validUnit(a, FLength | FNonNeg, HTMLStandardMode)))
                 return nullptr;
         } else if (!validUnit(a, unit, HTMLStandardMode)) {
             return nullptr;
@@ -1693,7 +1758,7 @@ StyleRuleBase* BisonCSSParser::createSupportsRule(bool conditionIsSupported, Rul
 {
     m_allowImportRules = m_allowNamespaceDeclarations = false;
 
-    RefPtr<CSSRuleSourceData> data = popSupportsRuleData();
+    RefPtrWillBeRawPtr<CSSRuleSourceData> data = popSupportsRuleData();
     RefPtrWillBeRawPtr<StyleRuleSupports> rule = nullptr;
     String conditionText;
     unsigned conditionOffset = data->ruleHeaderRange.start + 9;
@@ -1720,9 +1785,9 @@ StyleRuleBase* BisonCSSParser::createSupportsRule(bool conditionIsSupported, Rul
 void BisonCSSParser::markSupportsRuleHeaderStart()
 {
     if (!m_supportsRuleDataStack)
-        m_supportsRuleDataStack = adoptPtr(new RuleSourceDataList());
+        m_supportsRuleDataStack = adoptPtrWillBeNoop(new RuleSourceDataList());
 
-    RefPtr<CSSRuleSourceData> data = CSSRuleSourceData::create(CSSRuleSourceData::SUPPORTS_RULE);
+    RefPtrWillBeRawPtr<CSSRuleSourceData> data = CSSRuleSourceData::create(CSSRuleSourceData::SUPPORTS_RULE);
     data->ruleHeaderRange.start = m_tokenizer.tokenStartOffset();
     m_supportsRuleDataStack->append(data);
 }
@@ -1737,10 +1802,10 @@ void BisonCSSParser::markSupportsRuleHeaderEnd()
         m_supportsRuleDataStack->last()->ruleHeaderRange.end = m_tokenizer.tokenStart<UChar>() - m_tokenizer.m_dataStart16.get();
 }
 
-PassRefPtr<CSSRuleSourceData> BisonCSSParser::popSupportsRuleData()
+PassRefPtrWillBeRawPtr<CSSRuleSourceData> BisonCSSParser::popSupportsRuleData()
 {
     ASSERT(m_supportsRuleDataStack && !m_supportsRuleDataStack->isEmpty());
-    RefPtr<CSSRuleSourceData> data = m_supportsRuleDataStack->last();
+    RefPtrWillBeRawPtr<CSSRuleSourceData> data = m_supportsRuleDataStack->last();
     m_supportsRuleDataStack->removeLast();
     return data.release();
 }
@@ -1782,15 +1847,16 @@ ALWAYS_INLINE static void makeLower(const CharacterType* input, CharacterType* o
     }
 }
 
-void BisonCSSParser::tokenToLowerCase(const CSSParserString& token)
+void BisonCSSParser::tokenToLowerCase(CSSParserString& token)
 {
+    // Since it's our internal token, we know that we created it out
+    // of our writable work buffers. Therefore the const_cast is just
+    // ugly and not a potential crash.
     size_t length = token.length();
-    if (m_tokenizer.is8BitSource()) {
-        size_t offset = token.characters8() - m_tokenizer.m_dataStart8.get();
-        makeLower(token.characters8(), m_tokenizer.m_dataStart8.get() + offset, length);
+    if (token.is8Bit()) {
+        makeLower(token.characters8(), const_cast<LChar*>(token.characters8()), length);
     } else {
-        size_t offset = token.characters16() - m_tokenizer.m_dataStart16.get();
-        makeLower(token.characters16(), m_tokenizer.m_dataStart16.get() + offset, length);
+        makeLower(token.characters16(), const_cast<UChar*>(token.characters16()), length);
     }
 }
 
@@ -1834,7 +1900,7 @@ void BisonCSSParser::logError(const String& message, const CSSParserLocation& lo
     } else {
         lineNumberInStyleSheet = location.lineNumber;
     }
-    PageConsole& console = m_styleSheet->singleOwnerDocument()->frameHost()->console();
+    FrameConsole& console = m_styleSheet->singleOwnerDocument()->frame()->console();
     console.addMessage(CSSMessageSource, WarningMessageLevel, message, m_styleSheet->baseURL().string(), lineNumberInStyleSheet + m_startPosition.m_line.zeroBasedInt() + 1, columnNumber + 1);
 }