summaryrefslogtreecommitdiff
path: root/Source/WebCore/css
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-02-03 09:55:33 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-02-03 09:55:33 +0100
commitcd44dc59cdfc39534aef4d417e9f3c412e3be139 (patch)
tree8d89889ba95ed6ec9322e733846cc9cce9d7dff1 /Source/WebCore/css
parentd11f84f5b5cdc0d92a08af01b13472fdd5f9acb9 (diff)
downloadqtwebkit-cd44dc59cdfc39534aef4d417e9f3c412e3be139.tar.gz
Imported WebKit commit fce473cb4d55aa9fe9d0b0322a2fffecb731b961 (http://svn.webkit.org/repository/webkit/trunk@106560)
Diffstat (limited to 'Source/WebCore/css')
-rw-r--r--Source/WebCore/css/CSSAllInOne.cpp3
-rw-r--r--Source/WebCore/css/CSSBorderImage.cpp51
-rw-r--r--Source/WebCore/css/CSSBorderImage.h35
-rw-r--r--Source/WebCore/css/CSSBorderImageValue.cpp81
-rw-r--r--Source/WebCore/css/CSSBorderImageValue.h70
-rwxr-xr-xSource/WebCore/css/CSSCalculationValue.cpp316
-rwxr-xr-xSource/WebCore/css/CSSCalculationValue.h99
-rw-r--r--Source/WebCore/css/CSSCanvasValue.h7
-rw-r--r--Source/WebCore/css/CSSCharsetRule.idl2
-rw-r--r--Source/WebCore/css/CSSComputedStyleDeclaration.cpp174
-rw-r--r--Source/WebCore/css/CSSComputedStyleDeclaration.h43
-rw-r--r--Source/WebCore/css/CSSElementStyleDeclaration.cpp40
-rw-r--r--Source/WebCore/css/CSSElementStyleDeclaration.h61
-rw-r--r--Source/WebCore/css/CSSFontFaceRule.cpp2
-rw-r--r--Source/WebCore/css/CSSFontFaceRule.h3
-rw-r--r--Source/WebCore/css/CSSFontSelector.cpp8
-rw-r--r--Source/WebCore/css/CSSGradientValue.cpp86
-rw-r--r--Source/WebCore/css/CSSInlineStyleDeclaration.h58
-rw-r--r--Source/WebCore/css/CSSMutableStyleDeclaration.cpp218
-rw-r--r--Source/WebCore/css/CSSMutableStyleDeclaration.h148
-rw-r--r--Source/WebCore/css/CSSPageRule.idl2
-rw-r--r--Source/WebCore/css/CSSParser.cpp1870
-rw-r--r--Source/WebCore/css/CSSParser.h69
-rw-r--r--Source/WebCore/css/CSSPrimitiveValue.cpp41
-rw-r--r--Source/WebCore/css/CSSPrimitiveValue.h58
-rw-r--r--Source/WebCore/css/CSSPrimitiveValueMappings.h32
-rw-r--r--Source/WebCore/css/CSSProperty.cpp2
-rw-r--r--Source/WebCore/css/CSSPropertyLonghand.cpp9
-rw-r--r--Source/WebCore/css/CSSPropertyNames.in2
-rw-r--r--Source/WebCore/css/CSSRule.idl2
-rw-r--r--Source/WebCore/css/CSSStyleApplyProperty.cpp191
-rw-r--r--Source/WebCore/css/CSSStyleDeclaration.cpp123
-rw-r--r--Source/WebCore/css/CSSStyleDeclaration.h65
-rw-r--r--Source/WebCore/css/CSSStyleDeclaration.idl4
-rw-r--r--Source/WebCore/css/CSSStyleRule.cpp9
-rw-r--r--Source/WebCore/css/CSSStyleRule.h6
-rw-r--r--Source/WebCore/css/CSSStyleRule.idl2
-rw-r--r--Source/WebCore/css/CSSStyleSelector.cpp1198
-rw-r--r--Source/WebCore/css/CSSStyleSelector.h92
-rw-r--r--Source/WebCore/css/CSSValue.cpp14
-rw-r--r--Source/WebCore/css/CSSValue.h4
-rw-r--r--Source/WebCore/css/CSSValue.idl2
-rw-r--r--Source/WebCore/css/CSSValueKeywords.in23
-rw-r--r--Source/WebCore/css/MediaList.idl2
-rw-r--r--Source/WebCore/css/MediaQueryEvaluator.cpp18
-rw-r--r--Source/WebCore/css/SVGCSSParser.cpp6
-rw-r--r--Source/WebCore/css/SelectorChecker.cpp54
-rw-r--r--Source/WebCore/css/SelectorChecker.h8
-rw-r--r--Source/WebCore/css/StyleSheetList.h5
-rw-r--r--Source/WebCore/css/WebKitCSSKeyframeRule.cpp2
-rw-r--r--Source/WebCore/css/WebKitCSSKeyframeRule.h9
-rw-r--r--Source/WebCore/css/WebKitCSSKeyframesRule.idl2
-rw-r--r--Source/WebCore/css/WebKitCSSRegionRule.cpp5
-rw-r--r--Source/WebCore/css/WebKitCSSRegionRule.h2
-rw-r--r--Source/WebCore/css/WebKitCSSRegionRule.idl37
-rw-r--r--Source/WebCore/css/svg.css5
-rw-r--r--Source/WebCore/css/tokenizer.flex130
57 files changed, 3776 insertions, 1834 deletions
diff --git a/Source/WebCore/css/CSSAllInOne.cpp b/Source/WebCore/css/CSSAllInOne.cpp
index 50901aac7..7d5f250d1 100644
--- a/Source/WebCore/css/CSSAllInOne.cpp
+++ b/Source/WebCore/css/CSSAllInOne.cpp
@@ -26,14 +26,13 @@
// This all-in-one cpp file cuts down on template bloat to allow us to build our Windows release build.
#include "CSSAspectRatioValue.cpp"
+#include "CSSBorderImage.cpp"
#include "CSSBorderImageSliceValue.cpp"
-#include "CSSBorderImageValue.cpp"
#include "CSSCanvasValue.cpp"
#include "CSSCharsetRule.cpp"
#include "CSSComputedStyleDeclaration.cpp"
#include "CSSCrossfadeValue.cpp"
#include "CSSCursorImageValue.cpp"
-#include "CSSElementStyleDeclaration.cpp"
#include "CSSFlexValue.cpp"
#include "CSSFontFace.cpp"
#include "CSSFontFaceRule.cpp"
diff --git a/Source/WebCore/css/CSSBorderImage.cpp b/Source/WebCore/css/CSSBorderImage.cpp
new file mode 100644
index 000000000..ac3e51ef1
--- /dev/null
+++ b/Source/WebCore/css/CSSBorderImage.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "CSSBorderImage.h"
+
+namespace WebCore {
+
+PassRefPtr<CSSValueList> createBorderImageValue(PassRefPtr<CSSValue> image, PassRefPtr<CSSValue> imageSlice, PassRefPtr<CSSValue> borderSlice,
+ PassRefPtr<CSSValue> outset, PassRefPtr<CSSValue> repeat)
+{
+ RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ if (image)
+ list->append(image);
+
+ if (borderSlice || outset) {
+ RefPtr<CSSValueList> listSlash = CSSValueList::createSlashSeparated();
+ if (imageSlice)
+ listSlash->append(imageSlice);
+
+ if (borderSlice)
+ listSlash->append(borderSlice);
+
+ if (outset)
+ listSlash->append(outset);
+
+ list->append(listSlash);
+ } else if (imageSlice)
+ list->append(imageSlice);
+ if (repeat)
+ list->append(repeat);
+ return list.release();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/css/CSSBorderImage.h b/Source/WebCore/css/CSSBorderImage.h
new file mode 100644
index 000000000..b0769f31d
--- /dev/null
+++ b/Source/WebCore/css/CSSBorderImage.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef CSSBorderImage_h
+#define CSSBorderImage_h
+
+#include "CSSBorderImageSliceValue.h"
+#include "CSSValueList.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+PassRefPtr<CSSValueList> createBorderImageValue(PassRefPtr<CSSValue> image, PassRefPtr<CSSValue> imageSlice, PassRefPtr<CSSValue> borderSlice,
+ PassRefPtr<CSSValue> outset, PassRefPtr<CSSValue> repeat);
+
+} // namespace WebCore
+
+#endif // CSSBorderImage_h
diff --git a/Source/WebCore/css/CSSBorderImageValue.cpp b/Source/WebCore/css/CSSBorderImageValue.cpp
deleted file mode 100644
index 846ea6dc5..000000000
--- a/Source/WebCore/css/CSSBorderImageValue.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * (C) 1999-2003 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2008 Apple 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
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "CSSBorderImageValue.h"
-
-#include "PlatformString.h"
-#include "Rect.h"
-
-namespace WebCore {
-
-CSSBorderImageValue::CSSBorderImageValue(PassRefPtr<CSSValue> image, PassRefPtr<CSSBorderImageSliceValue> imageSlice,
- PassRefPtr<CSSValue> borderSlice, PassRefPtr<CSSValue> outset, PassRefPtr<CSSValue> repeat)
- : CSSValue(BorderImageClass)
- , m_image(image)
- , m_imageSlice(imageSlice)
- , m_borderSlice(borderSlice)
- , m_outset(outset)
- , m_repeat(repeat)
-{
-}
-
-String CSSBorderImageValue::customCssText() const
-{
- // Image first.
- String text;
-
- if (m_image)
- text += m_image->cssText();
-
- // Now the slices.
- if (m_imageSlice) {
- if (!text.isEmpty())
- text += " ";
- text += m_imageSlice->cssText();
- }
-
- // Now the border widths.
- if (m_borderSlice) {
- text += " / ";
- text += m_borderSlice->cssText();
- }
-
- if (m_outset) {
- text += " / ";
- text += m_outset->cssText();
- }
-
- if (m_repeat) {
- // Now the keywords.
- if (!text.isEmpty())
- text += " ";
- text += m_repeat->cssText();
- }
-
- return text;
-}
-
-void CSSBorderImageValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const CSSStyleSheet* styleSheet)
-{
- m_image->addSubresourceStyleURLs(urls, styleSheet);
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/css/CSSBorderImageValue.h b/Source/WebCore/css/CSSBorderImageValue.h
deleted file mode 100644
index 675758cc3..000000000
--- a/Source/WebCore/css/CSSBorderImageValue.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * (C) 1999-2003 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2008 Apple 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
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef CSSBorderImageValue_h
-#define CSSBorderImageValue_h
-
-#include "CSSBorderImageSliceValue.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
-class Rect;
-
-class CSSBorderImageValue : public CSSValue {
-public:
- static PassRefPtr<CSSBorderImageValue> create(PassRefPtr<CSSValue> image, PassRefPtr<CSSBorderImageSliceValue> imageSlice,
- PassRefPtr<CSSValue> borderSlice, PassRefPtr<CSSValue> outset, PassRefPtr<CSSValue> repeat)
- {
- return adoptRef(new CSSBorderImageValue(image, imageSlice, borderSlice, outset, repeat));
- }
-
- String customCssText() const;
-
- CSSValue* imageValue() const { return m_image.get(); }
-
- void addSubresourceStyleURLs(ListHashSet<KURL>&, const CSSStyleSheet*);
-
- // The border image.
- RefPtr<CSSValue> m_image;
-
- // These four values are used to make "cuts" in the image. They can be numbers
- // or percentages.
- RefPtr<CSSBorderImageSliceValue> m_imageSlice;
-
- // These four values are used to make "cuts" in the border image drawing area.
- // They can be numbers, percentages or lengths.
- RefPtr<CSSValue> m_borderSlice;
-
- // The outset values are used to inflate the border image drawing area.
- RefPtr<CSSValue> m_outset;
-
- // Values for how to handle the scaling/stretching/tiling of the image slices.
- RefPtr<CSSValue> m_repeat;
-
-private:
- CSSBorderImageValue(PassRefPtr<CSSValue> image, PassRefPtr<CSSBorderImageSliceValue>, PassRefPtr<CSSValue> borderSlice,
- PassRefPtr<CSSValue> outset, PassRefPtr<CSSValue> repeat);
-};
-
-} // namespace WebCore
-
-#endif // CSSBorderImageValue_h
diff --git a/Source/WebCore/css/CSSCalculationValue.cpp b/Source/WebCore/css/CSSCalculationValue.cpp
new file mode 100755
index 000000000..11907f280
--- /dev/null
+++ b/Source/WebCore/css/CSSCalculationValue.cpp
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CSSCalculationValue.h"
+
+#include "CSSStyleSelector.h"
+#include "CSSValueList.h"
+#include "Length.h"
+
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/text/StringBuilder.h>
+
+static const int maxExpressionDepth = 100;
+
+enum ParseState {
+ OK,
+ TooDeep,
+ NoMoreTokens
+};
+
+namespace WebCore {
+
+static CalculationCategory unitCategory(CSSPrimitiveValue::UnitTypes type)
+{
+ switch (type) {
+ case CSSPrimitiveValue::CSS_NUMBER:
+ case CSSPrimitiveValue::CSS_PARSER_INTEGER:
+ return CalcNumber;
+ case CSSPrimitiveValue::CSS_PERCENTAGE:
+ return CalcPercent;
+ case CSSPrimitiveValue::CSS_EMS:
+ case CSSPrimitiveValue::CSS_EXS:
+ case CSSPrimitiveValue::CSS_PX:
+ case CSSPrimitiveValue::CSS_CM:
+ case CSSPrimitiveValue::CSS_MM:
+ case CSSPrimitiveValue::CSS_IN:
+ case CSSPrimitiveValue::CSS_PT:
+ case CSSPrimitiveValue::CSS_PC:
+ case CSSPrimitiveValue::CSS_REMS:
+ return CalcLength;
+ default:
+ return CalcOther;
+ }
+}
+
+String CSSCalcValue::customCssText() const
+{
+ return "";
+}
+
+CSSCalcExpressionNode::~CSSCalcExpressionNode()
+{
+}
+
+class CSSCalcPrimitiveValue : public CSSCalcExpressionNode {
+public:
+
+ static PassRefPtr<CSSCalcPrimitiveValue> create(CSSPrimitiveValue* value, bool isInteger)
+ {
+ return adoptRef(new CSSCalcPrimitiveValue(value, isInteger));
+ }
+
+ virtual String cssText() const
+ {
+ return m_value->cssText();
+ }
+
+
+private:
+ explicit CSSCalcPrimitiveValue(CSSPrimitiveValue* value, bool isInteger)
+ : CSSCalcExpressionNode(unitCategory((CSSPrimitiveValue::UnitTypes)value->primitiveType()), isInteger)
+ , m_value(value)
+ {
+ }
+
+ RefPtr<CSSPrimitiveValue> m_value;
+};
+
+static const CalculationCategory addSubtractResult[CalcOther][CalcOther] = {
+ { CalcNumber, CalcOther, CalcPercentNumber, CalcPercentNumber, CalcOther },
+ { CalcOther, CalcLength, CalcPercentLength, CalcOther, CalcPercentLength },
+ { CalcPercentNumber, CalcPercentLength, CalcPercent, CalcPercentNumber, CalcPercentLength },
+ { CalcPercentNumber, CalcOther, CalcPercentNumber, CalcPercentNumber, CalcOther },
+ { CalcOther, CalcPercentLength, CalcPercentLength, CalcOther, CalcPercentLength },
+};
+
+class CSSCalcBinaryOperation : public CSSCalcExpressionNode {
+public:
+ static PassRefPtr<CSSCalcBinaryOperation> create(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op)
+ {
+ CalculationCategory leftCategory = leftSide->category();
+ CalculationCategory rightCategory = rightSide->category();
+ CalculationCategory newCategory = CalcOther;
+
+ ASSERT(leftCategory != CalcOther && rightCategory != CalcOther);
+
+ switch (op) {
+ case CalcAdd:
+ case CalcSubtract:
+ if (leftCategory == CalcOther || rightCategory == CalcOther)
+ return 0;
+ newCategory = addSubtractResult[leftCategory][rightCategory];
+ break;
+
+ case CalcMultiply:
+ if (leftCategory != CalcNumber && rightCategory != CalcNumber)
+ return 0;
+
+ newCategory = leftCategory == CalcNumber ? rightCategory : leftCategory;
+ break;
+
+ case CalcDivide:
+ case CalcMod:
+ if (rightCategory != CalcNumber || rightSide->isZero())
+ return 0;
+ newCategory = leftCategory;
+ break;
+ }
+
+ if (newCategory == CalcOther)
+ return 0;
+
+ return adoptRef(new CSSCalcBinaryOperation(leftSide, rightSide, op, newCategory));
+ }
+
+private:
+ CSSCalcBinaryOperation(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op, CalculationCategory category)
+ : CSSCalcExpressionNode(category, leftSide->isInteger() && rightSide->isInteger())
+ , m_leftSide(leftSide)
+ , m_rightSide(rightSide)
+ , m_operator(op)
+ {
+ }
+
+ const RefPtr<CSSCalcExpressionNode> m_leftSide;
+ const RefPtr<CSSCalcExpressionNode> m_rightSide;
+ const CalcOperator m_operator;
+};
+
+static ParseState checkDepthAndIndex(int* depth, unsigned index, CSSParserValueList* tokens)
+{
+ (*depth)++;
+ if (*depth > maxExpressionDepth)
+ return TooDeep;
+ if (index >= tokens->size())
+ return NoMoreTokens;
+ return OK;
+}
+
+class CSSCalcExpressionNodeParser {
+public:
+ PassRefPtr<CSSCalcExpressionNode> parseCalc(CSSParserValueList* tokens)
+ {
+ unsigned index = 0;
+ Value result;
+ bool ok = parseValueExpression(tokens, 0, &index, &result);
+ ASSERT(index <= tokens->size());
+ if (!ok || index != tokens->size())
+ return 0;
+ return result.value;
+ }
+
+private:
+ struct Value {
+ RefPtr<CSSCalcExpressionNode> value;
+ };
+
+ char operatorValue(CSSParserValueList* tokens, unsigned index)
+ {
+ if (index >= tokens->size())
+ return 0;
+ CSSParserValue* value = tokens->valueAt(index);
+ if (value->unit != CSSParserValue::Operator)
+ return 0;
+
+ return value->iValue;
+ }
+
+ bool parseValue(CSSParserValueList* tokens, unsigned* index, Value* result)
+ {
+ CSSParserValue* parserValue = tokens->valueAt(*index);
+ if (parserValue->unit == CSSParserValue::Operator || parserValue->unit == CSSParserValue::Function)
+ return false;
+
+ RefPtr<CSSValue> value = parserValue->createCSSValue();
+ if (!value || !value->isPrimitiveValue())
+ return false;
+
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value.get());
+ result->value = CSSCalcPrimitiveValue::create(primitiveValue, parserValue->isInt);
+
+ ++*index;
+ return true;
+ }
+
+ bool parseValueTerm(CSSParserValueList* tokens, int depth, unsigned* index, Value* result)
+ {
+ if (checkDepthAndIndex(&depth, *index, tokens) != OK)
+ return false;
+
+ if (operatorValue(tokens, *index) == '(') {
+ unsigned currentIndex = *index + 1;
+ if (!parseValueExpression(tokens, depth, &currentIndex, result))
+ return false;
+
+ if (operatorValue(tokens, currentIndex) != ')')
+ return false;
+ *index = currentIndex + 1;
+ return true;
+ }
+
+ return parseValue(tokens, index, result);
+ }
+
+ bool parseValueMultiplicativeExpression(CSSParserValueList* tokens, int depth, unsigned* index, Value* result)
+ {
+ if (checkDepthAndIndex(&depth, *index, tokens) != OK)
+ return false;
+
+ if (!parseValueTerm(tokens, depth, index, result))
+ return false;
+
+ while (*index < tokens->size() - 1) {
+ char operatorCharacter = operatorValue(tokens, *index);
+ if (operatorCharacter != CalcMultiply && operatorCharacter != CalcDivide && operatorCharacter != CalcMod)
+ break;
+ ++*index;
+
+ Value rhs;
+ if (!parseValueTerm(tokens, depth, index, &rhs))
+ return false;
+
+ result->value = CSSCalcBinaryOperation::create(result->value, rhs.value, static_cast<CalcOperator>(operatorCharacter));
+ if (!result->value)
+ return false;
+ }
+
+ ASSERT(*index <= tokens->size());
+ return true;
+ }
+
+ bool parseAdditiveValueExpression(CSSParserValueList* tokens, int depth, unsigned* index, Value* result)
+ {
+ if (checkDepthAndIndex(&depth, *index, tokens) != OK)
+ return false;
+
+ if (!parseValueMultiplicativeExpression(tokens, depth, index, result))
+ return false;
+
+ while (*index < tokens->size() - 1) {
+ char operatorCharacter = operatorValue(tokens, *index);
+ if (operatorCharacter != CalcAdd && operatorCharacter != CalcSubtract)
+ break;
+ ++*index;
+
+ Value rhs;
+ if (!parseValueMultiplicativeExpression(tokens, depth, index, &rhs))
+ return false;
+
+ result->value = CSSCalcBinaryOperation::create(result->value, rhs.value, static_cast<CalcOperator>(operatorCharacter));
+ if (!result->value)
+ return false;
+ }
+
+ ASSERT(*index <= tokens->size());
+ return true;
+ }
+
+ bool parseValueExpression(CSSParserValueList* tokens, int depth, unsigned* index, Value* result)
+ {
+ return parseAdditiveValueExpression(tokens, depth, index, result);
+ }
+};
+
+PassRefPtr<CSSCalcValue> CSSCalcValue::create(CSSParserString name, CSSParserValueList* parserValueList)
+{
+ CSSCalcExpressionNodeParser parser;
+ RefPtr<CSSCalcExpressionNode> expression;
+
+ if (equalIgnoringCase(name, "-webkit-calc("))
+ expression = parser.parseCalc(parserValueList);
+ // FIXME calc (http://webkit.org/b/16662) Add parsing for min and max here
+
+ return expression ? adoptRef(new CSSCalcValue(expression)) : 0;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/css/CSSCalculationValue.h b/Source/WebCore/css/CSSCalculationValue.h
new file mode 100755
index 000000000..4d4639d11
--- /dev/null
+++ b/Source/WebCore/css/CSSCalculationValue.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CSSCalculationValue_h
+#define CSSCalculationValue_h
+
+#include "CSSParserValues.h"
+#include "CSSValue.h"
+#include "CalculationValue.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSParserValueList;
+class CSSValueList;
+class RenderStyle;
+class CalcValue;
+class CalcExpressionNode;
+
+enum CalculationCategory {
+ CalcNumber = 0,
+ CalcLength,
+ CalcPercent,
+ CalcPercentNumber,
+ CalcPercentLength,
+ CalcOther
+};
+
+class CSSCalcExpressionNode : public RefCounted<CSSCalcExpressionNode> {
+public:
+
+ virtual ~CSSCalcExpressionNode() = 0;
+
+ CalculationCategory category() const { return m_category; }
+ bool isInteger() const { return m_isInteger; }
+ bool isZero() const { return false; }
+
+protected:
+ CSSCalcExpressionNode(CalculationCategory category, bool isInteger)
+ : m_category(category)
+ , m_isInteger(isInteger)
+ {
+ }
+
+ CalculationCategory m_category;
+ bool m_isInteger;
+};
+
+class CSSCalcValue : public CSSValue {
+public:
+ static PassRefPtr<CSSCalcValue> create(CSSParserString name, CSSParserValueList*);
+
+ CalculationCategory category() const { return m_expression->category(); }
+ bool isInt() const { return m_expression->isInteger(); }
+
+ String customCssText() const;
+
+private:
+ CSSCalcValue(PassRefPtr<CSSCalcExpressionNode> expression)
+ : CSSValue(CalculationClass)
+ , m_expression(expression)
+ {
+ }
+
+ const RefPtr<CSSCalcExpressionNode> m_expression;
+};
+
+} // namespace WebCore
+
+#endif // CSSCalculationValue_h
diff --git a/Source/WebCore/css/CSSCanvasValue.h b/Source/WebCore/css/CSSCanvasValue.h
index efad7e692..159e61956 100644
--- a/Source/WebCore/css/CSSCanvasValue.h
+++ b/Source/WebCore/css/CSSCanvasValue.h
@@ -35,7 +35,7 @@ class Document;
class CSSCanvasValue : public CSSImageGeneratorValue {
public:
- static PassRefPtr<CSSCanvasValue> create() { return adoptRef(new CSSCanvasValue); }
+ static PassRefPtr<CSSCanvasValue> create(const String& name) { return adoptRef(new CSSCanvasValue(name)); }
~CSSCanvasValue();
String customCssText() const;
@@ -47,12 +47,11 @@ public:
bool isPending() const { return false; }
void loadSubimages(CachedResourceLoader*) { }
- void setName(const String& name) { m_name = name; }
-
private:
- CSSCanvasValue()
+ CSSCanvasValue(const String& name)
: CSSImageGeneratorValue(CanvasClass)
, m_canvasObserver(this)
+ , m_name(name)
, m_element(0)
{
}
diff --git a/Source/WebCore/css/CSSCharsetRule.idl b/Source/WebCore/css/CSSCharsetRule.idl
index 2b158ff8b..87f796aff 100644
--- a/Source/WebCore/css/CSSCharsetRule.idl
+++ b/Source/WebCore/css/CSSCharsetRule.idl
@@ -25,7 +25,7 @@ module css {
#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
readonly attribute [ConvertNullStringTo=Null] DOMString encoding;
#else
- attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString encoding
+ attribute [ConvertNullStringTo=Null, TreatNullAs=EmptyString] DOMString encoding
setter raises(DOMException);
#endif
};
diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp
index 112abbe83..90f98c8d3 100644
--- a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp
+++ b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp
@@ -26,9 +26,10 @@
#include "AnimationController.h"
#include "CSSAspectRatioValue.h"
-#include "CSSBorderImageValue.h"
+#include "CSSBorderImage.h"
#include "CSSLineBoxContainValue.h"
#include "CSSMutableStyleDeclaration.h"
+#include "CSSParser.h"
#include "CSSPrimitiveValue.h"
#include "CSSPrimitiveValueMappings.h"
#include "CSSProperty.h"
@@ -42,7 +43,9 @@
#include "CounterContent.h"
#include "CursorList.h"
#if ENABLE(CSS_SHADERS)
+#include "CustomFilterNumberParameter.h"
#include "CustomFilterOperation.h"
+#include "CustomFilterParameter.h"
#endif
#include "Document.h"
#include "ExceptionCode.h"
@@ -56,6 +59,7 @@
#include "RenderStyle.h"
#include "ShadowValue.h"
#if ENABLE(CSS_FILTERS)
+#include "StyleCustomFilterProgram.h"
#include "WebKitCSSFilterValue.h"
#endif
#include "WebKitCSSTransformValue.h"
@@ -217,12 +221,14 @@ static const int computedProperties[] = {
#endif
CSSPropertyWebkitFlexOrder,
CSSPropertyWebkitFlexPack,
+ CSSPropertyWebkitFlexAlign,
CSSPropertyWebkitFlexItemAlign,
CSSPropertyWebkitFlexDirection,
CSSPropertyWebkitFlexFlow,
CSSPropertyWebkitFlexWrap,
CSSPropertyWebkitFontKerning,
CSSPropertyWebkitFontSmoothing,
+ CSSPropertyWebkitFontVariantLigatures,
#if ENABLE(CSS_GRID_LAYOUT)
CSSPropertyWebkitGridColumns,
CSSPropertyWebkitGridRows,
@@ -496,7 +502,7 @@ static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image,
// Create the repeat rules.
RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image, cssValuePool);
- return CSSBorderImageValue::create(imageValue.release(), imageSlices.release(), borderSlices.release(), outset.release(), repeat);
+ return createBorderImageValue(imageValue, imageSlices, borderSlices, outset, repeat);
}
inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(int value, const RenderStyle* style, CSSValuePool* cssValuePool)
@@ -710,6 +716,30 @@ static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const Rend
return list.release();
}
+#if ENABLE(CSS_SHADERS)
+PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForCustomFilterNumberParameter(const CustomFilterNumberParameter* numberParameter) const
+{
+ RefPtr<CSSValueList> numberParameterValue = CSSValueList::createSpaceSeparated();
+ CSSValuePool* cssValuePool = m_node->document()->cssValuePool().get();
+ for (unsigned i = 0; i < numberParameter->size(); ++i)
+ numberParameterValue->append(cssValuePool->createValue(numberParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER));
+ return numberParameterValue.release();
+}
+
+PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForCustomFilterParameter(const CustomFilterParameter* parameter) const
+{
+ // FIXME: Add here computed style for the other types: boolean, transform, matrix, texture.
+ ASSERT(parameter);
+ switch (parameter->parameterType()) {
+ case CustomFilterParameter::NUMBER:
+ return valueForCustomFilterNumberParameter(static_cast<const CustomFilterNumberParameter*>(parameter));
+ }
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+#endif // ENABLE(CSS_SHADERS)
+
#if ENABLE(CSS_FILTERS)
PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(RenderStyle* style) const
{
@@ -801,13 +831,16 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(RenderStyle* st
// The output should be verbose, even if the values are the default ones.
+ ASSERT(customOperation->program());
+ StyleCustomFilterProgram* program = static_cast<StyleCustomFilterProgram*>(customOperation->program());
+
RefPtr<CSSValueList> shadersList = CSSValueList::createSpaceSeparated();
- if (customOperation->vertexShader())
- shadersList->append(customOperation->vertexShader()->cssValue());
+ if (program->vertexShader())
+ shadersList->append(program->vertexShader()->cssValue());
else
shadersList->append(cssValuePool->createIdentifierValue(CSSValueNone));
- if (customOperation->fragmentShader())
- shadersList->append(customOperation->fragmentShader()->cssValue());
+ if (program->fragmentShader())
+ shadersList->append(program->fragmentShader()->cssValue());
else
shadersList->append(cssValuePool->createIdentifierValue(CSSValueNone));
filterValue->append(shadersList.release());
@@ -824,6 +857,20 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(RenderStyle* st
filterValue->append(meshParameters.release());
+ const CustomFilterParameterList& parameters = customOperation->parameters();
+ size_t parametersSize = parameters.size();
+ if (!parametersSize)
+ break;
+ RefPtr<CSSValueList> parametersCSSValue = CSSValueList::createCommaSeparated();
+ for (size_t i = 0; i < parametersSize; ++i) {
+ const CustomFilterParameter* parameter = parameters.at(i).get();
+ RefPtr<CSSValueList> parameterCSSNameAndValue = CSSValueList::createSpaceSeparated();
+ parameterCSSNameAndValue->append(cssValuePool->createValue(parameter->name(), CSSPrimitiveValue::CSS_STRING));
+ parameterCSSNameAndValue->append(valueForCustomFilterParameter(parameter));
+ parametersCSSValue->append(parameterCSSNameAndValue.release());
+ }
+
+ filterValue->append(parametersCSSValue.release());
break;
}
#endif
@@ -1521,7 +1568,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
return cssValuePool->createValue(style->flexOrder(), CSSPrimitiveValue::CSS_NUMBER);
case CSSPropertyWebkitFlexPack:
return cssValuePool->createValue(style->flexPack());
+ case CSSPropertyWebkitFlexAlign:
+ return cssValuePool->createValue(style->flexAlign());
case CSSPropertyWebkitFlexItemAlign:
+ // FIXME: If flex-item-align:auto, then we should return the parent's flex-align.
+ // http://webkit.org/b/76326
return cssValuePool->createValue(style->flexItemAlign());
case CSSPropertyWebkitFlexDirection:
return cssValuePool->createValue(style->flexDirection());
@@ -1871,6 +1922,23 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
return cssValuePool->createValue(style->fontDescription().kerning());
case CSSPropertyWebkitFontSmoothing:
return cssValuePool->createValue(style->fontDescription().fontSmoothing());
+ case CSSPropertyWebkitFontVariantLigatures: {
+ FontDescription::LigaturesState commonLigaturesState = style->fontDescription().commonLigaturesState();
+ FontDescription::LigaturesState discretionaryLigaturesState = style->fontDescription().discretionaryLigaturesState();
+ FontDescription::LigaturesState historicalLigaturesState = style->fontDescription().historicalLigaturesState();
+ if (commonLigaturesState == FontDescription::NormalLigaturesState && discretionaryLigaturesState == FontDescription::NormalLigaturesState
+ && historicalLigaturesState == FontDescription::NormalLigaturesState)
+ return cssValuePool->createIdentifierValue(CSSValueNormal);
+
+ RefPtr<CSSValueList> valueList = CSSValueList::createSpaceSeparated();
+ if (commonLigaturesState != FontDescription::NormalLigaturesState)
+ valueList->append(cssValuePool->createIdentifierValue(commonLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoCommonLigatures : CSSValueCommonLigatures));
+ if (discretionaryLigaturesState != FontDescription::NormalLigaturesState)
+ valueList->append(cssValuePool->createIdentifierValue(discretionaryLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures));
+ if (historicalLigaturesState != FontDescription::NormalLigaturesState)
+ valueList->append(cssValuePool->createIdentifierValue(historicalLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures));
+ return valueList;
+ }
case CSSPropertyZIndex:
if (style->hasAutoZIndex())
return cssValuePool->createIdentifierValue(CSSValueAuto);
@@ -2408,24 +2476,8 @@ String CSSComputedStyleDeclaration::getPropertyValue(int propertyID) const
return "";
}
-bool CSSComputedStyleDeclaration::getPropertyPriority(int /*propertyID*/) const
-{
- // All computed styles have a priority of false (not "important").
- return false;
-}
-
-String CSSComputedStyleDeclaration::removeProperty(int /*propertyID*/, ExceptionCode& ec)
-{
- ec = NO_MODIFICATION_ALLOWED_ERR;
- return String();
-}
-
-void CSSComputedStyleDeclaration::setProperty(int /*propertyID*/, const String& /*value*/, bool /*important*/, ExceptionCode& ec)
-{
- ec = NO_MODIFICATION_ALLOWED_ERR;
-}
-unsigned CSSComputedStyleDeclaration::virtualLength() const
+unsigned CSSComputedStyleDeclaration::length() const
{
Node* node = m_node.get();
if (!node)
@@ -2454,12 +2506,12 @@ bool CSSComputedStyleDeclaration::cssPropertyMatches(const CSSProperty* property
if (style && style->fontDescription().keywordSize()) {
int sizeValue = cssIdentifierForFontSizeKeyword(style->fontDescription().keywordSize());
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(property->value());
- if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_IDENT && primitiveValue->getIdent() == sizeValue)
+ if (primitiveValue->isIdent() && primitiveValue->getIdent() == sizeValue)
return true;
}
}
-
- return CSSStyleDeclaration::cssPropertyMatches(property);
+ RefPtr<CSSValue> value = getPropertyCSSValue(property->id());
+ return value && value->cssText() == property->value()->cssText();
}
PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::copy() const
@@ -2510,4 +2562,74 @@ PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForSid
return list.release();
}
+PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::copyPropertiesInSet(const int* set, unsigned length) const
+{
+ Vector<CSSProperty> list;
+ list.reserveInitialCapacity(length);
+ for (unsigned i = 0; i < length; ++i) {
+ RefPtr<CSSValue> value = getPropertyCSSValue(set[i]);
+ if (value)
+ list.append(CSSProperty(set[i], value.release(), false));
+ }
+ return CSSMutableStyleDeclaration::create(list);
+}
+
+PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName)
+{
+ int propertyID = cssPropertyID(propertyName);
+ if (!propertyID)
+ return 0;
+ return getPropertyCSSValue(propertyID);
+}
+
+String CSSComputedStyleDeclaration::getPropertyValue(const String &propertyName)
+{
+ int propertyID = cssPropertyID(propertyName);
+ if (!propertyID)
+ return String();
+ return getPropertyValue(propertyID);
+}
+
+String CSSComputedStyleDeclaration::getPropertyPriority(const String&)
+{
+ // All computed styles have a priority of not "important".
+ return "";
+}
+
+String CSSComputedStyleDeclaration::getPropertyShorthand(const String&)
+{
+ return "";
+}
+
+bool CSSComputedStyleDeclaration::isPropertyImplicit(const String&)
+{
+ return false;
+}
+
+void CSSComputedStyleDeclaration::setProperty(const String&, const String&, const String&, ExceptionCode& ec)
+{
+ ec = NO_MODIFICATION_ALLOWED_ERR;
+}
+
+String CSSComputedStyleDeclaration::removeProperty(const String&, ExceptionCode& ec)
+{
+ ec = NO_MODIFICATION_ALLOWED_ERR;
+ return String();
+}
+
+PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
+{
+ return getPropertyCSSValue(propertyID);
+}
+
+String CSSComputedStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID)
+{
+ return getPropertyValue(propertyID);
+}
+
+void CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const String&, bool, ExceptionCode& ec)
+{
+ ec = NO_MODIFICATION_ALLOWED_ERR;
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.h b/Source/WebCore/css/CSSComputedStyleDeclaration.h
index 6ef90af6e..b44a5cff0 100644
--- a/Source/WebCore/css/CSSComputedStyleDeclaration.h
+++ b/Source/WebCore/css/CSSComputedStyleDeclaration.h
@@ -38,6 +38,11 @@ class RenderStyle;
class ShadowData;
class SVGPaint;
+#if ENABLE(CSS_SHADERS)
+class CustomFilterNumberParameter;
+class CustomFilterParameter;
+#endif
+
enum EUpdateLayout { DoNotUpdateLayout = false, UpdateLayout = true };
class CSSComputedStyleDeclaration : public CSSStyleDeclaration {
@@ -45,16 +50,9 @@ public:
friend PassRefPtr<CSSComputedStyleDeclaration> computedStyle(PassRefPtr<Node>, bool allowVisitedStyle, const String& pseudoElementName);
virtual ~CSSComputedStyleDeclaration();
- virtual String cssText() const;
-
- virtual unsigned virtualLength() const;
- virtual String item(unsigned index) const;
-
- virtual PassRefPtr<CSSValue> getPropertyCSSValue(int propertyID) const;
- virtual String getPropertyValue(int propertyID) const;
- virtual bool getPropertyPriority(int propertyID) const;
- virtual int getPropertyShorthand(int /*propertyID*/) const { return -1; }
- virtual bool isPropertyImplicit(int /*propertyID*/) const { return false; }
+ PassRefPtr<CSSValue> getPropertyCSSValue(int propertyID) const;
+ String getPropertyValue(int propertyID) const;
+ bool getPropertyPriority(int propertyID) const;
virtual PassRefPtr<CSSMutableStyleDeclaration> copy() const;
virtual PassRefPtr<CSSMutableStyleDeclaration> makeMutable();
@@ -66,16 +64,28 @@ public:
PassRefPtr<CSSValue> getSVGPropertyCSSValue(int propertyID, EUpdateLayout) const;
#endif
-protected:
- virtual bool cssPropertyMatches(const CSSProperty*) const;
+ PassRefPtr<CSSMutableStyleDeclaration> copyPropertiesInSet(const int* set, unsigned length) const;
private:
CSSComputedStyleDeclaration(PassRefPtr<Node>, bool allowVisitedStyle, const String&);
+ // CSSOM functions. Don't make these public.
+ virtual unsigned length() const;
+ virtual String item(unsigned index) const;
+ virtual PassRefPtr<CSSValue> getPropertyCSSValue(const String& propertyName);
+ virtual String getPropertyValue(const String& propertyName);
+ virtual String getPropertyPriority(const String& propertyName);
+ virtual String getPropertyShorthand(const String& propertyName);
+ virtual bool isPropertyImplicit(const String& propertyName);
+ virtual void setProperty(const String& propertyName, const String& value, const String& priority, ExceptionCode&);
+ virtual String removeProperty(const String& propertyName, ExceptionCode&);
+ virtual String cssText() const;
virtual void setCssText(const String&, ExceptionCode&);
+ virtual PassRefPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID);
+ virtual String getPropertyValueInternal(CSSPropertyID);
+ virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionCode&);
- virtual String removeProperty(int propertyID, ExceptionCode&);
- virtual void setProperty(int propertyId, const String& value, bool important, ExceptionCode&);
+ virtual bool cssPropertyMatches(const CSSProperty*) const;
PassRefPtr<CSSValue> valueForShadow(const ShadowData*, int, RenderStyle*) const;
PassRefPtr<CSSPrimitiveValue> currentColorOrValidColor(RenderStyle*, const Color&) const;
@@ -83,6 +93,11 @@ private:
PassRefPtr<SVGPaint> adjustSVGPaintForCurrentColor(PassRefPtr<SVGPaint>, RenderStyle*) const;
#endif
+#if ENABLE(CSS_SHADERS)
+ PassRefPtr<CSSValue> valueForCustomFilterNumberParameter(const CustomFilterNumberParameter*) const;
+ PassRefPtr<CSSValue> valueForCustomFilterParameter(const CustomFilterParameter*) const;
+#endif
+
#if ENABLE(CSS_FILTERS)
PassRefPtr<CSSValue> valueForFilter(RenderStyle*) const;
#endif
diff --git a/Source/WebCore/css/CSSElementStyleDeclaration.cpp b/Source/WebCore/css/CSSElementStyleDeclaration.cpp
deleted file mode 100644
index 81782619c..000000000
--- a/Source/WebCore/css/CSSElementStyleDeclaration.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "CSSElementStyleDeclaration.h"
-
-#include "StyledElement.h"
-
-namespace WebCore {
-
-CSSStyleSheet* CSSElementStyleDeclaration::styleSheet() const
-{
- if (m_element && m_element->document())
- return m_element->document()->elementSheet();
- return 0;
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/css/CSSElementStyleDeclaration.h b/Source/WebCore/css/CSSElementStyleDeclaration.h
deleted file mode 100644
index 71ca518d5..000000000
--- a/Source/WebCore/css/CSSElementStyleDeclaration.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CSSElementStyleDeclaration_h
-#define CSSElementStyleDeclaration_h
-
-#include "CSSMutableStyleDeclaration.h"
-
-namespace WebCore {
-
-class StyledElement;
-
-// Base class for CSSInlineStyleDeclaration and FontFaceStyleDeclaration (SVG).
-
-class CSSElementStyleDeclaration : public CSSMutableStyleDeclaration {
-public:
- StyledElement* element() const { return m_element; }
- void clearElement() { m_element = 0; }
-
- virtual CSSStyleSheet* styleSheet() const;
-
-protected:
- CSSElementStyleDeclaration(StyledElement* element, bool isInline)
- : CSSMutableStyleDeclaration()
- , m_element(element)
- {
- m_isElementStyleDeclaration = true;
- m_isInlineStyleDeclaration = isInline;
- }
-
- virtual ~CSSElementStyleDeclaration() { }
-
-private:
- StyledElement* m_element;
-};
-
-} // namespace WebCore
-
-#endif // CSSElementStyleDeclaration_h
diff --git a/Source/WebCore/css/CSSFontFaceRule.cpp b/Source/WebCore/css/CSSFontFaceRule.cpp
index b4c697662..53d605dbd 100644
--- a/Source/WebCore/css/CSSFontFaceRule.cpp
+++ b/Source/WebCore/css/CSSFontFaceRule.cpp
@@ -41,7 +41,7 @@ String CSSFontFaceRule::cssText() const
{
String result("@font-face");
result += " { ";
- result += m_style->cssText();
+ result += m_style->asText();
result += "}";
return result;
}
diff --git a/Source/WebCore/css/CSSFontFaceRule.h b/Source/WebCore/css/CSSFontFaceRule.h
index 3d1f76cf3..545c90a63 100644
--- a/Source/WebCore/css/CSSFontFaceRule.h
+++ b/Source/WebCore/css/CSSFontFaceRule.h
@@ -42,10 +42,11 @@ public:
~CSSFontFaceRule();
- CSSMutableStyleDeclaration* style() const { return m_style.get(); }
+ CSSStyleDeclaration* style() const { return m_style.get(); }
String cssText() const;
+ CSSMutableStyleDeclaration* declaration() const { return m_style.get(); }
void setDeclaration(PassRefPtr<CSSMutableStyleDeclaration> style) { m_style = style; }
void addSubresourceStyleURLs(ListHashSet<KURL>& urls);
diff --git a/Source/WebCore/css/CSSFontSelector.cpp b/Source/WebCore/css/CSSFontSelector.cpp
index 4c90ae3d7..b13fffdda 100644
--- a/Source/WebCore/css/CSSFontSelector.cpp
+++ b/Source/WebCore/css/CSSFontSelector.cpp
@@ -86,7 +86,7 @@ bool CSSFontSelector::isEmpty() const
void CSSFontSelector::addFontFaceRule(const CSSFontFaceRule* fontFaceRule)
{
// Obtain the font-family property and the src property. Both must be defined.
- const CSSMutableStyleDeclaration* style = fontFaceRule->style();
+ const CSSMutableStyleDeclaration* style = fontFaceRule->declaration();
RefPtr<CSSValue> fontFamily = style->getPropertyCSSValue(CSSPropertyFontFamily);
RefPtr<CSSValue> src = style->getPropertyCSSValue(CSSPropertySrc);
RefPtr<CSSValue> unicodeRange = style->getPropertyCSSValue(CSSPropertyUnicodeRange);
@@ -285,9 +285,9 @@ void CSSFontSelector::addFontFaceRule(const CSSFontFaceRule* fontFaceRule)
for (int i = 0; i < familyLength; i++) {
CSSPrimitiveValue* item = static_cast<CSSPrimitiveValue*>(familyList->itemWithoutBoundsCheck(i));
String familyName;
- if (item->primitiveType() == CSSPrimitiveValue::CSS_STRING)
+ if (item->isString())
familyName = static_cast<FontFamilyValue*>(item)->familyName();
- else if (item->primitiveType() == CSSPrimitiveValue::CSS_IDENT) {
+ else if (item->isIdent()) {
// We need to use the raw text for all the generic family types, since @font-face is a way of actually
// defining what font to use for those types.
String familyName;
@@ -615,6 +615,8 @@ void CSSFontSelector::beginLoadTimerFired(Timer<WebCore::CSSFontSelector>*)
// Balances incrementRequestCount() in beginLoadingFontSoon().
cachedResourceLoader->decrementRequestCount(fontsToBeginLoading[i].get());
}
+ // Ensure that if the request count reaches zero, the frame loader will know about it.
+ cachedResourceLoader->loadDone();
}
}
diff --git a/Source/WebCore/css/CSSGradientValue.cpp b/Source/WebCore/css/CSSGradientValue.cpp
index 41977fb03..d8d7253d1 100644
--- a/Source/WebCore/css/CSSGradientValue.cpp
+++ b/Source/WebCore/css/CSSGradientValue.cpp
@@ -117,7 +117,7 @@ void CSSGradientValue::addStops(Gradient* gradient, RenderObject* renderer, Rend
Color color = renderer->document()->styleSelector()->colorFromPrimitiveValue(stop.m_color.get());
float offset;
- if (stop.m_position->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ if (stop.m_position->isPercentage())
offset = stop.m_position->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE) / 100;
else
offset = stop.m_position->getFloatValue(CSSPrimitiveValue::CSS_NUMBER);
@@ -150,10 +150,9 @@ void CSSGradientValue::addStops(Gradient* gradient, RenderObject* renderer, Rend
stops[i].color = renderer->document()->styleSelector()->colorFromPrimitiveValue(stop.m_color.get());
if (stop.m_position) {
- int type = stop.m_position->primitiveType();
- if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ if (stop.m_position->isPercentage())
stops[i].offset = stop.m_position->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE) / 100;
- else if (CSSPrimitiveValue::isUnitTypeLength(type)) {
+ else if (stop.m_position->isLength()) {
float length = stop.m_position->computeLength<float>(style, rootStyle, style->effectiveZoom());
if (!computedGradientLength) {
FloatSize gradientSize(gradientStart - gradientEnd);
@@ -363,32 +362,28 @@ static float positionFromValue(CSSPrimitiveValue* value, RenderStyle* style, Ren
{
float zoomFactor = style->effectiveZoom();
- switch (value->primitiveType()) {
- case CSSPrimitiveValue::CSS_NUMBER:
+ if (value->isNumber())
return value->getFloatValue() * zoomFactor;
- case CSSPrimitiveValue::CSS_PERCENTAGE:
+ if (value->isPercentage())
return value->getFloatValue() / 100.f * (isHorizontal ? size.width() : size.height());
- case CSSPrimitiveValue::CSS_IDENT:
- switch (value->getIdent()) {
- case CSSValueTop:
- ASSERT(!isHorizontal);
- return 0;
- case CSSValueLeft:
- ASSERT(isHorizontal);
- return 0;
- case CSSValueBottom:
- ASSERT(!isHorizontal);
- return size.height();
- case CSSValueRight:
- ASSERT(isHorizontal);
- return size.width();
- }
-
- default:
- return value->computeLength<float>(style, rootStyle, zoomFactor);
+ switch (value->getIdent()) {
+ case CSSValueTop:
+ ASSERT(!isHorizontal);
+ return 0;
+ case CSSValueLeft:
+ ASSERT(isHorizontal);
+ return 0;
+ case CSSValueBottom:
+ ASSERT(!isHorizontal);
+ return size.height();
+ case CSSValueRight:
+ ASSERT(isHorizontal);
+ return size.width();
}
+
+ return value->computeLength<float>(style, rootStyle, zoomFactor);
}
FloatPoint CSSGradientValue::computeEndPoint(CSSPrimitiveValue* first, CSSPrimitiveValue* second, RenderStyle* style, RenderStyle* rootStyle, const IntSize& size)
@@ -416,8 +411,7 @@ bool CSSGradientValue::isCacheable() const
if (!stop.m_position)
continue;
- unsigned short unitType = stop.m_position->primitiveType();
- if (unitType == CSSPrimitiveValue::CSS_EMS || unitType == CSSPrimitiveValue::CSS_EXS || unitType == CSSPrimitiveValue::CSS_REMS)
+ if (stop.m_position->isFontRelativeLength())
return false;
}
@@ -640,9 +634,9 @@ float CSSRadialGradientValue::resolveRadius(CSSPrimitiveValue* radius, RenderSty
float zoomFactor = style->effectiveZoom();
float result = 0;
- if (radius->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) // Can the radius be a percentage?
+ if (radius->isNumber()) // Can the radius be a percentage?
result = radius->getFloatValue() * zoomFactor;
- else if (widthOrHeight && radius->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ else if (widthOrHeight && radius->isPercentage())
result = *widthOrHeight * radius->getFloatValue() / 100;
else
result = radius->computeLength<float>(style, rootStyle, zoomFactor);
@@ -761,29 +755,27 @@ PassRefPtr<Gradient> CSSRadialGradientValue::createGradient(RenderObject* render
} else {
enum GradientShape { Circle, Ellipse };
GradientShape shape = Ellipse;
- if (m_shape && m_shape->primitiveType() == CSSPrimitiveValue::CSS_IDENT && m_shape->getIdent() == CSSValueCircle)
+ if (m_shape && m_shape->getIdent() == CSSValueCircle)
shape = Circle;
enum GradientFill { ClosestSide, ClosestCorner, FarthestSide, FarthestCorner };
GradientFill fill = FarthestCorner;
- if (m_sizingBehavior && m_sizingBehavior->primitiveType() == CSSPrimitiveValue::CSS_IDENT) {
- switch (m_sizingBehavior->getIdent()) {
- case CSSValueContain:
- case CSSValueClosestSide:
- fill = ClosestSide;
- break;
- case CSSValueClosestCorner:
- fill = ClosestCorner;
- break;
- case CSSValueFarthestSide:
- fill = FarthestSide;
- break;
- case CSSValueCover:
- case CSSValueFarthestCorner:
- fill = FarthestCorner;
- break;
- }
+ switch (m_sizingBehavior ? m_sizingBehavior->getIdent() : 0) {
+ case CSSValueContain:
+ case CSSValueClosestSide:
+ fill = ClosestSide;
+ break;
+ case CSSValueClosestCorner:
+ fill = ClosestCorner;
+ break;
+ case CSSValueFarthestSide:
+ fill = FarthestSide;
+ break;
+ case CSSValueCover:
+ case CSSValueFarthestCorner:
+ fill = FarthestCorner;
+ break;
}
// Now compute the end radii based on the second point, shape and fill.
diff --git a/Source/WebCore/css/CSSInlineStyleDeclaration.h b/Source/WebCore/css/CSSInlineStyleDeclaration.h
deleted file mode 100644
index 718e40959..000000000
--- a/Source/WebCore/css/CSSInlineStyleDeclaration.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2008, 2011 Apple Inc. All rights reserved.
- * Copyright (C) 2011 Andreas Kling (kling@webkit.org)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CSSInlineStyleDeclaration_h
-#define CSSInlineStyleDeclaration_h
-
-#include "CSSElementStyleDeclaration.h"
-
-namespace WebCore {
-
-class CSSInlineStyleDeclaration : public CSSElementStyleDeclaration {
-public:
- virtual ~CSSInlineStyleDeclaration() { }
-
- static PassRefPtr<CSSInlineStyleDeclaration> create(StyledElement* element)
- {
- return adoptRef(new CSSInlineStyleDeclaration(element));
- }
-
-private:
- CSSInlineStyleDeclaration(StyledElement* element)
- : CSSElementStyleDeclaration(element, /* isInline */ true)
- {
- }
-};
-
-inline CSSInlineStyleDeclaration* toCSSInlineStyleDeclaration(CSSMutableStyleDeclaration* decl)
-{
- ASSERT(!decl || decl->isInlineStyleDeclaration());
- return static_cast<CSSInlineStyleDeclaration*>(decl);
-}
-
-} // namespace WebCore
-
-#endif // CSSInlineStyleDeclaration_h
diff --git a/Source/WebCore/css/CSSMutableStyleDeclaration.cpp b/Source/WebCore/css/CSSMutableStyleDeclaration.cpp
index c831b07df..c7d5d06f6 100644
--- a/Source/WebCore/css/CSSMutableStyleDeclaration.cpp
+++ b/Source/WebCore/css/CSSMutableStyleDeclaration.cpp
@@ -23,7 +23,6 @@
#include "CSSMutableStyleDeclaration.h"
#include "CSSImageValue.h"
-#include "CSSInlineStyleDeclaration.h"
#include "CSSParser.h"
#include "CSSPropertyLonghand.h"
#include "CSSPropertyNames.h"
@@ -66,17 +65,14 @@ public:
#if ENABLE(MUTATION_OBSERVERS)
if (!s_currentDecl->isInlineStyleDeclaration())
return;
-
- CSSInlineStyleDeclaration* inlineDecl = toCSSInlineStyleDeclaration(s_currentDecl);
- if (!inlineDecl->element())
+ if (!s_currentDecl->parentElement())
return;
-
- m_mutationRecipients = MutationObserverInterestGroup::createForAttributesMutation(inlineDecl->element(), HTMLNames::styleAttr);
+ m_mutationRecipients = MutationObserverInterestGroup::createForAttributesMutation(s_currentDecl->parentElement(), HTMLNames::styleAttr);
if (!m_mutationRecipients)
return;
- AtomicString oldValue = m_mutationRecipients->isOldValueRequested() ? inlineDecl->element()->getAttribute(HTMLNames::styleAttr) : nullAtom;
- m_mutation = MutationRecord::createAttributes(inlineDecl->element(), HTMLNames::styleAttr, oldValue);
+ AtomicString oldValue = m_mutationRecipients->isOldValueRequested() ? s_currentDecl->parentElement()->getAttribute(HTMLNames::styleAttr) : nullAtom;
+ m_mutation = MutationRecord::createAttributes(s_currentDecl->parentElement(), HTMLNames::styleAttr, oldValue);
#endif
}
@@ -91,17 +87,16 @@ public:
m_mutationRecipients->enqueueMutationRecord(m_mutation);
s_shouldDeliver = false;
#endif
-
if (!s_shouldNotifyInspector) {
s_currentDecl = 0;
return;
}
-
- CSSInlineStyleDeclaration* inlineDecl = toCSSInlineStyleDeclaration(s_currentDecl);
+ // We have to clear internal state before calling Inspector's code.
+ CSSMutableStyleDeclaration* localCopyStyleDecl = s_currentDecl;
s_currentDecl = 0;
s_shouldNotifyInspector = false;
- if (inlineDecl->element() && inlineDecl->element()->document())
- InspectorInstrumentation::didInvalidateStyleAttr(inlineDecl->element()->document(), inlineDecl->element());
+ if (localCopyStyleDecl->isInlineStyleDeclaration() && localCopyStyleDecl->parentElement() && localCopyStyleDecl->parentElement()->document())
+ InspectorInstrumentation::didInvalidateStyleAttr(localCopyStyleDecl->parentElement()->document(), localCopyStyleDecl->parentElement());
}
#if ENABLE(MUTATION_OBSERVERS)
@@ -139,7 +134,6 @@ bool StyleAttributeMutationScope::s_shouldDeliver = false;
} // namespace
CSSMutableStyleDeclaration::CSSMutableStyleDeclaration()
- : CSSStyleDeclaration(0)
{
// This constructor is used for various inline style declarations, so disable strict parsing.
m_strictParsing = false;
@@ -180,13 +174,17 @@ CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const CS
}
}
+CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(StyledElement* element)
+ : CSSStyleDeclaration(element)
+{
+}
+
CSSMutableStyleDeclaration::~CSSMutableStyleDeclaration()
{
}
void CSSMutableStyleDeclaration::copyPropertiesFrom(const CSSMutableStyleDeclaration& other)
{
- ASSERT(!m_iteratorCount);
m_properties = other.m_properties;
}
@@ -613,8 +611,6 @@ bool CSSMutableStyleDeclaration::removeShorthandProperty(int propertyID, bool no
String CSSMutableStyleDeclaration::removeProperty(int propertyID, bool notifyChanged, bool returnText)
{
- ASSERT(!m_iteratorCount);
-
#if ENABLE(MUTATION_OBSERVERS)
StyleAttributeMutationScope mutationScope(this);
#endif
@@ -646,15 +642,13 @@ String CSSMutableStyleDeclaration::removeProperty(int propertyID, bool notifyCha
void CSSMutableStyleDeclaration::setNeedsStyleRecalc()
{
- if (isElementStyleDeclaration() && static_cast<CSSElementStyleDeclaration*>(this)->element()) {
- StyledElement* element = static_cast<CSSElementStyleDeclaration*>(this)->element();
- if (!isInlineStyleDeclaration())
- element->setNeedsStyleRecalc(FullStyleChange);
- else {
- element->setNeedsStyleRecalc(InlineStyleChange);
- element->invalidateStyleAttribute();
- StyleAttributeMutationScope(this).didInvalidateStyleAttr();
- }
+ if (isInlineStyleDeclaration()) {
+ StyledElement* element = parentElement();
+ if (!element)
+ return;
+ element->setNeedsStyleRecalc(InlineStyleChange);
+ element->invalidateStyleAttribute();
+ StyleAttributeMutationScope(this).didInvalidateStyleAttr();
return;
}
@@ -664,10 +658,21 @@ void CSSMutableStyleDeclaration::setNeedsStyleRecalc()
}
}
-bool CSSMutableStyleDeclaration::getPropertyPriority(int propertyID) const
+bool CSSMutableStyleDeclaration::propertyIsImportant(int propertyID) const
{
const CSSProperty* property = findPropertyWithId(propertyID);
- return property ? property->isImportant() : false;
+ if (property)
+ return property->isImportant();
+
+ CSSPropertyLonghand longhands = longhandForProperty(propertyID);
+ if (!longhands.length())
+ return false;
+
+ for (unsigned i = 0; i < longhands.length(); ++i) {
+ if (!propertyIsImportant(longhands.properties()[i]))
+ return false;
+ }
+ return true;
}
int CSSMutableStyleDeclaration::getPropertyShorthand(int propertyID) const
@@ -682,22 +687,8 @@ bool CSSMutableStyleDeclaration::isPropertyImplicit(int propertyID) const
return property ? property->isImplicit() : false;
}
-void CSSMutableStyleDeclaration::setProperty(int propertyID, const String& value, bool important, ExceptionCode& ec)
-{
- ec = 0;
- setProperty(propertyID, value, important, true);
-}
-
-String CSSMutableStyleDeclaration::removeProperty(int propertyID, ExceptionCode& ec)
-{
- ec = 0;
- return removeProperty(propertyID, true, true);
-}
-
bool CSSMutableStyleDeclaration::setProperty(int propertyID, const String& value, bool important, bool notifyChanged)
{
- ASSERT(!m_iteratorCount);
-
#if ENABLE(MUTATION_OBSERVERS)
StyleAttributeMutationScope mutationScope(this);
#endif
@@ -728,10 +719,8 @@ bool CSSMutableStyleDeclaration::setProperty(int propertyID, const String& value
return true;
}
-void CSSMutableStyleDeclaration::setPropertyInternal(const CSSProperty& property, CSSProperty* slot)
+void CSSMutableStyleDeclaration::setProperty(const CSSProperty& property, CSSProperty* slot)
{
- ASSERT(!m_iteratorCount);
-
#if ENABLE(MUTATION_OBSERVERS)
StyleAttributeMutationScope mutationScope(this);
#endif
@@ -753,7 +742,7 @@ void CSSMutableStyleDeclaration::setPropertyInternal(const CSSProperty& property
bool CSSMutableStyleDeclaration::setProperty(int propertyID, int value, bool important, bool notifyChanged)
{
CSSProperty property(propertyID, CSSPrimitiveValue::createIdentifier(value), important);
- setPropertyInternal(property);
+ setProperty(property);
if (notifyChanged)
setNeedsStyleRecalc();
return true;
@@ -762,7 +751,7 @@ bool CSSMutableStyleDeclaration::setProperty(int propertyID, int value, bool imp
bool CSSMutableStyleDeclaration::setProperty(int propertyID, double value, CSSPrimitiveValue::UnitTypes unit, bool important, bool notifyChanged)
{
CSSProperty property(propertyID, CSSPrimitiveValue::create(value, unit), important);
- setPropertyInternal(property);
+ setProperty(property);
if (notifyChanged)
setNeedsStyleRecalc();
return true;
@@ -770,8 +759,6 @@ bool CSSMutableStyleDeclaration::setProperty(int propertyID, double value, CSSPr
void CSSMutableStyleDeclaration::parseDeclaration(const String& styleDeclaration)
{
- ASSERT(!m_iteratorCount);
-
#if ENABLE(MUTATION_OBSERVERS)
StyleAttributeMutationScope mutationScope(this);
#endif
@@ -789,8 +776,6 @@ void CSSMutableStyleDeclaration::parseDeclaration(const String& styleDeclaration
void CSSMutableStyleDeclaration::addParsedProperties(const CSSProperty* const* properties, int numProperties)
{
- ASSERT(!m_iteratorCount);
-
#if ENABLE(MUTATION_OBSERVERS)
StyleAttributeMutationScope mutationScope(this);
#endif
@@ -809,14 +794,12 @@ void CSSMutableStyleDeclaration::addParsedProperties(const CSSProperty* const* p
void CSSMutableStyleDeclaration::addParsedProperty(const CSSProperty& property)
{
- ASSERT(!m_iteratorCount);
-
#if ENABLE(MUTATION_OBSERVERS)
StyleAttributeMutationScope mutationScope(this);
#endif
// Only add properties that have no !important counterpart present
- if (!getPropertyPriority(property.id()) || property.isImportant()) {
+ if (!propertyIsImportant(property.id()) || property.isImportant()) {
removeProperty(property.id(), false, false);
m_properties.append(property);
}
@@ -826,9 +809,9 @@ void CSSMutableStyleDeclaration::addParsedProperty(const CSSProperty& property)
#endif
}
-unsigned CSSMutableStyleDeclaration::virtualLength() const
+unsigned CSSMutableStyleDeclaration::length() const
{
- return length();
+ return propertyCount();
}
String CSSMutableStyleDeclaration::item(unsigned i) const
@@ -838,7 +821,7 @@ String CSSMutableStyleDeclaration::item(unsigned i) const
return getPropertyName(static_cast<CSSPropertyID>(m_properties[i].id()));
}
-String CSSMutableStyleDeclaration::cssText() const
+String CSSMutableStyleDeclaration::asText() const
{
String result = "";
@@ -909,8 +892,6 @@ void CSSMutableStyleDeclaration::setCssText(const String& text, ExceptionCode& e
void CSSMutableStyleDeclaration::merge(const CSSMutableStyleDeclaration* other, bool argOverridesOnConflict)
{
- ASSERT(!m_iteratorCount);
-
#if ENABLE(MUTATION_OBSERVERS)
StyleAttributeMutationScope mutationScope(this);
#endif
@@ -922,7 +903,7 @@ void CSSMutableStyleDeclaration::merge(const CSSMutableStyleDeclaration* other,
if (old) {
if (!argOverridesOnConflict && old->value())
continue;
- setPropertyInternal(toMerge, old);
+ setProperty(toMerge, old);
} else
m_properties.append(toMerge);
}
@@ -983,8 +964,6 @@ void CSSMutableStyleDeclaration::removeBlockProperties()
bool CSSMutableStyleDeclaration::removePropertiesInSet(const int* set, unsigned length, bool notifyChanged)
{
- ASSERT(!m_iteratorCount);
-
if (m_properties.isEmpty())
return false;
@@ -1052,4 +1031,119 @@ CSSProperty* CSSMutableStyleDeclaration::findPropertyWithId(int propertyID)
return 0;
}
+String CSSMutableStyleDeclaration::cssText() const
+{
+ return asText();
+}
+
+PassRefPtr<CSSValue> CSSMutableStyleDeclaration::getPropertyCSSValue(const String& propertyName)
+{
+ int propertyID = cssPropertyID(propertyName);
+ if (!propertyID)
+ return 0;
+ return getPropertyCSSValue(propertyID);
+}
+
+String CSSMutableStyleDeclaration::getPropertyValue(const String &propertyName)
+{
+ int propertyID = cssPropertyID(propertyName);
+ if (!propertyID)
+ return String();
+ return getPropertyValue(propertyID);
+}
+
+String CSSMutableStyleDeclaration::getPropertyPriority(const String& propertyName)
+{
+ int propertyID = cssPropertyID(propertyName);
+ if (!propertyID)
+ return String();
+ return propertyIsImportant(propertyID) ? "important" : "";
+}
+
+String CSSMutableStyleDeclaration::getPropertyShorthand(const String& propertyName)
+{
+ int propertyID = cssPropertyID(propertyName);
+ if (!propertyID)
+ return String();
+ int shorthandID = getPropertyShorthand(propertyID);
+ if (!shorthandID)
+ return String();
+ return getPropertyName(static_cast<CSSPropertyID>(shorthandID));
+}
+
+bool CSSMutableStyleDeclaration::isPropertyImplicit(const String& propertyName)
+{
+ int propertyID = cssPropertyID(propertyName);
+ if (!propertyID)
+ return false;
+ return isPropertyImplicit(propertyID);
+}
+
+void CSSMutableStyleDeclaration::setProperty(const String& propertyName, const String& value, const String& priority, ExceptionCode& ec)
+{
+ int propertyID = cssPropertyID(propertyName);
+ if (!propertyID)
+ return;
+ bool important = priority.find("important", 0, false) != notFound;
+ ec = 0;
+ setProperty(propertyID, value, important, true);
+}
+
+String CSSMutableStyleDeclaration::removeProperty(const String& propertyName, ExceptionCode& ec)
+{
+ int propertyID = cssPropertyID(propertyName);
+ if (!propertyID)
+ return String();
+ ec = 0;
+ return removeProperty(propertyID, true, true);
+}
+
+PassRefPtr<CSSValue> CSSMutableStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
+{
+ return getPropertyCSSValue(propertyID);
+}
+
+String CSSMutableStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID)
+{
+ return getPropertyValue(propertyID);
+}
+
+void CSSMutableStyleDeclaration::setPropertyInternal(CSSPropertyID propertyID, const String& value, bool important, ExceptionCode& ec)
+{
+ ec = 0;
+ setProperty(propertyID, value, important, true);
+}
+
+PassRefPtr<CSSMutableStyleDeclaration> CSSMutableStyleDeclaration::copyPropertiesInSet(const int* set, unsigned length) const
+{
+ Vector<CSSProperty> list;
+ list.reserveInitialCapacity(length);
+ for (unsigned i = 0; i < length; ++i) {
+ RefPtr<CSSValue> value = getPropertyCSSValue(set[i]);
+ if (value)
+ list.append(CSSProperty(set[i], value.release(), false));
+ }
+ return CSSMutableStyleDeclaration::create(list);
+}
+
+bool CSSMutableStyleDeclaration::cssPropertyMatches(const CSSProperty* property) const
+{
+ RefPtr<CSSValue> value = getPropertyCSSValue(property->id());
+ return value && value->cssText() == property->value()->cssText();
+}
+
+void CSSMutableStyleDeclaration::removeEquivalentProperties(const CSSStyleDeclaration* style)
+{
+ Vector<int> propertiesToRemove;
+ size_t size = m_properties.size();
+ for (size_t i = 0; i < size; ++i) {
+ const CSSProperty& property = m_properties[i];
+ if (style->cssPropertyMatches(&property))
+ propertiesToRemove.append(property.id());
+ }
+ // FIXME: This should use mass removal.
+ for (unsigned i = 0; i < propertiesToRemove.size(); ++i)
+ removeProperty(propertiesToRemove[i]);
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/css/CSSMutableStyleDeclaration.h b/Source/WebCore/css/CSSMutableStyleDeclaration.h
index f483fbe5c..73af49f2e 100644
--- a/Source/WebCore/css/CSSMutableStyleDeclaration.h
+++ b/Source/WebCore/css/CSSMutableStyleDeclaration.h
@@ -31,27 +31,7 @@
namespace WebCore {
-class CSSMutableStyleDeclarationConstIterator {
-public:
- CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclaration* decl, CSSProperty* current);
- CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclarationConstIterator& o);
- ~CSSMutableStyleDeclarationConstIterator();
-
- const CSSProperty& operator*() const { return *m_current; }
- const CSSProperty* operator->() const { return m_current; }
-
- bool operator!=(const CSSMutableStyleDeclarationConstIterator& o) { ASSERT(m_decl == o.m_decl); return m_current != o.m_current; }
- bool operator==(const CSSMutableStyleDeclarationConstIterator& o) { ASSERT(m_decl == o.m_decl); return m_current == o.m_current; }
-
- CSSMutableStyleDeclarationConstIterator& operator=(const CSSMutableStyleDeclarationConstIterator& o);
-
- CSSMutableStyleDeclarationConstIterator& operator++();
- CSSMutableStyleDeclarationConstIterator& operator--();
-
-private:
- const CSSMutableStyleDeclaration* m_decl;
- CSSProperty* m_current;
-};
+class StyledElement;
class CSSMutableStyleDeclaration : public CSSStyleDeclaration {
public:
@@ -73,39 +53,30 @@ public:
{
return adoptRef(new CSSMutableStyleDeclaration(0, properties));
}
+ static PassRefPtr<CSSMutableStyleDeclaration> createInline(StyledElement* element)
+ {
+ return adoptRef(new CSSMutableStyleDeclaration(element));
+ }
- // Used by StyledElement::copyNonAttributeProperties().
- void copyPropertiesFrom(const CSSMutableStyleDeclaration&);
-
- typedef CSSMutableStyleDeclarationConstIterator const_iterator;
-
- const_iterator begin() { return const_iterator(this, m_properties.begin()); }
- const_iterator end() { return const_iterator(this, m_properties.end()); }
-
- virtual String cssText() const;
- virtual void setCssText(const String&, ExceptionCode&);
-
- virtual unsigned virtualLength() const;
- unsigned length() const { return m_properties.size(); }
-
- virtual String item(unsigned index) const;
-
- virtual PassRefPtr<CSSValue> getPropertyCSSValue(int propertyID) const;
- virtual String getPropertyValue(int propertyID) const;
- virtual bool getPropertyPriority(int propertyID) const;
- virtual int getPropertyShorthand(int propertyID) const;
- virtual bool isPropertyImplicit(int propertyID) const;
+ unsigned propertyCount() const { return m_properties.size(); }
+ bool isEmpty() const { return m_properties.isEmpty(); }
+ const CSSProperty& propertyAt(unsigned index) const { return m_properties[index]; }
- virtual void setProperty(int propertyId, const String& value, bool important, ExceptionCode&);
- virtual String removeProperty(int propertyID, ExceptionCode&);
+ PassRefPtr<CSSValue> getPropertyCSSValue(int propertyID) const;
+ String getPropertyValue(int propertyID) const;
+ bool propertyIsImportant(int propertyID) const;
+ int getPropertyShorthand(int propertyID) const;
+ bool isPropertyImplicit(int propertyID) const;
virtual PassRefPtr<CSSMutableStyleDeclaration> copy() const;
bool setProperty(int propertyID, int value, bool important = false) { return setProperty(propertyID, value, important, true); }
bool setProperty(int propertyId, double value, CSSPrimitiveValue::UnitTypes unit, bool important = false) { return setProperty(propertyId, value, unit, important, true); }
bool setProperty(int propertyID, const String& value, bool important = false) { return setProperty(propertyID, value, important, true); }
-
+ void setProperty(const CSSProperty&, CSSProperty* slot = 0);
+
void removeProperty(int propertyID) { removeProperty(propertyID, true, false); }
+ String removeProperty(int propertyID, bool notifyChanged, bool returnText);
// The following parses an entire new style declaration.
void parseDeclaration(const String& styleDeclaration);
@@ -127,19 +98,40 @@ public:
void addSubresourceStyleURLs(ListHashSet<KURL>&);
-protected:
- CSSMutableStyleDeclaration(CSSRule* parentRule);
- CSSMutableStyleDeclaration();
+ // Used by StyledElement::copyNonAttributeProperties().
+ void copyPropertiesFrom(const CSSMutableStyleDeclaration&);
- void setPropertyInternal(const CSSProperty&, CSSProperty* slot = 0);
- String removeProperty(int propertyID, bool notifyChanged, bool returnText);
+ void removeEquivalentProperties(const CSSStyleDeclaration*);
+
+ PassRefPtr<CSSMutableStyleDeclaration> copyPropertiesInSet(const int* set, unsigned length) const;
+
+ String asText() const;
private:
+ CSSMutableStyleDeclaration();
+ CSSMutableStyleDeclaration(CSSRule* parentRule);
CSSMutableStyleDeclaration(CSSRule* parentRule, const Vector<CSSProperty>&);
CSSMutableStyleDeclaration(CSSRule* parentRule, const CSSProperty* const *, int numProperties);
+ CSSMutableStyleDeclaration(StyledElement*);
virtual PassRefPtr<CSSMutableStyleDeclaration> makeMutable();
+ // CSSOM functions. Don't make these public.
+ virtual unsigned length() const;
+ virtual String item(unsigned index) const;
+ virtual PassRefPtr<CSSValue> getPropertyCSSValue(const String& propertyName);
+ virtual String getPropertyValue(const String& propertyName);
+ virtual String getPropertyPriority(const String& propertyName);
+ virtual String getPropertyShorthand(const String& propertyName);
+ virtual bool isPropertyImplicit(const String& propertyName);
+ virtual void setProperty(const String& propertyName, const String& value, const String& priority, ExceptionCode&);
+ virtual String removeProperty(const String& propertyName, ExceptionCode&);
+ virtual String cssText() const;
+ virtual void setCssText(const String&, ExceptionCode&);
+ virtual PassRefPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID);
+ virtual String getPropertyValueInternal(CSSPropertyID);
+ virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionCode&);
+
void setNeedsStyleRecalc();
String getShorthandValue(const int* properties, size_t) const;
@@ -160,62 +152,14 @@ private:
bool removeShorthandProperty(int propertyID, bool notifyChanged);
bool removePropertiesInSet(const int* set, unsigned length, bool notifyChanged);
- Vector<CSSProperty>::const_iterator findPropertyWithId(int propertyId) const;
- Vector<CSSProperty>::iterator findPropertyWithId(int propertyId);
+ virtual bool cssPropertyMatches(const CSSProperty*) const;
- Vector<CSSProperty, 4> m_properties;
+ const CSSProperty* findPropertyWithId(int propertyId) const;
+ CSSProperty* findPropertyWithId(int propertyId);
- friend class CSSMutableStyleDeclarationConstIterator;
+ Vector<CSSProperty, 4> m_properties;
};
-inline CSSMutableStyleDeclarationConstIterator::CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclaration* decl, CSSProperty* current)
-: m_decl(decl)
-, m_current(current)
-{
-#ifndef NDEBUG
- const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount++;
-#endif
-}
-
-inline CSSMutableStyleDeclarationConstIterator::CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclarationConstIterator& o)
-: m_decl(o.m_decl)
-, m_current(o.m_current)
-{
-#ifndef NDEBUG
- const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount++;
-#endif
-}
-
-inline CSSMutableStyleDeclarationConstIterator::~CSSMutableStyleDeclarationConstIterator()
-{
-#ifndef NDEBUG
- const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount--;
-#endif
-}
-
-inline CSSMutableStyleDeclarationConstIterator& CSSMutableStyleDeclarationConstIterator::operator=(const CSSMutableStyleDeclarationConstIterator& o)
-{
- m_decl = o.m_decl;
- m_current = o.m_current;
-#ifndef NDEBUG
- const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount++;
-#endif
- return *this;
-}
-
-inline CSSMutableStyleDeclarationConstIterator& CSSMutableStyleDeclarationConstIterator::operator++()
-{
- ASSERT(m_current != const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_properties.end());
- ++m_current;
- return *this;
-}
-
-inline CSSMutableStyleDeclarationConstIterator& CSSMutableStyleDeclarationConstIterator::operator--()
-{
- --m_current;
- return *this;
-}
-
} // namespace WebCore
#endif // CSSMutableStyleDeclaration_h
diff --git a/Source/WebCore/css/CSSPageRule.idl b/Source/WebCore/css/CSSPageRule.idl
index 989fd8d50..a71c24ba8 100644
--- a/Source/WebCore/css/CSSPageRule.idl
+++ b/Source/WebCore/css/CSSPageRule.idl
@@ -23,7 +23,7 @@ module css {
// Introduced in DOM Level 2:
interface CSSPageRule : CSSRule {
- attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString selectorText;
+ attribute [ConvertNullStringTo=Null, TreatNullAs=EmptyString] DOMString selectorText;
readonly attribute CSSStyleDeclaration style;
diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp
index 2f5cab605..ac8d177e5 100644
--- a/Source/WebCore/css/CSSParser.cpp
+++ b/Source/WebCore/css/CSSParser.cpp
@@ -26,7 +26,7 @@
#include "CSSParser.h"
#include "CSSAspectRatioValue.h"
-#include "CSSBorderImageValue.h"
+#include "CSSBorderImage.h"
#include "CSSCanvasValue.h"
#include "CSSCharsetRule.h"
#include "CSSCrossfadeValue.h"
@@ -73,6 +73,7 @@
#include "Pair.h"
#include "Rect.h"
#include "RenderTheme.h"
+#include "Settings.h"
#include "ShadowValue.h"
#if ENABLE(CSS_FILTERS)
#include "WebKitCSSFilterValue.h"
@@ -200,7 +201,9 @@ CSSParser::CSSParser(bool strictParsing)
, m_propertyRange(UINT_MAX, UINT_MAX)
, m_ruleRangeMap(0)
, m_currentRuleData(0)
- , yy_start(1)
+ , m_parsingMode(NormalMode)
+ , m_currentCharacter(0)
+ , m_token(0)
, m_lineNumber(0)
, m_lastSelectorLineNumber(0)
, m_allowImportRules(true)
@@ -242,27 +245,22 @@ void CSSParserString::lower()
void CSSParser::setupParser(const char* prefix, const String& string, const char* suffix)
{
- int length = string.length() + strlen(prefix) + strlen(suffix) + 2;
+ int length = string.length() + strlen(prefix) + strlen(suffix) + 1;
- m_data = adoptArrayPtr(new UChar[length]);
+ m_dataStart = adoptArrayPtr(new UChar[length]);
for (unsigned i = 0; i < strlen(prefix); i++)
- m_data[i] = prefix[i];
+ m_dataStart[i] = prefix[i];
- memcpy(m_data.get() + strlen(prefix), string.characters(), string.length() * sizeof(UChar));
+ memcpy(m_dataStart.get() + strlen(prefix), string.characters(), string.length() * sizeof(UChar));
unsigned start = strlen(prefix) + string.length();
unsigned end = start + strlen(suffix);
for (unsigned i = start; i < end; i++)
- m_data[i] = suffix[i - start];
+ m_dataStart[i] = suffix[i - start];
- m_data[length - 1] = 0;
- m_data[length - 2] = 0;
+ m_dataStart[length - 1] = 0;
- yy_hold_char = 0;
- yyleng = 0;
- yytext = m_data.get();
- yy_c_buf_p = yytext;
- yy_hold_char = *yy_c_buf_p;
+ m_currentCharacter = m_tokenStart = m_dataStart.get();
resetRuleBodyMarks();
}
@@ -413,28 +411,58 @@ static inline bool isSimpleLengthPropertyID(int propertyId, bool& acceptsNegativ
static bool parseSimpleLengthValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important, bool strict, CSSStyleSheet* contextStyleSheet = 0)
{
- const UChar* characters = string.characters();
- unsigned length = string.length();
- if (!characters || !length)
- return false;
bool acceptsNegativeNumbers;
- if (!isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers))
+ unsigned length = string.length();
+
+ if (!length)
return false;
+ double number;
+ bool ok;
CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER;
- if (length > 2 && (characters[length - 2] | 0x20) == 'p' && (characters[length - 1] | 0x20) == 'x') {
- length -= 2;
- unit = CSSPrimitiveValue::CSS_PX;
- } else if (length > 1 && characters[length - 1] == '%') {
- length -= 1;
- unit = CSSPrimitiveValue::CSS_PERCENTAGE;
+
+ if (string.is8Bit()) {
+ const LChar* characters8 = string.characters8();
+ if (!characters8)
+ return false;
+
+ if (!isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers))
+ return false;
+
+ if (length > 2 && (characters8[length - 2] | 0x20) == 'p' && (characters8[length - 1] | 0x20) == 'x') {
+ length -= 2;
+ unit = CSSPrimitiveValue::CSS_PX;
+ } else if (length > 1 && characters8[length - 1] == '%') {
+ length -= 1;
+ unit = CSSPrimitiveValue::CSS_PERCENTAGE;
+ }
+
+ // We rely on charactersToDouble for validation as well. The function
+ // will set "ok" to "false" if the entire passed-in character range does
+ // not represent a double.
+ number = charactersToDouble(characters8, length, &ok);
+ } else {
+ const UChar* characters16 = string.characters16();
+ if (!characters16)
+ return false;
+
+ if (!isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers))
+ return false;
+
+ if (length > 2 && (characters16[length - 2] | 0x20) == 'p' && (characters16[length - 1] | 0x20) == 'x') {
+ length -= 2;
+ unit = CSSPrimitiveValue::CSS_PX;
+ } else if (length > 1 && characters16[length - 1] == '%') {
+ length -= 1;
+ unit = CSSPrimitiveValue::CSS_PERCENTAGE;
+ }
+
+ // We rely on charactersToDouble for validation as well. The function
+ // will set "ok" to "false" if the entire passed-in character range does
+ // not represent a double.
+ number = charactersToDouble(characters16, length, &ok);
}
- // We rely on charactersToDouble for validation as well. The function
- // will set "ok" to "false" if the entire passed-in character range does
- // not represent a double.
- bool ok;
- double number = charactersToDouble(characters, length, &ok);
if (!ok)
return false;
if (unit == CSSPrimitiveValue::CSS_NUMBER) {
@@ -456,18 +484,18 @@ static bool parseSimpleLengthValue(CSSMutableStyleDeclaration* declaration, int
return true;
}
-bool CSSParser::parseMappedAttributeValue(CSSMappedAttributeDeclaration* declaration, StyledElement* element, int propertyId, const String& value)
+bool CSSParser::parseMappedAttributeValue(CSSMappedAttributeDeclaration* mappedAttribute, StyledElement* element, int propertyId, const String& value)
{
- ASSERT(declaration);
+ ASSERT(mappedAttribute);
ASSERT(element);
ASSERT(element->document());
CSSStyleSheet* elementSheet = element->document()->elementSheet();
- if (parseSimpleLengthValue(declaration, propertyId, value, false, false, elementSheet))
+ if (parseSimpleLengthValue(mappedAttribute->declaration(), propertyId, value, false, false, elementSheet))
return true;
- if (parseColorValue(declaration, propertyId, value, false, false, elementSheet))
+ if (parseColorValue(mappedAttribute->declaration(), propertyId, value, false, false, elementSheet))
return true;
CSSParser parser(false);
- return parser.parseValue(declaration, propertyId, value, false, elementSheet);
+ return parser.parseValue(mappedAttribute->declaration(), propertyId, value, false, elementSheet);
}
bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important, bool strict)
@@ -527,7 +555,7 @@ bool CSSParser::parseColor(RGBA32& color, const String& string, bool strict)
return false;
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
- if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_RGBCOLOR)
+ if (!primitiveValue->isRGBColor())
return false;
color = primitiveValue->getRGBA32Value();
@@ -691,13 +719,54 @@ Document* CSSParser::findDocument() const
return m_styleSheet->findDocument();
}
+bool CSSParser::validCalculationUnit(CSSParserValue* value, Units unitflags)
+{
+ if (!parseCalculation(value))
+ return false;
+
+ bool b = false;
+ switch (m_parsedCalculation->category()) {
+ case CalcLength:
+ b = (unitflags & FLength);
+ break;
+ case CalcPercent:
+ b = (unitflags & FPercent);
+ // FIXME calc (http://webkit.org/b/16662): test FNonNeg here, eg
+ // if (b && (unitflags & FNonNeg) && m_parsedCalculation->doubleValue() < 0)
+ // b = false;
+ break;
+ case CalcNumber:
+ b = (unitflags & FNumber);
+ if (!b && (unitflags & FInteger) && m_parsedCalculation->isInt())
+ b = true;
+ // FIXME calc (http://webkit.org/b/16662): test FNonNeg here, eg
+ // if (b && (unitflags & FNonNeg) && m_parsedCalculation->doubleValue() < 0)
+ // b = false;
+ break;
+ case CalcPercentLength:
+ b = (unitflags & FPercent) && (unitflags & FLength);
+ break;
+ case CalcPercentNumber:
+ b = (unitflags & FPercent) && (unitflags & FNumber);
+ break;
+ case CalcOther:
+ break;
+ }
+ if (!b)
+ m_parsedCalculation.release();
+ return b;
+}
+
bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, bool strict)
{
+ if (isCalculation(value))
+ return validCalculationUnit(value, unitflags);
+
bool b = false;
switch (value->unit) {
case CSSPrimitiveValue::CSS_NUMBER:
b = (unitflags & FNumber);
- if (!b && ((unitflags & (FLength | FAngle | FTime)) && (value->fValue == 0 || !strict))) {
+ if (!b && ((unitflags & (FLength | FAngle | FTime)) && (!value->fValue || !strict))) {
value->unit = (unitflags & FLength) ? CSSPrimitiveValue::CSS_PX :
((unitflags & FAngle) ? CSSPrimitiveValue::CSS_DEG : CSSPrimitiveValue::CSS_MS);
b = true;
@@ -743,6 +812,14 @@ bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, bool strict)
inline PassRefPtr<CSSPrimitiveValue> CSSParser::createPrimitiveNumericValue(CSSParserValue* value)
{
+ if (m_parsedCalculation) {
+ ASSERT(isCalculation(value));
+ // FIXME calc() http://webkit.org/b/16662: create a CSSPrimitiveValue here, ie
+ // return CSSPrimitiveValue::create(m_parsedCalculation.release());
+ m_parsedCalculation.release();
+ return 0;
+ }
+
ASSERT((value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
|| (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_REMS));
return cssValuePool()->createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit));
@@ -840,6 +917,11 @@ inline PassRefPtr<CSSPrimitiveValue> CSSParser::parseValidPrimitive(int id, CSSP
return createPrimitiveNumericValue(value);
if (value->unit >= CSSParserValue::Q_EMS)
return CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS);
+ if (isCalculation(value))
+ // FIXME calc() http://webkit.org/b/16662: create a primitive value here, ie
+ // return CSSPrimitiveValue::create(m_parsedCalculation.release());
+ m_parsedCalculation.release();
+
return 0;
}
@@ -853,6 +935,10 @@ bool CSSParser::parseValue(int propId, bool important)
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);
+
int id = value->id;
// In quirks mode, we will look for units that have been incorrectly separated from the number they belong to
@@ -1037,7 +1123,7 @@ bool CSSParser::parseValue(int propId, bool important)
case CSSPropertyClear: // none | left | right | both | inherit
if (id == CSSValueNone || id == CSSValueLeft
- || id == CSSValueRight|| id == CSSValueBoth)
+ || id == CSSValueRight || id == CSSValueBoth)
validPrimitive = true;
break;
@@ -1315,7 +1401,7 @@ bool CSSParser::parseValue(int propId, bool important)
case CSSPropertyMaxWidth: // <length> | <percentage> | none | inherit
case CSSPropertyWebkitMaxLogicalWidth:
case CSSPropertyWebkitMaxLogicalHeight:
- if (id == CSSValueNone || id == CSSValueIntrinsic || id == CSSValueMinIntrinsic) {
+ if (id == CSSValueNone) {
validPrimitive = true;
break;
}
@@ -1473,7 +1559,10 @@ bool CSSParser::parseValue(int propId, bool important)
validPrimitive = true;
break;
- case CSSPropertyBorderImage:
+ case CSSPropertyBorderImage: {
+ RefPtr<CSSValue> result;
+ return parseBorderImage(propId, result, important);
+ }
case CSSPropertyWebkitBorderImage:
case CSSPropertyWebkitMaskBoxImage: {
RefPtr<CSSValue> result;
@@ -1635,7 +1724,10 @@ bool CSSParser::parseValue(int propId, bool important)
}
break;
case CSSPropertyWebkitFlexPack:
- validPrimitive = id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter || id == CSSValueJustify;
+ validPrimitive = id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter || id == CSSValueJustify || id == CSSValueDistribute;
+ break;
+ case CSSPropertyWebkitFlexAlign:
+ validPrimitive = id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter || id == CSSValueBaseline || id == CSSValueStretch;
break;
case CSSPropertyWebkitFlexItemAlign:
validPrimitive = id == CSSValueAuto || id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter || id == CSSValueBaseline || id == CSSValueStretch;
@@ -1972,7 +2064,7 @@ bool CSSParser::parseValue(int propId, bool important)
}
break;
case CSSPropertyWebkitLineGridSnap:
- if (id == CSSValueNone || id == CSSValueBaseline || id == CSSValueBounds)
+ if (id == CSSValueNone || id == CSSValueBaseline || id == CSSValueContain)
validPrimitive = true;
break;
case CSSPropertyWebkitLocale:
@@ -2233,6 +2325,13 @@ bool CSSParser::parseValue(int propId, bool important)
validPrimitive = true;
break;
+ case CSSPropertyWebkitFontVariantLigatures:
+ if (id == CSSValueNormal)
+ validPrimitive = true;
+ else
+ return parseFontVariantLigatures(important);
+ break;
+
case CSSPropertyWebkitWrapShapeInside:
case CSSPropertyWebkitWrapShapeOutside:
if (id == CSSValueAuto)
@@ -2267,6 +2366,7 @@ bool CSSParser::parseValue(int propId, bool important)
parsedValue = parseValidPrimitive(id, value);
m_valueList->next();
}
+ ASSERT(!m_parsedCalculation);
if (parsedValue) {
if (!m_valueList->current() || inShorthand()) {
addProperty(propId, parsedValue.release(), important);
@@ -2883,7 +2983,7 @@ PassRefPtr<CSSValue> CSSParser::parseBackgroundColor()
int id = m_valueList->current()->id;
if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor ||
(id >= CSSValueGrey && id < CSSValueWebkitText && !m_strict))
- return cssValuePool()->createIdentifierValue(id);
+ return cssValuePool()->createIdentifierValue(id);
return parseColor();
}
@@ -2974,8 +3074,11 @@ PassRefPtr<CSSValue> CSSParser::parseFillPositionComponent(CSSParserValueList* v
} else if (cumulativeFlags & (XFillPosition | AmbiguousFillPosition)) {
cumulativeFlags |= YFillPosition;
individualFlag = YFillPosition;
- } else
+ } else {
+ if (m_parsedCalculation)
+ m_parsedCalculation.release();
return 0;
+ }
return createPrimitiveNumericValue(valueList->current());
}
return 0;
@@ -4774,10 +4877,10 @@ static inline bool mightBeRGBA(const UChar* characters, unsigned length)
if (length < 5)
return false;
return characters[4] == '('
- && (characters[0] | 0x20) == 'r'
- && (characters[1] | 0x20) == 'g'
- && (characters[2] | 0x20) == 'b'
- && (characters[3] | 0x20) == 'a';
+ && isASCIIAlphaCaselessEqual(characters[0], 'r')
+ && isASCIIAlphaCaselessEqual(characters[1], 'g')
+ && isASCIIAlphaCaselessEqual(characters[2], 'b')
+ && isASCIIAlphaCaselessEqual(characters[3], 'a');
}
static inline bool mightBeRGB(const UChar* characters, unsigned length)
@@ -4785,9 +4888,9 @@ static inline bool mightBeRGB(const UChar* characters, unsigned length)
if (length < 4)
return false;
return characters[3] == '('
- && (characters[0] | 0x20) == 'r'
- && (characters[1] | 0x20) == 'g'
- && (characters[2] | 0x20) == 'b';
+ && isASCIIAlphaCaselessEqual(characters[0], 'r')
+ && isASCIIAlphaCaselessEqual(characters[1], 'g')
+ && isASCIIAlphaCaselessEqual(characters[2], 'b');
}
bool CSSParser::fastParseColor(RGBA32& rgb, const String& name, bool strict)
@@ -4857,22 +4960,49 @@ bool CSSParser::fastParseColor(RGBA32& rgb, const String& name, bool strict)
}
return false;
}
+
+inline double CSSParser::parsedDouble(CSSParserValue *v, ReleaseParsedCalcValueCondition releaseCalc)
+{
+ // FIXME calc (http://webkit.org/b/16662): evaluate calc here, eg
+ // const double result = m_parsedCalculation ? m_parsedCalculation->doubleValue() : v->fValue;
+ const double result = m_parsedCalculation ? 0 : v->fValue;
+ if (releaseCalc == ReleaseParsedCalcValue)
+ m_parsedCalculation.release();
+ return result;
+}
-static inline int colorIntFromValue(CSSParserValue* v)
+bool CSSParser::isCalculation(CSSParserValue* value)
{
- if (v->fValue <= 0.0)
+ return (value->unit == CSSParserValue::Function)
+ && (equalIgnoringCase(value->function->name, "-webkit-calc(")
+ || equalIgnoringCase(value->function->name, "-webkit-min(")
+ || equalIgnoringCase(value->function->name, "-webkit-max("));
+}
+
+inline int CSSParser::colorIntFromValue(CSSParserValue* v)
+{
+ bool isPercent;
+
+ if (m_parsedCalculation)
+ isPercent = m_parsedCalculation->category() == CalcPercent;
+ else
+ isPercent = v->unit == CSSPrimitiveValue::CSS_PERCENTAGE;
+
+ const double value = parsedDouble(v, ReleaseParsedCalcValue);
+
+ if (value <= 0.0)
return 0;
- if (v->unit == CSSPrimitiveValue::CSS_PERCENTAGE) {
- if (v->fValue >= 100.0)
+ if (isPercent) {
+ if (value >= 100.0)
return 255;
- return static_cast<int>(v->fValue * 256.0 / 100.0);
+ return static_cast<int>(value * 256.0 / 100.0);
}
- if (v->fValue >= 255.0)
+ if (value >= 255.0)
return 255;
- return static_cast<int>(v->fValue);
+ return static_cast<int>(value);
}
bool CSSParser::parseColorParameters(CSSParserValue* value, int* colorArray, bool parseAlpha)
@@ -4887,6 +5017,7 @@ bool CSSParser::parseColorParameters(CSSParserValue* value, int* colorArray, boo
unitType = FPercent;
else
return false;
+
colorArray[0] = colorIntFromValue(v);
for (int i = 1; i < 3; i++) {
v = args->next();
@@ -4904,9 +5035,10 @@ bool CSSParser::parseColorParameters(CSSParserValue* value, int* colorArray, boo
v = args->next();
if (!validUnit(v, FNumber, true))
return false;
+ 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>(max(0.0, min(1.0, v->fValue)) * nextafter(256.0, 0.0));
+ colorArray[3] = static_cast<int>(max(0.0, min(1.0, value)) * nextafter(256.0, 0.0));
}
return true;
}
@@ -4924,7 +5056,7 @@ bool CSSParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bo
if (!validUnit(v, FNumber, true))
return false;
// normalize the Hue value and change it to be between 0 and 1.0
- colorArray[0] = (((static_cast<int>(v->fValue) % 360) + 360) % 360) / 360.0;
+ 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 != ',')
@@ -4932,7 +5064,7 @@ bool CSSParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bo
v = args->next();
if (!validUnit(v, FPercent, true))
return false;
- colorArray[i] = max(0.0, min(100.0, v->fValue)) / 100.0; // needs to be value between 0 and 1.0
+ colorArray[i] = max(0.0, min(100.0, parsedDouble(v, ReleaseParsedCalcValue))) / 100.0; // needs to be value between 0 and 1.0
}
if (parseAlpha) {
v = args->next();
@@ -4941,7 +5073,7 @@ bool CSSParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bo
v = args->next();
if (!validUnit(v, FNumber, true))
return false;
- colorArray[3] = max(0.0, min(1.0, v->fValue));
+ colorArray[3] = max(0.0, min(1.0, parsedDouble(v, ReleaseParsedCalcValue)));
}
return true;
}
@@ -5009,9 +5141,9 @@ bool CSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c)
// This class tracks parsing state for shadow values. If it goes out of scope (e.g., due to an early return)
// without the allowBreak bit being set, then it will clean up all of the objects and destroy them.
struct ShadowParseContext {
- ShadowParseContext(CSSPropertyID prop, CSSValuePool* cssValuePool)
+ ShadowParseContext(CSSPropertyID prop, CSSParser* parser)
: property(prop)
- , m_cssValuePool(cssValuePool)
+ , m_parser(parser)
, allowX(true)
, allowY(false)
, allowBlur(false)
@@ -5054,7 +5186,7 @@ struct ShadowParseContext {
void commitLength(CSSParserValue* v)
{
- RefPtr<CSSPrimitiveValue> val = m_cssValuePool->createValue(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
+ RefPtr<CSSPrimitiveValue> val = m_parser->createPrimitiveNumericValue(v);
if (allowX) {
x = val.release();
@@ -5096,7 +5228,7 @@ struct ShadowParseContext {
void commitStyle(CSSParserValue* v)
{
- style = m_cssValuePool->createIdentifierValue(v->id);
+ style = m_parser->cssValuePool()->createIdentifierValue(v->id);
allowStyle = false;
if (allowX)
allowBreak = false;
@@ -5108,7 +5240,7 @@ struct ShadowParseContext {
}
CSSPropertyID property;
- CSSValuePool* m_cssValuePool;
+ CSSParser* m_parser;
RefPtr<CSSValueList> values;
RefPtr<CSSPrimitiveValue> x;
@@ -5129,7 +5261,7 @@ struct ShadowParseContext {
PassRefPtr<CSSValueList> CSSParser::parseShadow(CSSParserValueList* valueList, int propId)
{
- ShadowParseContext context(static_cast<CSSPropertyID>(propId), cssValuePool());
+ ShadowParseContext context(static_cast<CSSPropertyID>(propId), this);
CSSParserValue* val;
while ((val = valueList->current())) {
// Check for a comma break first.
@@ -5288,9 +5420,8 @@ bool CSSParser::parseFlex(int propId, bool important)
}
struct BorderImageParseContext {
- BorderImageParseContext(CSSValuePool* cssValuePool)
- : m_cssValuePool(cssValuePool)
- , m_canAdvance(false)
+ BorderImageParseContext()
+ : m_canAdvance(false)
, m_allowCommit(true)
, m_allowImage(true)
, m_allowImageSlice(true)
@@ -5370,13 +5501,27 @@ struct BorderImageParseContext {
m_allowImage = !m_image;
}
- PassRefPtr<CSSValue> commitBorderImage()
+ PassRefPtr<CSSValue> commitWebKitBorderImage()
{
- // Make our new border image value now.
- return CSSBorderImageValue::create(m_image, m_imageSlice, m_borderSlice, m_outset, m_repeat);
+ return createBorderImageValue(m_image, m_imageSlice, m_borderSlice, m_outset, m_repeat);
+ }
+
+ void commitBorderImage(CSSParser* parser, bool important)
+ {
+ commitBorderImageProperty(CSSPropertyBorderImageSource, parser, m_image, important);
+ commitBorderImageProperty(CSSPropertyBorderImageSlice, parser, m_imageSlice, important);
+ commitBorderImageProperty(CSSPropertyBorderImageWidth, parser, m_borderSlice, important);
+ commitBorderImageProperty(CSSPropertyBorderImageOutset, parser, m_outset, important);
+ commitBorderImageProperty(CSSPropertyBorderImageRepeat, parser, m_repeat, important);
}
- CSSValuePool* m_cssValuePool;
+ void commitBorderImageProperty(int propId, CSSParser* parser, PassRefPtr<CSSValue> value, bool important)
+ {
+ if (value)
+ parser->addProperty(propId, value, important);
+ else
+ parser->addProperty(propId, parser->cssValuePool()->createImplicitInitialValue(), important, true);
+ }
bool m_canAdvance;
@@ -5397,10 +5542,10 @@ struct BorderImageParseContext {
RefPtr<CSSValue> m_repeat;
};
-bool CSSParser::parseBorderImage(int propId, RefPtr<CSSValue>& result)
+bool CSSParser::parseBorderImage(int propId, RefPtr<CSSValue>& result, bool important)
{
ShorthandScope scope(this, propId);
- BorderImageParseContext context(cssValuePool());
+ BorderImageParseContext context;
while (CSSParserValue* val = m_valueList->current()) {
context.setCanAdvance(false);
@@ -5453,8 +5598,11 @@ bool CSSParser::parseBorderImage(int propId, RefPtr<CSSValue>& result)
}
if (context.allowCommit()) {
- // Need to fully commit as a single value.
- result = context.commitBorderImage();
+ if (propId == CSSPropertyBorderImage)
+ context.commitBorderImage(this, important);
+ else
+ // Need to fully commit as a single value.
+ result = context.commitWebKitBorderImage();
return true;
}
@@ -5497,8 +5645,8 @@ bool CSSParser::parseBorderImageRepeat(RefPtr<CSSValue>& result)
class BorderImageSliceParseContext {
public:
- BorderImageSliceParseContext(CSSValuePool* cssValuePool)
- : m_cssValuePool(cssValuePool)
+ BorderImageSliceParseContext(CSSParser* parser)
+ : m_parser(parser)
, m_allowNumber(true)
, m_allowFill(false)
, m_allowFinalCommit(false)
@@ -5512,7 +5660,7 @@ public:
void commitNumber(CSSParserValue* v)
{
- RefPtr<CSSPrimitiveValue> val = m_cssValuePool->createValue(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
+ RefPtr<CSSPrimitiveValue> val = m_parser->createPrimitiveNumericValue(v);
if (!m_top)
m_top = val;
else if (!m_right)
@@ -5539,16 +5687,16 @@ public:
// We need to clone and repeat values for any omissions.
ASSERT(m_top);
if (!m_right) {
- m_right = m_cssValuePool->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
- m_bottom = m_cssValuePool->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
- m_left = m_cssValuePool->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+ m_right = m_top;
+ m_bottom = m_top;
+ m_left = m_top;
}
if (!m_bottom) {
- m_bottom = m_cssValuePool->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
- m_left = m_cssValuePool->createValue(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
+ m_bottom = m_top;
+ m_left = m_right;
}
if (!m_left)
- m_left = m_cssValuePool->createValue(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
+ m_left = m_right;
// Now build a rect value to hold all four of our primitive values.
RefPtr<Quad> quad = Quad::create();
@@ -5558,11 +5706,11 @@ public:
quad->setLeft(m_left);
// Make our new border image value now.
- return CSSBorderImageSliceValue::create(m_cssValuePool->createValue(quad.release()), m_fill);
+ return CSSBorderImageSliceValue::create(m_parser->cssValuePool()->createValue(quad.release()), m_fill);
}
private:
- CSSValuePool* m_cssValuePool;
+ CSSParser* m_parser;
bool m_allowNumber;
bool m_allowFill;
@@ -5578,10 +5726,11 @@ private:
bool CSSParser::parseBorderImageSlice(int propId, RefPtr<CSSBorderImageSliceValue>& result)
{
- BorderImageSliceParseContext context(cssValuePool());
+ BorderImageSliceParseContext context(this);
CSSParserValue* val;
while ((val = m_valueList->current())) {
- if (context.allowNumber() && validUnit(val, FInteger | FNonNeg | FPercent, true)) {
+ // FIXME calc() http://webkit.org/b/16662 : calc is parsed but values are not created yet.
+ if (context.allowNumber() && !isCalculation(val) && validUnit(val, FInteger | FNonNeg | FPercent, true)) {
context.commitNumber(val);
} else if (context.allowFill() && val->id == CSSValueFill)
context.commitFill();
@@ -5614,8 +5763,8 @@ bool CSSParser::parseBorderImageSlice(int propId, RefPtr<CSSBorderImageSliceValu
class BorderImageQuadParseContext {
public:
- BorderImageQuadParseContext(CSSValuePool* cssValuePool)
- : m_cssValuePool(cssValuePool)
+ BorderImageQuadParseContext(CSSParser* parser)
+ : m_parser(parser)
, m_allowNumber(true)
, m_allowFinalCommit(false)
{ }
@@ -5628,9 +5777,9 @@ public:
{
RefPtr<CSSPrimitiveValue> val;
if (v->id == CSSValueAuto)
- val = m_cssValuePool->createIdentifierValue(v->id);
+ val = m_parser->cssValuePool()->createIdentifierValue(v->id);
else
- val = m_cssValuePool->createValue(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
+ val = m_parser->createPrimitiveNumericValue(v);
if (!m_top)
m_top = val;
@@ -5655,16 +5804,16 @@ public:
// We need to clone and repeat values for any omissions.
ASSERT(m_top);
if (!m_right) {
- m_right = m_cssValuePool->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
- m_bottom = m_cssValuePool->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
- m_left = m_cssValuePool->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+ m_right = m_top;
+ m_bottom = m_top;
+ m_left = m_top;
}
if (!m_bottom) {
- m_bottom = m_cssValuePool->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
- m_left = m_cssValuePool->createValue(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
+ m_bottom = m_top;
+ m_left = m_right;
}
if (!m_left)
- m_left = m_cssValuePool->createValue(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
+ m_left = m_right;
// Now build a quad value to hold all four of our primitive values.
RefPtr<Quad> quad = Quad::create();
@@ -5674,11 +5823,11 @@ public:
quad->setLeft(m_left);
// Make our new value now.
- return m_cssValuePool->createValue(quad.release());
+ return m_parser->cssValuePool()->createValue(quad.release());
}
private:
- CSSValuePool* m_cssValuePool;
+ CSSParser* m_parser;
bool m_allowNumber;
bool m_allowFinalCommit;
@@ -5691,7 +5840,7 @@ private:
bool CSSParser::parseBorderImageQuad(Units validUnits, RefPtr<CSSPrimitiveValue>& result)
{
- BorderImageQuadParseContext context(cssValuePool());
+ BorderImageQuadParseContext context(this);
CSSParserValue* val;
while ((val = m_valueList->current())) {
if (context.allowNumber() && (validUnit(val, validUnits, true) || val->id == CSSValueAuto)) {
@@ -5881,7 +6030,7 @@ static PassRefPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue
else if (equalIgnoringCase(a->string, "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, (CSSPrimitiveValue::UnitTypes)a->unit);
+ result = cssValuePool->createValue(a->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(a->unit));
return result;
}
@@ -6434,19 +6583,17 @@ bool CSSParser::parseCrossfade(CSSParserValueList* valueList, RefPtr<CSSValue>&
bool CSSParser::parseCanvas(CSSParserValueList* valueList, RefPtr<CSSValue>& canvas)
{
- RefPtr<CSSCanvasValue> result = CSSCanvasValue::create();
-
// Walk the arguments.
CSSParserValueList* args = valueList->current()->function->args.get();
if (!args || args->size() != 1)
return false;
// The first argument is the canvas name. It is an identifier.
- CSSParserValue* a = args->current();
- if (!a || a->unit != CSSPrimitiveValue::CSS_IDENT)
+ CSSParserValue* value = args->current();
+ if (!value || value->unit != CSSPrimitiveValue::CSS_IDENT)
return false;
- result->setName(a->string);
- canvas = result;
+
+ canvas = CSSCanvasValue::create(value->string);
return true;
}
@@ -6803,7 +6950,6 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParse
case WebKitCSSFilterValue::SaturateFilterOperation:
case WebKitCSSFilterValue::InvertFilterOperation:
case WebKitCSSFilterValue::OpacityFilterOperation:
- case WebKitCSSFilterValue::BrightnessFilterOperation:
case WebKitCSSFilterValue::ContrastFilterOperation: {
// One optional argument, 0-1 or 0%-100%, if missing use 100%.
if (args->size() > 1)
@@ -6816,9 +6962,8 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParse
double amount = value->fValue;
- // Saturate, Brightness and Contrast allow values over 100%.
+ // Saturate and Contrast allow values over 100%.
if (filterType != WebKitCSSFilterValue::SaturateFilterOperation
- && filterType != WebKitCSSFilterValue::BrightnessFilterOperation
&& filterType != WebKitCSSFilterValue::ContrastFilterOperation) {
double maxAllowed = value->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 100.0 : 1.0;
if (amount > maxAllowed)
@@ -6829,6 +6974,26 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParse
}
break;
}
+ case WebKitCSSFilterValue::BrightnessFilterOperation: {
+ // One optional argument, -1 to +1 or -100% to +100%, if missing use 0,
+ if (args->size() > 1)
+ return 0;
+
+ if (args->size()) {
+ CSSParserValue* value = args->current();
+ if (!validUnit(value, FNumber | FPercent, true))
+ return 0;
+
+ double amount = value->fValue;
+ double minAllowed = value->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? -100.0 : -1.0;
+ double maxAllowed = value->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 100.0 : 1.0;
+ if (amount < minAllowed || amount > maxAllowed)
+ return 0;
+
+ filterValue->append(cssValuePool()->createValue(amount, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)));
+ }
+ break;
+ }
case WebKitCSSFilterValue::HueRotateFilterOperation: {
// hue-rotate() takes one optional angle.
if (args->size() > 1)
@@ -6901,6 +7066,13 @@ PassRefPtr<CSSValueList> CSSParser::parseFilter()
#if ENABLE(CSS_SHADERS)
if (filterType == WebKitCSSFilterValue::CustomFilterOperation) {
+ // Make sure parsing fails if custom filters are disabled.
+ if (Document* document = findDocument()) {
+ Settings* settings = document->settings();
+ if (!settings || !settings->isCSSCustomFilterEnabled())
+ return 0;
+ }
+
RefPtr<WebKitCSSFilterValue> filterValue = parseCustomFilter(value);
if (!filterValue)
return 0;
@@ -7227,236 +7399,1271 @@ bool CSSParser::parseFontFeatureSettings(bool important)
return false;
}
-static inline int yyerror(const char*) { return 1; }
+bool CSSParser::parseFontVariantLigatures(bool important)
+{
+ 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)
+ return false;
+
+ switch (value->id) {
+ case CSSValueNoCommonLigatures:
+ case CSSValueCommonLigatures:
+ if (sawCommonLigaturesValue)
+ return false;
+ sawCommonLigaturesValue = true;
+ ligatureValues->append(cssValuePool()->createIdentifierValue(value->id));
+ break;
+ case CSSValueNoDiscretionaryLigatures:
+ case CSSValueDiscretionaryLigatures:
+ if (sawDiscretionaryLigaturesValue)
+ return false;
+ sawDiscretionaryLigaturesValue = true;
+ ligatureValues->append(cssValuePool()->createIdentifierValue(value->id));
+ break;
+ case CSSValueNoHistoricalLigatures:
+ case CSSValueHistoricalLigatures:
+ if (sawHistoricalLigaturesValue)
+ return false;
+ sawHistoricalLigaturesValue = true;
+ ligatureValues->append(cssValuePool()->createIdentifierValue(value->id));
+ break;
+ default:
+ return false;
+ }
+ }
+
+ if (!ligatureValues->length())
+ return false;
+
+ addProperty(CSSPropertyWebkitFontVariantLigatures, ligatureValues.release(), important);
+ return true;
+}
+
+bool CSSParser::parseCalculation(CSSParserValue* value)
+{
+ ASSERT(isCalculation(value));
+
+ CSSParserValueList* args = value->function->args.get();
+ if (!args || !args->size())
+ return false;
+
+ ASSERT(!m_parsedCalculation);
+ m_parsedCalculation = CSSCalcValue::create(value->function->name, args);
+
+ if (!m_parsedCalculation)
+ return false;
+
+ return true;
+}
#define END_TOKEN 0
#include "CSSGrammar.h"
+enum CharacterType {
+ // Types for the main switch.
+
+ // The first 4 types must be grouped together, as they
+ // represent the allowed chars in an identifier.
+ CharacterCaselessU,
+ CharacterIdentifierStart,
+ CharacterNumber,
+ CharacterDash,
+
+ CharacterOther,
+ CharacterNull,
+ CharacterWhiteSpace,
+ CharacterEndMediaQuery,
+ CharacterEndNthChild,
+ CharacterQuote,
+ CharacterExclamationMark,
+ CharacterHashmark,
+ CharacterDollar,
+ CharacterAsterisk,
+ CharacterPlus,
+ CharacterDot,
+ CharacterSlash,
+ CharacterLess,
+ CharacterAt,
+ CharacterBackSlash,
+ CharacterXor,
+ CharacterVerticalBar,
+ CharacterTilde,
+};
+
+// 128 ASCII codes
+static const CharacterType typesOfASCIICharacters[128] = {
+/* 0 - Null */ CharacterNull,
+/* 1 - Start of Heading */ CharacterOther,
+/* 2 - Start of Text */ CharacterOther,
+/* 3 - End of Text */ CharacterOther,
+/* 4 - End of Transm. */ CharacterOther,
+/* 5 - Enquiry */ CharacterOther,
+/* 6 - Acknowledgment */ CharacterOther,
+/* 7 - Bell */ CharacterOther,
+/* 8 - Back Space */ CharacterOther,
+/* 9 - Horizontal Tab */ CharacterWhiteSpace,
+/* 10 - Line Feed */ CharacterWhiteSpace,
+/* 11 - Vertical Tab */ CharacterOther,
+/* 12 - Form Feed */ CharacterWhiteSpace,
+/* 13 - Carriage Return */ CharacterWhiteSpace,
+/* 14 - Shift Out */ CharacterOther,
+/* 15 - Shift In */ CharacterOther,
+/* 16 - Data Line Escape */ CharacterOther,
+/* 17 - Device Control 1 */ CharacterOther,
+/* 18 - Device Control 2 */ CharacterOther,
+/* 19 - Device Control 3 */ CharacterOther,
+/* 20 - Device Control 4 */ CharacterOther,
+/* 21 - Negative Ack. */ CharacterOther,
+/* 22 - Synchronous Idle */ CharacterOther,
+/* 23 - End of Transmit */ CharacterOther,
+/* 24 - Cancel */ CharacterOther,
+/* 25 - End of Medium */ CharacterOther,
+/* 26 - Substitute */ CharacterOther,
+/* 27 - Escape */ CharacterOther,
+/* 28 - File Separator */ CharacterOther,
+/* 29 - Group Separator */ CharacterOther,
+/* 30 - Record Separator */ CharacterOther,
+/* 31 - Unit Separator */ CharacterOther,
+/* 32 - Space */ CharacterWhiteSpace,
+/* 33 - ! */ CharacterExclamationMark,
+/* 34 - " */ CharacterQuote,
+/* 35 - # */ CharacterHashmark,
+/* 36 - $ */ CharacterDollar,
+/* 37 - % */ CharacterOther,
+/* 38 - & */ CharacterOther,
+/* 39 - ' */ CharacterQuote,
+/* 40 - ( */ CharacterOther,
+/* 41 - ) */ CharacterEndNthChild,
+/* 42 - * */ CharacterAsterisk,
+/* 43 - + */ CharacterPlus,
+/* 44 - , */ CharacterOther,
+/* 45 - - */ CharacterDash,
+/* 46 - . */ CharacterDot,
+/* 47 - / */ CharacterSlash,
+/* 48 - 0 */ CharacterNumber,
+/* 49 - 1 */ CharacterNumber,
+/* 50 - 2 */ CharacterNumber,
+/* 51 - 3 */ CharacterNumber,
+/* 52 - 4 */ CharacterNumber,
+/* 53 - 5 */ CharacterNumber,
+/* 54 - 6 */ CharacterNumber,
+/* 55 - 7 */ CharacterNumber,
+/* 56 - 8 */ CharacterNumber,
+/* 57 - 9 */ CharacterNumber,
+/* 58 - : */ CharacterOther,
+/* 59 - ; */ CharacterEndMediaQuery,
+/* 60 - < */ CharacterLess,
+/* 61 - = */ CharacterOther,
+/* 62 - > */ CharacterOther,
+/* 63 - ? */ CharacterOther,
+/* 64 - @ */ CharacterAt,
+/* 65 - A */ CharacterIdentifierStart,
+/* 66 - B */ CharacterIdentifierStart,
+/* 67 - C */ CharacterIdentifierStart,
+/* 68 - D */ CharacterIdentifierStart,
+/* 69 - E */ CharacterIdentifierStart,
+/* 70 - F */ CharacterIdentifierStart,
+/* 71 - G */ CharacterIdentifierStart,
+/* 72 - H */ CharacterIdentifierStart,
+/* 73 - I */ CharacterIdentifierStart,
+/* 74 - J */ CharacterIdentifierStart,
+/* 75 - K */ CharacterIdentifierStart,
+/* 76 - L */ CharacterIdentifierStart,
+/* 77 - M */ CharacterIdentifierStart,
+/* 78 - N */ CharacterIdentifierStart,
+/* 79 - O */ CharacterIdentifierStart,
+/* 80 - P */ CharacterIdentifierStart,
+/* 81 - Q */ CharacterIdentifierStart,
+/* 82 - R */ CharacterIdentifierStart,
+/* 83 - S */ CharacterIdentifierStart,
+/* 84 - T */ CharacterIdentifierStart,
+/* 85 - U */ CharacterCaselessU,
+/* 86 - V */ CharacterIdentifierStart,
+/* 87 - W */ CharacterIdentifierStart,
+/* 88 - X */ CharacterIdentifierStart,
+/* 89 - Y */ CharacterIdentifierStart,
+/* 90 - Z */ CharacterIdentifierStart,
+/* 91 - [ */ CharacterOther,
+/* 92 - \ */ CharacterBackSlash,
+/* 93 - ] */ CharacterOther,
+/* 94 - ^ */ CharacterXor,
+/* 95 - _ */ CharacterIdentifierStart,
+/* 96 - ` */ CharacterOther,
+/* 97 - a */ CharacterIdentifierStart,
+/* 98 - b */ CharacterIdentifierStart,
+/* 99 - c */ CharacterIdentifierStart,
+/* 100 - d */ CharacterIdentifierStart,
+/* 101 - e */ CharacterIdentifierStart,
+/* 102 - f */ CharacterIdentifierStart,
+/* 103 - g */ CharacterIdentifierStart,
+/* 104 - h */ CharacterIdentifierStart,
+/* 105 - i */ CharacterIdentifierStart,
+/* 106 - j */ CharacterIdentifierStart,
+/* 107 - k */ CharacterIdentifierStart,
+/* 108 - l */ CharacterIdentifierStart,
+/* 109 - m */ CharacterIdentifierStart,
+/* 110 - n */ CharacterIdentifierStart,
+/* 111 - o */ CharacterIdentifierStart,
+/* 112 - p */ CharacterIdentifierStart,
+/* 113 - q */ CharacterIdentifierStart,
+/* 114 - r */ CharacterIdentifierStart,
+/* 115 - s */ CharacterIdentifierStart,
+/* 116 - t */ CharacterIdentifierStart,
+/* 117 - u */ CharacterCaselessU,
+/* 118 - v */ CharacterIdentifierStart,
+/* 119 - w */ CharacterIdentifierStart,
+/* 120 - x */ CharacterIdentifierStart,
+/* 121 - y */ CharacterIdentifierStart,
+/* 122 - z */ CharacterIdentifierStart,
+/* 123 - { */ CharacterEndMediaQuery,
+/* 124 - | */ CharacterVerticalBar,
+/* 125 - } */ CharacterOther,
+/* 126 - ~ */ CharacterTilde,
+/* 127 - Delete */ CharacterOther,
+};
+
+// Utility functions for the CSS tokenizer.
+
+static inline bool isCSSLetter(UChar character)
+{
+ return character >= 128 || typesOfASCIICharacters[character] <= CharacterDash;
+}
+
+static inline bool isCSSEscape(UChar character)
+{
+ return character >= ' ' && character != 127;
+}
+
+static inline bool isURILetter(UChar character)
+{
+ return (character >= '*' && character != 127) || (character >= '#' && character <= '&') || character == '!';
+}
+
+static inline bool isIdentifierStartAfterDash(UChar* currentCharacter)
+{
+ return isASCIIAlpha(currentCharacter[0]) || currentCharacter[0] == '_' || currentCharacter[0] >= 128
+ || (currentCharacter[0] == '\\' && isCSSEscape(currentCharacter[1]));
+}
+
+static inline bool isEqualToCSSIdentifier(UChar* cssString, const char* constantString)
+{
+ // Compare an UChar memory data with a zero terminated string.
+ do {
+ // The input must be part of an identifier if constantChar or constString
+ // contains '-'. Otherwise toASCIILowerUnchecked('\r') would be equal to '-'.
+ ASSERT((*constantString >= 'a' && *constantString <= 'z') || *constantString == '-');
+ ASSERT(*constantString != '-' || isCSSLetter(*cssString));
+ if (toASCIILowerUnchecked(*cssString++) != (*constantString++))
+ return false;
+ } while (*constantString);
+ return true;
+}
+
+static UChar* checkAndSkipEscape(UChar* currentCharacter)
+{
+ // Returns with 0, if escape check is failed. Otherwise
+ // it returns with the following character.
+ ASSERT(*currentCharacter == '\\');
+
+ ++currentCharacter;
+ if (!isCSSEscape(*currentCharacter))
+ return 0;
+
+ if (isASCIIHexDigit(*currentCharacter)) {
+ int length = 6;
+
+ do {
+ ++currentCharacter;
+ } while (isASCIIHexDigit(*currentCharacter) && --length);
+
+ // Optional space after the escape sequence.
+ if (isHTMLSpace(*currentCharacter))
+ ++currentCharacter;
+ return currentCharacter;
+ }
+ return currentCharacter + 1;
+}
+
+static inline UChar* skipWhiteSpace(UChar* currentCharacter)
+{
+ while (isHTMLSpace(*currentCharacter))
+ ++currentCharacter;
+ return currentCharacter;
+}
+
+// Main CSS tokenizer functions.
+
+inline bool CSSParser::isIdentifierStart()
+{
+ // Check whether an identifier is started.
+ return isIdentifierStartAfterDash((*m_currentCharacter != '-') ? m_currentCharacter : m_currentCharacter + 1);
+}
+
+inline UChar* CSSParser::checkAndSkipString(UChar* currentCharacter, UChar quote)
+{
+ // Returns with 0, if string check is failed. Otherwise
+ // it returns with the following character. This is necessary
+ // since we cannot revert escape sequences, thus strings
+ // must be validated before parsing.
+ while (true) {
+ if (UNLIKELY(*currentCharacter == quote)) {
+ // String parsing is successful.
+ return currentCharacter + 1;
+ }
+ if (UNLIKELY(*currentCharacter <= '\r' && (!*currentCharacter || *currentCharacter == '\n' || (*currentCharacter | 0x1) == '\r'))) {
+ // String parsing is failed for character '\0', '\n', '\f' or '\r'.
+ return 0;
+ }
+
+ if (LIKELY(currentCharacter[0] != '\\'))
+ ++currentCharacter;
+ else if (currentCharacter[1] == '\n' || currentCharacter[1] == '\f')
+ currentCharacter += 2;
+ else if (currentCharacter[1] == '\r')
+ currentCharacter += currentCharacter[2] == '\n' ? 3 : 2;
+ else {
+ currentCharacter = checkAndSkipEscape(currentCharacter);
+ if (!currentCharacter)
+ return 0;
+ }
+ }
+}
+
+void CSSParser::parseEscape(UChar*& result)
+{
+ ASSERT(*m_currentCharacter == '\\' && isCSSEscape(m_currentCharacter[1]));
+
+ ++m_currentCharacter;
+ if (isASCIIHexDigit(*m_currentCharacter)) {
+ unsigned unicode = 0;
+ int length = 6;
+
+ do {
+ unicode = (unicode << 4) + toASCIIHexValue(*m_currentCharacter++);
+ } while (--length && isASCIIHexDigit(*m_currentCharacter));
+
+ // Characters above 0xffff are not handled.
+ if (unicode > 0xffff)
+ unicode = 0xfffd;
+
+ // Optional space after the escape sequence.
+ if (isHTMLSpace(*m_currentCharacter))
+ ++m_currentCharacter;
+ *result = unicode;
+ } else
+ *result = *m_currentCharacter++;
+ ++result;
+}
+
+inline void CSSParser::parseIdentifier(UChar*& result, bool& hasEscape)
+{
+ // If a valid identifier start is found, we can safely
+ // parse the identifier until the next invalid character.
+ ASSERT(isIdentifierStart());
+ hasEscape = false;
+ do {
+ if (LIKELY(*m_currentCharacter != '\\'))
+ *result++ = *m_currentCharacter++;
+ else {
+ hasEscape = true;
+ parseEscape(result);
+ }
+ } while (isCSSLetter(m_currentCharacter[0]) || (m_currentCharacter[0] == '\\' && isCSSEscape(m_currentCharacter[1])));
+}
+
+inline void CSSParser::parseString(UChar*& result, UChar quote)
+{
+ while (true) {
+ if (UNLIKELY(*m_currentCharacter == quote)) {
+ // String parsing is done.
+ ++m_currentCharacter;
+ return;
+ }
+ ASSERT(*m_currentCharacter > '\r' || (*m_currentCharacter < '\n' && *m_currentCharacter) || *m_currentCharacter == '\v');
+
+ if (LIKELY(m_currentCharacter[0] != '\\'))
+ *result++ = *m_currentCharacter++;
+ else if (m_currentCharacter[1] == '\n' || m_currentCharacter[1] == '\f')
+ m_currentCharacter += 2;
+ else if (m_currentCharacter[1] == '\r')
+ m_currentCharacter += m_currentCharacter[2] == '\n' ? 3 : 2;
+ else
+ parseEscape(result);
+ }
+}
+
+inline void CSSParser::parseURI(UChar*& start, UChar*& result)
+{
+ UChar* uriStart = skipWhiteSpace(m_currentCharacter);
+
+ if (*uriStart == '"' || *uriStart == '\'') {
+ UChar quote = *uriStart;
+ ++uriStart;
+
+ UChar* stringEnd = checkAndSkipString(uriStart, quote);
+ if (!stringEnd)
+ return;
+ stringEnd = skipWhiteSpace(stringEnd);
+ if (*stringEnd != ')')
+ return;
+
+ start = result = m_currentCharacter = uriStart;
+ parseString(result, quote);
+
+ m_currentCharacter = stringEnd + 1;
+ m_token = URI;
+ } else {
+ UChar* stringEnd = uriStart;
+
+ while (isURILetter(*stringEnd)) {
+ if (*stringEnd != '\\')
+ ++stringEnd;
+ else {
+ stringEnd = checkAndSkipEscape(stringEnd);
+ if (!stringEnd)
+ return;
+ }
+ }
+
+ stringEnd = skipWhiteSpace(stringEnd);
+ if (*stringEnd != ')')
+ return;
+
+ start = result = m_currentCharacter = uriStart;
+ while (isURILetter(*m_currentCharacter)) {
+ if (LIKELY(*m_currentCharacter != '\\'))
+ *result++ = *m_currentCharacter++;
+ else
+ parseEscape(result);
+ }
+
+ m_currentCharacter = stringEnd + 1;
+ m_token = URI;
+ }
+}
+
+inline bool CSSParser::parseUnicodeRange()
+{
+ UChar* currentCharacter = m_currentCharacter + 1;
+ int length = 6;
+ ASSERT(*m_currentCharacter == '+');
+
+ while (isASCIIHexDigit(*currentCharacter) && length) {
+ ++currentCharacter;
+ --length;
+ }
+
+ if (length && *currentCharacter == '?') {
+ // At most 5 hex digit followed by a question mark.
+ do {
+ ++currentCharacter;
+ --length;
+ } while (*currentCharacter == '?' && length);
+ m_currentCharacter = currentCharacter;
+ return true;
+ }
+
+ if (length < 6) {
+ // At least one hex digit.
+ if (currentCharacter[0] == '-' && isASCIIHexDigit(currentCharacter[1])) {
+ // Followed by a dash and a hex digit.
+ ++currentCharacter;
+ length = 6;
+ do {
+ ++currentCharacter;
+ } while (--length && isASCIIHexDigit(*currentCharacter));
+ }
+ m_currentCharacter = currentCharacter;
+ return true;
+ }
+ return false;
+}
+
+bool CSSParser::parseNthChild()
+{
+ UChar* currentCharacter = m_currentCharacter;
+
+ while (isASCIIDigit(*currentCharacter))
+ ++currentCharacter;
+ if (isASCIIAlphaCaselessEqual(*currentCharacter, 'n')) {
+ m_currentCharacter = currentCharacter + 1;
+ return true;
+ }
+ return false;
+}
+
+bool CSSParser::parseNthChildExtra()
+{
+ UChar* currentCharacter = skipWhiteSpace(m_currentCharacter);
+ if (*currentCharacter != '+' && *currentCharacter != '-')
+ return false;
+
+ currentCharacter = skipWhiteSpace(currentCharacter + 1);
+ if (!isASCIIDigit(*currentCharacter))
+ return false;
+
+ do {
+ ++currentCharacter;
+ } while (isASCIIDigit(*currentCharacter));
+
+ m_currentCharacter = currentCharacter;
+ return true;
+}
+
+inline void CSSParser::detectFunctionTypeToken(int length)
+{
+ ASSERT(length > 0);
+ UChar* name = m_tokenStart;
+
+ switch (length) {
+ case 3:
+ if (isASCIIAlphaCaselessEqual(name[0], 'n') && isASCIIAlphaCaselessEqual(name[1], 'o') && isASCIIAlphaCaselessEqual(name[2], 't'))
+ m_token = NOTFUNCTION;
+ else if (isASCIIAlphaCaselessEqual(name[0], 'u') && isASCIIAlphaCaselessEqual(name[1], 'r') && isASCIIAlphaCaselessEqual(name[2], 'l'))
+ m_token = URI;
+ return;
+
+ case 9:
+ if (isEqualToCSSIdentifier(name, "nth-child"))
+ m_parsingMode = NthChildMode;
+ return;
+
+ case 11:
+ if (isEqualToCSSIdentifier(name, "nth-of-type"))
+ m_parsingMode = NthChildMode;
+ return;
+
+ case 14:
+ if (isEqualToCSSIdentifier(name, "nth-last-child"))
+ m_parsingMode = NthChildMode;
+ return;
+
+ case 16:
+ if (isEqualToCSSIdentifier(name, "nth-last-of-type"))
+ m_parsingMode = NthChildMode;
+ return;
+ }
+}
+
+inline void CSSParser::detectMediaQueryToken(int length)
+{
+ ASSERT(m_parsingMode == MediaQueryMode);
+ UChar* name = m_tokenStart;
+
+ if (length == 3) {
+ if (isASCIIAlphaCaselessEqual(name[0], 'a') && isASCIIAlphaCaselessEqual(name[1], 'n') && isASCIIAlphaCaselessEqual(name[2], 'd'))
+ m_token = MEDIA_AND;
+ else if (isASCIIAlphaCaselessEqual(name[0], 'n') && isASCIIAlphaCaselessEqual(name[1], 'o') && isASCIIAlphaCaselessEqual(name[2], 't'))
+ m_token = MEDIA_NOT;
+ } else if (length == 4) {
+ if (isASCIIAlphaCaselessEqual(name[0], 'o') && isASCIIAlphaCaselessEqual(name[1], 'n')
+ && isASCIIAlphaCaselessEqual(name[2], 'l') && isASCIIAlphaCaselessEqual(name[3], 'y'))
+ m_token = MEDIA_ONLY;
+ }
+}
+
+inline void CSSParser::detectNumberToken(UChar* type, int length)
+{
+ ASSERT(length > 0);
+
+ switch (toASCIILowerUnchecked(type[0])) {
+ case 'c':
+ if (length == 2 && isASCIIAlphaCaselessEqual(type[1], 'm'))
+ m_token = CMS;
+ return;
+
+ case 'd':
+ if (length == 3 && isASCIIAlphaCaselessEqual(type[1], 'e') && isASCIIAlphaCaselessEqual(type[2], 'g'))
+ m_token = DEGS;
+ return;
+
+ case 'e':
+ if (length == 2) {
+ if (isASCIIAlphaCaselessEqual(type[1], 'm'))
+ m_token = EMS;
+ else if (isASCIIAlphaCaselessEqual(type[1], 'x'))
+ m_token = EXS;
+ }
+ return;
+
+ case 'g':
+ if (length == 4 && isASCIIAlphaCaselessEqual(type[1], 'r')
+ && isASCIIAlphaCaselessEqual(type[2], 'a') && isASCIIAlphaCaselessEqual(type[3], 'd'))
+ m_token = GRADS;
+ return;
+
+ case 'h':
+ if (length == 2 && isASCIIAlphaCaselessEqual(type[1], 'z'))
+ m_token = HERTZ;
+ return;
+
+ case 'i':
+ if (length == 2 && isASCIIAlphaCaselessEqual(type[1], 'n'))
+ m_token = INS;
+ return;
+
+ case 'k':
+ if (length == 3 && isASCIIAlphaCaselessEqual(type[1], 'h') && isASCIIAlphaCaselessEqual(type[2], 'z'))
+ m_token = KHERTZ;
+ return;
+
+ case 'm':
+ if (length == 2) {
+ if (isASCIIAlphaCaselessEqual(type[1], 'm'))
+ m_token = MMS;
+ else if (isASCIIAlphaCaselessEqual(type[1], 's'))
+ m_token = MSECS;
+ }
+ return;
+
+ case 'p':
+ if (length == 2) {
+ if (isASCIIAlphaCaselessEqual(type[1], 'x'))
+ m_token = PXS;
+ else if (isASCIIAlphaCaselessEqual(type[1], 't'))
+ m_token = PTS;
+ else if (isASCIIAlphaCaselessEqual(type[1], 'c'))
+ m_token = PCS;
+ }
+ return;
+
+ case 'r':
+ if (length == 3) {
+ if (isASCIIAlphaCaselessEqual(type[1], 'a') && isASCIIAlphaCaselessEqual(type[2], 'd'))
+ m_token = RADS;
+ else if (isASCIIAlphaCaselessEqual(type[1], 'e') && isASCIIAlphaCaselessEqual(type[2], 'm'))
+ m_token = REMS;
+ }
+ return;
+
+ case 's':
+ if (length == 1)
+ m_token = SECS;
+ return;
+
+ case 't':
+ if (length == 4 && isASCIIAlphaCaselessEqual(type[1], 'u')
+ && isASCIIAlphaCaselessEqual(type[2], 'r') && isASCIIAlphaCaselessEqual(type[3], 'n'))
+ m_token = TURNS;
+ return;
+
+ default:
+ if (type[0] == '_' && length == 5 && type[1] == '_' && isASCIIAlphaCaselessEqual(type[2], 'q')
+ && isASCIIAlphaCaselessEqual(type[3], 'e') && isASCIIAlphaCaselessEqual(type[4], 'm'))
+ m_token = QEMS;
+ return;
+ }
+}
+
+inline void CSSParser::detectDashToken(int length)
+{
+ UChar* name = m_tokenStart;
+
+ if (length == 11) {
+ if (isASCIIAlphaCaselessEqual(name[10], 'y') && isEqualToCSSIdentifier(name + 1, "webkit-an"))
+ m_token = ANYFUNCTION;
+ else if (isASCIIAlphaCaselessEqual(name[10], 'n') && isEqualToCSSIdentifier(name + 1, "webkit-mi"))
+ m_token = MINFUNCTION;
+ else if (isASCIIAlphaCaselessEqual(name[10], 'x') && isEqualToCSSIdentifier(name + 1, "webkit-ma"))
+ m_token = MAXFUNCTION;
+ } else if (length == 12 && isEqualToCSSIdentifier(name + 1, "webkit-calc"))
+ m_token = CALCFUNCTION;
+}
+
+inline void CSSParser::detectAtToken(int length, bool hasEscape)
+{
+ UChar* name = m_tokenStart;
+ ASSERT(name[0] == '@' && length >= 2);
+
+ // charset, font-face, import, media, namespace, page,
+ // -webkit-keyframes, and -webkit-mediaquery are not affected by hasEscape.
+ switch (toASCIILowerUnchecked(name[1])) {
+ case 'b':
+ if (hasEscape)
+ return;
+
+ switch (length) {
+ case 12:
+ if (isEqualToCSSIdentifier(name + 2, "ottom-left"))
+ m_token = BOTTOMLEFT_SYM;
+ return;
+
+ case 13:
+ if (isEqualToCSSIdentifier(name + 2, "ottom-right"))
+ m_token = BOTTOMRIGHT_SYM;
+ return;
+
+ case 14:
+ if (isEqualToCSSIdentifier(name + 2, "ottom-center"))
+ m_token = BOTTOMCENTER_SYM;
+ return;
+
+ case 19:
+ if (isEqualToCSSIdentifier(name + 2, "ottom-left-corner"))
+ m_token = BOTTOMLEFTCORNER_SYM;
+ return;
+
+ case 20:
+ if (isEqualToCSSIdentifier(name + 2, "ottom-right-corner"))
+ m_token = BOTTOMRIGHTCORNER_SYM;
+ return;
+ }
+ return;
+
+ case 'c':
+ if (length == 8 && isEqualToCSSIdentifier(name + 2, "harset"))
+ m_token = CHARSET_SYM;
+ return;
+
+ case 'f':
+ if (length == 10 && isEqualToCSSIdentifier(name + 2, "ont-face"))
+ m_token = FONT_FACE_SYM;
+ return;
+
+ case 'i':
+ if (length == 7 && isEqualToCSSIdentifier(name + 2, "mport")) {
+ m_parsingMode = MediaQueryMode;
+ m_token = IMPORT_SYM;
+ }
+ return;
+
+ case 'l':
+ if (hasEscape)
+ return;
+
+ if (length == 9) {
+ if (isEqualToCSSIdentifier(name + 2, "eft-top"))
+ m_token = LEFTTOP_SYM;
+ } else if (length == 12) {
+ // Checking the last character first could further reduce the possibile cases.
+ if (isASCIIAlphaCaselessEqual(name[11], 'e') && isEqualToCSSIdentifier(name + 2, "eft-middl"))
+ m_token = LEFTMIDDLE_SYM;
+ else if (isASCIIAlphaCaselessEqual(name[11], 'm') && isEqualToCSSIdentifier(name + 2, "eft-botto"))
+ m_token = LEFTBOTTOM_SYM;
+ }
+ return;
+
+ case 'm':
+ if (length == 6 && isEqualToCSSIdentifier(name + 2, "edia")) {
+ m_parsingMode = MediaQueryMode;
+ m_token = MEDIA_SYM;
+ }
+ return;
+
+ case 'n':
+ if (length == 10 && isEqualToCSSIdentifier(name + 2, "amespace"))
+ m_token = NAMESPACE_SYM;
+ return;
+
+ case 'p':
+ if (length == 5 && isEqualToCSSIdentifier(name + 2, "age"))
+ m_token = PAGE_SYM;
+ return;
+
+ case 'r':
+ if (hasEscape)
+ return;
+
+ if (length == 10) {
+ if (isEqualToCSSIdentifier(name + 2, "ight-top"))
+ m_token = RIGHTTOP_SYM;
+ } else if (length == 13) {
+ // Checking the last character first could further reduce the possibile cases.
+ if (isASCIIAlphaCaselessEqual(name[12], 'e') && isEqualToCSSIdentifier(name + 2, "ight-middl"))
+ m_token = RIGHTMIDDLE_SYM;
+ else if (isASCIIAlphaCaselessEqual(name[12], 'm') && isEqualToCSSIdentifier(name + 2, "ight-botto"))
+ m_token = RIGHTBOTTOM_SYM;
+ }
+ return;
+
+ case 't':
+ if (hasEscape)
+ return;
+
+ switch (length) {
+ case 9:
+ if (isEqualToCSSIdentifier(name + 2, "op-left"))
+ m_token = TOPLEFT_SYM;
+ return;
+
+ case 10:
+ if (isEqualToCSSIdentifier(name + 2, "op-right"))
+ m_token = TOPRIGHT_SYM;
+ return;
+
+ case 11:
+ if (isEqualToCSSIdentifier(name + 2, "op-center"))
+ m_token = TOPCENTER_SYM;
+ return;
+
+ case 16:
+ if (isEqualToCSSIdentifier(name + 2, "op-left-corner"))
+ m_token = TOPLEFTCORNER_SYM;
+ return;
+
+ case 17:
+ if (isEqualToCSSIdentifier(name + 2, "op-right-corner"))
+ m_token = TOPRIGHTCORNER_SYM;
+ return;
+ }
+ return;
+
+ case '-':
+ switch (length) {
+ case 13:
+ if (!hasEscape && isEqualToCSSIdentifier(name + 2, "webkit-rule"))
+ m_token = WEBKIT_RULE_SYM;
+ return;
+
+ case 14:
+ if (hasEscape)
+ return;
+
+ // Checking the last character first could further reduce the possibile cases.
+ if (isASCIIAlphaCaselessEqual(name[13], 's') && isEqualToCSSIdentifier(name + 2, "webkit-decl"))
+ m_token = WEBKIT_DECLS_SYM;
+ else if (isASCIIAlphaCaselessEqual(name[13], 'e') && isEqualToCSSIdentifier(name + 2, "webkit-valu"))
+ m_token = WEBKIT_VALUE_SYM;
+ return;
+
+ case 15:
+ if (!hasEscape && isEqualToCSSIdentifier(name + 2, "webkit-region"))
+ m_token = WEBKIT_REGION_RULE_SYM;
+ return;
+
+ case 17:
+ if (!hasEscape && isEqualToCSSIdentifier(name + 2, "webkit-selector"))
+ m_token = WEBKIT_SELECTOR_SYM;
+ return;
+
+ case 18:
+ if (isEqualToCSSIdentifier(name + 2, "webkit-keyframes"))
+ m_token = WEBKIT_KEYFRAMES_SYM;
+ return;
+
+ case 19:
+ if (isEqualToCSSIdentifier(name + 2, "webkit-mediaquery")) {
+ m_parsingMode = MediaQueryMode;
+ m_token = WEBKIT_MEDIAQUERY_SYM;
+ }
+ return;
+
+ case 22:
+ if (!hasEscape && isEqualToCSSIdentifier(name + 2, "webkit-keyframe-rule"))
+ m_token = WEBKIT_KEYFRAME_RULE_SYM;
+ return;
+ }
+ }
+}
+
int CSSParser::lex(void* yylvalWithoutType)
{
YYSTYPE* yylval = static_cast<YYSTYPE*>(yylvalWithoutType);
- int length;
+ // Write pointer for the next character.
+ UChar* result;
+ bool hasEscape;
- lex();
+ // The input buffer is terminated by two \0, so
+ // it is safe to read two characters ahead anytime.
- UChar* t = text(&length);
+#ifndef NDEBUG
+ // In debug we check with an ASSERT that the length is > 0 for string types.
+ yylval->string.characters = 0;
+ yylval->string.length = 0;
+#endif
- switch (token()) {
- case WHITESPACE:
- case SGML_CD:
- case INCLUDES:
- case DASHMATCH:
+restartAfterComment:
+ m_tokenStart = result = m_currentCharacter;
+ m_token = *m_currentCharacter;
+ ++m_currentCharacter;
+
+ switch ((m_token <= 127) ? typesOfASCIICharacters[m_token] : CharacterIdentifierStart) {
+ case CharacterCaselessU:
+ if (UNLIKELY(*m_currentCharacter == '+'))
+ if (parseUnicodeRange()) {
+ m_token = UNICODERANGE;
+ yylval->string.characters = m_tokenStart;
+ yylval->string.length = m_currentCharacter - m_tokenStart;
+ break;
+ }
+ // Fall through to CharacterIdentifierStart.
+
+ case CharacterIdentifierStart:
+ --m_currentCharacter;
+ parseIdentifier(result, hasEscape);
+ m_token = IDENT;
+
+ yylval->string.characters = m_tokenStart;
+ yylval->string.length = result - m_tokenStart;
+
+ if (UNLIKELY(*m_currentCharacter == '(')) {
+ m_token = FUNCTION;
+ if (!hasEscape)
+ detectFunctionTypeToken(result - m_tokenStart);
+ ++m_currentCharacter;
+ ++result;
+ ++yylval->string.length;
+
+ if (token() == URI) {
+ m_token = FUNCTION;
+ // Check whether it is really an URI.
+ parseURI(yylval->string.characters, result);
+ yylval->string.length = result - yylval->string.characters;
+ }
+ } else if (UNLIKELY(m_parsingMode != NormalMode) && !hasEscape) {
+ if (m_parsingMode == MediaQueryMode)
+ detectMediaQueryToken(result - m_tokenStart);
+ else if (m_parsingMode == NthChildMode && isASCIIAlphaCaselessEqual(m_tokenStart[0], 'n')) {
+ if (result - m_tokenStart == 1) {
+ // String "n" is IDENT but "n+1" is NTH.
+ if (parseNthChildExtra()) {
+ m_token = NTH;
+ yylval->string.length = m_currentCharacter - m_tokenStart;
+ }
+ } else if (result - m_tokenStart == 2 && m_tokenStart[1] == '-') {
+ // String "n-" is IDENT but "n-1" is NTH.
+ // Speculatively decrease m_currentCharacter to detect an nth-child token.
+ m_currentCharacter--;
+ if (parseNthChildExtra()) {
+ m_token = NTH;
+ yylval->string.length = m_currentCharacter - m_tokenStart;
+ } else {
+ // Revert the change to m_currentCharacter if unsuccessful.
+ m_currentCharacter++;
+ }
+ }
+ }
+ }
break;
- case URI:
- case STRING:
- case IDENT:
- case NTH:
- case HEX:
- case IDSEL:
- case DIMEN:
- case UNICODERANGE:
- case FUNCTION:
- case ANYFUNCTION:
- case NOTFUNCTION:
- case CALCFUNCTION:
- case MINFUNCTION:
- case MAXFUNCTION:
- yylval->string.characters = t;
- yylval->string.length = length;
- break;
-
- case IMPORT_SYM:
- case PAGE_SYM:
- case MEDIA_SYM:
- case FONT_FACE_SYM:
- case CHARSET_SYM:
- case NAMESPACE_SYM:
- case WEBKIT_KEYFRAMES_SYM:
-
- case IMPORTANT_SYM:
- break;
-
- case QEMS:
- length--;
- case GRADS:
- case TURNS:
- length--;
- case DEGS:
- case RADS:
- case KHERTZ:
- case REMS:
- length--;
- case MSECS:
- case HERTZ:
- case EMS:
- case EXS:
- case PXS:
- case CMS:
- case MMS:
- case INS:
- case PTS:
- case PCS:
- length--;
- case SECS:
- case PERCENTAGE:
- length--;
- case FLOATTOKEN:
- case INTEGER:
- yylval->number = charactersToDouble(t, length);
+ case CharacterDot:
+ if (!isASCIIDigit(m_currentCharacter[0]))
+ break;
+ // Fall through to CharacterNumber.
+
+ case CharacterNumber: {
+ bool dotSeen = (m_token == '.');
+
+ while (true) {
+ if (!isASCIIDigit(m_currentCharacter[0])) {
+ // Only one dot is allowed for a number,
+ // and it must be followed by a digit.
+ if (m_currentCharacter[0] != '.' || dotSeen || !isASCIIDigit(m_currentCharacter[1]))
+ break;
+ dotSeen = true;
+ }
+ ++m_currentCharacter;
+ }
+
+ if (UNLIKELY(m_parsingMode == NthChildMode) && !dotSeen && isASCIIAlphaCaselessEqual(*m_currentCharacter, 'n')) {
+ // "[0-9]+n" is always an NthChild.
+ ++m_currentCharacter;
+ parseNthChildExtra();
+ m_token = NTH;
+ yylval->string.characters = m_tokenStart;
+ yylval->string.length = m_currentCharacter - m_tokenStart;
+ break;
+ }
+
+ yylval->number = charactersToDouble(m_tokenStart, m_currentCharacter - m_tokenStart);
+
+ // Type of the function.
+ if (isIdentifierStart()) {
+ UChar* type = m_currentCharacter;
+ result = m_currentCharacter;
+
+ parseIdentifier(result, hasEscape);
+ if (*m_currentCharacter == '+') {
+ // Any identifier followed by a '+' sign is an invalid dimension.
+ ++m_currentCharacter;
+ m_token = INVALIDDIMEN;
+ } else {
+ m_token = DIMEN;
+ if (!hasEscape)
+ detectNumberToken(type, m_currentCharacter - type);
+
+ if (m_token == DIMEN) {
+ // The decoded number is overwritten, but this is intentional.
+ yylval->string.characters = m_tokenStart;
+ yylval->string.length = m_currentCharacter - m_tokenStart;
+ }
+ }
+ } else if (*m_currentCharacter == '%') {
+ // Although the CSS grammar says {num}% we follow
+ // webkit at the moment which uses {num}%+.
+ do {
+ ++m_currentCharacter;
+ } while (*m_currentCharacter == '%');
+ m_token = PERCENTAGE;
+ } else
+ m_token = dotSeen ? FLOATTOKEN : INTEGER;
+ break;
+ }
+
+ case CharacterDash:
+ if (isIdentifierStartAfterDash(m_currentCharacter)) {
+ --m_currentCharacter;
+ parseIdentifier(result, hasEscape);
+ m_token = IDENT;
+
+ if (*m_currentCharacter == '(') {
+ m_token = FUNCTION;
+ if (!hasEscape)
+ detectDashToken(result - m_tokenStart);
+ ++m_currentCharacter;
+ ++result;
+ } else if (UNLIKELY(m_parsingMode == NthChildMode) && !hasEscape && isASCIIAlphaCaselessEqual(m_tokenStart[1], 'n')) {
+ if (result - m_tokenStart == 2) {
+ // String "-n" is IDENT but "-n+1" is NTH.
+ if (parseNthChildExtra()) {
+ m_token = NTH;
+ result = m_currentCharacter;
+ }
+ } else if (result - m_tokenStart == 3 && m_tokenStart[2] == '-') {
+ // String "-n-" is IDENT but "-n-1" is NTH.
+ // Speculatively decrease m_currentCharacter to detect an nth-child token.
+ m_currentCharacter--;
+ if (parseNthChildExtra()) {
+ m_token = NTH;
+ yylval->string.length = m_currentCharacter - m_tokenStart;
+ } else {
+ // Revert the change to m_currentCharacter if unsuccessful.
+ m_currentCharacter++;
+ }
+ }
+ }
+ yylval->string.characters = m_tokenStart;
+ yylval->string.length = result - m_tokenStart;
+ } else if (m_currentCharacter[0] == '-' && m_currentCharacter[1] == '>') {
+ m_currentCharacter += 2;
+ m_token = SGML_CD;
+ } else if (UNLIKELY(m_parsingMode == NthChildMode)) {
+ // "-[0-9]+n" is always an NthChild.
+ if (parseNthChild()) {
+ parseNthChildExtra();
+ m_token = NTH;
+ yylval->string.characters = m_tokenStart;
+ yylval->string.length = m_currentCharacter - m_tokenStart;
+ }
+ }
break;
- default:
+ case CharacterOther:
+ // m_token is simply the current character.
break;
- }
- return token();
-}
+ case CharacterNull:
+ // Do not advance pointer at the end of input.
+ --m_currentCharacter;
+ break;
-void CSSParser::recheckAtKeyword(const UChar* str, int len)
-{
- String ruleName(str, len);
- if (equalIgnoringCase(ruleName, "@import"))
- yyTok = IMPORT_SYM;
- else if (equalIgnoringCase(ruleName, "@page"))
- yyTok = PAGE_SYM;
- else if (equalIgnoringCase(ruleName, "@media"))
- yyTok = MEDIA_SYM;
- else if (equalIgnoringCase(ruleName, "@font-face"))
- yyTok = FONT_FACE_SYM;
- else if (equalIgnoringCase(ruleName, "@charset"))
- yyTok = CHARSET_SYM;
- else if (equalIgnoringCase(ruleName, "@namespace"))
- yyTok = NAMESPACE_SYM;
- else if (equalIgnoringCase(ruleName, "@-webkit-keyframes"))
- yyTok = WEBKIT_KEYFRAMES_SYM;
- else if (equalIgnoringCase(ruleName, "@-webkit-mediaquery"))
- yyTok = WEBKIT_MEDIAQUERY_SYM;
-}
-
-UChar* CSSParser::text(int *length)
-{
- UChar* start = yytext;
- int l = yyleng;
- switch (yyTok) {
- case STRING:
- l--;
- /* nobreak */
- case HEX:
- case IDSEL:
- start++;
- l--;
+ case CharacterWhiteSpace:
+ m_token = WHITESPACE;
+ // Might start with a '\n'.
+ --m_currentCharacter;
+ do {
+ if (*m_currentCharacter == '\n')
+ ++m_lineNumber;
+ ++m_currentCharacter;
+ } while (*m_currentCharacter <= ' ' && (typesOfASCIICharacters[*m_currentCharacter] == CharacterWhiteSpace));
break;
- case URI:
- // "url("{w}{string}{w}")"
- // "url("{w}{url}{w}")"
- // strip "url(" and ")"
- start += 4;
- l -= 5;
- // strip {w}
- while (l && isHTMLSpace(*start)) {
- ++start;
- --l;
- }
- while (l && isHTMLSpace(start[l - 1]))
- --l;
- if (l && (*start == '"' || *start == '\'')) {
- ASSERT(l >= 2 && start[l - 1] == *start);
- ++start;
- l -= 2;
+
+ case CharacterEndMediaQuery:
+ if (m_parsingMode == MediaQueryMode)
+ m_parsingMode = NormalMode;
+ break;
+
+ case CharacterEndNthChild:
+ if (m_parsingMode == NthChildMode)
+ m_parsingMode = NormalMode;
+ break;
+
+ case CharacterQuote:
+ if (checkAndSkipString(m_currentCharacter, m_token)) {
+ ++result;
+ parseString(result, m_token);
+ m_token = STRING;
+ yylval->string.characters = m_tokenStart + 1;
+ yylval->string.length = result - (m_tokenStart + 1);
}
break;
- default:
+
+ case CharacterExclamationMark: {
+ UChar* start = skipWhiteSpace(m_currentCharacter);
+ if (isEqualToCSSIdentifier(start, "important")) {
+ m_token = IMPORTANT_SYM;
+ m_currentCharacter = start + 9;
+ }
break;
}
- // process escapes
- UChar* out = start;
- UChar* escape = 0;
+ case CharacterHashmark: {
+ UChar* start = m_currentCharacter;
+ result = m_currentCharacter;
- bool sawEscape = false;
+ if (isASCIIDigit(*m_currentCharacter)) {
+ // This must be a valid hex number token.
+ do {
+ ++m_currentCharacter;
+ } while (isASCIIHexDigit(*m_currentCharacter));
+ m_token = HEX;
+ yylval->string.characters = start;
+ yylval->string.length = m_currentCharacter - start;
+ } else if (isIdentifierStart()) {
+ m_token = IDSEL;
+ parseIdentifier(result, hasEscape);
+ if (!hasEscape) {
+ // Check whether the identifier is also a valid hex number.
+ UChar* current = start;
+ m_token = HEX;
+ do {
+ if (!isASCIIHexDigit(*current)) {
+ m_token = IDSEL;
+ break;
+ }
+ ++current;
+ } while (current < result);
+ }
+ yylval->string.characters = start;
+ yylval->string.length = result - start;
+ }
+ break;
+ }
- for (int i = 0; i < l; i++) {
- UChar* current = start + i;
- if (escape == current - 1) {
- if (isASCIIHexDigit(*current))
- continue;
- if (yyTok == STRING &&
- (*current == '\n' || *current == '\r' || *current == '\f')) {
- // ### handle \r\n case
- if (*current != '\r')
- escape = 0;
- continue;
+ case CharacterSlash:
+ // Ignore comments. They are not even considered as white spaces.
+ if (*m_currentCharacter == '*') {
+ ++m_currentCharacter;
+ while (m_currentCharacter[0] != '*' || m_currentCharacter[1] != '/') {
+ if (m_currentCharacter[0] == '\n')
+ ++m_lineNumber;
+ if (m_currentCharacter[0] == '\0' && m_currentCharacter[1] == '\0') {
+ // Unterminated comments are simply ignored.
+ m_currentCharacter -= 2;
+ break;
+ }
+ ++m_currentCharacter;
}
- // in all other cases copy the char to output
- // ###
- *out++ = *current;
- escape = 0;
- continue;
+ m_currentCharacter += 2;
+ goto restartAfterComment;
}
- if (escape == current - 2 && yyTok == STRING &&
- *(current-1) == '\r' && *current == '\n') {
- escape = 0;
- continue;
+ break;
+
+ case CharacterDollar:
+ if (*m_currentCharacter == '=') {
+ ++m_currentCharacter;
+ m_token = ENDSWITH;
}
- if (escape > current - 7 && isASCIIHexDigit(*current))
- continue;
- if (escape) {
- // add escaped char
- unsigned uc = 0;
- escape++;
- while (escape < current) {
- uc *= 16;
- uc += toASCIIHexValue(*escape);
- escape++;
+ break;
+
+ case CharacterAsterisk:
+ if (*m_currentCharacter == '=') {
+ ++m_currentCharacter;
+ m_token = CONTAINS;
+ }
+ break;
+
+ case CharacterPlus:
+ if (UNLIKELY(m_parsingMode == NthChildMode)) {
+ // Simplest case. "+[0-9]*n" is always NthChild.
+ if (parseNthChild()) {
+ parseNthChildExtra();
+ m_token = NTH;
+ yylval->string.characters = m_tokenStart;
+ yylval->string.length = m_currentCharacter - m_tokenStart;
}
- // can't handle chars outside ucs2
- if (uc > 0xffff)
- uc = 0xfffd;
- *out++ = uc;
- escape = 0;
- if (isHTMLSpace(*current))
- continue;
}
- if (!escape && *current == '\\') {
- escape = current;
- sawEscape = true;
- continue;
+ break;
+
+ case CharacterLess:
+ if (m_currentCharacter[0] == '!' && m_currentCharacter[1] == '-' && m_currentCharacter[2] == '-') {
+ m_currentCharacter += 3;
+ m_token = SGML_CD;
}
- *out++ = *current;
- }
- if (escape) {
- // add escaped char
- unsigned uc = 0;
- escape++;
- while (escape < start+l) {
- uc *= 16;
- uc += toASCIIHexValue(*escape);
- escape++;
+ break;
+
+ case CharacterAt:
+ if (isIdentifierStart()) {
+ m_token = ATKEYWORD;
+ ++result;
+ parseIdentifier(result, hasEscape);
+ detectAtToken(result - m_tokenStart, hasEscape);
+ }
+ break;
+
+ case CharacterBackSlash:
+ if (isCSSEscape(*m_currentCharacter)) {
+ --m_currentCharacter;
+ parseIdentifier(result, hasEscape);
+ m_token = IDENT;
+ yylval->string.characters = m_tokenStart;
+ yylval->string.length = result - m_tokenStart;
+ }
+ break;
+
+ case CharacterXor:
+ if (*m_currentCharacter == '=') {
+ ++m_currentCharacter;
+ m_token = BEGINSWITH;
+ }
+ break;
+
+ case CharacterVerticalBar:
+ if (*m_currentCharacter == '=') {
+ ++m_currentCharacter;
+ m_token = DASHMATCH;
+ }
+ break;
+
+ case CharacterTilde:
+ if (*m_currentCharacter == '=') {
+ ++m_currentCharacter;
+ m_token = INCLUDES;
}
- // can't handle chars outside ucs2
- if (uc > 0xffff)
- uc = 0xfffd;
- *out++ = uc;
+ break;
+
+ default:
+ ASSERT_NOT_REACHED();
+ break;
}
- *length = out - start;
+#ifndef NDEBUG
+ switch (token()) {
+ case STRING:
+ ASSERT(yylval->string.characters == m_tokenStart + 1);
+ break;
- // If we have an unrecognized @-keyword, and if we handled any escapes at all, then
- // we should attempt to adjust yyTok to the correct type.
- if (yyTok == ATKEYWORD && sawEscape)
- recheckAtKeyword(start, *length);
+ case IDENT:
+ case NTH:
+ case DIMEN:
+ case UNICODERANGE:
+ case FUNCTION:
+ case ANYFUNCTION:
+ case NOTFUNCTION:
+ case CALCFUNCTION:
+ case MINFUNCTION:
+ case MAXFUNCTION:
+ ASSERT(yylval->string.characters == m_tokenStart && yylval->string.length > 0);
+ break;
- return start;
-}
+ case URI:
+ ASSERT(yylval->string.characters && yylval->string.characters != m_tokenStart);
+ break;
-void CSSParser::countLines()
-{
- for (UChar* current = yytext; current < yytext + yyleng; ++current) {
- if (*current == '\n')
- ++m_lineNumber;
+ case HEX:
+ case IDSEL:
+ ASSERT(yylval->string.characters == m_tokenStart + 1 && yylval->string.length > 0);
+ break;
}
+#endif
+
+ return token();
}
CSSParserSelector* CSSParser::createFloatingSelector()
@@ -7862,27 +9069,27 @@ void CSSParser::updateLastMediaLine(MediaList* media)
void CSSParser::markSelectorListStart()
{
- m_selectorListRange.start = yytext - m_data.get();
+ m_selectorListRange.start = m_tokenStart - m_dataStart.get();
}
void CSSParser::markSelectorListEnd()
{
if (!m_currentRuleData)
return;
- UChar* listEnd = yytext;
- while (listEnd > m_data.get() + 1) {
+ UChar* listEnd = m_tokenStart;
+ while (listEnd > m_dataStart.get() + 1) {
if (isHTMLSpace(*(listEnd - 1)))
--listEnd;
else
break;
}
- m_selectorListRange.end = listEnd - m_data.get();
+ m_selectorListRange.end = listEnd - m_dataStart.get();
}
void CSSParser::markRuleBodyStart()
{
- unsigned offset = yytext - m_data.get();
- if (*yytext == '{')
+ unsigned offset = m_tokenStart - m_dataStart.get();
+ if (*m_tokenStart == '{')
++offset; // Skip the rule body opening brace.
if (offset > m_ruleBodyRange.start)
m_ruleBodyRange.start = offset;
@@ -7891,7 +9098,7 @@ void CSSParser::markRuleBodyStart()
void CSSParser::markRuleBodyEnd()
{
- unsigned offset = yytext - m_data.get();
+ unsigned offset = m_tokenStart - m_dataStart.get();
if (offset > m_ruleBodyRange.end)
m_ruleBodyRange.end = offset;
}
@@ -7900,15 +9107,15 @@ void CSSParser::markPropertyStart()
{
if (!m_inStyleRuleOrDeclaration)
return;
- m_propertyRange.start = yytext - m_data.get();
+ m_propertyRange.start = m_tokenStart - m_dataStart.get();
}
void CSSParser::markPropertyEnd(bool isImportantFound, bool isPropertyParsed)
{
if (!m_inStyleRuleOrDeclaration)
return;
- unsigned offset = yytext - m_data.get();
- if (*yytext == ';') // Include semicolon into the property text.
+ unsigned offset = m_tokenStart - m_dataStart.get();
+ if (*m_tokenStart == ';') // Include semicolon into the property text.
++offset;
m_propertyRange.end = offset;
if (m_propertyRange.start != UINT_MAX && m_currentRuleData) {
@@ -7916,7 +9123,7 @@ void CSSParser::markPropertyEnd(bool isImportantFound, bool isPropertyParsed)
const unsigned start = m_propertyRange.start;
const unsigned end = m_propertyRange.end;
ASSERT(start < end);
- String propertyString = String(m_data.get() + start, end - start).stripWhiteSpace();
+ String propertyString = String(m_dataStart.get() + start, end - start).stripWhiteSpace();
if (propertyString.endsWith(";", true))
propertyString = propertyString.left(propertyString.length() - 1);
size_t colonIndex = propertyString.find(":");
@@ -8135,33 +9342,4 @@ bool isValidNthToken(const CSSParserString& token)
|| equalIgnoringCase(token, "n") || equalIgnoringCase(token, "-n");
}
-#define YY_DECL int CSSParser::lex()
-#define yyconst const
-typedef int yy_state_type;
-typedef unsigned YY_CHAR;
-// The following line makes sure we treat non-Latin-1 Unicode characters correctly.
-#define YY_SC_TO_UI(c) (c > 0xff ? 0xff : c)
-#define YY_DO_BEFORE_ACTION \
- yytext = yy_bp; \
- yyleng = (int) (yy_cp - yy_bp); \
- yy_hold_char = *yy_cp; \
- *yy_cp = 0; \
- yy_c_buf_p = yy_cp;
-#define YY_BREAK break;
-#define ECHO
-#define YY_RULE_SETUP
-#define INITIAL 0
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-#define yyterminate() yyTok = END_TOKEN; return yyTok
-#define YY_FATAL_ERROR(a)
-// The following line is needed to build the tokenizer with a condition stack.
-// The macro is used in the tokenizer grammar with lines containing
-// BEGIN(mediaqueries) and BEGIN(initial). yy_start acts as index to
-// tokenizer transition table, and 'mediaqueries' and 'initial' are
-// offset multipliers that specify which transitions are active
-// in the tokenizer during in each condition (tokenizer state).
-#define BEGIN yy_start = 1 + 2 *
-
-#include "tokenizer.cpp"
-
}
diff --git a/Source/WebCore/css/CSSParser.h b/Source/WebCore/css/CSSParser.h
index adc19025a..b7384eee9 100644
--- a/Source/WebCore/css/CSSParser.h
+++ b/Source/WebCore/css/CSSParser.h
@@ -23,6 +23,7 @@
#ifndef CSSParser_h
#define CSSParser_h
+#include "CSSCalculationValue.h"
#include "CSSGradientValue.h"
#include "CSSParserValues.h"
#include "CSSPropertySourceData.h"
@@ -173,7 +174,7 @@ public:
// CSS3 Parsing Routines (for properties specific to CSS3)
PassRefPtr<CSSValueList> parseShadow(CSSParserValueList*, int propId);
- bool parseBorderImage(int propId, RefPtr<CSSValue>&);
+ bool parseBorderImage(int propId, RefPtr<CSSValue>&, bool important = false);
bool parseBorderImageRepeat(RefPtr<CSSValue>&);
bool parseBorderImageSlice(int propId, RefPtr<CSSBorderImageSliceValue>&);
bool parseBorderImageWidth(RefPtr<CSSPrimitiveValue>&);
@@ -211,6 +212,7 @@ public:
bool parseTextEmphasisStyle(bool important);
bool parseLineBoxContain(bool important);
+ bool parseCalculation(CSSParserValue*);
bool parseFontFeatureTag(CSSValueList*);
bool parseFontFeatureSettings(bool important);
@@ -218,6 +220,8 @@ public:
bool parseFlowThread(int propId, bool important);
bool parseRegionThread(int propId, bool important);
+ bool parseFontVariantLigatures(bool important);
+
int yyparse();
CSSParserSelector* createFloatingSelector();
@@ -315,12 +319,29 @@ public:
void resetRuleBodyMarks() { m_ruleBodyRange.start = m_ruleBodyRange.end = 0; }
void resetPropertyMarks() { m_propertyRange.start = m_propertyRange.end = UINT_MAX; }
int lex(void* yylval);
- int token() { return yyTok; }
- UChar* text(int* length);
- void countLines();
- int lex();
+ int token() { return m_token; }
+ PassRefPtr<CSSPrimitiveValue> createPrimitiveNumericValue(CSSParserValue*);
+ PassRefPtr<CSSPrimitiveValue> createPrimitiveStringValue(CSSParserValue*);
+
private:
+ inline bool isIdentifierStart();
+
+ static inline UChar* checkAndSkipString(UChar*, UChar);
+
+ void parseEscape(UChar*&);
+ inline void parseIdentifier(UChar*&, bool&);
+ inline void parseString(UChar*&, UChar);
+ inline void parseURI(UChar*&, UChar*&);
+ inline bool parseUnicodeRange();
+ bool parseNthChild();
+ bool parseNthChildExtra();
+ inline void detectFunctionTypeToken(int);
+ inline void detectMediaQueryToken(int);
+ inline void detectNumberToken(UChar*, int);
+ inline void detectDashToken(int);
+ inline void detectAtToken(int, bool);
+
void setStyleSheet(CSSStyleSheet*);
void ensureCSSValuePool();
@@ -356,15 +377,17 @@ private:
bool parseColor(const String&);
- OwnArrayPtr<UChar> m_data;
- UChar* yytext;
- UChar* yy_c_buf_p;
- UChar yy_hold_char;
- int yy_last_accepting_state;
- UChar* yy_last_accepting_cpos;
- int yyleng;
- int yyTok;
- int yy_start;
+ enum ParsingMode {
+ NormalMode,
+ MediaQueryMode,
+ NthChildMode
+ };
+
+ ParsingMode m_parsingMode;
+ OwnArrayPtr<UChar> m_dataStart;
+ UChar* m_currentCharacter;
+ UChar* m_tokenStart;
+ int m_token;
int m_lineNumber;
int m_lastSelectorLineNumber;
@@ -386,6 +409,8 @@ private:
Vector<OwnPtr<CSSParserSelector> > m_reusableSelectorVector;
Vector<OwnPtr<CSSParserSelector> > m_reusableRegionSelectorVector;
+ RefPtr<CSSCalcValue> m_parsedCalculation;
+
// defines units allowed for a certain property, used in parseUnit
enum Units {
FUnknown = 0x0000,
@@ -405,13 +430,19 @@ private:
return static_cast<Units>(static_cast<unsigned>(a) | static_cast<unsigned>(b));
}
- static bool validUnit(CSSParserValue*, Units, bool strict);
+ bool validCalculationUnit(CSSParserValue*, Units);
+ bool validUnit(CSSParserValue*, Units, bool strict);
bool parseBorderImageQuad(Units, RefPtr<CSSPrimitiveValue>&);
-
- PassRefPtr<CSSPrimitiveValue> createPrimitiveNumericValue(CSSParserValue*);
- PassRefPtr<CSSPrimitiveValue> createPrimitiveStringValue(CSSParserValue*);
-
+ int colorIntFromValue(CSSParserValue*);
+
+ enum ReleaseParsedCalcValueCondition {
+ ReleaseParsedCalcValue,
+ DoNotReleaseParsedCalcValue
+ };
+ double parsedDouble(CSSParserValue*, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
+ bool isCalculation(CSSParserValue*);
+
friend class TransformOperationInfo;
#if ENABLE(CSS_FILTERS)
friend class FilterOperationInfo;
diff --git a/Source/WebCore/css/CSSPrimitiveValue.cpp b/Source/WebCore/css/CSSPrimitiveValue.cpp
index a439cbf52..9021a6353 100644
--- a/Source/WebCore/css/CSSPrimitiveValue.cpp
+++ b/Source/WebCore/css/CSSPrimitiveValue.cpp
@@ -338,38 +338,60 @@ void CSSPrimitiveValue::cleanup()
}
}
-template<> int CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, double multiplier, bool computingFontSize)
+double CSSPrimitiveValue::computeDegrees()
+{
+ switch (m_primitiveUnitType) {
+ case CSS_DEG:
+ return getDoubleValue();
+ case CSS_RAD:
+ return rad2deg(getDoubleValue());
+ case CSS_GRAD:
+ return grad2deg(getDoubleValue());
+ case CSS_TURN:
+ return turn2deg(getDoubleValue());
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+}
+
+template<> int CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize)
{
return roundForImpreciseConversion<int, INT_MAX, INT_MIN>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize));
}
-template<> Length CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, double multiplier, bool computingFontSize)
+template<> unsigned CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize)
+{
+ return roundForImpreciseConversion<unsigned, UINT_MAX, 0>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize));
+}
+
+template<> Length CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize)
{
// FIXME: Length.h no longer expects 28 bit integers, so these bounds should be INT_MAX and INT_MIN
return Length(roundForImpreciseConversion<int, intMaxForLength, intMinForLength>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)), Fixed);
}
-template<> short CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, double multiplier, bool computingFontSize)
+template<> short CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize)
{
return roundForImpreciseConversion<short, SHRT_MAX, SHRT_MIN>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize));
}
-template<> unsigned short CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, double multiplier, bool computingFontSize)
+template<> unsigned short CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize)
{
return roundForImpreciseConversion<unsigned short, USHRT_MAX, 0>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize));
}
-template<> float CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, double multiplier, bool computingFontSize)
+template<> float CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize)
{
return static_cast<float>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize));
}
-template<> double CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, double multiplier, bool computingFontSize)
+template<> double CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize)
{
return computeLengthDouble(style, rootStyle, multiplier, computingFontSize);
}
-double CSSPrimitiveValue::computeLengthDouble(RenderStyle* style, RenderStyle* rootStyle, double multiplier, bool computingFontSize)
+double CSSPrimitiveValue::computeLengthDouble(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize)
{
unsigned short type = primitiveType();
@@ -394,7 +416,8 @@ double CSSPrimitiveValue::computeLengthDouble(RenderStyle* style, RenderStyle* r
break;
case CSS_REMS:
applyZoomMultiplier = false;
- factor = computingFontSize ? rootStyle->fontDescription().specifiedSize() : rootStyle->fontDescription().computedSize();
+ if (rootStyle)
+ factor = computingFontSize ? rootStyle->fontDescription().specifiedSize() : rootStyle->fontDescription().computedSize();
break;
case CSS_PX:
break;
@@ -420,7 +443,7 @@ double CSSPrimitiveValue::computeLengthDouble(RenderStyle* style, RenderStyle* r
}
double result = getDoubleValue() * factor;
- if (!applyZoomMultiplier || multiplier == 1.0)
+ if (!applyZoomMultiplier || multiplier == 1.0f)
return result;
// Any original result that was >= 1 should not be allowed to fall below 1. This keeps border lines from
diff --git a/Source/WebCore/css/CSSPrimitiveValue.h b/Source/WebCore/css/CSSPrimitiveValue.h
index 8fd4ad209..3f15ff78d 100644
--- a/Source/WebCore/css/CSSPrimitiveValue.h
+++ b/Source/WebCore/css/CSSPrimitiveValue.h
@@ -116,12 +116,36 @@ public:
UOther
};
- static bool isUnitTypeLength(int type) { return (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) ||
- type == CSSPrimitiveValue::CSS_REMS; }
+ bool isAngle() const
+ {
+ return m_primitiveUnitType == CSS_DEG
+ || m_primitiveUnitType == CSS_RAD
+ || m_primitiveUnitType == CSS_GRAD
+ || m_primitiveUnitType == CSS_TURN;
+ }
+ bool isAttr() const { return m_primitiveUnitType == CSS_ATTR; }
+ bool isCounter() const { return m_primitiveUnitType == CSS_COUNTER; }
+ bool isFontIndependentLength() const { return m_primitiveUnitType >= CSS_PX && m_primitiveUnitType <= CSS_PC; }
+ bool isFontRelativeLength() const
+ {
+ return m_primitiveUnitType == CSS_EMS || m_primitiveUnitType == CSS_EXS || m_primitiveUnitType == CSS_REMS;
+ }
+ bool isIdent() const { return m_primitiveUnitType == CSS_IDENT; }
+ bool isLength() const
+ {
+ return (m_primitiveUnitType >= CSS_EMS && m_primitiveUnitType <= CSS_PC)
+ || m_primitiveUnitType == CSS_REMS;
+ }
+ bool isNumber() const { return m_primitiveUnitType == CSS_NUMBER; }
+ bool isPercentage() const { return m_primitiveUnitType == CSS_PERCENTAGE; }
+ bool isPx() const { return m_primitiveUnitType == CSS_PX; }
+ bool isRect() const { return m_primitiveUnitType == CSS_RECT; }
+ bool isRGBColor() const { return m_primitiveUnitType == CSS_RGBCOLOR; }
+ bool isShape() const { return m_primitiveUnitType == CSS_SHAPE; }
+ bool isString() const { return m_primitiveUnitType == CSS_STRING; }
+ bool isTime() const { return m_primitiveUnitType == CSS_S || m_primitiveUnitType == CSS_MS; }
+ bool isURI() const { return m_primitiveUnitType == CSS_URI; }
- bool isLength() const { return isUnitTypeLength(m_primitiveUnitType); }
- bool isPercentage() const { return m_primitiveUnitType == CSSPrimitiveValue::CSS_PERCENTAGE; }
- bool isNumber() const { return m_primitiveUnitType == CSSPrimitiveValue::CSS_NUMBER; }
static PassRefPtr<CSSPrimitiveValue> createIdentifier(int identifier) { return adoptRef(new CSSPrimitiveValue(identifier)); }
static PassRefPtr<CSSPrimitiveValue> createColor(unsigned rgbValue) { return adoptRef(new CSSPrimitiveValue(rgbValue)); }
@@ -150,6 +174,23 @@ public:
unsigned short primitiveType() const { return m_primitiveUnitType; }
+ double computeDegrees();
+
+ enum TimeUnit { Seconds, Milliseconds };
+ template <typename T, TimeUnit timeUnit> T computeTime()
+ {
+ if (timeUnit == Seconds && m_primitiveUnitType == CSS_S)
+ return getValue<T>();
+ if (timeUnit == Seconds && m_primitiveUnitType == CSS_MS)
+ return getValue<T>() / 1000;
+ if (timeUnit == Milliseconds && m_primitiveUnitType == CSS_MS)
+ return getValue<T>();
+ if (timeUnit == Milliseconds && m_primitiveUnitType == CSS_S)
+ return getValue<T>() * 1000;
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+
/*
* computes a length in pixels out of the given CSSValue. Need the RenderStyle to get
* the fontinfo in case val is defined in em or ex.
@@ -160,7 +201,10 @@ public:
* this is screen/printer dependent, so we probably need a config option for this,
* and some tool to calibrate.
*/
- template<typename T> T computeLength(RenderStyle* currStyle, RenderStyle* rootStyle, double multiplier = 1.0, bool computingFontSize = false);
+ template<typename T> T computeLength(RenderStyle* currStyle, RenderStyle* rootStyle, float multiplier = 1.0f, bool computingFontSize = false);
+
+ // Converts to a Length, mapping various unit types appropriately.
+ template<int> Length convertToLength(RenderStyle* currStyle, RenderStyle* rootStyle, double multiplier = 1.0, bool computingFontSize = false);
// use with care!!!
void setPrimitiveType(unsigned short type) { m_primitiveUnitType = type; }
@@ -260,7 +304,7 @@ private:
bool getDoubleValueInternal(UnitTypes targetUnitType, double* result) const;
- double computeLengthDouble(RenderStyle* currentStyle, RenderStyle* rootStyle, double multiplier, bool computingFontSize);
+ double computeLengthDouble(RenderStyle* currentStyle, RenderStyle* rootStyle, float multiplier, bool computingFontSize);
union {
int ident;
diff --git a/Source/WebCore/css/CSSPrimitiveValueMappings.h b/Source/WebCore/css/CSSPrimitiveValueMappings.h
index 6d85beeb3..c5916466c 100644
--- a/Source/WebCore/css/CSSPrimitiveValueMappings.h
+++ b/Source/WebCore/css/CSSPrimitiveValueMappings.h
@@ -36,6 +36,7 @@
#include "FontDescription.h"
#include "FontSmoothingMode.h"
#include "GraphicsTypes.h"
+#include "Length.h"
#include "Path.h"
#include "RenderStyleConstants.h"
#include "SVGRenderStyleDefs.h"
@@ -284,6 +285,9 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(CompositeOperator e)
case CompositePlusLighter:
m_value.ident = CSSValuePlusLighter;
break;
+ case CompositeDifference:
+ ASSERT_NOT_REACHED();
+ break;
}
}
@@ -1217,6 +1221,9 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EFlexPack e)
case PackJustify:
m_value.ident = CSSValueJustify;
break;
+ case PackDistribute:
+ m_value.ident = CSSValueDistribute;
+ break;
}
}
@@ -1231,6 +1238,8 @@ template<> inline CSSPrimitiveValue::operator EFlexPack() const
return PackCenter;
case CSSValueJustify:
return PackJustify;
+ case CSSValueDistribute:
+ return PackDistribute;
default:
ASSERT_NOT_REACHED();
return PackStart;
@@ -3142,8 +3151,8 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineGridSnap gridSnap)
case LineGridSnapBaseline:
m_value.ident = CSSValueBaseline;
break;
- case LineGridSnapBounds:
- m_value.ident = CSSValueBounds;
+ case LineGridSnapContain:
+ m_value.ident = CSSValueContain;
break;
}
}
@@ -3155,8 +3164,8 @@ template<> inline CSSPrimitiveValue::operator LineGridSnap() const
return LineGridSnapNone;
case CSSValueBaseline:
return LineGridSnapBaseline;
- case CSSValueBounds:
- return LineGridSnapBounds;
+ case CSSValueContain:
+ return LineGridSnapContain;
default:
ASSERT_NOT_REACHED();
return LineGridSnapNone;
@@ -3673,6 +3682,21 @@ template<> inline CSSPrimitiveValue::operator WrapThrough() const
}
}
+enum LengthConversion { UnsupportedConversion = 0, FixedConversion = 1, AutoConversion = 2, PercentConversion = 4, FractionConversion = 8};
+template<int supported> Length CSSPrimitiveValue::convertToLength(RenderStyle* style, RenderStyle* rootStyle, double multiplier, bool computingFontSize)
+{
+ if ((supported & FixedConversion) && isLength())
+ return computeLength<Length>(style, rootStyle, multiplier, computingFontSize);
+ if ((supported & PercentConversion) && isPercentage())
+ return Length(getDoubleValue(), Percent);
+ if ((supported & FractionConversion) && isNumber())
+ return Length(getDoubleValue() * 100.0, Percent);
+ if ((supported & AutoConversion) && getIdent() == CSSValueAuto)
+ return Length(Auto);
+ ASSERT_NOT_REACHED();
+ return Length(Undefined);
+}
+
#if ENABLE(SVG)
template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EColorInterpolation e)
diff --git a/Source/WebCore/css/CSSProperty.cpp b/Source/WebCore/css/CSSProperty.cpp
index b3d056c56..1071bbef4 100644
--- a/Source/WebCore/css/CSSProperty.cpp
+++ b/Source/WebCore/css/CSSProperty.cpp
@@ -320,6 +320,7 @@ bool CSSProperty::isInheritedProperty(unsigned propertyID)
case CSSPropertyWebkitFontFeatureSettings:
case CSSPropertyWebkitFontKerning:
case CSSPropertyWebkitFontSmoothing:
+ case CSSPropertyWebkitFontVariantLigatures:
case CSSPropertyWebkitLocale:
case CSSPropertyWebkitHighlight:
case CSSPropertyWebkitHyphenateCharacter:
@@ -559,6 +560,7 @@ bool CSSProperty::isInheritedProperty(unsigned propertyID)
#endif
case CSSPropertyWebkitFlexOrder:
case CSSPropertyWebkitFlexPack:
+ case CSSPropertyWebkitFlexAlign:
case CSSPropertyWebkitFlexItemAlign:
case CSSPropertyWebkitFlexDirection:
case CSSPropertyWebkitFlexFlow:
diff --git a/Source/WebCore/css/CSSPropertyLonghand.cpp b/Source/WebCore/css/CSSPropertyLonghand.cpp
index bdd128c77..0d03b20bf 100644
--- a/Source/WebCore/css/CSSPropertyLonghand.cpp
+++ b/Source/WebCore/css/CSSPropertyLonghand.cpp
@@ -66,6 +66,15 @@ static void initShorthandMap(ShorthandMap& shorthandMap)
};
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderColor, borderColorProperties);
+ static const int borderImageProperties[] = {
+ CSSPropertyBorderImageSource,
+ CSSPropertyBorderImageSlice,
+ CSSPropertyBorderImageWidth,
+ CSSPropertyBorderImageOutset,
+ CSSPropertyBorderImageRepeat
+ };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderImage, borderImageProperties);
+
static const int borderStyleProperties[] = {
CSSPropertyBorderTopStyle,
CSSPropertyBorderRightStyle,
diff --git a/Source/WebCore/css/CSSPropertyNames.in b/Source/WebCore/css/CSSPropertyNames.in
index e69875bb8..ceb2798ec 100644
--- a/Source/WebCore/css/CSSPropertyNames.in
+++ b/Source/WebCore/css/CSSPropertyNames.in
@@ -23,6 +23,7 @@ text-rendering
-webkit-font-feature-settings
-webkit-font-kerning
-webkit-font-smoothing
+-webkit-font-variant-ligatures
-webkit-locale
-webkit-text-orientation
-epub-text-orientation = -webkit-text-orientation
@@ -254,6 +255,7 @@ z-index
#if defined(ENABLE_CSS_FILTERS) && ENABLE_CSS_FILTERS
-webkit-filter
#endif
+-webkit-flex-align
-webkit-flex-direction
-webkit-flex-flow
-webkit-flex-item-align
diff --git a/Source/WebCore/css/CSSRule.idl b/Source/WebCore/css/CSSRule.idl
index 0fda9efd4..69d7a8b45 100644
--- a/Source/WebCore/css/CSSRule.idl
+++ b/Source/WebCore/css/CSSRule.idl
@@ -43,7 +43,7 @@ module css {
readonly attribute unsigned short type;
- attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString cssText
+ attribute [ConvertNullStringTo=Null, TreatNullAs=EmptyString] DOMString cssText
setter raises (DOMException);
readonly attribute CSSStyleSheet parentStyleSheet;
diff --git a/Source/WebCore/css/CSSStyleApplyProperty.cpp b/Source/WebCore/css/CSSStyleApplyProperty.cpp
index 0b4a63336..629470b89 100644
--- a/Source/WebCore/css/CSSStyleApplyProperty.cpp
+++ b/Source/WebCore/css/CSSStyleApplyProperty.cpp
@@ -35,6 +35,7 @@
#include "Document.h"
#include "Element.h"
#include "Pair.h"
+#include "Rect.h"
#include "RenderObject.h"
#include "RenderStyle.h"
#include "Settings.h"
@@ -46,7 +47,7 @@ using namespace std;
namespace WebCore {
enum ExpandValueBehavior {SuppressValue = 0, ExpandValue};
-template <ExpandValueBehavior expandValue, CSSPropertyID one = CSSPropertyInvalid, CSSPropertyID two = CSSPropertyInvalid, CSSPropertyID three = CSSPropertyInvalid, CSSPropertyID four = CSSPropertyInvalid>
+template <ExpandValueBehavior expandValue, CSSPropertyID one = CSSPropertyInvalid, CSSPropertyID two = CSSPropertyInvalid, CSSPropertyID three = CSSPropertyInvalid, CSSPropertyID four = CSSPropertyInvalid, CSSPropertyID five = CSSPropertyInvalid>
class ApplyPropertyExpanding {
public:
@@ -68,6 +69,7 @@ public:
applyInheritValue<two>(selector);
applyInheritValue<three>(selector);
applyInheritValue<four>(selector);
+ applyInheritValue<five>(selector);
}
template <CSSPropertyID id>
@@ -88,6 +90,7 @@ public:
applyInitialValue<two>(selector);
applyInitialValue<three>(selector);
applyInitialValue<four>(selector);
+ applyInitialValue<five>(selector);
}
template <CSSPropertyID id>
@@ -111,6 +114,7 @@ public:
applyValue<two>(selector, value);
applyValue<three>(selector, value);
applyValue<four>(selector, value);
+ applyValue<five>(selector, value);
}
static PropertyHandler createHandler() { return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue); }
};
@@ -212,6 +216,51 @@ public:
static PropertyHandler createHandler() { return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue); }
};
+class ApplyPropertyClip {
+private:
+ static Length convertToLength(CSSStyleSelector* selector, CSSPrimitiveValue* value)
+ {
+ return value->convertToLength<FixedConversion | PercentConversion | FractionConversion | AutoConversion>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom());
+ }
+public:
+ static void applyInheritValue(CSSStyleSelector* selector)
+ {
+ RenderStyle* parentStyle = selector->parentStyle();
+ if (!parentStyle->hasClip())
+ return applyInitialValue(selector);
+ selector->style()->setClip(parentStyle->clipTop(), parentStyle->clipRight(), parentStyle->clipBottom(), parentStyle->clipLeft());
+ selector->style()->setHasClip(true);
+ }
+
+ static void applyInitialValue(CSSStyleSelector* selector)
+ {
+ selector->style()->setClip(Length(), Length(), Length(), Length());
+ selector->style()->setHasClip(false);
+ }
+
+ static void applyValue(CSSStyleSelector* selector, CSSValue* value)
+ {
+ if (!value->isPrimitiveValue())
+ return;
+
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+
+ if (Rect* rect = primitiveValue->getRectValue()) {
+ Length top = convertToLength(selector, rect->top());
+ Length right = convertToLength(selector, rect->right());
+ Length bottom = convertToLength(selector, rect->bottom());
+ Length left = convertToLength(selector, rect->left());
+ selector->style()->setClip(top, right, bottom, left);
+ selector->style()->setHasClip(true);
+ } else if (primitiveValue->getIdent() == CSSValueAuto) {
+ selector->style()->setClip(Length(), Length(), Length(), Length());
+ selector->style()->setHasClip(true);
+ }
+ }
+
+ static PropertyHandler createHandler() { return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue); }
+};
+
enum ColorInherit {NoInheritFromParent = 0, InheritFromParent};
Color defaultInitialColor();
Color defaultInitialColor() { return Color(); }
@@ -329,12 +378,11 @@ public:
else if (autoEnabled && primitiveValue->getIdent() == CSSValueAuto)
setValue(selector->style(), Length());
else {
- int type = primitiveValue->primitiveType();
- if (CSSPrimitiveValue::isUnitTypeLength(type)) {
+ if (primitiveValue->isLength()) {
Length length = primitiveValue->computeLength<Length>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom());
length.setQuirk(primitiveValue->isQuirkValue());
setValue(selector->style(), length);
- } else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ } else if (primitiveValue->isPercentage())
setValue(selector->style(), Length(primitiveValue->getDoubleValue(), Percent));
}
}
@@ -385,11 +433,11 @@ public:
Length radiusWidth;
Length radiusHeight;
- if (pair->first()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ if (pair->first()->isPercentage())
radiusWidth = Length(pair->first()->getDoubleValue(), Percent);
else
radiusWidth = Length(max(intMinForLength, min(intMaxForLength, pair->first()->computeLength<int>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom()))), Fixed);
- if (pair->second()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ if (pair->second()->isPercentage())
radiusHeight = Length(pair->second()->getDoubleValue(), Percent);
else
radiusHeight = Length(max(intMinForLength, min(intMaxForLength, pair->second()->computeLength<int>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom()))), Fixed);
@@ -669,12 +717,8 @@ public:
fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize && (ident == CSSValueLarger || ident == CSSValueSmaller));
} else {
- int type = primitiveValue->primitiveType();
fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize
- || (type != CSSPrimitiveValue::CSS_PERCENTAGE
- && type != CSSPrimitiveValue::CSS_EMS
- && type != CSSPrimitiveValue::CSS_EXS
- && type != CSSPrimitiveValue::CSS_REMS));
+ || !(primitiveValue->isPercentage() || primitiveValue->isFontRelativeLength()));
if (primitiveValue->isLength())
size = primitiveValue->computeLength<float>(selector->parentStyle(), selector->rootElementStyle(), 1.0, true);
else if (primitiveValue->isPercentage())
@@ -724,6 +768,90 @@ public:
}
};
+class ApplyPropertyFontVariantLigatures {
+public:
+ static void applyInheritValue(CSSStyleSelector* selector)
+ {
+ const FontDescription& parentFontDescription = selector->parentFontDescription();
+ FontDescription fontDescription = selector->fontDescription();
+
+ fontDescription.setCommonLigaturesState(parentFontDescription.commonLigaturesState());
+ fontDescription.setDiscretionaryLigaturesState(parentFontDescription.discretionaryLigaturesState());
+ fontDescription.setHistoricalLigaturesState(parentFontDescription.historicalLigaturesState());
+
+ selector->setFontDescription(fontDescription);
+ }
+
+ static void applyInitialValue(CSSStyleSelector* selector)
+ {
+ FontDescription fontDescription = selector->fontDescription();
+
+ fontDescription.setCommonLigaturesState(FontDescription::NormalLigaturesState);
+ fontDescription.setDiscretionaryLigaturesState(FontDescription::NormalLigaturesState);
+ fontDescription.setHistoricalLigaturesState(FontDescription::NormalLigaturesState);
+
+ selector->setFontDescription(fontDescription);
+ }
+
+ static void applyValue(CSSStyleSelector* selector, CSSValue* value)
+ {
+ FontDescription::LigaturesState commonLigaturesState = FontDescription::NormalLigaturesState;
+ FontDescription::LigaturesState discretionaryLigaturesState = FontDescription::NormalLigaturesState;
+ FontDescription::LigaturesState historicalLigaturesState = FontDescription::NormalLigaturesState;
+
+ if (value->isValueList()) {
+ CSSValueList* valueList = static_cast<CSSValueList*>(value);
+ for (size_t i = 0; i < valueList->length(); ++i) {
+ CSSValue* item = valueList->itemWithoutBoundsCheck(i);
+ ASSERT(item->isPrimitiveValue());
+ if (item->isPrimitiveValue()) {
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(item);
+ switch (primitiveValue->getIdent()) {
+ case CSSValueNoCommonLigatures:
+ commonLigaturesState = FontDescription::DisabledLigaturesState;
+ break;
+ case CSSValueCommonLigatures:
+ commonLigaturesState = FontDescription::EnabledLigaturesState;
+ break;
+ case CSSValueNoDiscretionaryLigatures:
+ discretionaryLigaturesState = FontDescription::DisabledLigaturesState;
+ break;
+ case CSSValueDiscretionaryLigatures:
+ discretionaryLigaturesState = FontDescription::EnabledLigaturesState;
+ break;
+ case CSSValueNoHistoricalLigatures:
+ historicalLigaturesState = FontDescription::DisabledLigaturesState;
+ break;
+ case CSSValueHistoricalLigatures:
+ historicalLigaturesState = FontDescription::EnabledLigaturesState;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+ }
+ }
+#if !ASSERT_DISABLED
+ else {
+ ASSERT(value->isPrimitiveValue());
+ ASSERT(static_cast<CSSPrimitiveValue*>(value)->getIdent() == CSSValueNormal);
+ }
+#endif
+
+ FontDescription fontDescription = selector->fontDescription();
+ fontDescription.setCommonLigaturesState(commonLigaturesState);
+ fontDescription.setDiscretionaryLigaturesState(discretionaryLigaturesState);
+ fontDescription.setHistoricalLigaturesState(historicalLigaturesState);
+ selector->setFontDescription(fontDescription);
+ }
+
+ static PropertyHandler createHandler()
+ {
+ return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue);
+ }
+};
+
enum BorderImageType { Image = 0, Mask };
template <BorderImageType borderImageType,
CSSPropertyID property,
@@ -779,7 +907,7 @@ public:
NinePieceImage image(getValue(selector->style()));
switch (modifier) {
case Outset:
- image.setOutset(LengthBox());
+ image.setOutset(LengthBox(0));
break;
case Repeat:
image.setHorizontalRule(StretchImageRule);
@@ -939,21 +1067,19 @@ public:
if (!item->isPrimitiveValue())
continue;
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(item);
- int type = primitiveValue->primitiveType();
- if (type == CSSPrimitiveValue::CSS_URI) {
+ if (primitiveValue->isURI()) {
if (primitiveValue->isCursorImageValue()) {
CSSCursorImageValue* image = static_cast<CSSCursorImageValue*>(primitiveValue);
if (image->updateIfSVGCursorIsUsed(selector->element())) // Elements with SVG cursors are not allowed to share style.
selector->style()->setUnique();
selector->style()->addCursor(selector->cachedOrPendingFromValue(CSSPropertyCursor, image), image->hotSpot());
}
- } else if (type == CSSPrimitiveValue::CSS_IDENT)
+ } else if (primitiveValue->isIdent())
selector->style()->setCursor(*primitiveValue);
}
} else if (value->isPrimitiveValue()) {
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
- int type = primitiveValue->primitiveType();
- if (type == CSSPrimitiveValue::CSS_IDENT && selector->style()->cursor() != ECursor(*primitiveValue))
+ if (primitiveValue->isIdent() && selector->style()->cursor() != ECursor(*primitiveValue))
selector->style()->setCursor(*primitiveValue);
}
}
@@ -1152,9 +1278,9 @@ public:
pageSizeType = PAGE_SIZE_RESOLVED;
width = height = primitiveValue->computeLength<Length>(selector->style(), selector->rootElementStyle());
} else {
- if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_IDENT)
- return;
switch (primitiveValue->getIdent()) {
+ case 0:
+ return;
case CSSValueAuto:
pageSizeType = PAGE_SIZE_AUTO;
break;
@@ -1224,7 +1350,7 @@ public:
return;
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
- if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_STRING) {
+ if (primitiveValue->isString()) {
selector->style()->setTextEmphasisFill(TextEmphasisFillFilled);
selector->style()->setTextEmphasisMark(TextEmphasisMarkCustom);
selector->style()->setTextEmphasisCustomMark(primitiveValue->getStringValue());
@@ -1471,11 +1597,11 @@ public:
float docZoom = selector->document()->renderer()->style()->zoom();
selector->setEffectiveZoom(docZoom);
selector->setZoom(docZoom);
- } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE) {
+ } else if (primitiveValue->isPercentage()) {
resetEffectiveZoom(selector);
if (float percent = primitiveValue->getFloatValue())
selector->setZoom(percent / 100.0f);
- } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) {
+ } else if (primitiveValue->isNumber()) {
resetEffectiveZoom(selector);
if (float number = primitiveValue->getFloatValue())
selector->setZoom(number);
@@ -1495,6 +1621,9 @@ private:
#if ENABLE(SVG)
if (selector->element() && selector->element()->isSVGElement() && selector->style()->styleType() == NOPSEUDO)
return (displayPropertyValue == INLINE || displayPropertyValue == BLOCK || displayPropertyValue == NONE);
+#else
+ UNUSED_PARAM(selector);
+ UNUSED_PARAM(displayPropertyValue);
#endif
return true;
}
@@ -1618,12 +1747,12 @@ CSSStyleApplyProperty::CSSStyleApplyProperty()
setPropertyHandler(CSSPropertyBorderBottomStyle, ApplyPropertyDefault<EBorderStyle, &RenderStyle::borderBottomStyle, EBorderStyle, &RenderStyle::setBorderBottomStyle, EBorderStyle, &RenderStyle::initialBorderStyle>::createHandler());
setPropertyHandler(CSSPropertyBorderLeftStyle, ApplyPropertyDefault<EBorderStyle, &RenderStyle::borderLeftStyle, EBorderStyle, &RenderStyle::setBorderLeftStyle, EBorderStyle, &RenderStyle::initialBorderStyle>::createHandler());
- setPropertyHandler(CSSPropertyBorderTopWidth, ApplyPropertyComputeLength<unsigned short, &RenderStyle::borderTopWidth, &RenderStyle::setBorderTopWidth, &RenderStyle::initialBorderWidth, NormalDisabled, ThicknessEnabled>::createHandler());
- setPropertyHandler(CSSPropertyBorderRightWidth, ApplyPropertyComputeLength<unsigned short, &RenderStyle::borderRightWidth, &RenderStyle::setBorderRightWidth, &RenderStyle::initialBorderWidth, NormalDisabled, ThicknessEnabled>::createHandler());
- setPropertyHandler(CSSPropertyBorderBottomWidth, ApplyPropertyComputeLength<unsigned short, &RenderStyle::borderBottomWidth, &RenderStyle::setBorderBottomWidth, &RenderStyle::initialBorderWidth, NormalDisabled, ThicknessEnabled>::createHandler());
- setPropertyHandler(CSSPropertyBorderLeftWidth, ApplyPropertyComputeLength<unsigned short, &RenderStyle::borderLeftWidth, &RenderStyle::setBorderLeftWidth, &RenderStyle::initialBorderWidth, NormalDisabled, ThicknessEnabled>::createHandler());
- setPropertyHandler(CSSPropertyOutlineWidth, ApplyPropertyComputeLength<unsigned short, &RenderStyle::outlineWidth, &RenderStyle::setOutlineWidth, &RenderStyle::initialBorderWidth, NormalDisabled, ThicknessEnabled>::createHandler());
- setPropertyHandler(CSSPropertyWebkitColumnRuleWidth, ApplyPropertyComputeLength<unsigned short, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth, &RenderStyle::initialBorderWidth, NormalDisabled, ThicknessEnabled>::createHandler());
+ setPropertyHandler(CSSPropertyBorderTopWidth, ApplyPropertyComputeLength<unsigned, &RenderStyle::borderTopWidth, &RenderStyle::setBorderTopWidth, &RenderStyle::initialBorderWidth, NormalDisabled, ThicknessEnabled>::createHandler());
+ setPropertyHandler(CSSPropertyBorderRightWidth, ApplyPropertyComputeLength<unsigned, &RenderStyle::borderRightWidth, &RenderStyle::setBorderRightWidth, &RenderStyle::initialBorderWidth, NormalDisabled, ThicknessEnabled>::createHandler());
+ setPropertyHandler(CSSPropertyBorderBottomWidth, ApplyPropertyComputeLength<unsigned, &RenderStyle::borderBottomWidth, &RenderStyle::setBorderBottomWidth, &RenderStyle::initialBorderWidth, NormalDisabled, ThicknessEnabled>::createHandler());
+ setPropertyHandler(CSSPropertyBorderLeftWidth, ApplyPropertyComputeLength<unsigned, &RenderStyle::borderLeftWidth, &RenderStyle::setBorderLeftWidth, &RenderStyle::initialBorderWidth, NormalDisabled, ThicknessEnabled>::createHandler());
+ setPropertyHandler(CSSPropertyOutlineWidth, ApplyPropertyComputeLength<unsigned short, &RenderStyle::outlineWidth, &RenderStyle::setOutlineWidth, &RenderStyle::initialOutlineWidth, NormalDisabled, ThicknessEnabled>::createHandler());
+ setPropertyHandler(CSSPropertyWebkitColumnRuleWidth, ApplyPropertyComputeLength<unsigned short, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth, &RenderStyle::initialColumnRuleWidth, NormalDisabled, ThicknessEnabled>::createHandler());
setPropertyHandler(CSSPropertyBorderTop, ApplyPropertyExpanding<SuppressValue, CSSPropertyBorderTopColor, CSSPropertyBorderTopStyle, CSSPropertyBorderTopWidth>::createHandler());
setPropertyHandler(CSSPropertyBorderRight, ApplyPropertyExpanding<SuppressValue, CSSPropertyBorderRightColor, CSSPropertyBorderRightStyle, CSSPropertyBorderRightWidth>::createHandler());
@@ -1635,7 +1764,7 @@ CSSStyleApplyProperty::CSSStyleApplyProperty()
setPropertyHandler(CSSPropertyBorderColor, ApplyPropertyExpanding<SuppressValue, CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor>::createHandler());
setPropertyHandler(CSSPropertyBorder, ApplyPropertyExpanding<SuppressValue, CSSPropertyBorderStyle, CSSPropertyBorderWidth, CSSPropertyBorderColor>::createHandler());
- setPropertyHandler(CSSPropertyBorderImage, ApplyPropertyBorderImage<Image, CSSPropertyBorderImage, &RenderStyle::borderImage, &RenderStyle::setBorderImage>::createHandler());
+ setPropertyHandler(CSSPropertyBorderImage, ApplyPropertyExpanding<SuppressValue, CSSPropertyBorderImageSource, CSSPropertyBorderImageSlice, CSSPropertyBorderImageWidth, CSSPropertyBorderImageOutset, CSSPropertyBorderImageRepeat>::createHandler());
setPropertyHandler(CSSPropertyWebkitBorderImage, ApplyPropertyBorderImage<Image, CSSPropertyWebkitBorderImage, &RenderStyle::borderImage, &RenderStyle::setBorderImage>::createHandler());
setPropertyHandler(CSSPropertyWebkitMaskBoxImage, ApplyPropertyBorderImage<Mask, CSSPropertyWebkitMaskBoxImage, &RenderStyle::maskBoxImage, &RenderStyle::setMaskBoxImage>::createHandler());
@@ -1665,6 +1794,8 @@ CSSStyleApplyProperty::CSSStyleApplyProperty()
setPropertyHandler(CSSPropertyLetterSpacing, ApplyPropertyComputeLength<int, &RenderStyle::letterSpacing, &RenderStyle::setLetterSpacing, &RenderStyle::initialLetterWordSpacing, NormalEnabled, ThicknessDisabled, SVGZoomEnabled>::createHandler());
setPropertyHandler(CSSPropertyWordSpacing, ApplyPropertyComputeLength<int, &RenderStyle::wordSpacing, &RenderStyle::setWordSpacing, &RenderStyle::initialLetterWordSpacing, NormalEnabled, ThicknessDisabled, SVGZoomEnabled>::createHandler());
+ setPropertyHandler(CSSPropertyClip, ApplyPropertyClip::createHandler());
+
setPropertyHandler(CSSPropertyCursor, ApplyPropertyCursor::createHandler());
setPropertyHandler(CSSPropertyCounterIncrement, ApplyPropertyCounter<Increment>::createHandler());
@@ -1672,6 +1803,7 @@ CSSStyleApplyProperty::CSSStyleApplyProperty()
setPropertyHandler(CSSPropertyWebkitFlexOrder, ApplyPropertyDefault<int, &RenderStyle::flexOrder, int, &RenderStyle::setFlexOrder, int, &RenderStyle::initialFlexOrder>::createHandler());
setPropertyHandler(CSSPropertyWebkitFlexPack, ApplyPropertyDefault<EFlexPack, &RenderStyle::flexPack, EFlexPack, &RenderStyle::setFlexPack, EFlexPack, &RenderStyle::initialFlexPack>::createHandler());
+ setPropertyHandler(CSSPropertyWebkitFlexAlign, ApplyPropertyDefault<EFlexAlign, &RenderStyle::flexAlign, EFlexAlign, &RenderStyle::setFlexAlign, EFlexAlign, &RenderStyle::initialFlexAlign>::createHandler());
setPropertyHandler(CSSPropertyWebkitFlexItemAlign, ApplyPropertyDefault<EFlexAlign, &RenderStyle::flexItemAlign, EFlexAlign, &RenderStyle::setFlexItemAlign, EFlexAlign, &RenderStyle::initialFlexItemAlign>::createHandler());
setPropertyHandler(CSSPropertyWebkitFlexDirection, ApplyPropertyDefault<EFlexDirection, &RenderStyle::flexDirection, EFlexDirection, &RenderStyle::setFlexDirection, EFlexDirection, &RenderStyle::initialFlexDirection>::createHandler());
setPropertyHandler(CSSPropertyWebkitFlexWrap, ApplyPropertyDefault<EFlexWrap, &RenderStyle::flexWrap, EFlexWrap, &RenderStyle::setFlexWrap, EFlexWrap, &RenderStyle::initialFlexWrap>::createHandler());
@@ -1684,6 +1816,7 @@ CSSStyleApplyProperty::CSSStyleApplyProperty()
setPropertyHandler(CSSPropertyWebkitFontKerning, ApplyPropertyFont<FontDescription::Kerning, &FontDescription::kerning, &FontDescription::setKerning, FontDescription::AutoKerning>::createHandler());
setPropertyHandler(CSSPropertyWebkitFontSmoothing, ApplyPropertyFont<FontSmoothingMode, &FontDescription::fontSmoothing, &FontDescription::setFontSmoothing, AutoSmoothing>::createHandler());
setPropertyHandler(CSSPropertyWebkitTextOrientation, ApplyPropertyFont<TextOrientation, &FontDescription::textOrientation, &FontDescription::setTextOrientation, TextOrientationVerticalRight>::createHandler());
+ setPropertyHandler(CSSPropertyWebkitFontVariantLigatures, ApplyPropertyFontVariantLigatures::createHandler());
setPropertyHandler(CSSPropertyFontWeight, ApplyPropertyFontWeight::createHandler());
setPropertyHandler(CSSPropertyTextAlign, ApplyPropertyTextAlign::createHandler());
diff --git a/Source/WebCore/css/CSSStyleDeclaration.cpp b/Source/WebCore/css/CSSStyleDeclaration.cpp
index a1d61b88f..133fea2b7 100644
--- a/Source/WebCore/css/CSSStyleDeclaration.cpp
+++ b/Source/WebCore/css/CSSStyleDeclaration.cpp
@@ -21,7 +21,6 @@
#include "config.h"
#include "CSSStyleDeclaration.h"
-#include "CSSElementStyleDeclaration.h"
#include "CSSMutableStyleDeclaration.h"
#include "CSSParser.h"
#include "CSSProperty.h"
@@ -29,6 +28,7 @@
#include "CSSRule.h"
#include "Node.h"
#include "SVGElement.h"
+#include "StyledElement.h"
#include <wtf/ASCIICType.h>
#include <wtf/text/CString.h>
#ifndef NDEBUG
@@ -39,84 +39,27 @@ using namespace WTF;
namespace WebCore {
-CSSStyleDeclaration::CSSStyleDeclaration(CSSRule* parent)
- : m_strictParsing(!parent || parent->useStrictParsing())
-#ifndef NDEBUG
- , m_iteratorCount(0)
-#endif
- , m_isElementStyleDeclaration(false)
+CSSStyleDeclaration::CSSStyleDeclaration(CSSRule* parentRule)
+ : m_strictParsing(!parentRule || parentRule->useStrictParsing())
, m_isInlineStyleDeclaration(false)
- , m_parentRule(parent)
-{
-}
-
-CSSStyleSheet* CSSStyleDeclaration::parentStyleSheet() const
-{
- if (parentRule())
- return parentRule()->parentStyleSheet();
- if (isElementStyleDeclaration())
- return static_cast<const CSSElementStyleDeclaration*>(this)->styleSheet();
- return 0;
-}
-
-PassRefPtr<CSSValue> CSSStyleDeclaration::getPropertyCSSValue(const String& propertyName)
-{
- int propID = cssPropertyID(propertyName);
- if (!propID)
- return 0;
- return getPropertyCSSValue(propID);
-}
-
-String CSSStyleDeclaration::getPropertyValue(const String &propertyName)
-{
- int propID = cssPropertyID(propertyName);
- if (!propID)
- return String();
- return getPropertyValue(propID);
-}
-
-String CSSStyleDeclaration::getPropertyPriority(const String& propertyName)
-{
- int propID = cssPropertyID(propertyName);
- if (!propID)
- return String();
- return getPropertyPriority(propID) ? "important" : "";
-}
-
-String CSSStyleDeclaration::getPropertyShorthand(const String& propertyName)
+ , m_parent(parentRule)
{
- int propID = cssPropertyID(propertyName);
- if (!propID)
- return String();
- int shorthandID = getPropertyShorthand(propID);
- if (!shorthandID)
- return String();
- return getPropertyName(static_cast<CSSPropertyID>(shorthandID));
}
-bool CSSStyleDeclaration::isPropertyImplicit(const String& propertyName)
+CSSStyleDeclaration::CSSStyleDeclaration(StyledElement* parentElement)
+ : m_strictParsing(false)
+ , m_isInlineStyleDeclaration(true)
+ , m_parent(parentElement)
{
- int propID = cssPropertyID(propertyName);
- if (!propID)
- return false;
- return isPropertyImplicit(propID);
}
-void CSSStyleDeclaration::setProperty(const String& propertyName, const String& value, const String& priority, ExceptionCode& ec)
-{
- int propID = cssPropertyID(propertyName);
- if (!propID)
- return;
- bool important = priority.find("important", 0, false) != notFound;
- setProperty(propID, value, important, ec);
-}
-
-String CSSStyleDeclaration::removeProperty(const String& propertyName, ExceptionCode& ec)
+CSSStyleSheet* CSSStyleDeclaration::parentStyleSheet() const
{
- int propID = cssPropertyID(propertyName);
- if (!propID)
- return String();
- return removeProperty(propID, ec);
+ if (m_isInlineStyleDeclaration) {
+ Document* document = m_parent.element ? m_parent.element->document() : 0;
+ return document ? document->elementSheet() : 0;
+ }
+ return m_parent.rule ? m_parent.rule->parentStyleSheet() : 0;
}
bool CSSStyleDeclaration::isPropertyName(const String& propertyName)
@@ -124,44 +67,6 @@ bool CSSStyleDeclaration::isPropertyName(const String& propertyName)
return cssPropertyID(propertyName);
}
-bool CSSStyleDeclaration::cssPropertyMatches(const CSSProperty* property) const
-{
- RefPtr<CSSValue> value = getPropertyCSSValue(property->id());
- return value && value->cssText() == property->value()->cssText();
-}
-
-void CSSStyleDeclaration::diff(CSSMutableStyleDeclaration* style) const
-{
- if (!style)
- return;
-
- Vector<int> propertiesToRemove;
- {
- CSSMutableStyleDeclaration::const_iterator end = style->end();
- for (CSSMutableStyleDeclaration::const_iterator it = style->begin(); it != end; ++it) {
- const CSSProperty& property = *it;
- if (cssPropertyMatches(&property))
- propertiesToRemove.append(property.id());
- }
- }
-
- // FIXME: This should use mass removal.
- for (unsigned i = 0; i < propertiesToRemove.size(); i++)
- style->removeProperty(propertiesToRemove[i]);
-}
-
-PassRefPtr<CSSMutableStyleDeclaration> CSSStyleDeclaration::copyPropertiesInSet(const int* set, unsigned length) const
-{
- Vector<CSSProperty> list;
- list.reserveInitialCapacity(length);
- for (unsigned i = 0; i < length; i++) {
- RefPtr<CSSValue> value = getPropertyCSSValue(set[i]);
- if (value)
- list.append(CSSProperty(set[i], value.release(), false));
- }
- return CSSMutableStyleDeclaration::create(list);
-}
-
#ifndef NDEBUG
void CSSStyleDeclaration::showStyle()
{
diff --git a/Source/WebCore/css/CSSStyleDeclaration.h b/Source/WebCore/css/CSSStyleDeclaration.h
index a54b0c60a..12910da46 100644
--- a/Source/WebCore/css/CSSStyleDeclaration.h
+++ b/Source/WebCore/css/CSSStyleDeclaration.h
@@ -21,6 +21,7 @@
#ifndef CSSStyleDeclaration_h
#define CSSStyleDeclaration_h
+#include "CSSPropertyNames.h"
#include "CSSRule.h"
#include <wtf/Forward.h>
@@ -30,6 +31,7 @@ class CSSMutableStyleDeclaration;
class CSSProperty;
class CSSStyleSheet;
class CSSValue;
+class StyledElement;
typedef int ExceptionCode;
@@ -40,70 +42,61 @@ public:
static bool isPropertyName(const String&);
- CSSRule* parentRule() const { return m_parentRule; }
- void clearParentRule() { m_parentRule = 0; }
+ CSSRule* parentRule() const { return m_isInlineStyleDeclaration ? 0 : m_parent.rule; }
+ void clearParentRule() { ASSERT(!m_isInlineStyleDeclaration); m_parent.rule = 0; }
+
+ StyledElement* parentElement() const { ASSERT(m_isInlineStyleDeclaration); return m_parent.element; }
+ void clearParentElement() { ASSERT(m_isInlineStyleDeclaration); m_parent.element = 0; }
CSSStyleSheet* parentStyleSheet() const;
virtual String cssText() const = 0;
virtual void setCssText(const String&, ExceptionCode&) = 0;
-
- unsigned length() const { return virtualLength(); }
- virtual unsigned virtualLength() const = 0;
- bool isEmpty() const { return !length(); }
+ virtual unsigned length() const = 0;
virtual String item(unsigned index) const = 0;
-
- PassRefPtr<CSSValue> getPropertyCSSValue(const String& propertyName);
- String getPropertyValue(const String& propertyName);
- String getPropertyPriority(const String& propertyName);
- String getPropertyShorthand(const String& propertyName);
- bool isPropertyImplicit(const String& propertyName);
-
- virtual PassRefPtr<CSSValue> getPropertyCSSValue(int propertyID) const = 0;
- virtual String getPropertyValue(int propertyID) const = 0;
- virtual bool getPropertyPriority(int propertyID) const = 0;
- virtual int getPropertyShorthand(int propertyID) const = 0;
- virtual bool isPropertyImplicit(int propertyID) const = 0;
-
- void setProperty(const String& propertyName, const String& value, const String& priority, ExceptionCode&);
- String removeProperty(const String& propertyName, ExceptionCode&);
- virtual void setProperty(int propertyId, const String& value, bool important, ExceptionCode&) = 0;
- virtual String removeProperty(int propertyID, ExceptionCode&) = 0;
+ virtual PassRefPtr<CSSValue> getPropertyCSSValue(const String& propertyName) = 0;
+ virtual String getPropertyValue(const String& propertyName) = 0;
+ virtual String getPropertyPriority(const String& propertyName) = 0;
+ virtual String getPropertyShorthand(const String& propertyName) = 0;
+ virtual bool isPropertyImplicit(const String& propertyName) = 0;
+ virtual void setProperty(const String& propertyName, const String& value, const String& priority, ExceptionCode&) = 0;
+ virtual String removeProperty(const String& propertyName, ExceptionCode&) = 0;
+
+ // CSSPropertyID versions of the CSSOM functions to support bindings and editing.
+ // Use the non-virtual methods in the concrete subclasses when possible.
+ virtual PassRefPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) = 0;
+ virtual String getPropertyValueInternal(CSSPropertyID) = 0;
+ virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionCode&) = 0;
virtual PassRefPtr<CSSMutableStyleDeclaration> copy() const = 0;
virtual PassRefPtr<CSSMutableStyleDeclaration> makeMutable() = 0;
- void diff(CSSMutableStyleDeclaration*) const;
-
- PassRefPtr<CSSMutableStyleDeclaration> copyPropertiesInSet(const int* set, unsigned length) const;
+ virtual bool cssPropertyMatches(const CSSProperty*) const = 0;
#ifndef NDEBUG
void showStyle();
#endif
- bool isElementStyleDeclaration() const { return m_isElementStyleDeclaration; }
bool isInlineStyleDeclaration() const { return m_isInlineStyleDeclaration; }
protected:
CSSStyleDeclaration(CSSRule* parentRule = 0);
-
- virtual bool cssPropertyMatches(const CSSProperty*) const;
+ CSSStyleDeclaration(StyledElement* parentElement);
// The bits in this section are only used by specific subclasses but kept here
// to maximize struct packing.
// CSSMutableStyleDeclaration bits:
bool m_strictParsing : 1;
-#ifndef NDEBUG
- unsigned m_iteratorCount : 4;
-#endif
-
- // CSSElementStyleDeclaration bits:
- bool m_isElementStyleDeclaration : 1;
bool m_isInlineStyleDeclaration : 1;
private:
- CSSRule* m_parentRule;
+ union Parent {
+ Parent(CSSRule* rule) : rule(rule) { }
+ Parent(StyledElement* element) : element(element) { }
+ CSSRule* rule;
+ StyledElement* element;
+ } m_parent;
};
} // namespace WebCore
diff --git a/Source/WebCore/css/CSSStyleDeclaration.idl b/Source/WebCore/css/CSSStyleDeclaration.idl
index d1b470f87..976130499 100644
--- a/Source/WebCore/css/CSSStyleDeclaration.idl
+++ b/Source/WebCore/css/CSSStyleDeclaration.idl
@@ -30,7 +30,7 @@ module css {
CustomGetPropertyNames,
V8DependentLifetime
] CSSStyleDeclaration {
- attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString cssText
+ attribute [ConvertNullStringTo=Null, TreatNullAs=EmptyString] DOMString cssText
setter raises(DOMException);
[ConvertNullStringTo=Null] DOMString getPropertyValue(in [Optional=CallWithDefaultValue] DOMString propertyName);
@@ -39,7 +39,7 @@ module css {
raises(DOMException);
[ConvertNullStringTo=Null] DOMString getPropertyPriority(in [Optional=CallWithDefaultValue] DOMString propertyName);
[OldStyleObjC] void setProperty(in [Optional=CallWithDefaultValue] DOMString propertyName,
- in [ConvertNullToNullString,Optional=CallWithDefaultValue] DOMString value,
+ in [TreatNullAs=EmptyString,Optional=CallWithDefaultValue] DOMString value,
in [Optional=CallWithDefaultValue] DOMString priority)
raises(DOMException);
diff --git a/Source/WebCore/css/CSSStyleRule.cpp b/Source/WebCore/css/CSSStyleRule.cpp
index 6296e64b7..535e9f15d 100644
--- a/Source/WebCore/css/CSSStyleRule.cpp
+++ b/Source/WebCore/css/CSSStyleRule.cpp
@@ -98,15 +98,8 @@ String CSSStyleRule::selectorText() const
void CSSStyleRule::setSelectorText(const String& selectorText)
{
Document* doc = 0;
-
if (CSSStyleSheet* styleSheet = m_style->parentStyleSheet())
doc = styleSheet->findDocument();
-
- if (!doc && m_style->isElementStyleDeclaration()) {
- if (StyledElement* element = static_cast<CSSElementStyleDeclaration*>(m_style.get())->element())
- doc = element->document();
- }
-
if (!doc)
return;
@@ -135,7 +128,7 @@ String CSSStyleRule::cssText() const
String result = selectorText();
result += " { ";
- result += m_style->cssText();
+ result += m_style->asText();
result += "}";
return result;
diff --git a/Source/WebCore/css/CSSStyleRule.h b/Source/WebCore/css/CSSStyleRule.h
index 111c5f1aa..713e68245 100644
--- a/Source/WebCore/css/CSSStyleRule.h
+++ b/Source/WebCore/css/CSSStyleRule.h
@@ -43,15 +43,15 @@ public:
String selectorText() const;
void setSelectorText(const String&);
- CSSMutableStyleDeclaration* style() const { return m_style.get(); }
+ CSSStyleDeclaration* style() const { return m_style.get(); }
String cssText() const;
void adoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); }
- void setDeclaration(PassRefPtr<CSSMutableStyleDeclaration> style) { m_style = style; }
+ void setDeclaration(PassRefPtr<CSSMutableStyleDeclaration> style) { ASSERT(style->parentRule() == this); m_style = style; }
const CSSSelectorList& selectorList() const { return m_selectorList; }
- CSSMutableStyleDeclaration* declaration() { return m_style.get(); }
+ CSSMutableStyleDeclaration* declaration() const { return m_style.get(); }
void addSubresourceStyleURLs(ListHashSet<KURL>& urls);
diff --git a/Source/WebCore/css/CSSStyleRule.idl b/Source/WebCore/css/CSSStyleRule.idl
index 4abfbfc45..aca408e29 100644
--- a/Source/WebCore/css/CSSStyleRule.idl
+++ b/Source/WebCore/css/CSSStyleRule.idl
@@ -23,7 +23,7 @@ module css {
// Introduced in DOM Level 2:
interface CSSStyleRule : CSSRule {
- attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString selectorText;
+ attribute [ConvertNullStringTo=Null, TreatNullAs=EmptyString] DOMString selectorText;
readonly attribute CSSStyleDeclaration style;
diff --git a/Source/WebCore/css/CSSStyleSelector.cpp b/Source/WebCore/css/CSSStyleSelector.cpp
index 97f19cfba..abac39885 100644
--- a/Source/WebCore/css/CSSStyleSelector.cpp
+++ b/Source/WebCore/css/CSSStyleSelector.cpp
@@ -33,7 +33,7 @@
#include "ContentData.h"
#include "Counter.h"
#include "CounterContent.h"
-#include "CSSBorderImageValue.h"
+#include "CSSBorderImage.h"
#include "CSSCursorImageValue.h"
#include "CSSFontFaceRule.h"
#include "CSSFontSelector.h"
@@ -65,6 +65,7 @@
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "HTMLProgressElement.h"
+#include "HTMLStyleElement.h"
#include "HTMLTextAreaElement.h"
#include "InspectorInstrumentation.h"
#include "KeyframeList.h"
@@ -81,6 +82,7 @@
#include "PerspectiveTransformOperation.h"
#include "QuotesData.h"
#include "Rect.h"
+#include "RenderRegion.h"
#include "RenderScrollbar.h"
#include "RenderScrollbarTheme.h"
#include "RenderStyleConstants.h"
@@ -123,8 +125,11 @@
#endif
#if ENABLE(CSS_SHADERS)
+#include "CustomFilterNumberParameter.h"
#include "CustomFilterOperation.h"
+#include "CustomFilterParameter.h"
#include "StyleCachedShader.h"
+#include "StyleCustomFilterProgram.h"
#include "StylePendingShader.h"
#include "StyleShader.h"
#include "WebKitCSSShaderValue.h"
@@ -218,16 +223,17 @@ public:
typedef HashMap<AtomicStringImpl*, OwnPtr<Vector<RuleData> > > AtomRuleMap;
- void addRulesFromSheet(CSSStyleSheet*, const MediaQueryEvaluator&, CSSStyleSelector* = 0);
+ void addRulesFromSheet(CSSStyleSheet*, const MediaQueryEvaluator&, CSSStyleSelector* = 0, const Element* = 0);
- void addStyleRule(CSSStyleRule* item);
- void addRule(CSSStyleRule* rule, CSSSelector* sel);
+ void addStyleRule(CSSStyleRule*);
+ void addRule(CSSStyleRule*, CSSSelector*);
void addPageRule(CSSPageRule*);
- void addToRuleSet(AtomicStringImpl* key, AtomRuleMap&, CSSStyleRule*, CSSSelector*);
+ void addToRuleSet(AtomicStringImpl* key, AtomRuleMap&, const RuleData&);
+ void addRegionRule(WebKitCSSRegionRule*);
void shrinkToFit();
void disableAutoShrinkToFit() { m_autoShrinkToFitEnabled = false; }
- void collectFeatures(CSSStyleSelector::Features&) const;
+ const CSSStyleSelector::Features& features() const { return m_features; }
const Vector<RuleData>* idRules(AtomicStringImpl* key) const { return m_idRules.get(key); }
const Vector<RuleData>* classRules(AtomicStringImpl* key) const { return m_classRules.get(key); }
@@ -249,6 +255,16 @@ public:
Vector<RuleData> m_pageRules;
unsigned m_ruleCount;
bool m_autoShrinkToFitEnabled;
+ CSSStyleSelector::Features m_features;
+
+ struct RuleSetSelectorPair {
+ RuleSetSelectorPair(CSSSelector* selector, RuleSet* ruleSet) : selector(selector), ruleSet(adoptPtr(ruleSet)) { }
+ RuleSetSelectorPair(const RuleSetSelectorPair& rs) : selector(rs.selector), ruleSet(const_cast<RuleSetSelectorPair*>(&rs)->ruleSet.release()) { }
+ CSSSelector* selector;
+ OwnPtr<RuleSet> ruleSet;
+ };
+
+ Vector<RuleSetSelectorPair> m_regionSelectorsAndRuleSets;
};
static RuleSet* defaultStyle;
@@ -257,9 +273,6 @@ static RuleSet* defaultPrintStyle;
static RuleSet* defaultViewSourceStyle;
static CSSStyleSheet* simpleDefaultStyleSheet;
-static RuleSet* siblingRulesInDefaultStyle;
-static RuleSet* uncommonAttributeRulesInDefaultStyle;
-
RenderStyle* CSSStyleSelector::s_styleNotYetAvailable;
static void loadFullDefaultStyle();
@@ -272,27 +285,6 @@ static inline bool elementCanUseSimpleDefaultStyle(Element* e)
return e->hasTagName(htmlTag) || e->hasTagName(headTag) || e->hasTagName(bodyTag) || e->hasTagName(divTag) || e->hasTagName(spanTag) || e->hasTagName(brTag) || e->hasTagName(aTag);
}
-static inline void collectSpecialRulesInDefaultStyle()
-{
- CSSStyleSelector::Features features;
- defaultStyle->collectFeatures(features);
- ASSERT(features.idsInRules.isEmpty());
- delete siblingRulesInDefaultStyle;
- delete uncommonAttributeRulesInDefaultStyle;
- siblingRulesInDefaultStyle = features.siblingRules.leakPtr();
- uncommonAttributeRulesInDefaultStyle = features.uncommonAttributeRules.leakPtr();
-}
-
-static inline void assertNoSiblingRulesInDefaultStyle()
-{
-#ifndef NDEBUG
- if (siblingRulesInDefaultStyle)
- return;
- collectSpecialRulesInDefaultStyle();
- ASSERT(!siblingRulesInDefaultStyle);
-#endif
-}
-
static const MediaQueryEvaluator& screenEval()
{
DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticScreenEval, ("screen"));
@@ -308,20 +300,16 @@ static const MediaQueryEvaluator& printEval()
static CSSMutableStyleDeclaration* leftToRightDeclaration()
{
DEFINE_STATIC_LOCAL(RefPtr<CSSMutableStyleDeclaration>, leftToRightDecl, (CSSMutableStyleDeclaration::create()));
- if (!leftToRightDecl->length()) {
- leftToRightDecl->setProperty(CSSPropertyDirection, "ltr", false);
- leftToRightDecl->setStrictParsing(false);
- }
+ if (leftToRightDecl->isEmpty())
+ leftToRightDecl->setProperty(CSSPropertyDirection, CSSValueLtr);
return leftToRightDecl.get();
}
static CSSMutableStyleDeclaration* rightToLeftDeclaration()
{
DEFINE_STATIC_LOCAL(RefPtr<CSSMutableStyleDeclaration>, rightToLeftDecl, (CSSMutableStyleDeclaration::create()));
- if (!rightToLeftDecl->length()) {
- rightToLeftDecl->setProperty(CSSPropertyDirection, "rtl", false);
- rightToLeftDecl->setStrictParsing(false);
- }
+ if (rightToLeftDecl->isEmpty())
+ rightToLeftDecl->setProperty(CSSPropertyDirection, CSSValueRtl);
return rightToLeftDecl.get();
}
@@ -336,6 +324,7 @@ CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleShee
, m_rootElementStyle(0)
, m_element(0)
, m_styledElement(0)
+ , m_regionForStyling(0)
, m_elementLinkState(NotInsideLink)
, m_parentNode(0)
, m_lineHeightValue(0)
@@ -349,6 +338,9 @@ CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleShee
#if ENABLE(CSS_SHADERS)
, m_hasPendingShaders(false)
#endif
+#if ENABLE(STYLE_SCOPED)
+ , m_scopingElementStackParent(0)
+#endif
{
Element* root = document->documentElement();
@@ -380,6 +372,8 @@ CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleShee
m_authorStyle = adoptPtr(new RuleSet);
// Adding rules from multiple sheets, shrink at the end.
+ // Adding global rules from multiple sheets, shrink at the end.
+ // Note that there usually is only 1 sheet for scoped rules, so auto-shrink-to-fit is fine.
m_authorStyle->disableAutoShrinkToFit();
// FIXME: This sucks! The user sheet is reparsed every time!
@@ -409,43 +403,70 @@ CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleShee
m_userStyle = tempUserStyle.release();
// Add rules from elements like SVG's <font-face>
- if (mappedElementSheet)
+ if (mappedElementSheet) {
+ // FIXME: see if style scopes can/should be added here.
m_authorStyle->addRulesFromSheet(mappedElementSheet, *m_medium, this);
-
- // add stylesheets from document
- unsigned length = styleSheets->length();
- for (unsigned i = 0; i < length; i++) {
- StyleSheet* sheet = styleSheets->item(i);
- if (sheet->isCSSStyleSheet() && !sheet->disabled())
- m_authorStyle->addRulesFromSheet(static_cast<CSSStyleSheet*>(sheet), *m_medium, this);
}
- m_authorStyle->shrinkToFit();
- collectFeatures();
+ // add stylesheets from document
+ appendAuthorStylesheets(0, styleSheets->vector());
+}
- if (document->renderer() && document->renderer()->style())
- document->renderer()->style()->font().update(fontSelector());
+static PassOwnPtr<RuleSet> makeRuleSet(const Vector<CSSStyleSelector::RuleSelectorPair>& rules)
+{
+ size_t size = rules.size();
+ if (!size)
+ return nullptr;
+ OwnPtr<RuleSet> ruleSet = adoptPtr(new RuleSet);
+ for (size_t i = 0; i < size; ++i)
+ ruleSet->addRule(rules[i].rule, rules[i].selector);
+ return ruleSet.release();
}
void CSSStyleSelector::collectFeatures()
{
+ m_features.clear();
// Collect all ids and rules using sibling selectors (:first-child and similar)
// in the current set of stylesheets. Style sharing code uses this information to reject
// sharing candidates.
- // Usually there are no sibling rules in the default style but the MathML sheet has some.
- if (siblingRulesInDefaultStyle)
- siblingRulesInDefaultStyle->collectFeatures(m_features);
- if (uncommonAttributeRulesInDefaultStyle)
- uncommonAttributeRulesInDefaultStyle->collectFeatures(m_features);
- m_authorStyle->collectFeatures(m_features);
+ m_features.add(defaultStyle->features());
+ m_features.add(m_authorStyle->features());
+#if ENABLE(STYLE_SCOPED)
+ for (ScopedRuleSetMap::iterator it = m_scopedAuthorStyles.begin(); it != m_scopedAuthorStyles.end(); ++it)
+ m_features.add(it->second->features());
+#endif
if (m_userStyle)
- m_userStyle->collectFeatures(m_features);
- if (m_features.siblingRules)
- m_features.siblingRules->shrinkToFit();
- if (m_features.uncommonAttributeRules)
- m_features.uncommonAttributeRules->shrinkToFit();
+ m_features.add(m_userStyle->features());
+
+ m_siblingRuleSet = makeRuleSet(m_features.siblingRules);
+ m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules);
}
+#if ENABLE(STYLE_SCOPED)
+Element* CSSStyleSelector::determineScopingElement(const CSSStyleSheet* sheet)
+{
+ ASSERT(sheet);
+
+ Node* ownerNode = sheet->findStyleSheetOwnerNode();
+ if (!ownerNode || !ownerNode->isHTMLElement() || !ownerNode->hasTagName(HTMLNames::styleTag))
+ return 0;
+
+ HTMLStyleElement* styleElement = static_cast<HTMLStyleElement*>(ownerNode);
+ if (!styleElement->scoped())
+ return 0;
+
+ return styleElement->parentElement();
+}
+
+inline RuleSet* CSSStyleSelector::scopedRuleSetForElement(const Element* element) const
+{
+ if (!element->hasScopedHTMLStyleChild())
+ return 0;
+ ScopedRuleSetMap::const_iterator it = m_scopedAuthorStyles.find(element);
+ return it != m_scopedAuthorStyles.end() ? it->second.get() : 0;
+}
+#endif
+
void CSSStyleSelector::appendAuthorStylesheets(unsigned firstNew, const Vector<RefPtr<StyleSheet> >& stylesheets)
{
// This handles sheets added to the end of the stylesheet list only. In other cases the style resolver
@@ -454,20 +475,89 @@ void CSSStyleSelector::appendAuthorStylesheets(unsigned firstNew, const Vector<R
for (unsigned i = firstNew; i < size; ++i) {
if (!stylesheets[i]->isCSSStyleSheet() || stylesheets[i]->disabled())
continue;
- m_authorStyle->addRulesFromSheet(static_cast<CSSStyleSheet*>(stylesheets[i].get()), *m_medium, this);
+ CSSStyleSheet* cssSheet = static_cast<CSSStyleSheet*>(stylesheets[i].get());
+#if ENABLE(STYLE_SCOPED)
+ const Element* scope = determineScopingElement(cssSheet);
+ if (scope) {
+ pair<ScopedRuleSetMap::iterator, bool> addResult = m_scopedAuthorStyles.add(scope, nullptr);
+ if (addResult.second)
+ addResult.first->second = adoptPtr(new RuleSet());
+ addResult.first->second->addRulesFromSheet(cssSheet, *m_medium, this, scope);
+ continue;
+ }
+#endif
+ m_authorStyle->addRulesFromSheet(cssSheet, *m_medium, this);
}
m_authorStyle->shrinkToFit();
- // FIXME: This really only needs to collect the features from the newly added sheets.
- m_features.clear();
collectFeatures();
if (document()->renderer() && document()->renderer()->style())
document()->renderer()->style()->font().update(fontSelector());
}
-void CSSStyleSelector::addRegionRule(PassRefPtr<WebKitCSSRegionRule> regionStyleRule)
+#if ENABLE(STYLE_SCOPED)
+void CSSStyleSelector::setupScopingElementStack(const Element* parent)
{
- m_regionStyleRules.append(regionStyleRule);
+ // The scoping element stack shouldn't be used if <style scoped> isn't used anywhere.
+ ASSERT(!m_scopedAuthorStyles.isEmpty());
+
+ m_scopingElementStack.shrink(0);
+ for (; parent; parent = parent->parentOrHostElement()) {
+ RuleSet* ruleSet = scopedRuleSetForElement(parent);
+ if (ruleSet)
+ m_scopingElementStack.append(ScopeStackFrame(parent, ruleSet));
+ }
+ m_scopingElementStack.reverse();
+ m_scopingElementStackParent = parent;
+}
+#endif
+
+void CSSStyleSelector::pushParent(Element* parent)
+{
+ const Element* parentsParent = parent->parentOrHostElement();
+ // We are not always invoked consistently. For example, script execution can cause us to enter
+ // style recalc in the middle of tree building. We may also be invoked from somewhere within the tree.
+ // Reset the stack in this case, or if we see a new root element.
+ // Otherwise just push the new parent.
+ if (!parentsParent || m_checker.parentStackIsEmpty())
+ m_checker.setupParentStack(parent);
+ else
+ m_checker.pushParent(parent);
+
+#if ENABLE(STYLE_SCOPED)
+ // Shortcut: Don't bother with the scoping element stack if <style scoped> isn't used anywhere.
+ if (m_scopedAuthorStyles.isEmpty()) {
+ ASSERT(!m_scopingElementStackParent);
+ ASSERT(m_scopingElementStack.isEmpty());
+ return;
+ }
+ // In some wacky cases during style resolve we may get invoked for random elements.
+ // Recreate the whole scoping element stack in such cases.
+ if (!scopingElementStackIsConsistent(parentsParent)) {
+ setupScopingElementStack(parent);
+ return;
+ }
+ // Otherwise just push the parent onto the stack.
+ RuleSet* ruleSet = scopedRuleSetForElement(parent);
+ if (ruleSet)
+ m_scopingElementStack.append(ScopeStackFrame(parent, ruleSet));
+ m_scopingElementStackParent = parent;
+#endif
+}
+
+void CSSStyleSelector::popParent(Element* parent)
+{
+ // Note that we may get invoked for some random elements in some wacky cases during style resolve.
+ // Pause maintaining the stack in this case.
+ if (m_checker.parentStackIsConsistent(parent))
+ m_checker.popParent();
+#if ENABLE(STYLE_SCOPED)
+ // Only bother to update the scoping element stack if it is consistent.
+ if (scopingElementStackIsConsistent(parent)) {
+ m_scopingElementStack.removeLast();
+ m_scopingElementStackParent = parent->parentOrHostElement();
+ }
+#endif
}
// This is a simplified style setting function for keyframe styles
@@ -513,6 +603,21 @@ CSSStyleSelector::Features::Features()
CSSStyleSelector::Features::~Features()
{
}
+
+void CSSStyleSelector::Features::add(const CSSStyleSelector::Features& other)
+{
+ HashSet<AtomicStringImpl*>::iterator end = other.idsInRules.end();
+ for (HashSet<AtomicStringImpl*>::iterator it = other.idsInRules.begin(); it != end; ++it)
+ idsInRules.add(*it);
+ end = other.attrsInRules.end();
+ for (HashSet<AtomicStringImpl*>::iterator it = other.attrsInRules.begin(); it != end; ++it)
+ attrsInRules.add(*it);
+ siblingRules.append(other.siblingRules);
+ uncommonAttributeRules.append(other.uncommonAttributeRules);
+ usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules;
+ usesBeforeAfterRules = usesBeforeAfterRules || other.usesBeforeAfterRules;
+ usesLinkRules = usesLinkRules || other.usesLinkRules;
+}
void CSSStyleSelector::Features::clear()
{
@@ -591,11 +696,8 @@ static void loadViewSourceStyle()
static void ensureDefaultStyleSheetsForElement(Element* element)
{
- if (simpleDefaultStyleSheet && !elementCanUseSimpleDefaultStyle(element)) {
+ if (simpleDefaultStyleSheet && !elementCanUseSimpleDefaultStyle(element))
loadFullDefaultStyle();
- assertNoSiblingRulesInDefaultStyle();
- collectSpecialRulesInDefaultStyle();
- }
#if ENABLE(SVG)
static bool loadedSVGUserAgentSheet;
@@ -605,21 +707,17 @@ static void ensureDefaultStyleSheetsForElement(Element* element)
CSSStyleSheet* svgSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet));
defaultStyle->addRulesFromSheet(svgSheet, screenEval());
defaultPrintStyle->addRulesFromSheet(svgSheet, printEval());
- assertNoSiblingRulesInDefaultStyle();
- collectSpecialRulesInDefaultStyle();
}
#endif
-#if ENABLE(MATHML)
static bool loadedMathMLUserAgentSheet;
+#if ENABLE(MATHML)
if (element->isMathMLElement() && !loadedMathMLUserAgentSheet) {
// MathML rules.
loadedMathMLUserAgentSheet = true;
CSSStyleSheet* mathMLSheet = parseUASheet(mathmlUserAgentStyleSheet, sizeof(mathmlUserAgentStyleSheet));
defaultStyle->addRulesFromSheet(mathMLSheet, screenEval());
defaultPrintStyle->addRulesFromSheet(mathMLSheet, printEval());
- // There are some sibling and uncommon attribute rules here.
- collectSpecialRulesInDefaultStyle();
}
#endif
@@ -631,7 +729,6 @@ static void ensureDefaultStyleSheetsForElement(Element* element)
CSSStyleSheet* mediaControlsSheet = parseUASheet(mediaRules);
defaultStyle->addRulesFromSheet(mediaControlsSheet, screenEval());
defaultPrintStyle->addRulesFromSheet(mediaControlsSheet, printEval());
- collectSpecialRulesInDefaultStyle();
}
#endif
@@ -643,9 +740,11 @@ static void ensureDefaultStyleSheetsForElement(Element* element)
CSSStyleSheet* fullscreenSheet = parseUASheet(fullscreenRules);
defaultStyle->addRulesFromSheet(fullscreenSheet, screenEval());
defaultQuirksStyle->addRulesFromSheet(fullscreenSheet, screenEval());
- collectSpecialRulesInDefaultStyle();
}
#endif
+
+ ASSERT(defaultStyle->features().idsInRules.isEmpty());
+ ASSERT_UNUSED(loadedMathMLUserAgentSheet, loadedMathMLUserAgentSheet || defaultStyle->features().siblingRules.isEmpty());
}
void CSSStyleSelector::addMatchedDeclaration(CSSMutableStyleDeclaration* styleDeclaration, unsigned linkMatchType)
@@ -656,36 +755,53 @@ void CSSStyleSelector::addMatchedDeclaration(CSSMutableStyleDeclaration* styleDe
newDeclaration.linkMatchType = linkMatchType;
}
-void CSSStyleSelector::matchRules(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)
+void CSSStyleSelector::collectMatchingRules(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)
{
- m_matchedRules.clear();
-
- if (!rules || !m_element)
- return;
+ ASSERT(rules);
+ ASSERT(m_element);
// We need to collect the rules for id, class, tag, and everything else into a buffer and
// then sort the buffer.
if (m_element->hasID())
- matchRulesForList(rules->idRules(m_element->idForStyleResolution().impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
+ collectMatchingRulesForList(rules->idRules(m_element->idForStyleResolution().impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
if (m_element->hasClass()) {
ASSERT(m_styledElement);
const SpaceSplitString& classNames = m_styledElement->classNames();
size_t size = classNames.size();
for (size_t i = 0; i < size; ++i)
- matchRulesForList(rules->classRules(classNames[i].impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
+ collectMatchingRulesForList(rules->classRules(classNames[i].impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
}
const AtomicString& pseudoId = m_element->shadowPseudoId();
if (!pseudoId.isEmpty()) {
ASSERT(m_styledElement);
- matchRulesForList(rules->shadowPseudoElementRules(pseudoId.impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
+ collectMatchingRulesForList(rules->shadowPseudoElementRules(pseudoId.impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
}
if (m_element->isLink())
- matchRulesForList(rules->linkPseudoClassRules(), firstRuleIndex, lastRuleIndex, includeEmptyRules);
+ collectMatchingRulesForList(rules->linkPseudoClassRules(), firstRuleIndex, lastRuleIndex, includeEmptyRules);
if (m_checker.matchesFocusPseudoClass(m_element))
- matchRulesForList(rules->focusPseudoClassRules(), firstRuleIndex, lastRuleIndex, includeEmptyRules);
- matchRulesForList(rules->tagRules(m_element->localName().impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
- matchRulesForList(rules->universalRules(), firstRuleIndex, lastRuleIndex, includeEmptyRules);
+ collectMatchingRulesForList(rules->focusPseudoClassRules(), firstRuleIndex, lastRuleIndex, includeEmptyRules);
+ collectMatchingRulesForList(rules->tagRules(m_element->localName().impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
+ collectMatchingRulesForList(rules->universalRules(), firstRuleIndex, lastRuleIndex, includeEmptyRules);
+}
+
+void CSSStyleSelector::collectMatchingRulesForRegion(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)
+{
+ if (!m_regionForStyling)
+ return;
+
+ unsigned size = rules->m_regionSelectorsAndRuleSets.size();
+ for (unsigned i = 0; i < size; ++i) {
+ CSSSelector* regionSelector = rules->m_regionSelectorsAndRuleSets.at(i).selector;
+ if (checkRegionSelector(regionSelector, static_cast<Element*>(m_regionForStyling->node()))) {
+ RuleSet* regionRules = rules->m_regionSelectorsAndRuleSets.at(i).ruleSet.get();
+ ASSERT(regionRules);
+ collectMatchingRules(regionRules, firstRuleIndex, lastRuleIndex, includeEmptyRules);
+ }
+ }
+}
+void CSSStyleSelector::sortAndTransferMatchedRules()
+{
if (m_matchedRules.isEmpty())
return;
@@ -712,6 +828,62 @@ void CSSStyleSelector::matchRules(RuleSet* rules, int& firstRuleIndex, int& last
}
}
+void CSSStyleSelector::matchScopedAuthorRules(int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)
+{
+#if ENABLE(STYLE_SCOPED)
+ if (m_scopedAuthorStyles.isEmpty())
+ return;
+
+ // Match scoped author rules by traversing the scoped element stack (rebuild it if it got inconsistent).
+ const Element* parent = m_element->parentOrHostElement();
+ if (!scopingElementStackIsConsistent(parent))
+ setupScopingElementStack(parent);
+ for (size_t i = m_scopingElementStack.size(); i; --i) {
+ collectMatchingRules(m_scopingElementStack[i - 1].m_ruleSet, firstRuleIndex, lastRuleIndex, includeEmptyRules);
+ collectMatchingRulesForRegion(m_scopingElementStack[i - 1].m_ruleSet, firstRuleIndex, lastRuleIndex, includeEmptyRules);
+ }
+ // Also include the current element.
+ RuleSet* ruleSet = scopedRuleSetForElement(m_element);
+ if (ruleSet) {
+ collectMatchingRules(ruleSet, firstRuleIndex, lastRuleIndex, includeEmptyRules);
+ collectMatchingRulesForRegion(ruleSet, firstRuleIndex, lastRuleIndex, includeEmptyRules);
+ }
+#else
+ UNUSED_PARAM(firstRuleIndex);
+ UNUSED_PARAM(lastRuleIndex);
+ UNUSED_PARAM(includeEmptyRules);
+#endif
+}
+
+void CSSStyleSelector::matchAuthorRules(int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)
+{
+ m_matchedRules.clear();
+
+ if (!m_element)
+ return;
+
+ // Match global author rules.
+ collectMatchingRules(m_authorStyle.get(), firstRuleIndex, lastRuleIndex, includeEmptyRules);
+ collectMatchingRulesForRegion(m_authorStyle.get(), firstRuleIndex, lastRuleIndex, includeEmptyRules);
+
+ matchScopedAuthorRules(firstRuleIndex, lastRuleIndex, includeEmptyRules);
+
+ sortAndTransferMatchedRules();
+}
+
+void CSSStyleSelector::matchRules(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)
+{
+ m_matchedRules.clear();
+
+ if (!rules || !m_element)
+ return;
+
+ collectMatchingRules(rules, firstRuleIndex, lastRuleIndex, includeEmptyRules);
+ collectMatchingRulesForRegion(rules, firstRuleIndex, lastRuleIndex, includeEmptyRules);
+
+ sortAndTransferMatchedRules();
+}
+
class MatchingUARulesScope {
public:
MatchingUARulesScope();
@@ -746,7 +918,7 @@ inline static bool matchesInTreeScope(TreeScope* treeScope, bool ruleReachesInto
return MatchingUARulesScope::isMatchingUARules() || treeScope->applyAuthorSheets() || ruleReachesIntoShadowDOM;
}
-void CSSStyleSelector::matchRulesForList(const Vector<RuleData>* rules, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)
+void CSSStyleSelector::collectMatchingRulesForList(const Vector<RuleData>* rules, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)
{
if (!rules)
return;
@@ -769,7 +941,7 @@ void CSSStyleSelector::matchRulesForList(const Vector<RuleData>* rules, int& fir
}
// If the rule has no properties to apply, then ignore it in the non-debug mode.
CSSMutableStyleDeclaration* decl = rule->declaration();
- if (!decl || (!decl->length() && !includeEmptyRules)) {
+ if (!decl || (decl->isEmpty() && !includeEmptyRules)) {
InspectorInstrumentation::didMatchRule(cookie, false);
continue;
}
@@ -820,42 +992,35 @@ void CSSStyleSelector::matchAllRules(MatchResult& result)
// Now we check user sheet rules.
if (m_matchAuthorAndUserStyles)
- matchRules(m_userStyle.get(), result.firstUserRule, result.lastUserRule, false);
+ matchRules(m_userStyle.get(), result.ranges.firstUserRule, result.ranges.lastUserRule, false);
// Now check author rules, beginning first with presentational attributes mapped from HTML.
if (m_styledElement) {
- // Ask if the HTML element has mapped attributes.
- if (m_styledElement->hasMappedAttributes()) {
- // Walk our attribute list and add in each decl.
- const NamedNodeMap* map = m_styledElement->attributeMap();
+ if (const NamedNodeMap* map = m_styledElement->attributeMap()) {
+ // Walk the element's attribute map and add all mapped attribute declarations.
for (unsigned i = 0; i < map->length(); ++i) {
- Attribute* attr = map->attributeItem(i);
- if (attr->decl()) {
- ASSERT(attr->isMappedAttribute());
- result.lastAuthorRule = m_matchedDecls.size();
- if (result.firstAuthorRule == -1)
- result.firstAuthorRule = result.lastAuthorRule;
- addMatchedDeclaration(attr->decl());
- }
+ Attribute* attribute = map->attributeItem(i);
+ if (!attribute->decl())
+ continue;
+ ASSERT(attribute->isMappedAttribute());
+ result.ranges.lastAuthorRule = m_matchedDecls.size();
+ if (result.ranges.firstAuthorRule == -1)
+ result.ranges.firstAuthorRule = result.ranges.lastAuthorRule;
+ addMatchedDeclaration(attribute->decl());
}
}
-
+
// Now we check additional mapped declarations.
// Tables and table cells share an additional mapped rule that must be applied
// after all attributes, since their mapped style depends on the values of multiple attributes.
- if (m_styledElement->canHaveAdditionalAttributeStyleDecls()) {
- Vector<CSSMutableStyleDeclaration*> additionalAttributeStyleDecls;
- m_styledElement->additionalAttributeStyleDecls(additionalAttributeStyleDecls);
- if (!additionalAttributeStyleDecls.isEmpty()) {
- unsigned additionalDeclsSize = additionalAttributeStyleDecls.size();
- if (result.firstAuthorRule == -1)
- result.firstAuthorRule = m_matchedDecls.size();
- result.lastAuthorRule = m_matchedDecls.size() + additionalDeclsSize - 1;
- for (unsigned i = 0; i < additionalDeclsSize; ++i)
- addMatchedDeclaration(additionalAttributeStyleDecls[i]);
- result.isCacheable = false;
- }
+ if (RefPtr<CSSMutableStyleDeclaration> additionalStyle = m_styledElement->additionalAttributeStyle()) {
+ if (result.ranges.firstAuthorRule == -1)
+ result.ranges.firstAuthorRule = m_matchedDecls.size();
+ result.ranges.lastAuthorRule = m_matchedDecls.size();
+ addMatchedDeclaration(additionalStyle.get());
+ result.isCacheable = false;
}
+
if (m_styledElement->isHTMLElement()) {
bool isAuto;
TextDirection textDirection = toHTMLElement(m_styledElement)->directionalityIfhasDirAutoAttribute(isAuto);
@@ -866,15 +1031,15 @@ void CSSStyleSelector::matchAllRules(MatchResult& result)
// Check the rules in author sheets next.
if (m_matchAuthorAndUserStyles)
- matchRules(m_authorStyle.get(), result.firstAuthorRule, result.lastAuthorRule, false);
+ matchAuthorRules(result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, false);
// Now check our inline style attribute.
if (m_matchAuthorAndUserStyles && m_styledElement) {
CSSMutableStyleDeclaration* inlineDecl = m_styledElement->inlineStyleDecl();
if (inlineDecl) {
- result.lastAuthorRule = m_matchedDecls.size();
- if (result.firstAuthorRule == -1)
- result.firstAuthorRule = result.lastAuthorRule;
+ result.ranges.lastAuthorRule = m_matchedDecls.size();
+ if (result.ranges.firstAuthorRule == -1)
+ result.ranges.firstAuthorRule = result.ranges.lastAuthorRule;
addMatchedDeclaration(inlineDecl);
result.isCacheable = false;
}
@@ -929,6 +1094,10 @@ Node* CSSStyleSelector::locateCousinList(Element* parent, unsigned& visitedNodeC
return 0;
if (!parent || !parent->isStyledElement())
return 0;
+#if ENABLE(STYLE_SCOPED)
+ if (parent->hasScopedHTMLStyleChild())
+ return 0;
+#endif
StyledElement* p = static_cast<StyledElement*>(parent);
if (p->inlineStyleDecl())
return 0;
@@ -1029,6 +1198,22 @@ bool CSSStyleSelector::canShareStyleWithControl(StyledElement* element) const
return true;
}
+static inline bool mappedAttributesEquivalent(NamedNodeMap* a, NamedNodeMap* b)
+{
+ ASSERT(a->mappedAttributeCount() == b->mappedAttributeCount());
+
+ for (size_t i = 0; i < a->length(); ++i) {
+ Attribute* attribute = a->attributeItem(i);
+ if (!attribute->decl())
+ continue;
+ ASSERT(attribute->isMappedAttribute());
+ Attribute* otherAttribute = b->getAttributeItem(attribute->name());
+ if (!otherAttribute || attribute->value() != otherAttribute->value() || attribute->decl() != otherAttribute->decl())
+ return false;
+ }
+ return true;
+}
+
bool CSSStyleSelector::canShareStyleWithElement(StyledElement* element) const
{
RenderStyle* style = element->renderStyle();
@@ -1043,7 +1228,8 @@ bool CSSStyleSelector::canShareStyleWithElement(StyledElement* element) const
return false;
if (element->inlineStyleDecl())
return false;
- if (element->hasMappedAttributes() != m_styledElement->hasMappedAttributes())
+ size_t mappedAttributeCount = element->mappedAttributeCount();
+ if (mappedAttributeCount != m_styledElement->mappedAttributeCount())
return false;
if (element->isLink() != m_element->isLink())
return false;
@@ -1075,6 +1261,11 @@ bool CSSStyleSelector::canShareStyleWithElement(StyledElement* element) const
if (element->hasID() && m_features.idsInRules.contains(element->idForStyleResolution().impl()))
return false;
+#if ENABLE(STYLE_SCOPED)
+ if (element->hasScopedHTMLStyleChild())
+ return false;
+#endif
+
bool isControl = element->isFormControlElement();
if (isControl != m_element->isFormControlElement())
@@ -1104,7 +1295,7 @@ bool CSSStyleSelector::canShareStyleWithElement(StyledElement* element) const
if (element->hasClass() && m_element->getAttribute(classAttr) != element->getAttribute(classAttr))
return false;
- if (element->hasMappedAttributes() && !element->attributeMap()->mappedMapsEquivalent(m_styledElement->attributeMap()))
+ if (mappedAttributeCount && !mappedAttributesEquivalent(element->attributeMap(), m_styledElement->attributeMap()))
return false;
if (element->isLink() && m_elementLinkState != style->insideLink())
@@ -1146,6 +1337,10 @@ RenderStyle* CSSStyleSelector::locateSharedStyle()
return 0;
if (parentStylePreventsSharing(m_parentStyle))
return 0;
+#if ENABLE(STYLE_SCOPED)
+ if (m_styledElement->hasScopedHTMLStyleChild())
+ return 0;
+#endif
// Check previous siblings and their cousins.
unsigned count = 0;
@@ -1164,10 +1359,10 @@ RenderStyle* CSSStyleSelector::locateSharedStyle()
return 0;
// Can't share if sibling rules apply. This is checked at the end as it should rarely fail.
- if (matchesRuleSet(m_features.siblingRules.get()))
+ if (matchesRuleSet(m_siblingRuleSet.get()))
return 0;
// Can't share if attribute rules apply.
- if (matchesRuleSet(m_features.uncommonAttributeRules.get()))
+ if (matchesRuleSet(m_uncommonAttributeRuleSet.get()))
return 0;
// Tracking child index requires unique style for each node. This may get set by the sibling rule match above.
if (parentStylePreventsSharing(m_parentStyle))
@@ -1184,17 +1379,17 @@ void CSSStyleSelector::matchUARules(MatchResult& result)
result.isCacheable = false;
RuleSet* userAgentStyleSheet = m_medium->mediaTypeMatchSpecific("print")
? defaultPrintStyle : defaultStyle;
- matchRules(userAgentStyleSheet, result.firstUARule, result.lastUARule, false);
+ matchRules(userAgentStyleSheet, result.ranges.firstUARule, result.ranges.lastUARule, false);
// In quirks mode, we match rules from the quirks user agent sheet.
if (!m_checker.strictParsing())
- matchRules(defaultQuirksStyle, result.firstUARule, result.lastUARule, false);
+ matchRules(defaultQuirksStyle, result.ranges.firstUARule, result.ranges.lastUARule, false);
// If document uses view source styles (in view source mode or in xml viewer mode), then we match rules from the view source style sheet.
if (m_checker.document()->isViewSource()) {
if (!defaultViewSourceStyle)
loadViewSourceStyle();
- matchRules(defaultViewSourceStyle, result.firstUARule, result.lastUARule, false);
+ matchRules(defaultViewSourceStyle, result.ranges.firstUARule, result.ranges.lastUARule, false);
}
}
@@ -1270,7 +1465,7 @@ static inline bool isAtShadowBoundary(Element* element)
// If resolveForRootDefault is true, style based on user agent style sheet only. This is used in media queries, where
// relative units are interpreted according to document root element style, styled only with UA stylesheet
-PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* element, RenderStyle* defaultParent, bool allowSharing, bool resolveForRootDefault)
+PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* element, RenderStyle* defaultParent, bool allowSharing, bool resolveForRootDefault, RenderRegion* regionForStyling)
{
// Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
// will vanish if a style recalc happens during loading.
@@ -1286,6 +1481,7 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* element, Rend
initElement(element);
initForStyleResolve(element, defaultParent);
+ m_regionForStyling = regionForStyling;
if (allowSharing) {
RenderStyle* sharedStyle = locateSharedStyle();
if (sharedStyle)
@@ -1333,7 +1529,7 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* element, Rend
PassRefPtr<RenderStyle> CSSStyleSelector::styleForKeyframe(const RenderStyle* elementStyle, const WebKitCSSKeyframeRule* keyframeRule, KeyframeValue& keyframe)
{
if (keyframeRule->style())
- addMatchedDeclaration(keyframeRule->style());
+ addMatchedDeclaration(keyframeRule->declaration());
ASSERT(!m_style);
@@ -1372,10 +1568,10 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForKeyframe(const RenderStyle* el
#endif
// Add all the animating properties to the keyframe.
- if (keyframeRule->style()) {
- CSSMutableStyleDeclaration::const_iterator end = keyframeRule->style()->end();
- for (CSSMutableStyleDeclaration::const_iterator it = keyframeRule->style()->begin(); it != end; ++it) {
- int property = (*it).id();
+ if (CSSMutableStyleDeclaration* styleDeclaration = keyframeRule->declaration()) {
+ unsigned propertyCount = styleDeclaration->propertyCount();
+ for (unsigned i = 0; i < propertyCount; ++i) {
+ int property = styleDeclaration->propertyAt(i).id();
// Timing-function within keyframes is special, because it is not animated; it just
// describes the timing function between this keyframe and the next.
if (property != CSSPropertyWebkitAnimationTimingFunction)
@@ -1463,8 +1659,8 @@ PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo,
matchUARules(matchResult);
if (m_matchAuthorAndUserStyles) {
- matchRules(m_userStyle.get(), matchResult.firstUserRule, matchResult.lastUserRule, false);
- matchRules(m_authorStyle.get(), matchResult.firstAuthorRule, matchResult.lastAuthorRule, false);
+ matchRules(m_userStyle.get(), matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, false);
+ matchAuthorRules(matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, false);
}
if (m_matchedDecls.isEmpty())
@@ -1501,6 +1697,7 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForPage(int pageIndex)
const String page = pageName(pageIndex);
matchPageRules(defaultPrintStyle, isLeft, isFirst, page);
matchPageRules(m_userStyle.get(), isLeft, isFirst, page);
+ // Only consider the global author RuleSet for @page rules, as per the HTML5 spec.
matchPageRules(m_authorStyle.get(), isLeft, isFirst, page);
m_lineHeightValue = 0;
bool inheritedOnly = false;
@@ -1742,15 +1939,23 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parent
#endif
}
-bool CSSStyleSelector::checkRegionStyle(Element* e)
+bool CSSStyleSelector::checkRegionStyle(Element* regionElement)
{
- m_checker.clearHasUnknownPseudoElements();
- m_checker.setPseudoStyle(NOPSEUDO);
+ // FIXME (BUG 72472): We don't add @-webkit-region rules of scoped style sheets for the moment,
+ // so all region rules are global by default. Verify whether that can stand or needs changing.
- for (Vector<RefPtr<WebKitCSSRegionRule> >::iterator it = m_regionStyleRules.begin(); it != m_regionStyleRules.end(); ++it) {
- const CSSSelectorList& regionSelectorList = (*it)->selectorList();
- for (CSSSelector* s = regionSelectorList.first(); s; s = regionSelectorList.next(s)) {
- if (m_checker.checkSelector(s, e))
+ unsigned rulesSize = m_authorStyle->m_regionSelectorsAndRuleSets.size();
+ for (unsigned i = 0; i < rulesSize; ++i) {
+ ASSERT(m_authorStyle->m_regionSelectorsAndRuleSets.at(i).ruleSet.get());
+ if (checkRegionSelector(m_authorStyle->m_regionSelectorsAndRuleSets.at(i).selector, regionElement))
+ return true;
+ }
+
+ if (m_userStyle) {
+ rulesSize = m_userStyle->m_regionSelectorsAndRuleSets.size();
+ for (unsigned i = 0; i < rulesSize; ++i) {
+ ASSERT(m_userStyle->m_regionSelectorsAndRuleSets.at(i).ruleSet.get());
+ if (checkRegionSelector(m_userStyle->m_regionSelectorsAndRuleSets.at(i).selector, regionElement))
return true;
}
}
@@ -1802,14 +2007,14 @@ PassRefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element* e,
// Now we check user sheet rules.
if (m_matchAuthorAndUserStyles)
- matchRules(m_userStyle.get(), dummy.firstUserRule, dummy.lastUserRule, rulesToInclude & EmptyCSSRules);
+ matchRules(m_userStyle.get(), dummy.ranges.firstUserRule, dummy.ranges.lastUserRule, rulesToInclude & EmptyCSSRules);
}
if (m_matchAuthorAndUserStyles && (rulesToInclude & AuthorCSSRules)) {
m_sameOriginOnly = !(rulesToInclude & CrossOriginCSSRules);
// Check the rules in author sheets.
- matchRules(m_authorStyle.get(), dummy.firstAuthorRule, dummy.lastAuthorRule, rulesToInclude & EmptyCSSRules);
+ matchAuthorRules(dummy.ranges.firstAuthorRule, dummy.ranges.lastAuthorRule, rulesToInclude & EmptyCSSRules);
m_sameOriginOnly = false;
}
@@ -1849,6 +2054,21 @@ inline bool CSSStyleSelector::checkSelector(const RuleData& ruleData)
return false;
return true;
}
+
+bool CSSStyleSelector::checkRegionSelector(CSSSelector* regionSelector, Element* regionElement)
+{
+ if (!regionSelector || !regionElement)
+ return false;
+
+ m_checker.clearHasUnknownPseudoElements();
+ m_checker.setPseudoStyle(NOPSEUDO);
+
+ for (CSSSelector* s = regionSelector; s; s = CSSSelectorList::next(s))
+ if (m_checker.checkSelector(s, regionElement))
+ return true;
+
+ return false;
+}
bool CSSStyleSelector::determineStylesheetSelectorScopes(CSSStyleSheet* stylesheet, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes)
{
@@ -1953,33 +2173,79 @@ RuleSet::RuleSet()
{
}
-void RuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map, CSSStyleRule* rule, CSSSelector* selector)
+static inline void collectFeaturesFromSelector(CSSStyleSelector::Features& features, const CSSSelector* selector)
+{
+ if (selector->m_match == CSSSelector::Id)
+ features.idsInRules.add(selector->value().impl());
+ if (selector->isAttributeSelector())
+ features.attrsInRules.add(selector->attribute().localName().impl());
+ switch (selector->pseudoType()) {
+ case CSSSelector::PseudoFirstLine:
+ features.usesFirstLineRules = true;
+ break;
+ case CSSSelector::PseudoBefore:
+ case CSSSelector::PseudoAfter:
+ features.usesBeforeAfterRules = true;
+ break;
+ case CSSSelector::PseudoLink:
+ case CSSSelector::PseudoVisited:
+ features.usesLinkRules = true;
+ break;
+ default:
+ break;
+ }
+}
+
+static void collectFeaturesFromRuleData(CSSStyleSelector::Features& features, const RuleData& ruleData)
+{
+ bool foundSiblingSelector = false;
+ for (CSSSelector* selector = ruleData.selector(); selector; selector = selector->tagHistory()) {
+ collectFeaturesFromSelector(features, selector);
+
+ if (CSSSelectorList* selectorList = selector->selectorList()) {
+ for (CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
+ if (!foundSiblingSelector && selector->isSiblingSelector())
+ foundSiblingSelector = true;
+ collectFeaturesFromSelector(features, subSelector);
+ }
+ } else if (!foundSiblingSelector && selector->isSiblingSelector())
+ foundSiblingSelector = true;
+ }
+ if (foundSiblingSelector)
+ features.siblingRules.append(CSSStyleSelector::RuleSelectorPair(ruleData.rule(), ruleData.selector()));
+ if (ruleData.containsUncommonAttributeSelector())
+ features.uncommonAttributeRules.append(CSSStyleSelector::RuleSelectorPair(ruleData.rule(), ruleData.selector()));
+}
+
+void RuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map, const RuleData& ruleData)
{
if (!key)
return;
OwnPtr<Vector<RuleData> >& rules = map.add(key, nullptr).first->second;
if (!rules)
rules = adoptPtr(new Vector<RuleData>);
- rules->append(RuleData(rule, selector, m_ruleCount++));
+ rules->append(ruleData);
}
-void RuleSet::addRule(CSSStyleRule* rule, CSSSelector* sel)
+void RuleSet::addRule(CSSStyleRule* rule, CSSSelector* selector)
{
- if (sel->m_match == CSSSelector::Id) {
- addToRuleSet(sel->value().impl(), m_idRules, rule, sel);
+ RuleData ruleData(rule, selector, m_ruleCount++);
+ collectFeaturesFromRuleData(m_features, ruleData);
+
+ if (selector->m_match == CSSSelector::Id) {
+ addToRuleSet(selector->value().impl(), m_idRules, ruleData);
return;
}
- if (sel->m_match == CSSSelector::Class) {
- addToRuleSet(sel->value().impl(), m_classRules, rule, sel);
+ if (selector->m_match == CSSSelector::Class) {
+ addToRuleSet(selector->value().impl(), m_classRules, ruleData);
return;
}
- if (sel->isUnknownPseudoElement()) {
- addToRuleSet(sel->value().impl(), m_shadowPseudoElementRules, rule, sel);
+ if (selector->isUnknownPseudoElement()) {
+ addToRuleSet(selector->value().impl(), m_shadowPseudoElementRules, ruleData);
return;
}
- if (SelectorChecker::isCommonPseudoClassSelector(sel)) {
- RuleData ruleData(rule, sel, m_ruleCount++);
- switch (sel->pseudoType()) {
+ if (SelectorChecker::isCommonPseudoClassSelector(selector)) {
+ switch (selector->pseudoType()) {
case CSSSelector::PseudoLink:
case CSSSelector::PseudoVisited:
case CSSSelector::PseudoAnyLink:
@@ -1993,13 +2259,12 @@ void RuleSet::addRule(CSSStyleRule* rule, CSSSelector* sel)
}
return;
}
- const AtomicString& localName = sel->tag().localName();
+ const AtomicString& localName = selector->tag().localName();
if (localName != starAtom) {
- addToRuleSet(localName.impl(), m_tagRules, rule, sel);
+ addToRuleSet(localName.impl(), m_tagRules, ruleData);
return;
}
-
- m_universalRules.append(RuleData(rule, sel, m_ruleCount++));
+ m_universalRules.append(ruleData);
}
void RuleSet::addPageRule(CSSPageRule* rule)
@@ -2007,7 +2272,27 @@ void RuleSet::addPageRule(CSSPageRule* rule)
m_pageRules.append(RuleData(rule, rule->selectorList().first(), m_pageRules.size()));
}
-void RuleSet::addRulesFromSheet(CSSStyleSheet* sheet, const MediaQueryEvaluator& medium, CSSStyleSelector* styleSelector)
+void RuleSet::addRegionRule(WebKitCSSRegionRule* rule)
+{
+ RuleSet* regionRuleSet = new RuleSet;
+ // The region rule set should take into account the position inside the parent rule set.
+ // Otherwise, the rules inside region block might be incorrectly positioned before other similar rules from
+ // the stylesheet that contains the region block.
+ regionRuleSet->m_ruleCount = m_ruleCount;
+
+ // Collect the region rules into a rule set
+ CSSRuleList* regionStylingRules = rule->cssRules();
+ unsigned rulesSize = regionStylingRules->length();
+ for (unsigned i = 0; i < rulesSize; ++i) {
+ CSSRule* regionStylingRule = regionStylingRules->item(i);
+ if (regionStylingRule->isStyleRule())
+ regionRuleSet->addStyleRule(static_cast<CSSStyleRule*>(regionStylingRule));
+ }
+
+ m_regionSelectorsAndRuleSets.append(RuleSetSelectorPair(rule->selectorList().first(), regionRuleSet));
+}
+
+void RuleSet::addRulesFromSheet(CSSStyleSheet* sheet, const MediaQueryEvaluator& medium, CSSStyleSelector* styleSelector, const Element* scope)
{
ASSERT(sheet);
@@ -2027,7 +2312,7 @@ void RuleSet::addRulesFromSheet(CSSStyleSheet* sheet, const MediaQueryEvaluator&
else if (rule->isImportRule()) {
CSSImportRule* import = static_cast<CSSImportRule*>(rule);
if (import->styleSheet() && (!import->media() || medium.eval(import->media(), styleSelector)))
- addRulesFromSheet(import->styleSheet(), medium, styleSelector);
+ addRulesFromSheet(import->styleSheet(), medium, styleSelector, scope);
}
else if (rule->isMediaRule()) {
CSSMediaRule* r = static_cast<CSSMediaRule*>(rule);
@@ -2043,24 +2328,40 @@ void RuleSet::addRulesFromSheet(CSSStyleSheet* sheet, const MediaQueryEvaluator&
addPageRule(static_cast<CSSPageRule*>(childItem));
else if (childItem->isFontFaceRule() && styleSelector) {
// Add this font face to our set.
+ // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment.
+ if (scope)
+ continue;
const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(childItem);
styleSelector->fontSelector()->addFontFaceRule(fontFaceRule);
styleSelector->invalidateMatchedDeclarationCache();
} else if (childItem->isKeyframesRule() && styleSelector) {
// Add this keyframe rule to our set.
+ // FIXME(BUG 72462): We don't add @keyframe rules of scoped style sheets for the moment.
+ if (scope)
+ continue;
styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(childItem));
}
} // for rules
} // if rules
} else if (rule->isFontFaceRule() && styleSelector) {
// Add this font face to our set.
+ // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment.
+ if (scope)
+ continue;
const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(rule);
styleSelector->fontSelector()->addFontFaceRule(fontFaceRule);
styleSelector->invalidateMatchedDeclarationCache();
- } else if (rule->isKeyframesRule())
+ } else if (rule->isKeyframesRule()) {
+ // FIXME (BUG 72462): We don't add @keyframe rules of scoped style sheets for the moment.
+ if (scope)
+ continue;
styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(rule));
- else if (rule->isRegionRule() && styleSelector)
- styleSelector->addRegionRule(static_cast<WebKitCSSRegionRule*>(rule));
+ } else if (rule->isRegionRule() && styleSelector) {
+ // FIXME (BUG 72472): We don't add @-webkit-region rules of scoped style sheets for the moment.
+ if (scope)
+ continue;
+ addRegionRule(static_cast<WebKitCSSRegionRule*>(rule));
+ }
}
if (m_autoShrinkToFitEnabled)
shrinkToFit();
@@ -2072,79 +2373,6 @@ void RuleSet::addStyleRule(CSSStyleRule* rule)
addRule(rule, s);
}
-static inline void collectFeaturesFromSelector(CSSStyleSelector::Features& features, const CSSSelector* selector)
-{
- if (selector->m_match == CSSSelector::Id && !selector->value().isEmpty())
- features.idsInRules.add(selector->value().impl());
- if (selector->isAttributeSelector())
- features.attrsInRules.add(selector->attribute().localName().impl());
- switch (selector->pseudoType()) {
- case CSSSelector::PseudoFirstLine:
- features.usesFirstLineRules = true;
- break;
- case CSSSelector::PseudoBefore:
- case CSSSelector::PseudoAfter:
- features.usesBeforeAfterRules = true;
- break;
- case CSSSelector::PseudoLink:
- case CSSSelector::PseudoVisited:
- features.usesLinkRules = true;
- break;
- default:
- break;
- }
-}
-
-static void collectFeaturesFromList(CSSStyleSelector::Features& features, const Vector<RuleData>& rules)
-{
- unsigned size = rules.size();
- for (unsigned i = 0; i < size; ++i) {
- const RuleData& ruleData = rules[i];
- bool foundSiblingSelector = false;
- for (CSSSelector* selector = ruleData.selector(); selector; selector = selector->tagHistory()) {
- collectFeaturesFromSelector(features, selector);
-
- if (CSSSelectorList* selectorList = selector->selectorList()) {
- for (CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
- if (selector->isSiblingSelector())
- foundSiblingSelector = true;
- collectFeaturesFromSelector(features, subSelector);
- }
- } else if (selector->isSiblingSelector())
- foundSiblingSelector = true;
- }
- if (foundSiblingSelector) {
- if (!features.siblingRules)
- features.siblingRules = adoptPtr(new RuleSet);
- features.siblingRules->addRule(ruleData.rule(), ruleData.selector());
- }
- if (ruleData.containsUncommonAttributeSelector()) {
- if (!features.uncommonAttributeRules)
- features.uncommonAttributeRules = adoptPtr(new RuleSet);
- features.uncommonAttributeRules->addRule(ruleData.rule(), ruleData.selector());
- }
- }
-}
-
-void RuleSet::collectFeatures(CSSStyleSelector::Features& features) const
-{
- AtomRuleMap::const_iterator end = m_idRules.end();
- for (AtomRuleMap::const_iterator it = m_idRules.begin(); it != end; ++it)
- collectFeaturesFromList(features, *it->second);
- end = m_classRules.end();
- for (AtomRuleMap::const_iterator it = m_classRules.begin(); it != end; ++it)
- collectFeaturesFromList(features, *it->second);
- end = m_tagRules.end();
- for (AtomRuleMap::const_iterator it = m_tagRules.begin(); it != end; ++it)
- collectFeaturesFromList(features, *it->second);
- end = m_shadowPseudoElementRules.end();
- for (AtomRuleMap::const_iterator it = m_shadowPseudoElementRules.begin(); it != end; ++it)
- collectFeaturesFromList(features, *it->second);
- collectFeaturesFromList(features, m_linkPseudoClassRules);
- collectFeaturesFromList(features, m_focusPseudoClassRules);
- collectFeaturesFromList(features, m_universalRules);
-}
-
static inline void shrinkMapVectorsToFit(RuleSet::AtomRuleMap& map)
{
RuleSet::AtomRuleMap::iterator end = map.end();
@@ -2177,20 +2405,17 @@ static Length convertToLength(CSSPrimitiveValue* primitiveValue, RenderStyle* st
if (ok)
*ok = false;
} else {
- int type = primitiveValue->primitiveType();
-
- if (!style && (type == CSSPrimitiveValue::CSS_EMS || type == CSSPrimitiveValue::CSS_EXS || type == CSSPrimitiveValue::CSS_REMS)) {
+ if (!style && primitiveValue->isFontRelativeLength()) {
if (ok)
*ok = false;
- } else if (CSSPrimitiveValue::isUnitTypeLength(type)) {
+ } else if (primitiveValue->isLength()) {
if (toFloat)
l = Length(primitiveValue->computeLength<double>(style, rootStyle, multiplier), Fixed);
else
l = primitiveValue->computeLength<Length>(style, rootStyle, multiplier);
- }
- else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ } else if (primitiveValue->isPercentage())
l = Length(primitiveValue->getDoubleValue(), Percent);
- else if (type == CSSPrimitiveValue::CSS_NUMBER)
+ else if (primitiveValue->isNumber())
l = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
else if (ok)
*ok = false;
@@ -2208,13 +2433,28 @@ static Length convertToFloatLength(CSSPrimitiveValue* primitiveValue, RenderStyl
return convertToLength(primitiveValue, style, rootStyle, true, multiplier, ok);
}
+static inline bool isInsideRegionRule(CSSMutableStyleDeclaration* styleDeclaration)
+{
+ ASSERT(styleDeclaration);
+
+ CSSRule* parentRule = styleDeclaration->parentRule();
+ while (parentRule) {
+ if (parentRule->isRegionRule())
+ return true;
+ parentRule = parentRule->parentRule();
+ }
+ return false;
+}
+
template <bool applyFirst>
void CSSStyleSelector::applyDeclaration(CSSMutableStyleDeclaration* styleDeclaration, bool isImportant, bool inheritedOnly)
{
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willProcessRule(document(), styleDeclaration->parentRule());
- CSSMutableStyleDeclaration::const_iterator end = styleDeclaration->end();
- for (CSSMutableStyleDeclaration::const_iterator it = styleDeclaration->begin(); it != end; ++it) {
- const CSSProperty& current = *it;
+ bool styleDeclarationInsideRegionRule = m_regionForStyling ? isInsideRegionRule(styleDeclaration) : false;
+
+ unsigned propertyCount = styleDeclaration->propertyCount();
+ for (unsigned i = 0; i < propertyCount; ++i) {
+ const CSSProperty& current = styleDeclaration->propertyAt(i);
if (isImportant != current.isImportant())
continue;
if (inheritedOnly && !current.isInherited()) {
@@ -2225,9 +2465,14 @@ void CSSStyleSelector::applyDeclaration(CSSMutableStyleDeclaration* styleDeclara
continue;
}
int property = current.id();
+
+ // Filter the properties that can be applied using region styling.
+ if (styleDeclarationInsideRegionRule && !CSSStyleSelector::isValidRegionStyleProperty(property))
+ continue;
+
if (applyFirst) {
COMPILE_ASSERT(firstCSSProperty == CSSPropertyColor, CSS_color_is_first_property);
- COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyColor + 17, CSS_zoom_is_end_of_first_prop_range);
+ COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyColor + 18, CSS_zoom_is_end_of_first_prop_range);
COMPILE_ASSERT(CSSPropertyLineHeight == CSSPropertyZoom + 1, CSS_line_height_is_after_zoom);
// give special priority to font-xxx, color properties, etc
if (property > CSSPropertyLineHeight)
@@ -2275,18 +2520,17 @@ unsigned CSSStyleSelector::computeDeclarationHash(MatchedStyleDeclaration* decla
return StringHasher::hashMemory(declarations, sizeof(MatchedStyleDeclaration) * size);
}
-bool operator==(const CSSStyleSelector::MatchResult& a, const CSSStyleSelector::MatchResult& b)
+bool operator==(const CSSStyleSelector::MatchRanges& a, const CSSStyleSelector::MatchRanges& b)
{
return a.firstUARule == b.firstUARule
&& a.lastUARule == b.lastUARule
&& a.firstAuthorRule == b.firstAuthorRule
&& a.lastAuthorRule == b.lastAuthorRule
&& a.firstUserRule == b.firstUserRule
- && a.lastUserRule == b.lastUserRule
- && a.isCacheable == b.isCacheable;
+ && a.lastUserRule == b.lastUserRule;
}
-bool operator!=(const CSSStyleSelector::MatchResult& a, const CSSStyleSelector::MatchResult& b)
+bool operator!=(const CSSStyleSelector::MatchRanges& a, const CSSStyleSelector::MatchRanges& b)
{
return !(a == b);
}
@@ -2309,8 +2553,7 @@ const CSSStyleSelector::MatchedStyleDeclarationCacheItem* CSSStyleSelector::find
if (it == m_matchedStyleDeclarationCache.end())
return 0;
MatchedStyleDeclarationCacheItem& cacheItem = it->second;
- ASSERT(cacheItem.matchResult.isCacheable);
-
+
size_t size = m_matchedDecls.size();
if (size != cacheItem.matchedStyleDeclarations.size())
return 0;
@@ -2318,7 +2561,7 @@ const CSSStyleSelector::MatchedStyleDeclarationCacheItem* CSSStyleSelector::find
if (m_matchedDecls[i] != cacheItem.matchedStyleDeclarations[i])
return 0;
}
- if (cacheItem.matchResult != matchResult)
+ if (cacheItem.ranges != matchResult.ranges)
return 0;
return &cacheItem;
}
@@ -2334,7 +2577,7 @@ void CSSStyleSelector::addToMatchedDeclarationCache(const RenderStyle* style, co
ASSERT(hash);
MatchedStyleDeclarationCacheItem cacheItem;
cacheItem.matchedStyleDeclarations.append(m_matchedDecls);
- cacheItem.matchResult = matchResult;
+ cacheItem.ranges = matchResult.ranges;
// Note that we don't cache the original RenderStyle instance. It may be further modified.
// The RenderStyle in the cache is really just a holder for the substructures and never used as-is.
cacheItem.renderStyle = RenderStyle::clone(style);
@@ -2388,9 +2631,9 @@ void CSSStyleSelector::applyMatchedDeclarations(const MatchResult& matchResult)
// and (4) normal important.
m_lineHeightValue = 0;
applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1, applyInheritedOnly);
- applyDeclarations<true>(true, matchResult.firstAuthorRule, matchResult.lastAuthorRule, applyInheritedOnly);
- applyDeclarations<true>(true, matchResult.firstUserRule, matchResult.lastUserRule, applyInheritedOnly);
- applyDeclarations<true>(true, matchResult.firstUARule, matchResult.lastUARule, applyInheritedOnly);
+ applyDeclarations<true>(true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
+ applyDeclarations<true>(true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
+ applyDeclarations<true>(true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
if (cacheItem && cacheItem->renderStyle->effectiveZoom() != m_style->effectiveZoom()) {
m_fontDirty = true;
@@ -2409,16 +2652,16 @@ void CSSStyleSelector::applyMatchedDeclarations(const MatchResult& matchResult)
applyInheritedOnly = false;
// Now do the normal priority UA properties.
- applyDeclarations<false>(false, matchResult.firstUARule, matchResult.lastUARule, applyInheritedOnly);
+ applyDeclarations<false>(false, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
// Cache our border and background so that we can examine them later.
cacheBorderAndBackground();
// Now do the author and user normal priority properties and all the !important properties.
- applyDeclarations<false>(false, matchResult.lastUARule + 1, m_matchedDecls.size() - 1, applyInheritedOnly);
- applyDeclarations<false>(true, matchResult.firstAuthorRule, matchResult.lastAuthorRule, applyInheritedOnly);
- applyDeclarations<false>(true, matchResult.firstUserRule, matchResult.lastUserRule, applyInheritedOnly);
- applyDeclarations<false>(true, matchResult.firstUARule, matchResult.lastUARule, applyInheritedOnly);
+ applyDeclarations<false>(false, matchResult.ranges.lastUARule + 1, m_matchedDecls.size() - 1, applyInheritedOnly);
+ applyDeclarations<false>(true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
+ applyDeclarations<false>(true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
+ applyDeclarations<false>(true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
loadPendingImages();
@@ -2476,7 +2719,7 @@ void CSSStyleSelector::matchPageRulesForList(const Vector<RuleData>* rules, bool
// If the rule has no properties to apply, then ignore it.
CSSMutableStyleDeclaration* decl = rule->declaration();
- if (!decl || !decl->length())
+ if (!decl || decl->isEmpty())
continue;
// Add this rule to our list of matched rules.
@@ -2553,6 +2796,20 @@ inline bool isValidVisitedLinkProperty(int id)
return false;
}
+// http://dev.w3.org/csswg/css3-regions/#the-at-region-style-rule
+// FIXME: add incremental support for other region styling properties.
+inline bool CSSStyleSelector::isValidRegionStyleProperty(int id)
+{
+ switch (static_cast<CSSPropertyID>(id)) {
+ case CSSPropertyBackgroundColor:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
// SVG handles zooming in a different way compared to CSS. The whole document is scaled instead
// of each individual length value in the render style / tree. CSSPrimitiveValue::computeLength*()
// multiplies each resolved length with the zoom multiplier - so for SVG we need to disable that.
@@ -2575,14 +2832,13 @@ static bool createGridTrackBreadth(CSSPrimitiveValue* primitiveValue, CSSStyleSe
return true;
}
- int type = primitiveValue->primitiveType();
- if (CSSPrimitiveValue::isUnitTypeLength(type)) {
+ if (primitiveValue->isLength()) {
length = primitiveValue->computeLength<Length>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom());
length.setQuirk(primitiveValue->isQuirkValue());
return true;
}
- if (type == CSSPrimitiveValue::CSS_PERCENTAGE) {
+ if (primitiveValue->isPercentage()) {
length = Length(primitiveValue->getDoubleValue(), Percent);
return true;
}
@@ -2723,46 +2979,6 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
case CSSPropertyOrphans:
HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(orphans, Orphans)
return;
-// rect
- case CSSPropertyClip:
- {
- Length top;
- Length right;
- Length bottom;
- Length left;
- bool hasClip = true;
- if (isInherit) {
- if (m_parentStyle->hasClip()) {
- top = m_parentStyle->clipTop();
- right = m_parentStyle->clipRight();
- bottom = m_parentStyle->clipBottom();
- left = m_parentStyle->clipLeft();
- } else {
- hasClip = false;
- top = right = bottom = left = Length();
- }
- } else if (isInitial) {
- hasClip = false;
- top = right = bottom = left = Length();
- } else if (!primitiveValue) {
- return;
- } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RECT) {
- Rect* rect = primitiveValue->getRectValue();
- if (!rect)
- return;
- top = convertToIntLength(rect->top(), style(), m_rootElementStyle, zoomFactor);
- right = convertToIntLength(rect->right(), style(), m_rootElementStyle, zoomFactor);
- bottom = convertToIntLength(rect->bottom(), style(), m_rootElementStyle, zoomFactor);
- left = convertToIntLength(rect->left(), style(), m_rootElementStyle, zoomFactor);
- } else if (primitiveValue->getIdent() != CSSValueAuto) {
- return;
- }
- m_style->setClip(top, right, bottom, left);
- m_style->setHasClip(hasClip);
-
- // rect, ident
- return;
- }
// lists
case CSSPropertyContent:
@@ -2791,12 +3007,11 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
continue;
CSSPrimitiveValue* contentValue = static_cast<CSSPrimitiveValue*>(item);
- switch (contentValue->primitiveType()) {
- case CSSPrimitiveValue::CSS_STRING:
+
+ if (contentValue->isString()) {
m_style->setContent(contentValue->getStringValue().impl(), didSet);
didSet = true;
- break;
- case CSSPrimitiveValue::CSS_ATTR: {
+ } else if (contentValue->isAttr()) {
// FIXME: Can a namespace be specified for an attr(foo)?
if (m_style->styleType() == NOPSEUDO)
m_style->setUnique();
@@ -2808,16 +3023,12 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
didSet = true;
// register the fact that the attribute value affects the style
m_features.attrsInRules.add(attr.localName().impl());
- break;
- }
- case CSSPrimitiveValue::CSS_URI: {
+ } else if (contentValue->isURI()) {
if (!contentValue->isImageValue())
break;
m_style->setContent(cachedOrPendingFromValue(CSSPropertyContent, static_cast<CSSImageValue*>(contentValue)), didSet);
didSet = true;
- break;
- }
- case CSSPrimitiveValue::CSS_COUNTER: {
+ } else if (contentValue->isCounter()) {
Counter* counterValue = contentValue->getCounterValue();
EListStyleType listStyleType = NoneListStyle;
int listStyleIdent = counterValue->listStyleIdent();
@@ -2826,9 +3037,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(counterValue->identifier(), listStyleType, counterValue->separator()));
m_style->setContent(counter.release(), didSet);
didSet = true;
- break;
- }
- case CSSPrimitiveValue::CSS_IDENT:
+ } else {
switch (contentValue->getIdent()) {
case CSSValueOpenQuote:
m_style->setContent(OPEN_QUOTE, didSet);
@@ -2876,12 +3085,12 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
CSSValue* item = i.value();
ASSERT(item->isPrimitiveValue());
primitiveValue = static_cast<CSSPrimitiveValue*>(item);
- ASSERT(primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_STRING);
+ ASSERT(primitiveValue->isString());
quotes[i.index()] = primitiveValue->getStringValue();
}
m_style->setQuotes(adoptRef(data));
} else if (primitiveValue) {
- ASSERT(primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_IDENT);
+ ASSERT(primitiveValue->isIdent());
if (primitiveValue->getIdent() == CSSValueNone)
m_style->setQuotes(adoptRef(QuotesData::create(0)));
}
@@ -2927,10 +3136,10 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
CSSPrimitiveValue* contentValue = static_cast<CSSPrimitiveValue*>(item);
AtomicString face;
Settings* settings = m_checker.document()->settings();
- if (contentValue->primitiveType() == CSSPrimitiveValue::CSS_STRING) {
+ if (contentValue->isString()) {
if (contentValue->isFontFamilyValue())
face = static_cast<FontFamilyValue*>(contentValue)->familyName();
- } else if (contentValue->primitiveType() == CSSPrimitiveValue::CSS_IDENT && settings) {
+ } else if (settings) {
switch (contentValue->getIdent()) {
case CSSValueWebkitBody:
face = settings->standardFontFamily();
@@ -3128,8 +3337,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
RefPtr<StyleReflection> reflection = StyleReflection::create();
reflection->setDirection(reflectValue->direction());
if (reflectValue->offset()) {
- int type = reflectValue->offset()->primitiveType();
- if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ if (reflectValue->offset()->isPercentage())
reflection->setOffset(Length(reflectValue->offset()->getDoubleValue(), Percent));
else
reflection->setOffset(reflectValue->offset()->computeLength<Length>(style(), m_rootElementStyle, zoomFactor));
@@ -3144,7 +3352,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
}
case CSSPropertyOpacity:
HANDLE_INHERIT_AND_INITIAL(opacity, Opacity)
- if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
+ if (!primitiveValue || !primitiveValue->isNumber())
return; // Error case.
// Clamp opacity to the range 0-1
m_style->setOpacity(clampTo<float>(primitiveValue->getDoubleValue(), 0, 1));
@@ -3231,7 +3439,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
return;
if (primitiveValue->getIdent() == CSSValueInfinite)
m_style->setMarqueeLoopCount(-1); // -1 means repeat forever.
- else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
+ else if (primitiveValue->isNumber())
m_style->setMarqueeLoopCount(primitiveValue->getIntValue());
return;
}
@@ -3239,8 +3447,8 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
HANDLE_INHERIT_AND_INITIAL(marqueeSpeed, MarqueeSpeed)
if (!primitiveValue)
return;
- if (primitiveValue->getIdent()) {
- switch (primitiveValue->getIdent()) {
+ if (int ident = primitiveValue->getIdent()) {
+ switch (ident) {
case CSSValueSlow:
m_style->setMarqueeSpeed(500); // 500 msec.
break;
@@ -3251,12 +3459,9 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
m_style->setMarqueeSpeed(10); // 10msec. Super fast.
break;
}
- }
- else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S)
- m_style->setMarqueeSpeed(1000 * primitiveValue->getIntValue());
- else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_MS)
- m_style->setMarqueeSpeed(primitiveValue->getIntValue());
- else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) // For scrollamount support.
+ } else if (primitiveValue->isTime())
+ m_style->setMarqueeSpeed(primitiveValue->computeTime<int, CSSPrimitiveValue::Milliseconds>());
+ else if (primitiveValue->isNumber()) // For scrollamount support.
m_style->setMarqueeSpeed(primitiveValue->getIntValue());
return;
}
@@ -3276,8 +3481,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
m_style->setMarqueeIncrement(Length(36, Fixed)); // 36px.
break;
}
- }
- else {
+ } else {
bool ok = true;
Length marqueeLength = convertToIntLength(primitiveValue, style(), m_rootElementStyle, 1, &ok);
if (ok)
@@ -3314,10 +3518,9 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
HANDLE_INHERIT_AND_INITIAL(lineClamp, LineClamp)
if (!primitiveValue)
return;
- int type = primitiveValue->primitiveType();
- if (type == CSSPrimitiveValue::CSS_NUMBER)
+ if (primitiveValue->isNumber())
m_style->setLineClamp(LineClampValue(primitiveValue->getIntValue(CSSPrimitiveValue::CSS_NUMBER), LineClampLineCount));
- else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ else if (primitiveValue->isPercentage())
m_style->setLineClamp(LineClampValue(primitiveValue->getIntValue(CSSPrimitiveValue::CSS_PERCENTAGE), LineClampPercentage));
return;
}
@@ -3428,10 +3631,9 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
}
float perspectiveValue;
- int type = primitiveValue->primitiveType();
- if (CSSPrimitiveValue::isUnitTypeLength(type))
+ if (primitiveValue->isLength())
perspectiveValue = primitiveValue->computeLength<float>(style(), m_rootElementStyle, zoomFactor);
- else if (type == CSSPrimitiveValue::CSS_NUMBER) {
+ else if (primitiveValue->isNumber()) {
// For backward compatibility, treat valueless numbers as px.
perspectiveValue = CSSPrimitiveValue::create(primitiveValue->getDoubleValue(), CSSPrimitiveValue::CSS_PX)->computeLength<float>(style(), m_rootElementStyle, zoomFactor);
} else
@@ -3584,7 +3786,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
return;
if (primitiveValue->getIdent() == CSSValueAuto)
m_style->setWrapShapeInside(0);
- else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_SHAPE)
+ else if (primitiveValue->isShape())
m_style->setWrapShapeInside(primitiveValue->getShapeValue());
return;
@@ -3594,7 +3796,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
return;
if (primitiveValue->getIdent() == CSSValueAuto)
m_style->setWrapShapeOutside(0);
- else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_SHAPE)
+ else if (primitiveValue->isShape())
m_style->setWrapShapeOutside(primitiveValue->getShapeValue());
return;
@@ -3628,8 +3830,8 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
case CSSPropertyWebkitFilter: {
HANDLE_INHERIT_AND_INITIAL(filter, Filter);
FilterOperations operations;
- createFilterOperations(value, style(), m_rootElementStyle, operations);
- m_style->setFilter(operations);
+ if (createFilterOperations(value, style(), m_rootElementStyle, operations))
+ m_style->setFilter(operations);
return;
}
#endif
@@ -3713,12 +3915,14 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
case CSSPropertyBorderSpacing:
case CSSPropertyWebkitBorderHorizontalSpacing:
case CSSPropertyWebkitBorderVerticalSpacing:
+ case CSSPropertyClip:
case CSSPropertyCounterIncrement:
case CSSPropertyCounterReset:
case CSSPropertyLetterSpacing:
case CSSPropertyWordSpacing:
case CSSPropertyWebkitFlexOrder:
case CSSPropertyWebkitFlexPack:
+ case CSSPropertyWebkitFlexAlign:
case CSSPropertyWebkitFlexItemAlign:
case CSSPropertyWebkitFlexDirection:
case CSSPropertyWebkitFlexFlow:
@@ -3812,6 +4016,8 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
case CSSPropertyWebkitColumnWidth:
case CSSPropertyWebkitFlowInto:
case CSSPropertyWebkitFlowFrom:
+ case CSSPropertyWebkitFontKerning:
+ case CSSPropertyWebkitFontVariantLigatures:
case CSSPropertyWebkitHighlight:
case CSSPropertyWebkitHyphenateCharacter:
case CSSPropertyWebkitHyphenateLimitAfter:
@@ -4002,25 +4208,23 @@ void CSSStyleSelector::mapFillSize(CSSPropertyID, FillLayer* layer, CSSValue* va
CSSPrimitiveValue* second = pair ? static_cast<CSSPrimitiveValue*>(pair->second()) : 0;
Length firstLength, secondLength;
- int firstType = first->primitiveType();
- int secondType = second ? second->primitiveType() : 0;
float zoomFactor = m_style->effectiveZoom();
if (first->getIdent() == CSSValueAuto)
firstLength = Length();
- else if (CSSPrimitiveValue::isUnitTypeLength(firstType))
+ else if (first->isLength())
firstLength = first->computeLength<Length>(style(), m_rootElementStyle, zoomFactor);
- else if (firstType == CSSPrimitiveValue::CSS_PERCENTAGE)
+ else if (first->isPercentage())
firstLength = Length(first->getDoubleValue(), Percent);
else
return;
if (!second || second->getIdent() == CSSValueAuto)
secondLength = Length();
- else if (CSSPrimitiveValue::isUnitTypeLength(secondType))
+ else if (second->isLength())
secondLength = second->computeLength<Length>(style(), m_rootElementStyle, zoomFactor);
- else if (secondType == CSSPrimitiveValue::CSS_PERCENTAGE)
+ else if (second->isPercentage())
secondLength = Length(second->getDoubleValue(), Percent);
else
return;
@@ -4044,10 +4248,9 @@ void CSSStyleSelector::mapFillXPosition(CSSPropertyID, FillLayer* layer, CSSValu
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
Length l;
- int type = primitiveValue->primitiveType();
- if (CSSPrimitiveValue::isUnitTypeLength(type))
+ if (primitiveValue->isLength())
l = primitiveValue->computeLength<Length>(style(), m_rootElementStyle, zoomFactor);
- else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ else if (primitiveValue->isPercentage())
l = Length(primitiveValue->getDoubleValue(), Percent);
else
return;
@@ -4068,10 +4271,9 @@ void CSSStyleSelector::mapFillYPosition(CSSPropertyID, FillLayer* layer, CSSValu
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
Length l;
- int type = primitiveValue->primitiveType();
- if (CSSPrimitiveValue::isUnitTypeLength(type))
+ if (primitiveValue->isLength())
l = primitiveValue->computeLength<Length>(style(), m_rootElementStyle, zoomFactor);
- else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ else if (primitiveValue->isPercentage())
l = Length(primitiveValue->getDoubleValue(), Percent);
else
return;
@@ -4089,10 +4291,7 @@ void CSSStyleSelector::mapAnimationDelay(Animation* animation, CSSValue* value)
return;
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
- if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S)
- animation->setDelay(primitiveValue->getFloatValue());
- else
- animation->setDelay(primitiveValue->getFloatValue()/1000.0f);
+ animation->setDelay(primitiveValue->computeTime<float, CSSPrimitiveValue::Seconds>());
}
void CSSStyleSelector::mapAnimationDirection(Animation* layer, CSSValue* value)
@@ -4120,10 +4319,7 @@ void CSSStyleSelector::mapAnimationDuration(Animation* animation, CSSValue* valu
return;
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
- if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S)
- animation->setDuration(primitiveValue->getFloatValue());
- else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_MS)
- animation->setDuration(primitiveValue->getFloatValue()/1000.0f);
+ animation->setDuration(primitiveValue->computeTime<float, CSSPrimitiveValue::Seconds>());
}
void CSSStyleSelector::mapAnimationFillMode(Animation* layer, CSSValue* value)
@@ -4271,35 +4467,47 @@ void CSSStyleSelector::mapAnimationTimingFunction(Animation* animation, CSSValue
void CSSStyleSelector::mapNinePieceImage(CSSPropertyID property, CSSValue* value, NinePieceImage& image)
{
- // If we're a primitive value, then we are "none" and don't need to alter the empty image at all.
- if (!value || value->isPrimitiveValue() || !value->isBorderImageValue())
+ // If we're not a value list, then we are "none" and don't need to alter the empty image at all.
+ if (!value || !value->isValueList())
return;
// Retrieve the border image value.
- CSSBorderImageValue* borderImage = static_cast<CSSBorderImageValue*>(value);
+ CSSValueList* borderImage = static_cast<CSSValueList*>(value);
// Set the image (this kicks off the load).
CSSPropertyID imageProperty;
- if (property == CSSPropertyWebkitBorderImage || property == CSSPropertyBorderImage)
+ if (property == CSSPropertyWebkitBorderImage)
imageProperty = CSSPropertyBorderImageSource;
else if (property == CSSPropertyWebkitMaskBoxImage)
imageProperty = CSSPropertyWebkitMaskBoxImageSource;
else
imageProperty = property;
- if (CSSValue* imageValue = borderImage->imageValue())
- image.setImage(styleImage(imageProperty, imageValue));
-
- // Map in the image slices.
- mapNinePieceImageSlice(borderImage->m_imageSlice.get(), image);
-
- // Map in the border slices.
- if (borderImage->m_borderSlice)
- image.setBorderSlices(mapNinePieceImageQuad(borderImage->m_borderSlice.get()));
-
- // Map in the outset.
- if (borderImage->m_outset)
- image.setOutset(mapNinePieceImageQuad(borderImage->m_outset.get()));
+ for (unsigned i = 0 ; i < borderImage->length() ; ++i) {
+ CSSValue* current = borderImage->item(i);
+
+ if (current->isImageValue() || current->isImageGeneratorValue())
+ image.setImage(styleImage(imageProperty, current));
+ else if (current->isBorderImageSliceValue())
+ mapNinePieceImageSlice(current, image);
+ else if (current->isValueList()) {
+ CSSValueList* slashList = static_cast<CSSValueList*>(current);
+ // Map in the image slices.
+ if (slashList->item(0) && slashList->item(0)->isBorderImageSliceValue())
+ mapNinePieceImageSlice(slashList->item(0), image);
+
+ // Map in the border slices.
+ if (slashList->item(1))
+ image.setBorderSlices(mapNinePieceImageQuad(slashList->item(1)));
+
+ // Map in the outset.
+ if (slashList->item(2))
+ image.setOutset(mapNinePieceImageQuad(slashList->item(2)));
+ } else if (current->isPrimitiveValue()) {
+ // Set the appropriate rules for stretch/round/repeat of the slices.
+ mapNinePieceImageRepeat(current, image);
+ }
+ }
if (property == CSSPropertyWebkitBorderImage) {
// We have to preserve the legacy behavior of -webkit-border-image and make the border slices
@@ -4314,9 +4522,6 @@ void CSSStyleSelector::mapNinePieceImage(CSSPropertyID property, CSSValue* value
if (image.borderSlices().left().isFixed())
style()->setBorderLeftWidth(image.borderSlices().left().value());
}
-
- // Set the appropriate rules for stretch/round/repeat of the slices
- mapNinePieceImageRepeat(borderImage->m_repeat.get(), image);
}
void CSSStyleSelector::mapNinePieceImageSlice(CSSValue* value, NinePieceImage& image)
@@ -4330,19 +4535,19 @@ void CSSStyleSelector::mapNinePieceImageSlice(CSSValue* value, NinePieceImage& i
// Set up a length box to represent our image slices.
LengthBox box;
Quad* slices = borderImageSlice->slices();
- if (slices->top()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ if (slices->top()->isPercentage())
box.m_top = Length(slices->top()->getDoubleValue(), Percent);
else
box.m_top = Length(slices->top()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
- if (slices->bottom()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ if (slices->bottom()->isPercentage())
box.m_bottom = Length(slices->bottom()->getDoubleValue(), Percent);
else
box.m_bottom = Length((int)slices->bottom()->getFloatValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
- if (slices->left()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ if (slices->left()->isPercentage())
box.m_left = Length(slices->left()->getDoubleValue(), Percent);
else
box.m_left = Length(slices->left()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
- if (slices->right()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ if (slices->right()->isPercentage())
box.m_right = Length(slices->right()->getDoubleValue(), Percent);
else
box.m_right = Length(slices->right()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
@@ -4366,30 +4571,30 @@ LengthBox CSSStyleSelector::mapNinePieceImageQuad(CSSValue* value)
// Set up a length box to represent our image slices.
LengthBox box; // Defaults to 'auto' so we don't have to handle that explicitly below.
Quad* slices = borderWidths->getQuadValue();
- if (slices->top()->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
+ if (slices->top()->isNumber())
box.m_top = Length(slices->top()->getIntValue(), Relative);
- else if (slices->top()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ else if (slices->top()->isPercentage())
box.m_top = Length(slices->top()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
else if (slices->top()->getIdent() != CSSValueAuto)
box.m_top = slices->top()->computeLength<Length>(style(), rootElementStyle(), zoom);
- if (slices->right()->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
+ if (slices->right()->isNumber())
box.m_right = Length(slices->right()->getIntValue(), Relative);
- else if (slices->right()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ else if (slices->right()->isPercentage())
box.m_right = Length(slices->right()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
else if (slices->right()->getIdent() != CSSValueAuto)
box.m_right = slices->right()->computeLength<Length>(style(), rootElementStyle(), zoom);
- if (slices->bottom()->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
+ if (slices->bottom()->isNumber())
box.m_bottom = Length(slices->bottom()->getIntValue(), Relative);
- else if (slices->bottom()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ else if (slices->bottom()->isPercentage())
box.m_bottom = Length(slices->bottom()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
else if (slices->bottom()->getIdent() != CSSValueAuto)
box.m_bottom = slices->bottom()->computeLength<Length>(style(), rootElementStyle(), zoom);
- if (slices->left()->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
+ if (slices->left()->isNumber())
box.m_left = Length(slices->left()->getIntValue(), Relative);
- else if (slices->left()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ else if (slices->left()->isPercentage())
box.m_left = Length(slices->left()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
else if (slices->left()->getIdent() != CSSValueAuto)
box.m_left = slices->left()->computeLength<Length>(style(), rootElementStyle(), zoom);
@@ -4693,15 +4898,13 @@ static Color colorForCSSValue(int cssValueId)
Color CSSStyleSelector::colorFromPrimitiveValue(CSSPrimitiveValue* value, bool forVisitedLink) const
{
- if (value->primitiveType() == CSSPrimitiveValue::CSS_RGBCOLOR)
+ if (value->isRGBColor())
return Color(value->getRGBA32Value());
- if (value->primitiveType() != CSSPrimitiveValue::CSS_IDENT)
- return Color();
-
int ident = value->getIdent();
-
switch (ident) {
+ case 0:
+ return Color();
case CSSValueWebkitText:
return m_element->document()->textColor();
case CSSValueWebkitLink:
@@ -4898,14 +5101,7 @@ bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle*
break;
}
case WebKitCSSTransformValue::RotateTransformOperation: {
- double angle = firstValue->getDoubleValue();
- if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
- angle = rad2deg(angle);
- else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
- angle = grad2deg(angle);
- else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_TURN)
- angle = turn2deg(angle);
-
+ double angle = firstValue->computeDegrees();
operations.operations().append(RotateTransformOperation::create(0, 0, 1, angle, getTransformOperationType(transformValue->operationType())));
break;
}
@@ -4915,11 +5111,7 @@ bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle*
double x = 0;
double y = 0;
double z = 0;
- double angle = firstValue->getDoubleValue();
- if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
- angle = rad2deg(angle);
- else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
- angle = grad2deg(angle);
+ double angle = firstValue->computeDegrees();
if (transformValue->operationType() == WebKitCSSTransformValue::RotateXTransformOperation)
x = 1;
@@ -4939,11 +5131,7 @@ bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle*
double x = firstValue->getDoubleValue();
double y = secondValue->getDoubleValue();
double z = thirdValue->getDoubleValue();
- double angle = fourthValue->getDoubleValue();
- if (fourthValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
- angle = rad2deg(angle);
- else if (fourthValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
- angle = grad2deg(angle);
+ double angle = fourthValue->computeDegrees();
operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(transformValue->operationType())));
break;
}
@@ -4952,13 +5140,7 @@ bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle*
case WebKitCSSTransformValue::SkewYTransformOperation: {
double angleX = 0;
double angleY = 0;
- double angle = firstValue->getDoubleValue();
- if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
- angle = rad2deg(angle);
- else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
- angle = grad2deg(angle);
- else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_TURN)
- angle = turn2deg(angle);
+ double angle = firstValue->computeDegrees();
if (transformValue->operationType() == WebKitCSSTransformValue::SkewYTransformOperation)
angleY = angle;
else {
@@ -4966,13 +5148,7 @@ bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle*
if (transformValue->operationType() == WebKitCSSTransformValue::SkewTransformOperation) {
if (transformValue->length() > 1) {
CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1));
- angleY = secondValue->getDoubleValue();
- if (secondValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
- angleY = rad2deg(angleY);
- else if (secondValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
- angleY = grad2deg(angleY);
- else if (secondValue->primitiveType() == CSSPrimitiveValue::CSS_TURN)
- angleY = turn2deg(angleY);
+ angleY = secondValue->computeDegrees();
}
}
}
@@ -5016,7 +5192,7 @@ bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle*
case WebKitCSSTransformValue::PerspectiveTransformOperation: {
bool ok = true;
Length p = Length(0, Fixed);
- if (CSSPrimitiveValue::isUnitTypeLength(firstValue->primitiveType()))
+ if (firstValue->isLength())
p = convertToFloatLength(firstValue, style, rootStyle, zoomFactor, &ok);
else {
// This is a quirk that should go away when 3d transforms are finalized.
@@ -5105,19 +5281,103 @@ void CSSStyleSelector::loadPendingShaders()
RefPtr<FilterOperation> filterOperation = filterOperations.at(i);
if (filterOperation->getOperationType() == FilterOperation::CUSTOM) {
CustomFilterOperation* customFilter = static_cast<CustomFilterOperation*>(filterOperation.get());
- if (customFilter->vertexShader() && customFilter->vertexShader()->isPendingShader()) {
- WebKitCSSShaderValue* shaderValue = static_cast<StylePendingShader*>(customFilter->vertexShader())->cssShaderValue();
- customFilter->setVertexShader(shaderValue->cachedShader(cachedResourceLoader));
+ ASSERT(customFilter->program());
+ StyleCustomFilterProgram* program = static_cast<StyleCustomFilterProgram*>(customFilter->program());
+ if (program->vertexShader() && program->vertexShader()->isPendingShader()) {
+ WebKitCSSShaderValue* shaderValue = static_cast<StylePendingShader*>(program->vertexShader())->cssShaderValue();
+ program->setVertexShader(shaderValue->cachedShader(cachedResourceLoader));
}
- if (customFilter->fragmentShader() && customFilter->fragmentShader()->isPendingShader()) {
- WebKitCSSShaderValue* shaderValue = static_cast<StylePendingShader*>(customFilter->fragmentShader())->cssShaderValue();
- customFilter->setFragmentShader(shaderValue->cachedShader(cachedResourceLoader));
+ if (program->fragmentShader() && program->fragmentShader()->isPendingShader()) {
+ WebKitCSSShaderValue* shaderValue = static_cast<StylePendingShader*>(program->fragmentShader())->cssShaderValue();
+ program->setFragmentShader(shaderValue->cachedShader(cachedResourceLoader));
}
}
}
m_hasPendingShaders = false;
}
+static bool sortParametersByNameComparator(const RefPtr<CustomFilterParameter>& a, const RefPtr<CustomFilterParameter>& b)
+{
+ return codePointCompareLessThan(a->name(), b->name());
+}
+
+PassRefPtr<CustomFilterParameter> CSSStyleSelector::parseCustomFilterNumberParamter(const String& name, CSSValueList* values)
+{
+ RefPtr<CustomFilterNumberParameter> numberParameter = CustomFilterNumberParameter::create(name);
+ for (unsigned i = 0; i < values->length(); ++i) {
+ CSSValue* value = values->itemWithoutBoundsCheck(i);
+ if (!value->isPrimitiveValue())
+ return 0;
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
+ return 0;
+ numberParameter->addValue(primitiveValue->getDoubleValue());
+ }
+ return numberParameter.release();
+}
+
+bool CSSStyleSelector::parseCustomFilterParameterList(CSSValue* parametersValue, CustomFilterParameterList& parameterList)
+{
+ HashSet<String> knownParameterNames;
+ CSSValueListIterator parameterIterator(parametersValue);
+ for (; parameterIterator.hasMore(); parameterIterator.advance()) {
+ if (!parameterIterator.value()->isValueList())
+ return false;
+ CSSValueListIterator iterator(parameterIterator.value());
+ if (!iterator.isPrimitiveValue())
+ return false;
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(iterator.value());
+ if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_STRING)
+ return false;
+
+ String name = primitiveValue->getStringValue();
+ // Do not allow duplicate parameter names.
+ if (knownParameterNames.contains(name))
+ return false;
+ knownParameterNames.add(name);
+
+ iterator.advance();
+
+ if (!iterator.hasMore())
+ return false;
+
+ // FIXME: Implement other parameters types parsing.
+ // booleans: https://bugs.webkit.org/show_bug.cgi?id=76438
+ // textures: https://bugs.webkit.org/show_bug.cgi?id=71442
+ // 3d-transforms: https://bugs.webkit.org/show_bug.cgi?id=71443
+ // mat2, mat3, mat4: https://bugs.webkit.org/show_bug.cgi?id=71444
+ RefPtr<CustomFilterParameter> parameter;
+ if (iterator.value()->isValueList()) {
+ CSSValueList* values = static_cast<CSSValueList*>(iterator.value());
+ iterator.advance();
+
+ // We can have only arrays of booleans or numbers, so use the first value to choose between those two.
+ // Make sure we have at least one value. We need up to 4 values (all booleans or all numbers).
+ if (!values->length() || values->length() > 4)
+ return false;
+
+ if (!values->itemWithoutBoundsCheck(0)->isPrimitiveValue())
+ return false;
+
+ CSSPrimitiveValue* firstPrimitiveValue = static_cast<CSSPrimitiveValue*>(values->itemWithoutBoundsCheck(0));
+ if (firstPrimitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
+ parameter = parseCustomFilterNumberParamter(name, values);
+ // FIXME: Implement the boolean array parameter here.
+ // https://bugs.webkit.org/show_bug.cgi?id=76438
+ }
+
+ if (!parameter)
+ return false;
+
+ parameterList.append(parameter.release());
+ }
+
+ // Make sure we sort the parameters before passing them down to the CustomFilterOperation.
+ std::sort(parameterList.begin(), parameterList.end(), sortParametersByNameComparator);
+
+ return true;
+}
+
PassRefPtr<CustomFilterOperation> CSSStyleSelector::createCustomFilterOperation(WebKitCSSFilterValue* filterValue)
{
ASSERT(filterValue->length());
@@ -5135,6 +5395,8 @@ PassRefPtr<CustomFilterOperation> CSSStyleSelector::createCustomFilterOperation(
CustomFilterOperation::MeshBoxType meshBoxType = CustomFilterOperation::FILTER_BOX;
CustomFilterOperation::MeshType meshType = CustomFilterOperation::ATTACHED;
+ CSSValue* parametersValue = 0;
+
if (filterValue->length() > 1) {
CSSValueListIterator iterator(filterValue->itemWithoutBoundsCheck(1));
@@ -5144,7 +5406,7 @@ PassRefPtr<CustomFilterOperation> CSSStyleSelector::createCustomFilterOperation(
if (iterator.hasMore() && iterator.isPrimitiveValue()) {
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(iterator.value());
- if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) {
+ if (primitiveValue->isNumber()) {
// If only one integer value is specified, it will set both
// the rows and the columns.
meshRows = meshColumns = primitiveValue->getIntValue();
@@ -5153,7 +5415,7 @@ PassRefPtr<CustomFilterOperation> CSSStyleSelector::createCustomFilterOperation(
// Try to match another number for the columns.
if (iterator.hasMore() && iterator.isPrimitiveValue()) {
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(iterator.value());
- if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) {
+ if (primitiveValue->isNumber()) {
meshColumns = primitiveValue->getIntValue();
iterator.advance();
}
@@ -5179,9 +5441,24 @@ PassRefPtr<CustomFilterOperation> CSSStyleSelector::createCustomFilterOperation(
iterator.advance();
}
}
+
+ if (!iterator.index()) {
+ // If no value was consumed from the mesh value, then it is just a parameter list, meaning that we end up
+ // having just two CSSListValues: list of shaders and list of parameters.
+ ASSERT(filterValue->length() == 2);
+ parametersValue = filterValue->itemWithoutBoundsCheck(1);
+ }
}
- return CustomFilterOperation::create(vertexShader, fragmentShader, meshRows, meshColumns, meshBoxType, meshType);
+ if (filterValue->length() > 2 && !parametersValue)
+ parametersValue = filterValue->itemWithoutBoundsCheck(2);
+
+ CustomFilterParameterList parameterList;
+ if (parametersValue && !parseCustomFilterParameterList(parametersValue, parameterList))
+ return 0;
+
+ RefPtr<StyleCustomFilterProgram> program = StyleCustomFilterProgram::create(vertexShader.release(), fragmentShader.release());
+ return CustomFilterOperation::create(program.release(), parameterList, meshRows, meshColumns, meshBoxType, meshType);
}
#endif
@@ -5205,8 +5482,10 @@ bool CSSStyleSelector::createFilterOperations(CSSValue* inValue, RenderStyle* st
#if ENABLE(CSS_SHADERS)
if (operationType == FilterOperation::CUSTOM) {
RefPtr<CustomFilterOperation> operation = createCustomFilterOperation(filterValue);
- if (operation)
- operations.operations().append(operation);
+ if (!operation)
+ return false;
+
+ operations.operations().append(operation);
continue;
}
#endif
@@ -5238,7 +5517,7 @@ bool CSSStyleSelector::createFilterOperations(CSSValue* inValue, RenderStyle* st
double amount = 1;
if (filterValue->length() == 1) {
amount = firstValue->getDoubleValue();
- if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ if (firstValue->isPercentage())
amount /= 100;
}
@@ -5247,15 +5526,8 @@ bool CSSStyleSelector::createFilterOperations(CSSValue* inValue, RenderStyle* st
}
case WebKitCSSFilterValue::HueRotateFilterOperation: {
double angle = 0;
- if (filterValue->length() == 1) {
- angle = firstValue->getDoubleValue();
- if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
- angle = rad2deg(angle);
- else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
- angle = grad2deg(angle);
- else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_TURN)
- angle = turn2deg(angle);
- }
+ if (filterValue->length() == 1)
+ angle = firstValue->computeDegrees();
operations.operations().append(BasicColorMatrixFilterOperation::create(angle, operationType));
break;
@@ -5264,7 +5536,7 @@ bool CSSStyleSelector::createFilterOperations(CSSValue* inValue, RenderStyle* st
case WebKitCSSFilterValue::BrightnessFilterOperation:
case WebKitCSSFilterValue::ContrastFilterOperation:
case WebKitCSSFilterValue::OpacityFilterOperation: {
- double amount = 1;
+ double amount = (filterValue->operationType() == WebKitCSSFilterValue::BrightnessFilterOperation) ? 0 : 1;
if (filterValue->length() == 1) {
amount = firstValue->getDoubleValue();
if (firstValue->isPercentage())
diff --git a/Source/WebCore/css/CSSStyleSelector.h b/Source/WebCore/css/CSSStyleSelector.h
index 856193f99..633f703a7 100644
--- a/Source/WebCore/css/CSSStyleSelector.h
+++ b/Source/WebCore/css/CSSStyleSelector.h
@@ -54,6 +54,7 @@ class CSSStyleSheet;
class CSSValue;
class ContainerNode;
class CustomFilterOperation;
+class CustomFilterParameter;
class Document;
class Element;
class Frame;
@@ -63,6 +64,7 @@ class KeyframeList;
class KeyframeValue;
class MediaQueryEvaluator;
class Node;
+class RenderRegion;
class RuleData;
class RuleSet;
class Settings;
@@ -78,6 +80,10 @@ class WebKitCSSFilterValue;
class WebKitCSSRegionRule;
class WebKitCSSShaderValue;
+#if ENABLE(CSS_SHADERS)
+typedef Vector<RefPtr<CustomFilterParameter> > CustomFilterParameterList;
+#endif
+
class MediaQueryResult {
WTF_MAKE_NONCOPYABLE(MediaQueryResult); WTF_MAKE_FAST_ALLOCATED;
public:
@@ -100,11 +106,15 @@ public:
bool strictParsing, bool matchAuthorAndUserStyles);
~CSSStyleSelector();
+#if ENABLE(STYLE_SCOPED)
+ static Element* determineScopingElement(const CSSStyleSheet*);
+#endif
+
// Using these during tree walk will allow style selector to optimize child and descendant selector lookups.
- void pushParent(Element* parent) { m_checker.pushParent(parent); }
- void popParent(Element* parent) { m_checker.popParent(parent); }
+ void pushParent(Element* parent);
+ void popParent(Element* parent);
- PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false);
+ PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false, RenderRegion* regionForStyling = 0);
void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList&);
@@ -197,12 +207,10 @@ public:
void visitedStateChanged(LinkHash visitedHash) { m_checker.visitedStateChanged(visitedHash); }
void addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule>);
- void addPageStyle(PassRefPtr<CSSPageRule>);
- void addRegionRule(PassRefPtr<WebKitCSSRegionRule>);
- bool checkRegionStyle(Element*);
+ bool checkRegionStyle(Element* regionElement);
- bool usesSiblingRules() const { return m_features.siblingRules; }
+ bool usesSiblingRules() const { return !m_features.siblingRules.isEmpty(); }
bool usesFirstLineRules() const { return m_features.usesFirstLineRules; }
bool usesBeforeAfterRules() const { return m_features.usesBeforeAfterRules; }
bool usesLinkRules() const { return m_features.usesLinkRules; }
@@ -216,19 +224,27 @@ public:
#if ENABLE(CSS_SHADERS)
StyleShader* styleShader(CSSValue*);
StyleShader* cachedOrPendingStyleShaderFromValue(WebKitCSSShaderValue*);
+ bool parseCustomFilterParameterList(CSSValue*, CustomFilterParameterList&);
+ PassRefPtr<CustomFilterParameter> parseCustomFilterNumberParamter(const String& name, CSSValueList*);
PassRefPtr<CustomFilterOperation> createCustomFilterOperation(WebKitCSSFilterValue*);
void loadPendingShaders();
#endif
#endif // ENABLE(CSS_FILTERS)
+ struct RuleSelectorPair {
+ RuleSelectorPair(CSSStyleRule* rule, CSSSelector* selector) : rule(rule), selector(selector) { }
+ CSSStyleRule* rule;
+ CSSSelector* selector;
+ };
struct Features {
Features();
~Features();
+ void add(const CSSStyleSelector::Features&);
void clear();
HashSet<AtomicStringImpl*> idsInRules;
HashSet<AtomicStringImpl*> attrsInRules;
- OwnPtr<RuleSet> siblingRules;
- OwnPtr<RuleSet> uncommonAttributeRules;
+ Vector<RuleSelectorPair> siblingRules;
+ Vector<RuleSelectorPair> uncommonAttributeRules;
bool usesFirstLineRules;
bool usesBeforeAfterRules;
bool usesLinkRules;
@@ -245,31 +261,43 @@ private:
void addMatchedRule(const RuleData* rule) { m_matchedRules.append(rule); }
void addMatchedDeclaration(CSSMutableStyleDeclaration*, unsigned linkMatchType = SelectorChecker::MatchAll);
- struct MatchResult {
- MatchResult() : firstUARule(-1), lastUARule(-1), firstAuthorRule(-1), lastAuthorRule(-1), firstUserRule(-1), lastUserRule(-1), isCacheable(true) { }
+ struct MatchRanges {
+ MatchRanges() : firstUARule(-1), lastUARule(-1), firstAuthorRule(-1), lastAuthorRule(-1), firstUserRule(-1), lastUserRule(-1) { }
int firstUARule;
int lastUARule;
int firstAuthorRule;
int lastAuthorRule;
int firstUserRule;
int lastUserRule;
+ };
+
+ struct MatchResult {
+ MatchResult() : isCacheable(true) { }
+ MatchRanges ranges;
bool isCacheable;
};
void matchAllRules(MatchResult&);
void matchUARules(MatchResult&);
void matchRules(RuleSet*, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules);
- void matchRulesForList(const Vector<RuleData>*, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules);
+ void matchAuthorRules(int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules);
+ void matchScopedAuthorRules(int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules);
+ void collectMatchingRules(RuleSet*, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules);
+ void collectMatchingRulesForRegion(RuleSet*, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules);
+ void collectMatchingRulesForList(const Vector<RuleData>*, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules);
bool fastRejectSelector(const RuleData&) const;
void sortMatchedRules();
+ void sortAndTransferMatchedRules();
bool checkSelector(const RuleData&);
-
+ bool checkRegionSelector(CSSSelector* regionSelector, Element* regionElement);
void applyMatchedDeclarations(const MatchResult&);
template <bool firstPass>
void applyDeclarations(bool important, int startIndex, int endIndex, bool inheritedOnly);
template <bool firstPass>
void applyDeclaration(CSSMutableStyleDeclaration*, bool isImportant, bool inheritedOnly);
+ static bool isValidRegionStyleProperty(int id);
+
void matchPageRules(RuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName);
void matchPageRulesForList(const Vector<RuleData>*, bool isLeftPage, bool isFirstPage, const String& pageName);
bool isLeftPage(int pageIndex) const;
@@ -281,6 +309,8 @@ private:
OwnPtr<RuleSet> m_userStyle;
Features m_features;
+ OwnPtr<RuleSet> m_siblingRuleSet;
+ OwnPtr<RuleSet> m_uncommonAttributeRuleSet;
bool m_hasUAAppearance;
BorderData m_borderData;
@@ -290,9 +320,6 @@ private:
typedef HashMap<AtomicStringImpl*, RefPtr<WebKitCSSKeyframesRule> > KeyframesRuleMap;
KeyframesRuleMap m_keyframesRuleMap;
- typedef Vector<RefPtr<WebKitCSSRegionRule> > RegionStyleRules;
- RegionStyleRules m_regionStyleRules;
-
public:
static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
@@ -358,7 +385,7 @@ private:
static unsigned computeDeclarationHash(MatchedStyleDeclaration*, unsigned size);
struct MatchedStyleDeclarationCacheItem {
Vector<MatchedStyleDeclaration> matchedStyleDeclarations;
- MatchResult matchResult;
+ MatchRanges ranges;
RefPtr<RenderStyle> renderStyle;
RefPtr<RenderStyle> parentRenderStyle;
};
@@ -399,6 +426,7 @@ private:
RenderStyle* m_rootElementStyle;
Element* m_element;
StyledElement* m_styledElement;
+ RenderRegion* m_regionForStyling;
EInsideLink m_elementLinkState;
ContainerNode* m_parentNode;
CSSValue* m_lineHeightValue;
@@ -412,16 +440,40 @@ private:
bool m_applyPropertyToRegularStyle;
bool m_applyPropertyToVisitedLinkStyle;
const CSSStyleApplyProperty& m_applyProperty;
-
+
#if ENABLE(CSS_SHADERS)
bool m_hasPendingShaders;
#endif
+#if ENABLE(STYLE_SCOPED)
+ typedef HashMap<const Element*, OwnPtr<RuleSet> > ScopedRuleSetMap;
+
+ RuleSet* scopedRuleSetForElement(const Element*) const;
+
+ void setupScopingElementStack(const Element*);
+ bool scopingElementStackIsConsistent(const Element* parent) const { return parent && parent == m_scopingElementStackParent; }
+
+ ScopedRuleSetMap m_scopedAuthorStyles;
+
+ struct ScopeStackFrame {
+ ScopeStackFrame() : m_element(0), m_ruleSet(0) { }
+ ScopeStackFrame(const Element* element, RuleSet* ruleSet) : m_element(element), m_ruleSet(ruleSet) { }
+ const Element* m_element;
+ RuleSet* m_ruleSet;
+ };
+ // Vector (used as stack) that keeps track of scoping elements (i.e., elements with a <style scoped> child)
+ // encountered during tree iteration for style resolution.
+ Vector<ScopeStackFrame> m_scopingElementStack;
+ // Element last seen as parent element when updating m_scopingElementStack.
+ // This is used to decide whether m_scopingElementStack is consistent, separately from SelectorChecker::m_parentStack.
+ const Element* m_scopingElementStackParent;
+#endif
+
friend class CSSStyleApplyProperty;
friend bool operator==(const MatchedStyleDeclaration&, const MatchedStyleDeclaration&);
friend bool operator!=(const MatchedStyleDeclaration&, const MatchedStyleDeclaration&);
- friend bool operator==(const MatchResult&, const MatchResult&);
- friend bool operator!=(const MatchResult&, const MatchResult&);
+ friend bool operator==(const MatchRanges&, const MatchRanges&);
+ friend bool operator!=(const MatchRanges&, const MatchRanges&);
};
} // namespace WebCore
diff --git a/Source/WebCore/css/CSSValue.cpp b/Source/WebCore/css/CSSValue.cpp
index 711e4c5ed..016cb0bba 100644
--- a/Source/WebCore/css/CSSValue.cpp
+++ b/Source/WebCore/css/CSSValue.cpp
@@ -28,8 +28,8 @@
#include "CSSValue.h"
#include "CSSAspectRatioValue.h"
-#include "CSSBorderImageValue.h"
#include "CSSBorderImageSliceValue.h"
+#include "CSSCalculationValue.h"
#include "CSSCanvasValue.h"
#include "CSSCrossfadeValue.h"
#include "CSSCursorImageValue.h"
@@ -89,8 +89,6 @@ void CSSValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const CSSStyleSh
static_cast<CSSPrimitiveValue*>(this)->addSubresourceStyleURLs(urls, styleSheet);
else if (isValueList())
static_cast<CSSValueList*>(this)->addSubresourceStyleURLs(urls, styleSheet);
- else if (classType() == BorderImageClass)
- static_cast<CSSBorderImageValue*>(this)->addSubresourceStyleURLs(urls, styleSheet);
else if (classType() == FontFaceSrcClass)
static_cast<CSSFontFaceSrcValue*>(this)->addSubresourceStyleURLs(urls, styleSheet);
else if (classType() == ReflectClass)
@@ -102,8 +100,6 @@ String CSSValue::cssText() const
switch (classType()) {
case AspectRatioClass:
return static_cast<const CSSAspectRatioValue*>(this)->customCssText();
- case BorderImageClass:
- return static_cast<const CSSBorderImageValue*>(this)->customCssText();
case BorderImageSliceClass:
return static_cast<const CSSBorderImageSliceValue*>(this)->customCssText();
case CanvasClass:
@@ -154,6 +150,8 @@ String CSSValue::cssText() const
return static_cast<const CSSLineBoxContainValue*>(this)->customCssText();
case FlexClass:
return static_cast<const CSSFlexValue*>(this)->customCssText();
+ case CalculationClass:
+ return static_cast<const CSSCalcValue*>(this)->customCssText();
#if ENABLE(CSS_FILTERS)
case WebKitCSSFilterClass:
return static_cast<const WebKitCSSFilterValue*>(this)->customCssText();
@@ -179,9 +177,6 @@ void CSSValue::destroy()
case AspectRatioClass:
delete static_cast<CSSAspectRatioValue*>(this);
return;
- case BorderImageClass:
- delete static_cast<CSSBorderImageValue*>(this);
- return;
case BorderImageSliceClass:
delete static_cast<CSSBorderImageSliceValue*>(this);
return;
@@ -257,6 +252,9 @@ void CSSValue::destroy()
case FlexClass:
delete static_cast<CSSFlexValue*>(this);
return;
+ case CalculationClass:
+ delete static_cast<CSSCalcValue*>(this);
+ return;
#if ENABLE(CSS_FILTERS)
case WebKitCSSFilterClass:
delete static_cast<WebKitCSSFilterValue*>(this);
diff --git a/Source/WebCore/css/CSSValue.h b/Source/WebCore/css/CSSValue.h
index fd5e6f520..61233212b 100644
--- a/Source/WebCore/css/CSSValue.h
+++ b/Source/WebCore/css/CSSValue.h
@@ -60,7 +60,6 @@ public:
bool isValueList() const { return m_classType >= ValueListClass; }
bool isAspectRatioValue() const { return m_classType == AspectRatioClass; }
- bool isBorderImageValue() const { return m_classType == BorderImageClass; }
bool isBorderImageSliceValue() const { return m_classType == BorderImageSliceClass; }
bool isCursorImageValue() const { return m_classType == CursorImageClass; }
bool isFontFamilyValue() const { return m_classType == FontFamilyClass; }
@@ -77,6 +76,7 @@ public:
bool isWebKitCSSTransformValue() const { return m_classType == WebKitCSSTransformClass; }
bool isCSSLineBoxContainValue() const { return m_classType == LineBoxContainClass; }
bool isFlexValue() const { return m_classType == FlexClass; }
+ bool isCalculationValue() const {return m_classType == CalculationClass; }
#if ENABLE(CSS_FILTERS)
bool isWebKitCSSFilterValue() const { return m_classType == WebKitCSSFilterClass; }
#if ENABLE(CSS_SHADERS)
@@ -113,7 +113,6 @@ protected:
// Other class types.
AspectRatioClass,
- BorderImageClass,
BorderImageSliceClass,
FontFeatureClass,
FontClass,
@@ -128,6 +127,7 @@ protected:
UnicodeRangeClass,
LineBoxContainClass,
FlexClass,
+ CalculationClass,
#if ENABLE(CSS_FILTERS) && ENABLE(CSS_SHADERS)
WebKitCSSShaderClass,
#endif
diff --git a/Source/WebCore/css/CSSValue.idl b/Source/WebCore/css/CSSValue.idl
index 25eb8033c..0edc3d7bd 100644
--- a/Source/WebCore/css/CSSValue.idl
+++ b/Source/WebCore/css/CSSValue.idl
@@ -34,7 +34,7 @@ module css {
const unsigned short CSS_VALUE_LIST = 2;
const unsigned short CSS_CUSTOM = 3;
- attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString cssText
+ attribute [ConvertNullStringTo=Null, TreatNullAs=EmptyString] DOMString cssText
setter raises(DOMException);
readonly attribute unsigned short cssValueType;
diff --git a/Source/WebCore/css/CSSValueKeywords.in b/Source/WebCore/css/CSSValueKeywords.in
index ba1c5f692..fd1052886 100644
--- a/Source/WebCore/css/CSSValueKeywords.in
+++ b/Source/WebCore/css/CSSValueKeywords.in
@@ -52,6 +52,17 @@ all
//
//normal
small-caps
+
+// -webkit-font-variant-ligatures:
+//
+// normal
+common-ligatures
+no-common-ligatures
+discretionary-ligatures
+no-discretionary-ligatures
+historical-ligatures
+no-historical-ligatures
+
//
// CSS_PROP_FONT_WEIGHT:
//
@@ -481,6 +492,13 @@ multiple
// baseline
// stretch
+// CSS_PROP_FLEX_PACK
+// start
+// end
+// center
+// justify
+distribute
+
// CSS_PROP_FLEX_FLOW
row
row-reverse
@@ -832,11 +850,6 @@ glyphs
inline-box
replaced
-// -webkit-line-grid-snap
-//none
-//baseline
-bounds
-
// -webkit-font-feature-settings
on
off
diff --git a/Source/WebCore/css/MediaList.idl b/Source/WebCore/css/MediaList.idl
index 2b441f00a..73b336c87 100644
--- a/Source/WebCore/css/MediaList.idl
+++ b/Source/WebCore/css/MediaList.idl
@@ -31,7 +31,7 @@ module stylesheets {
HasIndexGetter
] MediaList {
- attribute [ConvertNullToNullString, ConvertNullStringTo=Null] DOMString mediaText
+ attribute [TreatNullAs=EmptyString, ConvertNullStringTo=Null] DOMString mediaText
setter raises(DOMException);
readonly attribute unsigned long length;
diff --git a/Source/WebCore/css/MediaQueryEvaluator.cpp b/Source/WebCore/css/MediaQueryEvaluator.cpp
index 64d493392..c4be4365b 100644
--- a/Source/WebCore/css/MediaQueryEvaluator.cpp
+++ b/Source/WebCore/css/MediaQueryEvaluator.cpp
@@ -178,9 +178,9 @@ static bool parseAspectRatio(CSSValue* value, int& h, int& v)
CSSValue* i0 = valueList->itemWithoutBoundsCheck(0);
CSSValue* i1 = valueList->itemWithoutBoundsCheck(1);
CSSValue* i2 = valueList->itemWithoutBoundsCheck(2);
- if (i0->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i0)->primitiveType() == CSSPrimitiveValue::CSS_NUMBER
- && i1->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i1)->primitiveType() == CSSPrimitiveValue::CSS_STRING
- && i2->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i2)->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) {
+ if (i0->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i0)->isNumber()
+ && i1->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i1)->isString()
+ && i2->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i2)->isNumber()) {
String str = static_cast<CSSPrimitiveValue*>(i1)->getStringValue();
if (!str.isNull() && str.length() == 1 && str[0] == '/') {
h = static_cast<CSSPrimitiveValue*>(i0)->getIntValue(CSSPrimitiveValue::CSS_NUMBER);
@@ -210,7 +210,7 @@ bool compareValue(T a, T b, MediaFeaturePrefix op)
static bool numberValue(CSSValue* value, float& result)
{
if (value->isPrimitiveValue()
- && static_cast<CSSPrimitiveValue*>(value)->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) {
+ && static_cast<CSSPrimitiveValue*>(value)->isNumber()) {
result = static_cast<CSSPrimitiveValue*>(value)->getFloatValue(CSSPrimitiveValue::CSS_NUMBER);
return true;
}
@@ -313,7 +313,7 @@ static bool computeLength(CSSValue* value, bool strict, RenderStyle* style, Rend
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
- if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) {
+ if (primitiveValue->isNumber()) {
result = primitiveValue->getIntValue();
return !strict || !result;
}
@@ -332,7 +332,9 @@ static bool device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, F
FloatRect sg = screenRect(frame->page()->mainFrame()->view());
RenderStyle* rootStyle = frame->document()->documentElement()->renderStyle();
int length;
- return computeLength(value, !frame->document()->inQuirksMode(), style, rootStyle, length) && compareValue(static_cast<int>(sg.height()), length, op);
+ long height = sg.height();
+ InspectorInstrumentation::applyScreenHeightOverride(frame, &height);
+ return computeLength(value, !frame->document()->inQuirksMode(), style, rootStyle, length) && compareValue(static_cast<int>(height), length, op);
}
// ({,min-,max-}device-height)
// assume if we have a device, assume non-zero
@@ -345,7 +347,9 @@ static bool device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Fr
FloatRect sg = screenRect(frame->page()->mainFrame()->view());
RenderStyle* rootStyle = frame->document()->documentElement()->renderStyle();
int length;
- return computeLength(value, !frame->document()->inQuirksMode(), style, rootStyle, length) && compareValue(static_cast<int>(sg.width()), length, op);
+ long width = sg.width();
+ InspectorInstrumentation::applyScreenWidthOverride(frame, &width);
+ return computeLength(value, !frame->document()->inQuirksMode(), style, rootStyle, length) && compareValue(static_cast<int>(width), length, op);
}
// ({,min-,max-}device-width)
// assume if we have a device, assume non-zero
diff --git a/Source/WebCore/css/SVGCSSParser.cpp b/Source/WebCore/css/SVGCSSParser.cpp
index dd738fb3c..2c295765a 100644
--- a/Source/WebCore/css/SVGCSSParser.cpp
+++ b/Source/WebCore/css/SVGCSSParser.cpp
@@ -314,6 +314,12 @@ bool CSSParser::parseSVGValue(int propId, bool important)
parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
else if (value->unit >= CSSParserValue::Q_EMS)
parsedValue = CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS);
+ if (isCalculation(value)) {
+ // FIXME calc() http://webkit.org/b/16662 : actually create a CSSPrimitiveValue here, ie
+ // parsedValue = CSSPrimitiveValue::create(m_parsedCalculation.release());
+ m_parsedCalculation.release();
+ parsedValue = 0;
+ }
m_valueList->next();
}
if (!parsedValue || (m_valueList->current() && !inShorthand()))
diff --git a/Source/WebCore/css/SelectorChecker.cpp b/Source/WebCore/css/SelectorChecker.cpp
index f74eed02c..3677fcf79 100644
--- a/Source/WebCore/css/SelectorChecker.cpp
+++ b/Source/WebCore/css/SelectorChecker.cpp
@@ -40,6 +40,7 @@
#include "HTMLNames.h"
#include "HTMLOptionElement.h"
#include "HTMLProgressElement.h"
+#include "HTMLStyleElement.h"
#include "InspectorInstrumentation.h"
#include "NodeRenderStyle.h"
#include "Page.h"
@@ -125,42 +126,33 @@ void SelectorChecker::popParentStackFrame()
}
}
-void SelectorChecker::pushParent(Element* parent)
+void SelectorChecker::setupParentStack(Element* parent)
{
- if (m_parentStack.isEmpty()) {
- ASSERT(!m_ancestorIdentifierFilter);
- m_ancestorIdentifierFilter = adoptPtr(new BloomFilter<bloomFilterKeyBits>);
- // If the element is not the root itself, build the stack starting from the root.
- if (parent->parentOrHostNode()) {
- Vector<Element*, 30> ancestors;
- for (Element* ancestor = parent; ancestor; ancestor = ancestor->parentOrHostElement())
- ancestors.append(ancestor);
- int count = ancestors.size();
- for (int n = count - 1; n >= 0; --n)
- pushParentStackFrame(ancestors[n]);
- return;
- }
- } else if (!parent->parentOrHostElement()) {
- // We are not always invoked consistently. For example, script execution can cause us to enter
- // style recalc in the middle of tree building. Reset the stack if we see a new root element.
- ASSERT(m_ancestorIdentifierFilter);
- m_ancestorIdentifierFilter->clear();
- m_parentStack.resize(0);
- } else {
- ASSERT(m_ancestorIdentifierFilter);
- // We may get invoked for some random elements in some wacky cases during style resolve.
- // Pause maintaining the stack in this case.
- if (m_parentStack.last().element != parent->parentOrHostElement())
- return;
+ ASSERT(m_parentStack.isEmpty() == !m_ancestorIdentifierFilter);
+ // Kill whatever we stored before.
+ m_parentStack.shrink(0);
+ m_ancestorIdentifierFilter = adoptPtr(new BloomFilter<bloomFilterKeyBits>);
+ // Fast version if parent is a root element:
+ if (!parent->parentOrHostNode()) {
+ pushParentStackFrame(parent);
+ return;
}
- pushParentStackFrame(parent);
+ // Otherwise climb up the tree.
+ Vector<Element*, 30> ancestors;
+ for (Element* ancestor = parent; ancestor; ancestor = ancestor->parentOrHostElement())
+ ancestors.append(ancestor);
+ for (size_t n = ancestors.size(); n; --n)
+ pushParentStackFrame(ancestors[n - 1]);
}
-void SelectorChecker::popParent(Element* parent)
+void SelectorChecker::pushParent(Element* parent)
{
- if (m_parentStack.isEmpty() || m_parentStack.last().element != parent)
+ ASSERT(m_ancestorIdentifierFilter);
+ // We may get invoked for some random elements in some wacky cases during style resolve.
+ // Pause maintaining the stack in this case.
+ if (m_parentStack.last().element != parent->parentOrHostElement())
return;
- popParentStackFrame();
+ pushParentStackFrame(parent);
}
static inline void collectDescendantSelectorIdentifierHashes(const CSSSelector* selector, unsigned*& hash, const unsigned* end)
@@ -715,7 +707,7 @@ bool SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, PseudoId& d
if (sel->isAttributeSelector()) {
const QualifiedName& attr = sel->attribute();
- NamedNodeMap* attributes = e->attributes(true);
+ NamedNodeMap* attributes = e->updatedAttributes();
if (!attributes)
return false;
diff --git a/Source/WebCore/css/SelectorChecker.h b/Source/WebCore/css/SelectorChecker.h
index 1a01306f8..3f9469e5d 100644
--- a/Source/WebCore/css/SelectorChecker.h
+++ b/Source/WebCore/css/SelectorChecker.h
@@ -60,9 +60,11 @@ public:
inline bool fastRejectSelector(const unsigned* identifierHashes) const;
static void collectIdentifierHashes(const CSSSelector*, unsigned* identifierHashes, unsigned maximumIdentifierCount);
+ void setupParentStack(Element* parent);
void pushParent(Element* parent);
- void popParent(Element* parent);
- bool parentStackIsConsistent(ContainerNode* parentNode) const { return !m_parentStack.isEmpty() && m_parentStack.last().element == parentNode; }
+ void popParent() { popParentStackFrame(); }
+ bool parentStackIsEmpty() const { return m_parentStack.isEmpty(); }
+ bool parentStackIsConsistent(const ContainerNode* parentNode) const { return !m_parentStack.isEmpty() && m_parentStack.last().element == parentNode; }
EInsideLink determineLinkState(Element*) const;
void allVisitedStateChanged();
@@ -115,7 +117,7 @@ private:
mutable HashSet<LinkHash, LinkHashHash> m_linksCheckedForVisitedState;
struct ParentStackFrame {
- ParentStackFrame() { }
+ ParentStackFrame() : element(0) { }
ParentStackFrame(Element* element) : element(element) { }
Element* element;
Vector<unsigned, 4> identifierHashes;
diff --git a/Source/WebCore/css/StyleSheetList.h b/Source/WebCore/css/StyleSheetList.h
index 4eb7d6a27..3f81163e6 100644
--- a/Source/WebCore/css/StyleSheetList.h
+++ b/Source/WebCore/css/StyleSheetList.h
@@ -46,6 +46,11 @@ public:
HTMLStyleElement* getNamedItem(const String&) const;
+ const StyleSheetVector& vector() const
+ {
+ return m_sheets;
+ }
+
void swap(StyleSheetVector& sheets)
{
m_sheets.swap(sheets);
diff --git a/Source/WebCore/css/WebKitCSSKeyframeRule.cpp b/Source/WebCore/css/WebKitCSSKeyframeRule.cpp
index 23bdeca5f..674aa5a7b 100644
--- a/Source/WebCore/css/WebKitCSSKeyframeRule.cpp
+++ b/Source/WebCore/css/WebKitCSSKeyframeRule.cpp
@@ -46,7 +46,7 @@ String WebKitCSSKeyframeRule::cssText() const
String result = m_key;
result += " { ";
- result += m_style->cssText();
+ result += m_style->asText();
result += "}";
return result;
diff --git a/Source/WebCore/css/WebKitCSSKeyframeRule.h b/Source/WebCore/css/WebKitCSSKeyframeRule.h
index 052c86bf1..083518756 100644
--- a/Source/WebCore/css/WebKitCSSKeyframeRule.h
+++ b/Source/WebCore/css/WebKitCSSKeyframeRule.h
@@ -26,14 +26,13 @@
#ifndef WebKitCSSKeyframeRule_h
#define WebKitCSSKeyframeRule_h
+#include "CSSMutableStyleDeclaration.h"
#include "CSSRule.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
namespace WebCore {
-class CSSMutableStyleDeclaration;
-
typedef int ExceptionCode;
class WebKitCSSKeyframeRule : public CSSRule {
@@ -54,15 +53,13 @@ public:
void getKeys(Vector<float>& keys) const { parseKeyString(m_key, keys); }
- CSSMutableStyleDeclaration* style() const { return m_style.get(); }
+ CSSStyleDeclaration* style() const { return m_style.get(); }
String cssText() const;
+ CSSMutableStyleDeclaration* declaration() const { return m_style.get(); }
void setDeclaration(PassRefPtr<CSSMutableStyleDeclaration>);
- CSSMutableStyleDeclaration* declaration() { return m_style.get(); }
- const CSSMutableStyleDeclaration* declaration() const { return m_style.get(); }
-
private:
static void parseKeyString(const String& s, Vector<float>& keys);
diff --git a/Source/WebCore/css/WebKitCSSKeyframesRule.idl b/Source/WebCore/css/WebKitCSSKeyframesRule.idl
index 3b081307f..87c8dd65e 100644
--- a/Source/WebCore/css/WebKitCSSKeyframesRule.idl
+++ b/Source/WebCore/css/WebKitCSSKeyframesRule.idl
@@ -33,7 +33,7 @@ module css {
HasIndexGetter
] WebKitCSSKeyframesRule : CSSRule {
- attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString name;
+ attribute [ConvertNullStringTo=Null, TreatNullAs=EmptyString] DOMString name;
readonly attribute CSSRuleList cssRules;
void insertRule(in [Optional=CallWithDefaultValue] DOMString rule);
diff --git a/Source/WebCore/css/WebKitCSSRegionRule.cpp b/Source/WebCore/css/WebKitCSSRegionRule.cpp
index c049ed68b..d809aafba 100644
--- a/Source/WebCore/css/WebKitCSSRegionRule.cpp
+++ b/Source/WebCore/css/WebKitCSSRegionRule.cpp
@@ -13,7 +13,7 @@
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
@@ -31,8 +31,11 @@
#include "WebKitCSSRegionRule.h"
+#include "CSSParser.h"
#include "CSSParserValues.h"
#include "CSSRuleList.h"
+#include "Document.h"
+#include "ExceptionCode.h"
namespace WebCore {
WebKitCSSRegionRule::WebKitCSSRegionRule(CSSStyleSheet* parent, Vector<OwnPtr<CSSParserSelector> >* selectors, PassRefPtr<CSSRuleList> rules)
diff --git a/Source/WebCore/css/WebKitCSSRegionRule.h b/Source/WebCore/css/WebKitCSSRegionRule.h
index 6367b50f9..f4dede542 100644
--- a/Source/WebCore/css/WebKitCSSRegionRule.h
+++ b/Source/WebCore/css/WebKitCSSRegionRule.h
@@ -13,7 +13,7 @@
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
diff --git a/Source/WebCore/css/WebKitCSSRegionRule.idl b/Source/WebCore/css/WebKitCSSRegionRule.idl
new file mode 100644
index 000000000..dc8b0a96d
--- /dev/null
+++ b/Source/WebCore/css/WebKitCSSRegionRule.idl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+module css {
+
+ interface [
+ ] WebKitCSSRegionRule : CSSRule {
+ readonly attribute CSSRuleList cssRules;
+ };
+
+}
diff --git a/Source/WebCore/css/svg.css b/Source/WebCore/css/svg.css
index 171c1c41f..bc31269f8 100644
--- a/Source/WebCore/css/svg.css
+++ b/Source/WebCore/css/svg.css
@@ -46,11 +46,6 @@ svg:not(:root), symbol, image, marker, pattern, foreignObject {
overflow: hidden
}
-svg {
- width: 100%;
- height: 100%;
-}
-
text, foreignObject {
display: block
}
diff --git a/Source/WebCore/css/tokenizer.flex b/Source/WebCore/css/tokenizer.flex
deleted file mode 100644
index c28dbcafa..000000000
--- a/Source/WebCore/css/tokenizer.flex
+++ /dev/null
@@ -1,130 +0,0 @@
-%option case-insensitive
-%option noyywrap
-%option 8bit
-%option stack
-%s mediaquery
-%s forkeyword
-%s nthchild
-
-h [0-9a-fA-F]
-nonascii [\200-\377]
-unicode \\{h}{1,6}[ \t\r\n\f]?
-escape {unicode}|\\[ -~\200-\377]
-nmstart [_a-zA-Z]|{nonascii}|{escape}
-nmchar [_a-zA-Z0-9-]|{nonascii}|{escape}
-string1 \"([^\n\r\f\\"]|\\{nl}|{escape})*\"
-string2 \'([^\n\r\f\\']|\\{nl}|{escape})*\'
-
-ident -?{nmstart}{nmchar}*
-num [0-9]+|[0-9]*"."[0-9]+
-intnum [0-9]+
-string {string1}|{string2}
-url ([!#$%&*-~]|{nonascii}|{escape})*
-w [ \t\r\n\f]*
-nl \n|\r\n|\r|\f
-range \?{1,6}|{h}(\?{0,5}|{h}(\?{0,4}|{h}(\?{0,3}|{h}(\?{0,2}|{h}(\??|{h})))))
-nth [\+-]?{intnum}*n([\t\r\n ]*[\+-][\t\r\n ]*{intnum})?
-nthfunc "nth-"("child"|"of-type"|"last-child"|"last-of-type")
-
-%%
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/ {countLines(); /* ignore comments */ }
-
-[ \t\r\n\f]+ {countLines(); yyTok = WHITESPACE; return yyTok;}
-
-"<!--" {yyTok = SGML_CD; return yyTok;}
-"-->" {yyTok = SGML_CD; return yyTok;}
-"~=" {yyTok = INCLUDES; return yyTok;}
-"|=" {yyTok = DASHMATCH; return yyTok;}
-"^=" {yyTok = BEGINSWITH; return yyTok;}
-"$=" {yyTok = ENDSWITH; return yyTok;}
-"*=" {yyTok = CONTAINS; return yyTok;}
-<mediaquery>"not" {yyTok = MEDIA_NOT; return yyTok;}
-<mediaquery>"only" {yyTok = MEDIA_ONLY; return yyTok;}
-<mediaquery>"and" {yyTok = MEDIA_AND; return yyTok;}
-
-{string} {yyTok = STRING; return yyTok;}
-{ident} {yyTok = IDENT; return yyTok;}
-<nthchild>{nth} {yyTok = NTH; return yyTok;}
-<nthchild>")" {BEGIN(INITIAL); yyTok = *yytext; return yyTok;}
-
-"#"{h}+ {yyTok = HEX; return yyTok;}
-"#"{ident} {yyTok = IDSEL; return yyTok;}
-
-"@import" {BEGIN(mediaquery); yyTok = IMPORT_SYM; return yyTok;}
-"@page" {yyTok = PAGE_SYM; return yyTok;}
-"@top-left-corner" {yyTok = TOPLEFTCORNER_SYM; return yyTok;}
-"@top-left" {yyTok = TOPLEFT_SYM; return yyTok;}
-"@top-center" {yyTok = TOPCENTER_SYM; return yyTok;}
-"@top-right" {yyTok = TOPRIGHT_SYM; return yyTok;}
-"@top-right-corner" {yyTok = TOPRIGHTCORNER_SYM; return yyTok;}
-"@bottom-left-corner" {yyTok = BOTTOMLEFTCORNER_SYM; return yyTok;}
-"@bottom-left" {yyTok = BOTTOMLEFT_SYM; return yyTok;}
-"@bottom-center" {yyTok = BOTTOMCENTER_SYM; return yyTok;}
-"@bottom-right" {yyTok = BOTTOMRIGHT_SYM; return yyTok;}
-"@bottom-right-corner" {yyTok = BOTTOMRIGHTCORNER_SYM; return yyTok;}
-"@left-top" {yyTok = LEFTTOP_SYM; return yyTok;}
-"@left-middle" {yyTok = LEFTMIDDLE_SYM; return yyTok;}
-"@left-bottom" {yyTok = LEFTBOTTOM_SYM; return yyTok;}
-"@right-top" {yyTok = RIGHTTOP_SYM; return yyTok;}
-"@right-middle" {yyTok = RIGHTMIDDLE_SYM; return yyTok;}
-"@right-bottom" {yyTok = RIGHTBOTTOM_SYM; return yyTok;}
-"@media" {BEGIN(mediaquery); yyTok = MEDIA_SYM; return yyTok;}
-"@font-face" {yyTok = FONT_FACE_SYM; return yyTok;}
-"@charset" {yyTok = CHARSET_SYM; return yyTok;}
-"@namespace" {yyTok = NAMESPACE_SYM; return yyTok; }
-"@-webkit-rule" {yyTok = WEBKIT_RULE_SYM; return yyTok; }
-"@-webkit-decls" {yyTok = WEBKIT_DECLS_SYM; return yyTok; }
-"@-webkit-value" {yyTok = WEBKIT_VALUE_SYM; return yyTok; }
-"@-webkit-mediaquery" {BEGIN(mediaquery); yyTok = WEBKIT_MEDIAQUERY_SYM; return yyTok; }
-"@-webkit-selector" {yyTok = WEBKIT_SELECTOR_SYM; return yyTok; }
-"@-webkit-keyframes" {yyTok = WEBKIT_KEYFRAMES_SYM; return yyTok; }
-"@-webkit-keyframe-rule" {yyTok = WEBKIT_KEYFRAME_RULE_SYM; return yyTok; }
-"@-webkit-region" {yyTok = WEBKIT_REGION_RULE_SYM; return yyTok;}
-
-"@"{ident} {yyTok = ATKEYWORD; return yyTok; }
-
-"!"{w}"important" {yyTok = IMPORTANT_SYM; return yyTok;}
-
-{num}em {yyTok = EMS; return yyTok;}
-{num}rem {yyTok = REMS; return yyTok;}
-{num}__qem {yyTok = QEMS; return yyTok;} /* quirky ems */
-{num}ex {yyTok = EXS; return yyTok;}
-{num}px {yyTok = PXS; return yyTok;}
-{num}cm {yyTok = CMS; return yyTok;}
-{num}mm {yyTok = MMS; return yyTok;}
-{num}in {yyTok = INS; return yyTok;}
-{num}pt {yyTok = PTS; return yyTok;}
-{num}pc {yyTok = PCS; return yyTok;}
-{num}deg {yyTok = DEGS; return yyTok;}
-{num}rad {yyTok = RADS; return yyTok;}
-{num}grad {yyTok = GRADS; return yyTok;}
-{num}turn {yyTok = TURNS; return yyTok;}
-{num}ms {yyTok = MSECS; return yyTok;}
-{num}s {yyTok = SECS; return yyTok;}
-{num}Hz {yyTok = HERTZ; return yyTok;}
-{num}kHz {yyTok = KHERTZ; return yyTok;}
-{num}{ident} {yyTok = DIMEN; return yyTok;}
-{num}{ident}\+ {yyTok = INVALIDDIMEN; return yyTok;}
-{num}%+ {yyTok = PERCENTAGE; return yyTok;}
-{intnum} {yyTok = INTEGER; return yyTok;}
-{num} {yyTok = FLOATTOKEN; return yyTok;}
-
-"-webkit-any(" {yyTok = ANYFUNCTION; return yyTok;}
-"not(" {yyTok = NOTFUNCTION; return yyTok;}
-"url("{w}{string}{w}")" {yyTok = URI; return yyTok;}
-"url("{w}{url}{w}")" {yyTok = URI; return yyTok;}
-"-webkit-calc(" {yyTok = CALCFUNCTION; return yyTok;}
-"-webkit-min(" {yyTok = MINFUNCTION; return yyTok;}
-"-webkit-max(" {yyTok = MAXFUNCTION; return yyTok;}
-{nthfunc}"(" {BEGIN(nthchild); yyTok = FUNCTION; return yyTok;}
-{ident}"(" {yyTok = FUNCTION; return yyTok;}
-
-U\+{range} {yyTok = UNICODERANGE; return yyTok;}
-U\+{h}{1,6}-{h}{1,6} {yyTok = UNICODERANGE; return yyTok;}
-
-<mediaquery>"{" |
-<mediaquery>";" {BEGIN(INITIAL); yyTok = *yytext; return yyTok; }
-. {yyTok = *yytext; return yyTok;}
-
-%%