summaryrefslogtreecommitdiff
path: root/Source/WebCore/css/CSSParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/css/CSSParser.cpp')
-rw-r--r--Source/WebCore/css/CSSParser.cpp536
1 files changed, 433 insertions, 103 deletions
diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp
index d16537e6c..8ff97b8e9 100644
--- a/Source/WebCore/css/CSSParser.cpp
+++ b/Source/WebCore/css/CSSParser.cpp
@@ -6,6 +6,7 @@
* Copyright (C) 2008 Eric Seidel <eric@webkit.org>
* Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2012 Intel Corporation. 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
@@ -43,7 +44,6 @@
#include "CSSMediaRule.h"
#include "CSSPageRule.h"
#include "CSSPrimitiveValue.h"
-#include "CSSProperty.h"
#include "CSSPropertySourceData.h"
#include "CSSReflectValue.h"
#include "CSSSelector.h"
@@ -53,7 +53,6 @@
#include "CSSValueKeywords.h"
#include "CSSValueList.h"
#include "CSSValuePool.h"
-#include "StylePropertyShorthand.h"
#if ENABLE(CSS_VARIABLES)
#include "CSSVariableValue.h"
#endif
@@ -271,6 +270,9 @@ CSSParser::CSSParser(const CSSParserContext& context)
, m_lastSelectorLineNumber(0)
, m_allowImportRules(true)
, m_allowNamespaceDeclarations(true)
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ , m_inViewport(false)
+#endif
, m_selectorVector(adoptPtr(new CSSSelectorVector))
{
#if YYDEBUG > 0
@@ -337,11 +339,12 @@ AtomicString CSSParserString::lowerSubstring(unsigned position, unsigned length)
return AtomicString(result);
}
-void CSSParser::setupParser(const char* prefix, const String& string, const char* suffix)
+void CSSParser::setupParser(const char* prefix, unsigned prefixLength, const String& string, const char* suffix, unsigned suffixLength)
{
- m_parsedTextPrefixLength = strlen(prefix);
+ m_parsedTextPrefixLength = prefixLength;
unsigned stringLength = string.length();
- unsigned length = stringLength + m_parsedTextPrefixLength + strlen(suffix) + 1;
+ unsigned length = stringLength + m_parsedTextPrefixLength + suffixLength + 1;
+ m_length = length;
if (!stringLength || string.is8Bit()) {
m_dataStart8 = adoptArrayPtr(new LChar[length]);
@@ -352,7 +355,7 @@ void CSSParser::setupParser(const char* prefix, const String& string, const char
memcpy(m_dataStart8.get() + m_parsedTextPrefixLength, string.characters8(), stringLength * sizeof(LChar));
unsigned start = m_parsedTextPrefixLength + stringLength;
- unsigned end = start + strlen(suffix);
+ unsigned end = start + suffixLength;
for (unsigned i = start; i < end; i++)
m_dataStart8[i] = suffix[i - start];
@@ -362,7 +365,6 @@ void CSSParser::setupParser(const char* prefix, const String& string, const char
m_currentCharacter8 = m_dataStart8.get();
m_currentCharacter16 = 0;
setTokenStart<LChar>(m_currentCharacter8);
- m_length = length;
m_lexFunc = &CSSParser::realLex<LChar>;
return;
}
@@ -374,7 +376,7 @@ void CSSParser::setupParser(const char* prefix, const String& string, const char
memcpy(m_dataStart16.get() + m_parsedTextPrefixLength, string.characters(), stringLength * sizeof(UChar));
unsigned start = m_parsedTextPrefixLength + stringLength;
- unsigned end = start + strlen(suffix);
+ unsigned end = start + suffixLength;
for (unsigned i = start; i < end; i++)
m_dataStart16[i] = suffix[i - start];
@@ -384,7 +386,6 @@ void CSSParser::setupParser(const char* prefix, const String& string, const char
m_currentCharacter8 = 0;
m_currentCharacter16 = m_dataStart16.get();
setTokenStart<UChar>(m_currentCharacter16);
- m_length = length;
m_lexFunc = &CSSParser::realLex<UChar>;
}
@@ -829,8 +830,8 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int
if (valueID == CSSValueNone || valueID == CSSValueEdges)
return true;
break;
- case CSSPropertyWebkitLineBreak: // normal | after-white-space
- if (valueID == CSSValueNormal || valueID == CSSValueAfterWhiteSpace)
+ case CSSPropertyWebkitLineBreak: // auto | loose | normal | strict | after-white-space
+ if (valueID == CSSValueAuto || valueID == CSSValueLoose || valueID == CSSValueNormal || valueID == CSSValueStrict || valueID == CSSValueAfterWhiteSpace)
return true;
break;
case CSSPropertyWebkitLineSnap:
@@ -1572,7 +1573,7 @@ bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, CSSParserMode
case CSSPrimitiveValue::CSS_TURN:
b = (unitflags & FAngle);
break;
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
case CSSPrimitiveValue::CSS_DPPX:
case CSSPrimitiveValue::CSS_DPI:
case CSSPrimitiveValue::CSS_DPCM:
@@ -1601,8 +1602,8 @@ inline PassRefPtr<CSSPrimitiveValue> CSSParser::createPrimitiveNumericValue(CSSP
ASSERT(isCalculation(value));
return CSSPrimitiveValue::create(m_parsedCalculation.release());
}
-
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+
+#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_REMS)
|| (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMIN)
@@ -1664,7 +1665,7 @@ inline PassRefPtr<CSSPrimitiveValue> CSSParser::parseValidPrimitive(int identifi
return createPrimitiveNumericValue(value);
if (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMIN)
return createPrimitiveNumericValue(value);
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
if (value->unit >= CSSPrimitiveValue::CSS_DPPX && value->unit <= CSSPrimitiveValue::CSS_DPCM)
return createPrimitiveNumericValue(value);
#endif
@@ -1729,6 +1730,11 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important)
return true;
}
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ if (inViewport())
+ return parseViewportProperty(propId, important);
+#endif
+
bool validPrimitive = false;
RefPtr<CSSValue> parsedValue;
@@ -1876,15 +1882,18 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important)
coords.append(int(value->fValue));
value = m_valueList->next();
}
+ bool hasHotSpot = false;
IntPoint hotSpot(-1, -1);
int nrcoords = coords.size();
if (nrcoords > 0 && nrcoords != 2)
return false;
- if (nrcoords == 2)
+ if (nrcoords == 2) {
+ hasHotSpot = true;
hotSpot = IntPoint(coords[0], coords[1]);
+ }
if (!uri.isNull())
- list->append(CSSCursorImageValue::create(completeURL(uri), hotSpot));
+ list->append(CSSCursorImageValue::create(completeURL(uri), hasHotSpot, hotSpot));
if ((inStrictMode() && !value) || (value && !(value->unit == CSSParserValue::Operator && value->iValue == ',')))
return false;
@@ -2853,6 +2862,17 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important)
// These properties should be handled before in isValidKeywordPropertyAndValue().
ASSERT_NOT_REACHED();
return false;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ // Properties bellow are validated inside parseViewportProperty, because we
+ // check for parser state inViewportScope. We need to invalidate if someone
+ // adds them outside a @viewport rule.
+ case CSSPropertyMaxZoom:
+ case CSSPropertyMinZoom:
+ case CSSPropertyOrientation:
+ case CSSPropertyUserZoom:
+ validPrimitive = false;
+ break;
+#endif
#if ENABLE(SVG)
default:
return parseSVGValue(propId, important);
@@ -7210,76 +7230,241 @@ public:
, m_allowSingleArgument(false)
, m_unit(CSSParser::FUnknown)
{
- if (equalIgnoringCase(name, "scale(") || equalIgnoringCase(name, "scalex(") || equalIgnoringCase(name, "scaley(") || equalIgnoringCase(name, "scalez(")) {
- m_unit = CSSParser::FNumber;
- if (equalIgnoringCase(name, "scale("))
- m_type = WebKitCSSTransformValue::ScaleTransformOperation;
- else if (equalIgnoringCase(name, "scalex("))
- m_type = WebKitCSSTransformValue::ScaleXTransformOperation;
- else if (equalIgnoringCase(name, "scaley("))
- m_type = WebKitCSSTransformValue::ScaleYTransformOperation;
- else
- m_type = WebKitCSSTransformValue::ScaleZTransformOperation;
- } else if (equalIgnoringCase(name, "scale3d(")) {
- m_type = WebKitCSSTransformValue::Scale3DTransformOperation;
- m_argCount = 5;
- m_unit = CSSParser::FNumber;
- } else if (equalIgnoringCase(name, "rotate(")) {
- m_type = WebKitCSSTransformValue::RotateTransformOperation;
- m_unit = CSSParser::FAngle;
- } else if (equalIgnoringCase(name, "rotatex(") ||
- equalIgnoringCase(name, "rotatey(") ||
- equalIgnoringCase(name, "rotatez(")) {
- m_unit = CSSParser::FAngle;
- if (equalIgnoringCase(name, "rotatex("))
- m_type = WebKitCSSTransformValue::RotateXTransformOperation;
- else if (equalIgnoringCase(name, "rotatey("))
- m_type = WebKitCSSTransformValue::RotateYTransformOperation;
- else
- m_type = WebKitCSSTransformValue::RotateZTransformOperation;
- } else if (equalIgnoringCase(name, "rotate3d(")) {
- m_type = WebKitCSSTransformValue::Rotate3DTransformOperation;
- m_argCount = 7;
- m_unit = CSSParser::FNumber;
- } else if (equalIgnoringCase(name, "skew(") || equalIgnoringCase(name, "skewx(") || equalIgnoringCase(name, "skewy(")) {
- m_unit = CSSParser::FAngle;
- if (equalIgnoringCase(name, "skew("))
+ const UChar* characters;
+ unsigned nameLength = name.length();
+
+ const unsigned longestNameLength = 12;
+ UChar characterBuffer[longestNameLength];
+ if (name.is8Bit()) {
+ unsigned length = std::min(longestNameLength, nameLength);
+ const LChar* characters8 = name.characters8();
+ for (unsigned i = 0; i < length; ++i)
+ characterBuffer[i] = characters8[i];
+ characters = characterBuffer;
+ } else
+ characters = name.characters16();
+
+ switch (nameLength) {
+ case 5:
+ // Valid name: skew(.
+ if (((characters[0] == 's') || (characters[0] == 'S'))
+ & ((characters[1] == 'k') || (characters[1] == 'K'))
+ & ((characters[2] == 'e') || (characters[2] == 'E'))
+ & ((characters[3] == 'w') || (characters[3] == 'W'))
+ & (characters[4] == '(')) {
+ m_unit = CSSParser::FAngle;
m_type = WebKitCSSTransformValue::SkewTransformOperation;
- else if (equalIgnoringCase(name, "skewx("))
- m_type = WebKitCSSTransformValue::SkewXTransformOperation;
- else
- m_type = WebKitCSSTransformValue::SkewYTransformOperation;
- } else if (equalIgnoringCase(name, "translate(") || equalIgnoringCase(name, "translatex(") || equalIgnoringCase(name, "translatey(") || equalIgnoringCase(name, "translatez(")) {
- m_unit = CSSParser::FLength | CSSParser::FPercent;
- if (equalIgnoringCase(name, "translate("))
+ m_allowSingleArgument = true;
+ m_argCount = 3;
+ }
+ break;
+ case 6:
+ // Valid names: skewx(, skewy(, scale(.
+ if ((characters[1] == 'c') || (characters[1] == 'C')) {
+ if (((characters[0] == 's') || (characters[0] == 'S'))
+ & ((characters[2] == 'a') || (characters[2] == 'A'))
+ & ((characters[3] == 'l') || (characters[3] == 'L'))
+ & ((characters[4] == 'e') || (characters[4] == 'E'))
+ & (characters[5] == '(')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::ScaleTransformOperation;
+ m_allowSingleArgument = true;
+ m_argCount = 3;
+ }
+ } else if (((characters[0] == 's') || (characters[0] == 'S'))
+ & ((characters[1] == 'k') || (characters[1] == 'K'))
+ & ((characters[2] == 'e') || (characters[2] == 'E'))
+ & ((characters[3] == 'w') || (characters[3] == 'W'))
+ & (characters[5] == '(')) {
+ if ((characters[4] == 'x') || (characters[4] == 'X')) {
+ m_unit = CSSParser::FAngle;
+ m_type = WebKitCSSTransformValue::SkewXTransformOperation;
+ } else if ((characters[4] == 'y') || (characters[4] == 'Y')) {
+ m_unit = CSSParser::FAngle;
+ m_type = WebKitCSSTransformValue::SkewYTransformOperation;
+ }
+ }
+ break;
+ case 7:
+ // Valid names: matrix(, rotate(, scalex(, scaley(, scalez(.
+ if ((characters[0] == 'm') || (characters[0] == 'M')) {
+ if (((characters[1] == 'a') || (characters[1] == 'A'))
+ & ((characters[2] == 't') || (characters[2] == 'T'))
+ & ((characters[3] == 'r') || (characters[3] == 'R'))
+ & ((characters[4] == 'i') || (characters[4] == 'I'))
+ & ((characters[5] == 'x') || (characters[5] == 'X'))
+ & (characters[6] == '(')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::MatrixTransformOperation;
+ m_argCount = 11;
+ }
+ } else if ((characters[0] == 'r') || (characters[0] == 'R')) {
+ if (((characters[1] == 'o') || (characters[1] == 'O'))
+ & ((characters[2] == 't') || (characters[2] == 'T'))
+ & ((characters[3] == 'a') || (characters[3] == 'A'))
+ & ((characters[4] == 't') || (characters[4] == 'T'))
+ & ((characters[5] == 'e') || (characters[5] == 'E'))
+ & (characters[6] == '(')) {
+ m_unit = CSSParser::FAngle;
+ m_type = WebKitCSSTransformValue::RotateTransformOperation;
+ }
+ } else if (((characters[0] == 's') || (characters[0] == 'S'))
+ & ((characters[1] == 'c') || (characters[1] == 'C'))
+ & ((characters[2] == 'a') || (characters[2] == 'A'))
+ & ((characters[3] == 'l') || (characters[3] == 'L'))
+ & ((characters[4] == 'e') || (characters[4] == 'E'))
+ & (characters[6] == '(')) {
+ if ((characters[5] == 'x') || (characters[5] == 'X')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::ScaleXTransformOperation;
+ } else if ((characters[5] == 'y') || (characters[5] == 'Y')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::ScaleYTransformOperation;
+ } else if ((characters[5] == 'z') || (characters[5] == 'Z')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::ScaleZTransformOperation;
+ }
+ }
+ break;
+ case 8:
+ // Valid names: rotatex(, rotatey(, rotatez(, scale3d(.
+ if ((characters[0] == 's') || (characters[0] == 'S')) {
+ if (((characters[1] == 'c') || (characters[1] == 'C'))
+ & ((characters[2] == 'a') || (characters[2] == 'A'))
+ & ((characters[3] == 'l') || (characters[3] == 'L'))
+ & ((characters[4] == 'e') || (characters[4] == 'E'))
+ & (characters[5] == '3')
+ & ((characters[6] == 'd') || (characters[6] == 'D'))
+ & (characters[7] == '(')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::Scale3DTransformOperation;
+ m_argCount = 5;
+ }
+ } else if (((characters[0] == 'r') || (characters[0] == 'R'))
+ & ((characters[1] == 'o') || (characters[1] == 'O'))
+ & ((characters[2] == 't') || (characters[2] == 'T'))
+ & ((characters[3] == 'a') || (characters[3] == 'A'))
+ & ((characters[4] == 't') || (characters[4] == 'T'))
+ & ((characters[5] == 'e') || (characters[5] == 'E'))
+ & (characters[7] == '(')) {
+ if ((characters[6] == 'x') || (characters[6] == 'X')) {
+ m_unit = CSSParser::FAngle;
+ m_type = WebKitCSSTransformValue::RotateXTransformOperation;
+ } else if ((characters[6] == 'y') || (characters[6] == 'Y')) {
+ m_unit = CSSParser::FAngle;
+ m_type = WebKitCSSTransformValue::RotateYTransformOperation;
+ } else if ((characters[6] == 'z') || (characters[6] == 'Z')) {
+ m_unit = CSSParser::FAngle;
+ m_type = WebKitCSSTransformValue::RotateZTransformOperation;
+ }
+ }
+ break;
+ case 9:
+ // Valid names: matrix3d(, rotate3d(.
+ if ((characters[0] == 'm') || (characters[0] == 'M')) {
+ if (((characters[1] == 'a') || (characters[1] == 'A'))
+ & ((characters[2] == 't') || (characters[2] == 'T'))
+ & ((characters[3] == 'r') || (characters[3] == 'R'))
+ & ((characters[4] == 'i') || (characters[4] == 'I'))
+ & ((characters[5] == 'x') || (characters[5] == 'X'))
+ & (characters[6] == '3')
+ & ((characters[7] == 'd') || (characters[7] == 'D'))
+ & (characters[8] == '(')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::Matrix3DTransformOperation;
+ m_argCount = 31;
+ }
+ } else if (((characters[0] == 'r') || (characters[0] == 'R'))
+ & ((characters[1] == 'o') || (characters[1] == 'O'))
+ & ((characters[2] == 't') || (characters[2] == 'T'))
+ & ((characters[3] == 'a') || (characters[3] == 'A'))
+ & ((characters[4] == 't') || (characters[4] == 'T'))
+ & ((characters[5] == 'e') || (characters[5] == 'E'))
+ & (characters[6] == '3')
+ & ((characters[7] == 'd') || (characters[7] == 'D'))
+ & (characters[8] == '(')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::Rotate3DTransformOperation;
+ m_argCount = 7;
+ }
+ break;
+ case 10:
+ // Valid name: translate(.
+ if (((characters[0] == 't') || (characters[0] == 'T'))
+ & ((characters[1] == 'r') || (characters[1] == 'R'))
+ & ((characters[2] == 'a') || (characters[2] == 'A'))
+ & ((characters[3] == 'n') || (characters[3] == 'N'))
+ & ((characters[4] == 's') || (characters[4] == 'S'))
+ & ((characters[5] == 'l') || (characters[5] == 'L'))
+ & ((characters[6] == 'a') || (characters[6] == 'A'))
+ & ((characters[7] == 't') || (characters[7] == 'T'))
+ & ((characters[8] == 'e') || (characters[8] == 'E'))
+ & (characters[9] == '(')) {
+ m_unit = CSSParser::FLength | CSSParser::FPercent;
m_type = WebKitCSSTransformValue::TranslateTransformOperation;
- else if (equalIgnoringCase(name, "translatex("))
- m_type = WebKitCSSTransformValue::TranslateXTransformOperation;
- else if (equalIgnoringCase(name, "translatey("))
- m_type = WebKitCSSTransformValue::TranslateYTransformOperation;
- else
- m_type = WebKitCSSTransformValue::TranslateZTransformOperation;
- } else if (equalIgnoringCase(name, "translate3d(")) {
- m_type = WebKitCSSTransformValue::Translate3DTransformOperation;
- m_argCount = 5;
- m_unit = CSSParser::FLength | CSSParser::FPercent;
- } else if (equalIgnoringCase(name, "matrix(")) {
- m_type = WebKitCSSTransformValue::MatrixTransformOperation;
- m_argCount = 11;
- m_unit = CSSParser::FNumber;
- } else if (equalIgnoringCase(name, "matrix3d(")) {
- m_type = WebKitCSSTransformValue::Matrix3DTransformOperation;
- m_argCount = 31;
- m_unit = CSSParser::FNumber;
- } else if (equalIgnoringCase(name, "perspective(")) {
- m_type = WebKitCSSTransformValue::PerspectiveTransformOperation;
- m_unit = CSSParser::FNumber;
- }
-
- if (equalIgnoringCase(name, "scale(") || equalIgnoringCase(name, "skew(") || equalIgnoringCase(name, "translate(")) {
- m_allowSingleArgument = true;
- m_argCount = 3;
- }
+ m_allowSingleArgument = true;
+ m_argCount = 3;
+ }
+ break;
+ case 11:
+ // Valid names: translatex(, translatey(, translatez(.
+ if (((characters[0] == 't') || (characters[0] == 'T'))
+ & ((characters[1] == 'r') || (characters[1] == 'R'))
+ & ((characters[2] == 'a') || (characters[2] == 'A'))
+ & ((characters[3] == 'n') || (characters[3] == 'N'))
+ & ((characters[4] == 's') || (characters[4] == 'S'))
+ & ((characters[5] == 'l') || (characters[5] == 'L'))
+ & ((characters[6] == 'a') || (characters[6] == 'A'))
+ & ((characters[7] == 't') || (characters[7] == 'T'))
+ & ((characters[8] == 'e') || (characters[8] == 'E'))
+ & (characters[10] == '(')) {
+ if ((characters[9] == 'x') || (characters[9] == 'X')) {
+ m_unit = CSSParser::FLength | CSSParser::FPercent;
+ m_type = WebKitCSSTransformValue::TranslateXTransformOperation;
+ } else if ((characters[9] == 'y') || (characters[9] == 'Y')) {
+ m_unit = CSSParser::FLength | CSSParser::FPercent;
+ m_type = WebKitCSSTransformValue::TranslateYTransformOperation;
+ } else if ((characters[9] == 'z') || (characters[9] == 'Z')) {
+ m_unit = CSSParser::FLength | CSSParser::FPercent;
+ m_type = WebKitCSSTransformValue::TranslateZTransformOperation;
+ }
+ }
+ break;
+ case 12:
+ // Valid names: perspective(, translate3d(.
+ if ((characters[0] == 'p') || (characters[0] == 'P')) {
+ if (((characters[1] == 'e') || (characters[1] == 'E'))
+ & ((characters[2] == 'r') || (characters[2] == 'R'))
+ & ((characters[3] == 's') || (characters[3] == 'S'))
+ & ((characters[4] == 'p') || (characters[4] == 'P'))
+ & ((characters[5] == 'e') || (characters[5] == 'E'))
+ & ((characters[6] == 'c') || (characters[6] == 'C'))
+ & ((characters[7] == 't') || (characters[7] == 'T'))
+ & ((characters[8] == 'i') || (characters[8] == 'I'))
+ & ((characters[9] == 'v') || (characters[9] == 'V'))
+ & ((characters[10] == 'e') || (characters[10] == 'E'))
+ & (characters[11] == '(')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::PerspectiveTransformOperation;
+ }
+ } else if (((characters[0] == 't') || (characters[0] == 'T'))
+ & ((characters[1] == 'r') || (characters[1] == 'R'))
+ & ((characters[2] == 'a') || (characters[2] == 'A'))
+ & ((characters[3] == 'n') || (characters[3] == 'N'))
+ & ((characters[4] == 's') || (characters[4] == 'S'))
+ & ((characters[5] == 'l') || (characters[5] == 'L'))
+ & ((characters[6] == 'a') || (characters[6] == 'A'))
+ & ((characters[7] == 't') || (characters[7] == 'T'))
+ & ((characters[8] == 'e') || (characters[8] == 'E'))
+ & (characters[9] == '3')
+ & ((characters[10] == 'd') || (characters[10] == 'D'))
+ & (characters[11] == '(')) {
+ m_unit = CSSParser::FLength | CSSParser::FPercent;
+ m_type = WebKitCSSTransformValue::Translate3DTransformOperation;
+ m_argCount = 5;
+ }
+ break;
+ } // end switch ()
}
WebKitCSSTransformValue::TransformOperationType type() const { return m_type; }
@@ -8009,6 +8194,8 @@ bool CSSParser::parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& prop
switch (propId) {
case CSSPropertyWebkitPerspectiveOrigin:
+ if (m_valueList->size() > 2)
+ return false;
parseFillPosition(m_valueList.get(), value, value2);
break;
case CSSPropertyWebkitPerspectiveOriginX: {
@@ -9010,7 +9197,7 @@ inline void CSSParser::detectNumberToken(CharacterType* type, int length)
case 'd':
if (length == 3 && isASCIIAlphaCaselessEqual(type[1], 'e') && isASCIIAlphaCaselessEqual(type[2], 'g'))
m_token = DEGS;
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
else if (length > 2 && isASCIIAlphaCaselessEqual(type[1], 'p')) {
if (length == 4) {
// There is a discussion about the name of this unit on www-style.
@@ -9185,6 +9372,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;
@@ -9308,8 +9502,15 @@ inline void CSSParser::detectAtToken(int length, bool hasEscape)
return;
case 17:
- if (!hasEscape && isEqualToCSSIdentifier(name + 2, "webkit-selector"))
+ if (hasEscape)
+ return;
+
+ if (isASCIIAlphaCaselessEqual(name[16], 'r') && isEqualToCSSIdentifier(name + 2, "webkit-selecto"))
m_token = WEBKIT_SELECTOR_SYM;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ else if (isASCIIAlphaCaselessEqual(name[16], 't') && isEqualToCSSIdentifier(name + 2, "webkit-viewpor"))
+ m_token = WEBKIT_VIEWPORT_RULE_SYM;
+#endif
return;
case 18:
@@ -10017,6 +10218,24 @@ StyleRuleBase* CSSParser::createFontFaceRule()
return result;
}
+#if ENABLE(SHADOW_DOM)
+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);
+ }
+ StyleRuleHost* result = rule.get();
+ m_parsedRules.append(rule.release());
+ processAndAddNewRuleToSourceTreeIfNeeded();
+ return result;
+}
+#endif
+
void CSSParser::addNamespace(const AtomicString& prefix, const AtomicString& uri)
{
if (!m_styleSheet || !m_allowNamespaceDeclarations)
@@ -10038,7 +10257,7 @@ void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePre
{
AtomicString determinedNamespace = namespacePrefix != nullAtom && m_styleSheet ? m_styleSheet->determineNamespace(namespacePrefix) : m_defaultNamespace;
QualifiedName tag = QualifiedName(namespacePrefix, elementName, determinedNamespace);
- if (!specifiers->isUnknownPseudoElement()) {
+ if (!specifiers->isCustomPseudoElement()) {
specifiers->setTag(tag);
return;
}
@@ -10047,7 +10266,7 @@ void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePre
CSSParserSelector* history = specifiers;
while (history->tagHistory()) {
history = history->tagHistory();
- if (history->isUnknownPseudoElement() || history->hasShadowDescendant())
+ if (history->isCustomPseudoElement() || history->hasShadowDescendant())
lastShadowDescendant = history;
}
@@ -10066,12 +10285,12 @@ void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePre
CSSParserSelector* CSSParser::updateSpecifiers(CSSParserSelector* specifiers, CSSParserSelector* newSpecifier)
{
- if (newSpecifier->isUnknownPseudoElement()) {
+ if (newSpecifier->isCustomPseudoElement()) {
// Unknown pseudo element always goes at the top of selector chain.
newSpecifier->appendTagHistory(CSSSelector::ShadowDescendant, sinkFloatingSelector(specifiers));
return newSpecifier;
}
- if (specifiers->isUnknownPseudoElement()) {
+ if (specifiers->isCustomPseudoElement()) {
// Specifiers for unknown pseudo element go right behind it in the chain.
specifiers->insertTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier), CSSSelector::ShadowDescendant);
return specifiers;
@@ -10364,6 +10583,102 @@ void CSSParser::markPropertyEnd(bool isImportantFound, bool isPropertyParsed)
resetPropertyRange();
}
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+StyleRuleBase* CSSParser::createViewportRule()
+{
+ m_allowImportRules = m_allowNamespaceDeclarations = false;
+
+ RefPtr<StyleRuleViewport> rule = StyleRuleViewport::create();
+
+ rule->setProperties(createStylePropertySet());
+ clearProperties();
+
+ StyleRuleViewport* result = rule.get();
+ m_parsedRules.append(rule.release());
+ processAndAddNewRuleToSourceTreeIfNeeded();
+
+ return result;
+}
+
+bool CSSParser::parseViewportProperty(CSSPropertyID propId, bool important)
+{
+ CSSParserValue* value = m_valueList->current();
+ if (!value)
+ return false;
+
+ int id = value->id;
+ bool validPrimitive = false;
+
+ switch (propId) {
+ case CSSPropertyMinWidth: // auto | device-width | device-height | <length> | <percentage>
+ case CSSPropertyMaxWidth:
+ case CSSPropertyMinHeight:
+ case CSSPropertyMaxHeight:
+ if (id == CSSValueAuto || id == CSSValueDeviceWidth || id == CSSValueDeviceHeight)
+ validPrimitive = true;
+ else
+ validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
+ break;
+ case CSSPropertyWidth: // shorthand
+ return parseViewportShorthand(propId, CSSPropertyMinWidth, CSSPropertyMaxWidth, important);
+ case CSSPropertyHeight:
+ return parseViewportShorthand(propId, CSSPropertyMinHeight, CSSPropertyMaxHeight, important);
+ case CSSPropertyMinZoom: // auto | <number> | <percentage>
+ case CSSPropertyMaxZoom:
+ case CSSPropertyZoom:
+ if (id == CSSValueAuto)
+ validPrimitive = true;
+ else
+ validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg));
+ break;
+ case CSSPropertyUserZoom: // zoom | fixed
+ if (id == CSSValueZoom || id == CSSValueFixed)
+ validPrimitive = true;
+ break;
+ case CSSPropertyOrientation: // auto | portrait | landscape
+ if (id == CSSValueAuto || id == CSSValuePortrait || id == CSSValueLandscape)
+ validPrimitive = true;
+ default:
+ break;
+ }
+
+ RefPtr<CSSValue> parsedValue;
+ if (validPrimitive) {
+ parsedValue = parseValidPrimitive(id, value);
+ m_valueList->next();
+ }
+
+ if (parsedValue) {
+ if (!m_valueList->current() || inShorthand()) {
+ addProperty(propId, parsedValue.release(), important);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool CSSParser::parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important)
+{
+ unsigned numValues = m_valueList->size();
+
+ if (numValues > 2)
+ return false;
+
+ ShorthandScope scope(this, propId);
+
+ if (!parseViewportProperty(first, important))
+ return false;
+
+ // If just one value is supplied, the second value
+ // is implicitly initialized with the first value.
+ if (numValues == 1)
+ m_valueList->previous();
+
+ return parseViewportProperty(second, important);
+}
+#endif
+
template <typename CharacterType>
static CSSPropertyID cssPropertyID(const CharacterType* propertyName, unsigned length)
{
@@ -10556,20 +10871,16 @@ static bool isCSSTokenizerURL(const String& string)
return isCSSTokenizerURL(string.characters(), length);
}
-// We use single quotes for now because markup.cpp uses double quotes.
-String quoteCSSString(const String& string)
-{
- // This function expands each character to at most 3 characters ('\u0010' -> '\' '1' '0') as well as adds
- // 2 quote characters (before and after). Make sure the resulting size (3 * length + 2) will not overflow unsigned.
- if (string.length() >= (std::numeric_limits<unsigned>::max() / 3) - 2)
- return "";
+template <typename CharacterType>
+static inline String quoteCSSStringInternal(const CharacterType* characters, unsigned length)
+{
// For efficiency, we first pre-calculate the length of the quoted string, then we build the actual one.
// Please see below for the actual logic.
unsigned quotedStringSize = 2; // Two quotes surrounding the entire string.
bool afterEscape = false;
- for (unsigned i = 0; i < string.length(); ++i) {
- UChar ch = string[i];
+ for (unsigned i = 0; i < length; ++i) {
+ CharacterType ch = characters[i];
if (ch == '\\' || ch == '\'') {
quotedStringSize += 2;
afterEscape = false;
@@ -10582,12 +10893,12 @@ String quoteCSSString(const String& string)
}
}
- StringBuffer<UChar> buffer(quotedStringSize);
+ StringBuffer<CharacterType> buffer(quotedStringSize);
unsigned index = 0;
buffer[index++] = '\'';
afterEscape = false;
- for (unsigned i = 0; i < string.length(); ++i) {
- UChar ch = string[i];
+ for (unsigned i = 0; i < length; ++i) {
+ CharacterType ch = characters[i];
if (ch == '\\' || ch == '\'') {
buffer[index++] = '\\';
buffer[index++] = ch;
@@ -10610,6 +10921,25 @@ String quoteCSSString(const String& string)
return String::adopt(buffer);
}
+// We use single quotes for now because markup.cpp uses double quotes.
+String quoteCSSString(const String& string)
+{
+ // This function expands each character to at most 3 characters ('\u0010' -> '\' '1' '0') as well as adds
+ // 2 quote characters (before and after). Make sure the resulting size (3 * length + 2) will not overflow unsigned.
+
+ unsigned length = string.length();
+
+ if (!length)
+ return String("\'\'");
+
+ if (length > std::numeric_limits<unsigned>::max() / 3 - 2)
+ return emptyString();
+
+ if (string.is8Bit())
+ return quoteCSSStringInternal(string.characters8(), length);
+ return quoteCSSStringInternal(string.characters16(), length);
+}
+
String quoteCSSStringIfNeeded(const String& string)
{
return isCSSTokenizerIdentifier(string) ? string : quoteCSSString(string);