summaryrefslogtreecommitdiffstats
path: root/WebCore/css
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/css')
-rw-r--r--WebCore/css/CSSBorderImageValue.cpp64
-rw-r--r--WebCore/css/CSSBorderImageValue.h57
-rw-r--r--WebCore/css/CSSCharsetRule.cpp43
-rw-r--r--WebCore/css/CSSCharsetRule.h55
-rw-r--r--WebCore/css/CSSCharsetRule.idl37
-rw-r--r--WebCore/css/CSSComputedStyleDeclaration.cpp1042
-rw-r--r--WebCore/css/CSSComputedStyleDeclaration.h78
-rw-r--r--WebCore/css/CSSCursorImageValue.cpp130
-rw-r--r--WebCore/css/CSSCursorImageValue.h55
-rw-r--r--WebCore/css/CSSFontFace.cpp88
-rw-r--r--WebCore/css/CSSFontFace.h67
-rw-r--r--WebCore/css/CSSFontFaceRule.cpp54
-rw-r--r--WebCore/css/CSSFontFaceRule.h57
-rw-r--r--WebCore/css/CSSFontFaceRule.idl32
-rw-r--r--WebCore/css/CSSFontFaceSource.cpp187
-rw-r--r--WebCore/css/CSSFontFaceSource.h82
-rw-r--r--WebCore/css/CSSFontFaceSrcValue.cpp71
-rw-r--r--WebCore/css/CSSFontFaceSrcValue.h74
-rw-r--r--WebCore/css/CSSFontSelector.cpp369
-rw-r--r--WebCore/css/CSSFontSelector.h67
-rw-r--r--WebCore/css/CSSGrammar.y1164
-rw-r--r--WebCore/css/CSSHelper.cpp87
-rw-r--r--WebCore/css/CSSHelper.h46
-rw-r--r--WebCore/css/CSSImageValue.cpp75
-rw-r--r--WebCore/css/CSSImageValue.h51
-rw-r--r--WebCore/css/CSSImportRule.cpp129
-rw-r--r--WebCore/css/CSSImportRule.h70
-rw-r--r--WebCore/css/CSSImportRule.idl34
-rw-r--r--WebCore/css/CSSInheritedValue.cpp40
-rw-r--r--WebCore/css/CSSInheritedValue.h38
-rw-r--r--WebCore/css/CSSInitialValue.cpp40
-rw-r--r--WebCore/css/CSSInitialValue.h47
-rw-r--r--WebCore/css/CSSMediaRule.cpp151
-rw-r--r--WebCore/css/CSSMediaRule.h68
-rw-r--r--WebCore/css/CSSMediaRule.idl39
-rw-r--r--WebCore/css/CSSMutableStyleDeclaration.cpp729
-rw-r--r--WebCore/css/CSSMutableStyleDeclaration.h116
-rw-r--r--WebCore/css/CSSNamespace.h59
-rw-r--r--WebCore/css/CSSPageRule.cpp57
-rw-r--r--WebCore/css/CSSPageRule.h59
-rw-r--r--WebCore/css/CSSPageRule.idl37
-rw-r--r--WebCore/css/CSSParser.cpp4035
-rw-r--r--WebCore/css/CSSParser.h295
-rw-r--r--WebCore/css/CSSPrimitiveValue.cpp703
-rw-r--r--WebCore/css/CSSPrimitiveValue.h180
-rw-r--r--WebCore/css/CSSPrimitiveValue.idl79
-rw-r--r--WebCore/css/CSSPrimitiveValueMappings.h2212
-rw-r--r--WebCore/css/CSSProperty.cpp41
-rw-r--r--WebCore/css/CSSProperty.h75
-rw-r--r--WebCore/css/CSSPropertyNames.in217
-rw-r--r--WebCore/css/CSSQuirkPrimitiveValue.h46
-rw-r--r--WebCore/css/CSSRule.cpp52
-rw-r--r--WebCore/css/CSSRule.h65
-rw-r--r--WebCore/css/CSSRule.idl50
-rw-r--r--WebCore/css/CSSRuleList.cpp100
-rw-r--r--WebCore/css/CSSRuleList.h58
-rw-r--r--WebCore/css/CSSRuleList.idl39
-rw-r--r--WebCore/css/CSSSegmentedFontFace.cpp140
-rw-r--r--WebCore/css/CSSSegmentedFontFace.h87
-rw-r--r--WebCore/css/CSSSelector.cpp364
-rw-r--r--WebCore/css/CSSSelector.h200
-rw-r--r--WebCore/css/CSSStyleDeclaration.cpp156
-rw-r--r--WebCore/css/CSSStyleDeclaration.h80
-rw-r--r--WebCore/css/CSSStyleDeclaration.idl54
-rw-r--r--WebCore/css/CSSStyleRule.cpp86
-rw-r--r--WebCore/css/CSSStyleRule.h71
-rw-r--r--WebCore/css/CSSStyleRule.idl37
-rw-r--r--WebCore/css/CSSStyleSelector.cpp5177
-rw-r--r--WebCore/css/CSSStyleSelector.h318
-rw-r--r--WebCore/css/CSSStyleSheet.cpp206
-rw-r--r--WebCore/css/CSSStyleSheet.h85
-rw-r--r--WebCore/css/CSSStyleSheet.idl48
-rw-r--r--WebCore/css/CSSTimingFunctionValue.cpp47
-rw-r--r--WebCore/css/CSSTimingFunctionValue.h62
-rw-r--r--WebCore/css/CSSTransformValue.cpp94
-rw-r--r--WebCore/css/CSSTransformValue.h65
-rw-r--r--WebCore/css/CSSUnicodeRangeValue.cpp44
-rw-r--r--WebCore/css/CSSUnicodeRangeValue.h56
-rw-r--r--WebCore/css/CSSUnknownRule.h45
-rw-r--r--WebCore/css/CSSUnknownRule.idl30
-rw-r--r--WebCore/css/CSSValue.h55
-rw-r--r--WebCore/css/CSSValue.idl43
-rw-r--r--WebCore/css/CSSValueKeywords.in567
-rw-r--r--WebCore/css/CSSValueList.cpp66
-rw-r--r--WebCore/css/CSSValueList.h54
-rw-r--r--WebCore/css/CSSValueList.idl39
-rw-r--r--WebCore/css/Counter.h61
-rw-r--r--WebCore/css/Counter.idl33
-rw-r--r--WebCore/css/DashboardRegion.h43
-rw-r--r--WebCore/css/FontFamilyValue.cpp106
-rw-r--r--WebCore/css/FontFamilyValue.h44
-rw-r--r--WebCore/css/FontValue.cpp69
-rw-r--r--WebCore/css/FontValue.h51
-rw-r--r--WebCore/css/MediaFeatureNames.cpp55
-rw-r--r--WebCore/css/MediaFeatureNames.h69
-rw-r--r--WebCore/css/MediaList.cpp271
-rw-r--r--WebCore/css/MediaList.h70
-rw-r--r--WebCore/css/MediaList.idl48
-rw-r--r--WebCore/css/MediaQuery.cpp97
-rw-r--r--WebCore/css/MediaQuery.h62
-rw-r--r--WebCore/css/MediaQueryEvaluator.cpp414
-rw-r--r--WebCore/css/MediaQueryEvaluator.h91
-rw-r--r--WebCore/css/MediaQueryExp.cpp85
-rw-r--r--WebCore/css/MediaQueryExp.h68
-rw-r--r--WebCore/css/Pair.h56
-rw-r--r--WebCore/css/RGBColor.idl42
-rw-r--r--WebCore/css/Rect.h55
-rw-r--r--WebCore/css/Rect.idl33
-rw-r--r--WebCore/css/SVGCSSComputedStyleDeclaration.cpp190
-rw-r--r--WebCore/css/SVGCSSParser.cpp358
-rw-r--r--WebCore/css/SVGCSSPropertyNames.in48
-rw-r--r--WebCore/css/SVGCSSStyleSelector.cpp615
-rw-r--r--WebCore/css/SVGCSSValueKeywords.in298
-rw-r--r--WebCore/css/ShadowValue.cpp67
-rw-r--r--WebCore/css/ShadowValue.h53
-rw-r--r--WebCore/css/StyleBase.cpp63
-rw-r--r--WebCore/css/StyleBase.h91
-rw-r--r--WebCore/css/StyleList.cpp54
-rw-r--r--WebCore/css/StyleList.h50
-rw-r--r--WebCore/css/StyleSheet.cpp74
-rw-r--r--WebCore/css/StyleSheet.h72
-rw-r--r--WebCore/css/StyleSheet.idl39
-rw-r--r--WebCore/css/StyleSheetList.cpp94
-rw-r--r--WebCore/css/StyleSheetList.h57
-rw-r--r--WebCore/css/StyleSheetList.idl35
-rw-r--r--WebCore/css/html4.css658
-rwxr-xr-xWebCore/css/make-css-file-arrays.pl88
-rw-r--r--WebCore/css/makegrammar.pl55
-rw-r--r--WebCore/css/makeprop.pl114
-rw-r--r--WebCore/css/maketokenizer127
-rw-r--r--WebCore/css/makevalues.pl108
-rw-r--r--WebCore/css/quirks.css48
-rw-r--r--WebCore/css/svg.css65
-rw-r--r--WebCore/css/tokenizer.flex98
-rw-r--r--WebCore/css/view-source.css151
135 files changed, 28161 insertions, 0 deletions
diff --git a/WebCore/css/CSSBorderImageValue.cpp b/WebCore/css/CSSBorderImageValue.cpp
new file mode 100644
index 0000000..1f38997
--- /dev/null
+++ b/WebCore/css/CSSBorderImageValue.cpp
@@ -0,0 +1,64 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 "CSSImageValue.h"
+#include "PlatformString.h"
+#include "Rect.h"
+
+namespace WebCore {
+
+CSSBorderImageValue::CSSBorderImageValue(PassRefPtr<CSSImageValue> image, PassRefPtr<Rect> imageRect, int horizontalRule, int verticalRule)
+ : m_image(image)
+ , m_imageSliceRect(imageRect)
+ , m_horizontalSizeRule(horizontalRule)
+ , m_verticalSizeRule(verticalRule)
+{
+}
+
+String CSSBorderImageValue::cssText() const
+{
+ // Image first.
+ String text(m_image->cssText());
+ text += " ";
+
+ // Now the rect, but it isn't really a rect, so we dump manually
+ text += m_imageSliceRect->top()->cssText();
+ text += " ";
+ text += m_imageSliceRect->right()->cssText();
+ text += " ";
+ text += m_imageSliceRect->bottom()->cssText();
+ text += " ";
+ text += m_imageSliceRect->left()->cssText();
+
+ // Now the keywords.
+ text += " ";
+ text += CSSPrimitiveValue(m_horizontalSizeRule).cssText();
+ text += " ";
+ text += CSSPrimitiveValue(m_verticalSizeRule).cssText();
+
+ return text;
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSBorderImageValue.h b/WebCore/css/CSSBorderImageValue.h
new file mode 100644
index 0000000..42372ff
--- /dev/null
+++ b/WebCore/css/CSSBorderImageValue.h
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 "CSSValue.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSImageValue;
+class Rect;
+
+class CSSBorderImageValue : public CSSValue {
+public:
+ CSSBorderImageValue();
+ CSSBorderImageValue(PassRefPtr<CSSImageValue>, PassRefPtr<Rect>, int horizontalRule, int verticalRule);
+
+ virtual String cssText() const;
+
+public:
+ // The border image.
+ RefPtr<CSSImageValue> m_image;
+
+ // These four values are used to make "cuts" in the image. They can be numbers
+ // or percentages.
+ RefPtr<Rect> m_imageSliceRect;
+
+ // Values for how to handle the scaling/stretching/tiling of the image slices.
+ int m_horizontalSizeRule; // Rule for how to adjust the widths of the top/middle/bottom
+ int m_verticalSizeRule; // Rule for how to adjust the heights of the left/middle/right
+};
+
+} // namespace WebCore
+
+#endif // CSSBorderImageValue_h
diff --git a/WebCore/css/CSSCharsetRule.cpp b/WebCore/css/CSSCharsetRule.cpp
new file mode 100644
index 0000000..ac04108
--- /dev/null
+++ b/WebCore/css/CSSCharsetRule.cpp
@@ -0,0 +1,43 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@macrules.ru)
+ *
+ * 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 "CSSCharsetRule.h"
+
+namespace WebCore {
+
+CSSCharsetRule::CSSCharsetRule(StyleBase* parent, const String& encoding)
+ : CSSRule(parent)
+ , m_encoding(encoding)
+{
+}
+
+CSSCharsetRule::~CSSCharsetRule()
+{
+}
+
+String CSSCharsetRule::cssText() const
+{
+ return "@charset \"" + m_encoding + "\";";
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSCharsetRule.h b/WebCore/css/CSSCharsetRule.h
new file mode 100644
index 0000000..d860ed3
--- /dev/null
+++ b/WebCore/css/CSSCharsetRule.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2006 Apple Computer, Inc.
+ *
+ * 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 CSSCharsetRule_h
+#define CSSCharsetRule_h
+
+#include "CSSRule.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+typedef int ExceptionCode;
+
+class CSSCharsetRule : public CSSRule {
+public:
+ CSSCharsetRule(StyleBase* parent, const String& encoding);
+ virtual ~CSSCharsetRule();
+
+ virtual bool isCharsetRule() { return true; }
+
+ String encoding() const { return m_encoding; }
+ void setEncoding(const String& encoding, ExceptionCode&) { m_encoding = encoding; }
+
+ // Inherited from CSSRule
+ virtual unsigned short type() const { return CHARSET_RULE; }
+
+ virtual String cssText() const;
+
+protected:
+ String m_encoding;
+};
+
+} // namespace WebCore
+
+#endif // CSSCharsetRule_h
diff --git a/WebCore/css/CSSCharsetRule.idl b/WebCore/css/CSSCharsetRule.idl
new file mode 100644
index 0000000..ebe659c
--- /dev/null
+++ b/WebCore/css/CSSCharsetRule.idl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [
+ GenerateConstructor,
+ InterfaceUUID=94180bad-a74e-4df9-adbc-6ce4e5b96155,
+ ImplementationUUID=354aa39e-ad53-4e9a-a927-80c3966c47f2
+ ] CSSCharsetRule : CSSRule {
+#if defined(LANGUAGE_OBJECTIVE_C)
+ readonly attribute [ConvertNullStringTo=Null] DOMString encoding;
+#else
+ attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString encoding
+ setter raises(DOMException);
+#endif
+ };
+
+}
diff --git a/WebCore/css/CSSComputedStyleDeclaration.cpp b/WebCore/css/CSSComputedStyleDeclaration.cpp
new file mode 100644
index 0000000..d848c1b
--- /dev/null
+++ b/WebCore/css/CSSComputedStyleDeclaration.cpp
@@ -0,0 +1,1042 @@
+/**
+ *
+ * Copyright (C) 2004 Zack Rusin <zack@kde.org>
+ * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include "config.h"
+#include "CSSComputedStyleDeclaration.h"
+
+#include "CSSMutableStyleDeclaration.h"
+#include "CSSPrimitiveValue.h"
+#include "CSSPrimitiveValueMappings.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueList.h"
+#include "CachedImage.h"
+#include "DashboardRegion.h"
+#include "Document.h"
+#include "ExceptionCode.h"
+#include "Pair.h"
+#include "RenderObject.h"
+#include "ShadowValue.h"
+
+namespace WebCore {
+
+// List of all properties we know how to compute, omitting shorthands.
+static const int computedProperties[] = {
+ CSS_PROP_BACKGROUND_ATTACHMENT,
+ CSS_PROP_BACKGROUND_COLOR,
+ CSS_PROP_BACKGROUND_IMAGE,
+ // more specific background-position-x/y are non-standard
+ CSS_PROP_BACKGROUND_POSITION,
+ CSS_PROP_BACKGROUND_REPEAT,
+ CSS_PROP_BORDER_BOTTOM_COLOR,
+ CSS_PROP_BORDER_BOTTOM_STYLE,
+ CSS_PROP_BORDER_BOTTOM_WIDTH,
+ CSS_PROP_BORDER_COLLAPSE,
+ CSS_PROP_BORDER_LEFT_COLOR,
+ CSS_PROP_BORDER_LEFT_STYLE,
+ CSS_PROP_BORDER_LEFT_WIDTH,
+ CSS_PROP_BORDER_RIGHT_COLOR,
+ CSS_PROP_BORDER_RIGHT_STYLE,
+ CSS_PROP_BORDER_RIGHT_WIDTH,
+ CSS_PROP_BORDER_TOP_COLOR,
+ CSS_PROP_BORDER_TOP_STYLE,
+ CSS_PROP_BORDER_TOP_WIDTH,
+ CSS_PROP_BOTTOM,
+ CSS_PROP_CAPTION_SIDE,
+ CSS_PROP_CLEAR,
+ CSS_PROP_COLOR,
+ CSS_PROP_CURSOR,
+ CSS_PROP_DIRECTION,
+ CSS_PROP_DISPLAY,
+ CSS_PROP_EMPTY_CELLS,
+ CSS_PROP_FLOAT,
+ CSS_PROP_FONT_FAMILY,
+ CSS_PROP_FONT_SIZE,
+ CSS_PROP_FONT_STYLE,
+ CSS_PROP_FONT_VARIANT,
+ CSS_PROP_FONT_WEIGHT,
+ CSS_PROP_HEIGHT,
+ CSS_PROP_LEFT,
+ CSS_PROP_LETTER_SPACING,
+ CSS_PROP_LINE_HEIGHT,
+ CSS_PROP_LIST_STYLE_IMAGE,
+ CSS_PROP_LIST_STYLE_POSITION,
+ CSS_PROP_LIST_STYLE_TYPE,
+ CSS_PROP_MARGIN_BOTTOM,
+ CSS_PROP_MARGIN_LEFT,
+ CSS_PROP_MARGIN_RIGHT,
+ CSS_PROP_MARGIN_TOP,
+ CSS_PROP_MAX_HEIGHT,
+ CSS_PROP_MAX_WIDTH,
+ CSS_PROP_MIN_HEIGHT,
+ CSS_PROP_MIN_WIDTH,
+ CSS_PROP_OPACITY,
+ CSS_PROP_ORPHANS,
+ CSS_PROP_OUTLINE_COLOR,
+ CSS_PROP_OUTLINE_STYLE,
+ CSS_PROP_OUTLINE_WIDTH,
+ CSS_PROP_OVERFLOW_X,
+ CSS_PROP_OVERFLOW_Y,
+ CSS_PROP_PADDING_BOTTOM,
+ CSS_PROP_PADDING_LEFT,
+ CSS_PROP_PADDING_RIGHT,
+ CSS_PROP_PADDING_TOP,
+ CSS_PROP_PAGE_BREAK_AFTER,
+ CSS_PROP_PAGE_BREAK_BEFORE,
+ CSS_PROP_PAGE_BREAK_INSIDE,
+ CSS_PROP_POSITION,
+ CSS_PROP_RESIZE,
+ CSS_PROP_RIGHT,
+ CSS_PROP_TABLE_LAYOUT,
+ CSS_PROP_TEXT_ALIGN,
+ CSS_PROP_TEXT_DECORATION,
+ CSS_PROP_TEXT_INDENT,
+ CSS_PROP_TEXT_SHADOW,
+ CSS_PROP_TEXT_TRANSFORM,
+ CSS_PROP_TOP,
+ CSS_PROP_UNICODE_BIDI,
+ CSS_PROP_VERTICAL_ALIGN,
+ CSS_PROP_VISIBILITY,
+ CSS_PROP_WHITE_SPACE,
+ CSS_PROP_WIDOWS,
+ CSS_PROP_WIDTH,
+ CSS_PROP_WORD_SPACING,
+ CSS_PROP_WORD_WRAP,
+ CSS_PROP_Z_INDEX,
+
+ CSS_PROP__WEBKIT_APPEARANCE,
+ CSS_PROP__WEBKIT_BACKGROUND_CLIP,
+ CSS_PROP__WEBKIT_BACKGROUND_COMPOSITE,
+ CSS_PROP__WEBKIT_BACKGROUND_ORIGIN,
+ CSS_PROP__WEBKIT_BACKGROUND_SIZE,
+ CSS_PROP__WEBKIT_BORDER_FIT,
+ CSS_PROP__WEBKIT_BORDER_HORIZONTAL_SPACING,
+ CSS_PROP__WEBKIT_BORDER_VERTICAL_SPACING,
+ CSS_PROP__WEBKIT_BOX_ALIGN,
+ CSS_PROP__WEBKIT_BOX_DIRECTION,
+ CSS_PROP__WEBKIT_BOX_FLEX,
+ CSS_PROP__WEBKIT_BOX_FLEX_GROUP,
+ CSS_PROP__WEBKIT_BOX_LINES,
+ CSS_PROP__WEBKIT_BOX_ORDINAL_GROUP,
+ CSS_PROP__WEBKIT_BOX_ORIENT,
+ CSS_PROP__WEBKIT_BOX_PACK,
+ CSS_PROP__WEBKIT_BOX_SHADOW,
+ CSS_PROP__WEBKIT_BOX_SIZING,
+ CSS_PROP__WEBKIT_COLUMN_BREAK_AFTER,
+ CSS_PROP__WEBKIT_COLUMN_BREAK_BEFORE,
+ CSS_PROP__WEBKIT_COLUMN_BREAK_INSIDE,
+ CSS_PROP__WEBKIT_COLUMN_COUNT,
+ CSS_PROP__WEBKIT_COLUMN_GAP,
+ CSS_PROP__WEBKIT_COLUMN_RULE_COLOR,
+ CSS_PROP__WEBKIT_COLUMN_RULE_STYLE,
+ CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH,
+ CSS_PROP__WEBKIT_COLUMN_WIDTH,
+ CSS_PROP__WEBKIT_HIGHLIGHT,
+ CSS_PROP__WEBKIT_LINE_BREAK,
+ CSS_PROP__WEBKIT_LINE_CLAMP,
+ CSS_PROP__WEBKIT_MARGIN_BOTTOM_COLLAPSE,
+ CSS_PROP__WEBKIT_MARGIN_TOP_COLLAPSE,
+ CSS_PROP__WEBKIT_MARQUEE_DIRECTION,
+ CSS_PROP__WEBKIT_MARQUEE_INCREMENT,
+ CSS_PROP__WEBKIT_MARQUEE_REPETITION,
+ CSS_PROP__WEBKIT_MARQUEE_STYLE,
+ CSS_PROP__WEBKIT_NBSP_MODE,
+ CSS_PROP__WEBKIT_RTL_ORDERING,
+ CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT,
+ CSS_PROP__WEBKIT_TEXT_FILL_COLOR,
+ CSS_PROP__WEBKIT_TEXT_SECURITY,
+ CSS_PROP__WEBKIT_TEXT_STROKE_COLOR,
+ CSS_PROP__WEBKIT_TEXT_STROKE_WIDTH,
+ CSS_PROP__WEBKIT_USER_DRAG,
+ CSS_PROP__WEBKIT_USER_MODIFY,
+ CSS_PROP__WEBKIT_USER_SELECT,
+ CSS_PROP__WEBKIT_DASHBOARD_REGION,
+ CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS,
+ CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS,
+ CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS,
+ CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS
+
+#if ENABLE(SVG)
+ ,
+ CSS_PROP_CLIP_PATH,
+ CSS_PROP_CLIP_RULE,
+ CSS_PROP_MASK,
+ CSS_PROP_FILTER,
+ CSS_PROP_FLOOD_COLOR,
+ CSS_PROP_FLOOD_OPACITY,
+ CSS_PROP_LIGHTING_COLOR,
+ CSS_PROP_STOP_COLOR,
+ CSS_PROP_STOP_OPACITY,
+ CSS_PROP_POINTER_EVENTS,
+ CSS_PROP_COLOR_INTERPOLATION,
+ CSS_PROP_COLOR_INTERPOLATION_FILTERS,
+ CSS_PROP_COLOR_RENDERING,
+ CSS_PROP_FILL,
+ CSS_PROP_FILL_OPACITY,
+ CSS_PROP_FILL_RULE,
+ CSS_PROP_IMAGE_RENDERING,
+ CSS_PROP_MARKER_END,
+ CSS_PROP_MARKER_MID,
+ CSS_PROP_MARKER_START,
+ CSS_PROP_SHAPE_RENDERING,
+ CSS_PROP_STROKE,
+ CSS_PROP_STROKE_DASHARRAY,
+ CSS_PROP_STROKE_DASHOFFSET,
+ CSS_PROP_STROKE_LINECAP,
+ CSS_PROP_STROKE_LINEJOIN,
+ CSS_PROP_STROKE_MITERLIMIT,
+ CSS_PROP_STROKE_OPACITY,
+ CSS_PROP_STROKE_WIDTH,
+ CSS_PROP_TEXT_RENDERING,
+ CSS_PROP_ALIGNMENT_BASELINE,
+ CSS_PROP_BASELINE_SHIFT,
+ CSS_PROP_DOMINANT_BASELINE,
+ CSS_PROP_KERNING,
+ CSS_PROP_TEXT_ANCHOR,
+ CSS_PROP_WRITING_MODE,
+ CSS_PROP_GLYPH_ORIENTATION_HORIZONTAL,
+ CSS_PROP_GLYPH_ORIENTATION_VERTICAL
+#endif
+};
+
+const unsigned numComputedProperties = sizeof(computedProperties) / sizeof(computedProperties[0]);
+
+static PassRefPtr<CSSValue> valueForShadow(const ShadowData* shadow)
+{
+ if (!shadow)
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+
+ RefPtr<CSSValueList> list = new CSSValueList;
+ for (const ShadowData* s = shadow; s; s = s->next) {
+ RefPtr<CSSPrimitiveValue> x = new CSSPrimitiveValue(s->x, CSSPrimitiveValue::CSS_PX);
+ RefPtr<CSSPrimitiveValue> y = new CSSPrimitiveValue(s->y, CSSPrimitiveValue::CSS_PX);
+ RefPtr<CSSPrimitiveValue> blur = new CSSPrimitiveValue(s->blur, CSSPrimitiveValue::CSS_PX);
+ RefPtr<CSSPrimitiveValue> color = new CSSPrimitiveValue(s->color.rgb());
+ list->append(new ShadowValue(x.release(), y.release(), blur.release(), color.release()));
+ }
+ return list.release();
+}
+
+static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, int propertyID)
+{
+ if (!style)
+ return 0;
+
+ Length l;
+ switch (propertyID) {
+ case CSS_PROP_LEFT:
+ l = style->left();
+ break;
+ case CSS_PROP_RIGHT:
+ l = style->right();
+ break;
+ case CSS_PROP_TOP:
+ l = style->top();
+ break;
+ case CSS_PROP_BOTTOM:
+ l = style->bottom();
+ break;
+ default:
+ return 0;
+ }
+
+ if (style->position() == AbsolutePosition || style->position() == FixedPosition)
+ return new CSSPrimitiveValue(l);
+
+ if (style->position() == RelativePosition)
+ // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
+ // In other words if left is auto and right is not auto, then left's computed value is negative right.
+ // So we should get the opposite length unit and see if it is auto.
+ return new CSSPrimitiveValue(l);
+
+ return new CSSPrimitiveValue(CSS_VAL_AUTO);
+}
+
+static PassRefPtr<CSSPrimitiveValue> currentColorOrValidColor(RenderStyle* style, const Color& color)
+{
+ if (!color.isValid())
+ return new CSSPrimitiveValue(style->color().rgb());
+ return new CSSPrimitiveValue(color.rgb());
+}
+
+static PassRefPtr<CSSValue> getBorderRadiusCornerValue(IntSize radius)
+{
+ if (radius.width() == radius.height())
+ return new CSSPrimitiveValue(radius.width(), CSSPrimitiveValue::CSS_PX);
+
+ RefPtr<CSSValueList> list = new CSSValueList(true);
+ list->append(new CSSPrimitiveValue(radius.width(), CSSPrimitiveValue::CSS_PX));
+ list->append(new CSSPrimitiveValue(radius.height(), CSSPrimitiveValue::CSS_PX));
+ return list.release();
+}
+
+static IntRect sizingBox(RenderObject* renderer)
+{
+ return renderer->style()->boxSizing() == CONTENT_BOX ? renderer->contentBox() : renderer->borderBox();
+}
+
+CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n)
+ : m_node(n)
+{
+}
+
+CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
+{
+}
+
+String CSSComputedStyleDeclaration::cssText() const
+{
+ String result("");
+
+ for (unsigned i = 0; i < numComputedProperties; i++) {
+ if (i)
+ result += " ";
+ result += getPropertyName(static_cast<CSSPropertyID>(computedProperties[i]));
+ result += ": ";
+ result += getPropertyValue(computedProperties[i]);
+ result += ";";
+ }
+
+ return result;
+}
+
+void CSSComputedStyleDeclaration::setCssText(const String&, ExceptionCode& ec)
+{
+ ec = NO_MODIFICATION_ALLOWED_ERR;
+}
+
+PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int propertyID) const
+{
+ return getPropertyCSSValue(propertyID, UpdateLayout);
+}
+
+PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int propertyID, EUpdateLayout updateLayout) const
+{
+ Node* node = m_node.get();
+ if (!node)
+ return 0;
+
+ // Make sure our layout is up to date before we allow a query on these attributes.
+ if (updateLayout)
+ node->document()->updateLayoutIgnorePendingStylesheets();
+
+ RenderObject* renderer = node->renderer();
+
+ RenderStyle* style = node->computedStyle();
+ if (!style)
+ return 0;
+
+ switch (static_cast<CSSPropertyID>(propertyID)) {
+ case CSS_PROP_INVALID:
+ break;
+
+ case CSS_PROP_BACKGROUND_COLOR:
+ return new CSSPrimitiveValue(style->backgroundColor().rgb());
+ case CSS_PROP_BACKGROUND_IMAGE:
+ if (style->backgroundImage())
+ return new CSSPrimitiveValue(style->backgroundImage()->url(), CSSPrimitiveValue::CSS_URI);
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ case CSS_PROP__WEBKIT_BACKGROUND_SIZE: {
+ RefPtr<CSSValueList> list = new CSSValueList(true);
+ list->append(new CSSPrimitiveValue(style->backgroundSize().width));
+ list->append(new CSSPrimitiveValue(style->backgroundSize().height));
+ return list.release();
+ }
+ case CSS_PROP_BACKGROUND_REPEAT:
+ return new CSSPrimitiveValue(style->backgroundRepeat());
+ case CSS_PROP__WEBKIT_BACKGROUND_COMPOSITE:
+ return new CSSPrimitiveValue(style->backgroundComposite());
+ case CSS_PROP_BACKGROUND_ATTACHMENT:
+ if (style->backgroundAttachment())
+ return new CSSPrimitiveValue(CSS_VAL_SCROLL);
+ return new CSSPrimitiveValue(CSS_VAL_FIXED);
+ case CSS_PROP__WEBKIT_BACKGROUND_CLIP:
+ case CSS_PROP__WEBKIT_BACKGROUND_ORIGIN: {
+ EBackgroundBox box = (propertyID == CSS_PROP__WEBKIT_BACKGROUND_CLIP ? style->backgroundClip() : style->backgroundOrigin());
+ return new CSSPrimitiveValue(box);
+ }
+ case CSS_PROP_BACKGROUND_POSITION: {
+ RefPtr<CSSValueList> list = new CSSValueList(true);
+
+ list->append(new CSSPrimitiveValue(style->backgroundXPosition()));
+ list->append(new CSSPrimitiveValue(style->backgroundYPosition()));
+
+ return list.release();
+ }
+ case CSS_PROP_BACKGROUND_POSITION_X:
+ return new CSSPrimitiveValue(style->backgroundXPosition());
+ case CSS_PROP_BACKGROUND_POSITION_Y:
+ return new CSSPrimitiveValue(style->backgroundYPosition());
+ case CSS_PROP_BORDER_COLLAPSE:
+ if (style->borderCollapse())
+ return new CSSPrimitiveValue(CSS_VAL_COLLAPSE);
+ return new CSSPrimitiveValue(CSS_VAL_SEPARATE);
+ case CSS_PROP_BORDER_SPACING: {
+ RefPtr<CSSValueList> list = new CSSValueList(true);
+ list->append(new CSSPrimitiveValue(style->horizontalBorderSpacing(), CSSPrimitiveValue::CSS_PX));
+ list->append(new CSSPrimitiveValue(style->verticalBorderSpacing(), CSSPrimitiveValue::CSS_PX));
+ return list.release();
+ }
+ case CSS_PROP__WEBKIT_BORDER_HORIZONTAL_SPACING:
+ return new CSSPrimitiveValue(style->horizontalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
+ case CSS_PROP__WEBKIT_BORDER_VERTICAL_SPACING:
+ return new CSSPrimitiveValue(style->verticalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
+ case CSS_PROP_BORDER_TOP_COLOR:
+ return currentColorOrValidColor(style, style->borderTopColor());
+ case CSS_PROP_BORDER_RIGHT_COLOR:
+ return currentColorOrValidColor(style, style->borderRightColor());
+ case CSS_PROP_BORDER_BOTTOM_COLOR:
+ return currentColorOrValidColor(style, style->borderBottomColor());
+ case CSS_PROP_BORDER_LEFT_COLOR:
+ return currentColorOrValidColor(style, style->borderLeftColor());
+ case CSS_PROP_BORDER_TOP_STYLE:
+ return new CSSPrimitiveValue(style->borderTopStyle());
+ case CSS_PROP_BORDER_RIGHT_STYLE:
+ return new CSSPrimitiveValue(style->borderRightStyle());
+ case CSS_PROP_BORDER_BOTTOM_STYLE:
+ return new CSSPrimitiveValue(style->borderBottomStyle());
+ case CSS_PROP_BORDER_LEFT_STYLE:
+ return new CSSPrimitiveValue(style->borderLeftStyle());
+ case CSS_PROP_BORDER_TOP_WIDTH:
+ return new CSSPrimitiveValue(style->borderTopWidth(), CSSPrimitiveValue::CSS_PX);
+ case CSS_PROP_BORDER_RIGHT_WIDTH:
+ return new CSSPrimitiveValue(style->borderRightWidth(), CSSPrimitiveValue::CSS_PX);
+ case CSS_PROP_BORDER_BOTTOM_WIDTH:
+ return new CSSPrimitiveValue(style->borderBottomWidth(), CSSPrimitiveValue::CSS_PX);
+ case CSS_PROP_BORDER_LEFT_WIDTH:
+ return new CSSPrimitiveValue(style->borderLeftWidth(), CSSPrimitiveValue::CSS_PX);
+ case CSS_PROP_BOTTOM:
+ return getPositionOffsetValue(style, CSS_PROP_BOTTOM);
+ case CSS_PROP__WEBKIT_BOX_ALIGN:
+ return new CSSPrimitiveValue(style->boxAlign());
+ case CSS_PROP__WEBKIT_BOX_DIRECTION:
+ return new CSSPrimitiveValue(style->boxDirection());
+ case CSS_PROP__WEBKIT_BOX_FLEX:
+ return new CSSPrimitiveValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP__WEBKIT_BOX_FLEX_GROUP:
+ return new CSSPrimitiveValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP__WEBKIT_BOX_LINES:
+ return new CSSPrimitiveValue(style->boxLines());
+ case CSS_PROP__WEBKIT_BOX_ORDINAL_GROUP:
+ return new CSSPrimitiveValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP__WEBKIT_BOX_ORIENT:
+ return new CSSPrimitiveValue(style->boxOrient());
+ case CSS_PROP__WEBKIT_BOX_PACK: {
+ EBoxAlignment boxPack = style->boxPack();
+ ASSERT(boxPack != BSTRETCH);
+ ASSERT(boxPack != BBASELINE);
+ if (boxPack == BJUSTIFY || boxPack== BBASELINE)
+ return 0;
+ return new CSSPrimitiveValue(boxPack);
+ }
+ case CSS_PROP__WEBKIT_BOX_SHADOW:
+ return valueForShadow(style->boxShadow());
+ case CSS_PROP_CAPTION_SIDE:
+ return new CSSPrimitiveValue(style->captionSide());
+ case CSS_PROP_CLEAR:
+ return new CSSPrimitiveValue(style->clear());
+ case CSS_PROP_COLOR:
+ return new CSSPrimitiveValue(style->color().rgb());
+ case CSS_PROP__WEBKIT_COLUMN_COUNT:
+ if (style->hasAutoColumnCount())
+ return new CSSPrimitiveValue(CSS_VAL_AUTO);
+ return new CSSPrimitiveValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP__WEBKIT_COLUMN_GAP:
+ if (style->hasNormalColumnGap())
+ return new CSSPrimitiveValue(CSS_VAL_NORMAL);
+ return new CSSPrimitiveValue(style->columnGap(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP__WEBKIT_COLUMN_RULE_COLOR:
+ return currentColorOrValidColor(style, style->columnRuleColor());
+ case CSS_PROP__WEBKIT_COLUMN_RULE_STYLE:
+ return new CSSPrimitiveValue(style->columnRuleStyle());
+ case CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH:
+ return new CSSPrimitiveValue(style->columnRuleWidth(), CSSPrimitiveValue::CSS_PX);
+ case CSS_PROP__WEBKIT_COLUMN_BREAK_AFTER:
+ return new CSSPrimitiveValue(style->columnBreakAfter());
+ case CSS_PROP__WEBKIT_COLUMN_BREAK_BEFORE:
+ return new CSSPrimitiveValue(style->columnBreakBefore());
+ case CSS_PROP__WEBKIT_COLUMN_BREAK_INSIDE:
+ return new CSSPrimitiveValue(style->columnBreakInside());
+ case CSS_PROP__WEBKIT_COLUMN_WIDTH:
+ if (style->hasAutoColumnWidth())
+ return new CSSPrimitiveValue(CSS_VAL_AUTO);
+ return new CSSPrimitiveValue(style->columnWidth(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP_CURSOR: {
+ RefPtr<CSSValueList> list;
+ CursorList* cursors = style->cursors();
+ if (cursors && cursors->size() > 0) {
+ list = new CSSValueList;
+ for (unsigned i = 0; i < cursors->size(); ++i)
+ list->append(new CSSPrimitiveValue((*cursors)[i].cursorImage->url(), CSSPrimitiveValue::CSS_URI));
+ }
+ RefPtr<CSSValue> value = new CSSPrimitiveValue(style->cursor());
+ if (list) {
+ list->append(value);
+ return list.release();
+ }
+ return value.release();
+ }
+ case CSS_PROP_DIRECTION:
+ return new CSSPrimitiveValue(style->direction());
+ case CSS_PROP_DISPLAY:
+ return new CSSPrimitiveValue(style->display());
+ case CSS_PROP_EMPTY_CELLS:
+ return new CSSPrimitiveValue(style->emptyCells());
+ case CSS_PROP_FLOAT:
+ return new CSSPrimitiveValue(style->floating());
+ case CSS_PROP_FONT_FAMILY:
+ // FIXME: This only returns the first family.
+ return new CSSPrimitiveValue(style->fontDescription().family().family().string(), CSSPrimitiveValue::CSS_STRING);
+ case CSS_PROP_FONT_SIZE:
+ return new CSSPrimitiveValue(style->fontDescription().computedPixelSize(), CSSPrimitiveValue::CSS_PX);
+ case CSS_PROP__WEBKIT_BINDING:
+ break;
+ case CSS_PROP_FONT_STYLE:
+ if (style->fontDescription().italic())
+ return new CSSPrimitiveValue(CSS_VAL_ITALIC);
+ return new CSSPrimitiveValue(CSS_VAL_NORMAL);
+ case CSS_PROP_FONT_VARIANT:
+ if (style->fontDescription().smallCaps())
+ return new CSSPrimitiveValue(CSS_VAL_SMALL_CAPS);
+ return new CSSPrimitiveValue(CSS_VAL_NORMAL);
+ case CSS_PROP_FONT_WEIGHT:
+ // FIXME: this does not reflect the full range of weights
+ // that can be expressed with CSS
+ if (style->fontDescription().weight() == cBoldWeight)
+ return new CSSPrimitiveValue(CSS_VAL_BOLD);
+ return new CSSPrimitiveValue(CSS_VAL_NORMAL);
+ case CSS_PROP_HEIGHT:
+ if (renderer)
+ return new CSSPrimitiveValue(sizingBox(renderer).height(), CSSPrimitiveValue::CSS_PX);
+ return new CSSPrimitiveValue(style->height());
+ case CSS_PROP__WEBKIT_HIGHLIGHT:
+ if (style->highlight() == nullAtom)
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ return new CSSPrimitiveValue(style->highlight(), CSSPrimitiveValue::CSS_STRING);
+ case CSS_PROP__WEBKIT_BORDER_FIT:
+ if (style->borderFit() == BorderFitBorder)
+ return new CSSPrimitiveValue(CSS_VAL_BORDER);
+ return new CSSPrimitiveValue(CSS_VAL_LINES);
+ case CSS_PROP_LEFT:
+ return getPositionOffsetValue(style, CSS_PROP_LEFT);
+ case CSS_PROP_LETTER_SPACING:
+ if (!style->letterSpacing())
+ return new CSSPrimitiveValue(CSS_VAL_NORMAL);
+ return new CSSPrimitiveValue(style->letterSpacing(), CSSPrimitiveValue::CSS_PX);
+ case CSS_PROP__WEBKIT_LINE_CLAMP:
+ if (style->lineClamp() == -1)
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ return new CSSPrimitiveValue(style->lineClamp(), CSSPrimitiveValue::CSS_PERCENTAGE);
+ case CSS_PROP_LINE_HEIGHT: {
+ Length length = style->lineHeight();
+ if (length.isNegative())
+ return new CSSPrimitiveValue(CSS_VAL_NORMAL);
+ if (length.isPercent())
+ // This is imperfect, because it doesn't include the zoom factor and the real computation
+ // for how high to be in pixels does include things like minimum font size and the zoom factor.
+ // On the other hand, since font-size doesn't include the zoom factor, we really can't do
+ // that here either.
+ return new CSSPrimitiveValue(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, CSSPrimitiveValue::CSS_PX);
+ return new CSSPrimitiveValue(length.value(), CSSPrimitiveValue::CSS_PX);
+ }
+ case CSS_PROP_LIST_STYLE_IMAGE:
+ if (style->listStyleImage())
+ return new CSSPrimitiveValue(style->listStyleImage()->url(), CSSPrimitiveValue::CSS_URI);
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ case CSS_PROP_LIST_STYLE_POSITION:
+ return new CSSPrimitiveValue(style->listStylePosition());
+ case CSS_PROP_LIST_STYLE_TYPE:
+ return new CSSPrimitiveValue(style->listStyleType());
+ case CSS_PROP_MARGIN_TOP:
+ if (renderer)
+ // FIXME: Supposed to return the percentage if percentage was specified.
+ return new CSSPrimitiveValue(renderer->marginTop(), CSSPrimitiveValue::CSS_PX);
+ return new CSSPrimitiveValue(style->marginTop());
+ case CSS_PROP_MARGIN_RIGHT:
+ if (renderer)
+ // FIXME: Supposed to return the percentage if percentage was specified.
+ return new CSSPrimitiveValue(renderer->marginRight(), CSSPrimitiveValue::CSS_PX);
+ return new CSSPrimitiveValue(style->marginRight());
+ case CSS_PROP_MARGIN_BOTTOM:
+ if (renderer)
+ // FIXME: Supposed to return the percentage if percentage was specified.
+ return new CSSPrimitiveValue(renderer->marginBottom(), CSSPrimitiveValue::CSS_PX);
+ return new CSSPrimitiveValue(style->marginBottom());
+ case CSS_PROP_MARGIN_LEFT:
+ if (renderer)
+ // FIXME: Supposed to return the percentage if percentage was specified.
+ return new CSSPrimitiveValue(renderer->marginLeft(), CSSPrimitiveValue::CSS_PX);
+ return new CSSPrimitiveValue(style->marginLeft());
+ case CSS_PROP__WEBKIT_MARQUEE_DIRECTION:
+ return new CSSPrimitiveValue(style->marqueeDirection());
+ case CSS_PROP__WEBKIT_MARQUEE_INCREMENT:
+ return new CSSPrimitiveValue(style->marqueeIncrement());
+ case CSS_PROP__WEBKIT_MARQUEE_REPETITION:
+ if (style->marqueeLoopCount() < 0)
+ return new CSSPrimitiveValue(CSS_VAL_INFINITE);
+ return new CSSPrimitiveValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP__WEBKIT_MARQUEE_STYLE:
+ return new CSSPrimitiveValue(style->marqueeBehavior());
+ case CSS_PROP__WEBKIT_USER_MODIFY:
+ return new CSSPrimitiveValue(style->userModify());
+ case CSS_PROP_MAX_HEIGHT: {
+ const Length& maxHeight = style->maxHeight();
+ if (maxHeight.isFixed() && maxHeight.value() == undefinedLength)
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ return new CSSPrimitiveValue(maxHeight);
+ }
+ case CSS_PROP_MAX_WIDTH: {
+ const Length& maxWidth = style->maxHeight();
+ if (maxWidth.isFixed() && maxWidth.value() == undefinedLength)
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ return new CSSPrimitiveValue(maxWidth);
+ }
+ case CSS_PROP_MIN_HEIGHT:
+ return new CSSPrimitiveValue(style->minHeight());
+ case CSS_PROP_MIN_WIDTH:
+ return new CSSPrimitiveValue(style->minWidth());
+ case CSS_PROP_OPACITY:
+ return new CSSPrimitiveValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP_ORPHANS:
+ return new CSSPrimitiveValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP_OUTLINE_COLOR:
+ return currentColorOrValidColor(style, style->outlineColor());
+ case CSS_PROP_OUTLINE_STYLE:
+ if (style->outlineStyleIsAuto())
+ return new CSSPrimitiveValue(CSS_VAL_AUTO);
+ return new CSSPrimitiveValue(style->outlineStyle());
+ case CSS_PROP_OUTLINE_WIDTH:
+ return new CSSPrimitiveValue(style->outlineWidth(), CSSPrimitiveValue::CSS_PX);
+ case CSS_PROP_OVERFLOW:
+ return new CSSPrimitiveValue(max(style->overflowX(), style->overflowY()));
+ case CSS_PROP_OVERFLOW_X:
+ return new CSSPrimitiveValue(style->overflowX());
+ case CSS_PROP_OVERFLOW_Y:
+ return new CSSPrimitiveValue(style->overflowY());
+ case CSS_PROP_PADDING_TOP:
+ if (renderer)
+ return new CSSPrimitiveValue(renderer->paddingTop(), CSSPrimitiveValue::CSS_PX);
+ return new CSSPrimitiveValue(style->paddingTop());
+ case CSS_PROP_PADDING_RIGHT:
+ if (renderer)
+ return new CSSPrimitiveValue(renderer->paddingRight(), CSSPrimitiveValue::CSS_PX);
+ return new CSSPrimitiveValue(style->paddingRight());
+ case CSS_PROP_PADDING_BOTTOM:
+ if (renderer)
+ return new CSSPrimitiveValue(renderer->paddingBottom(), CSSPrimitiveValue::CSS_PX);
+ return new CSSPrimitiveValue(style->paddingBottom());
+ case CSS_PROP_PADDING_LEFT:
+ if (renderer)
+ return new CSSPrimitiveValue(renderer->paddingLeft(), CSSPrimitiveValue::CSS_PX);
+ return new CSSPrimitiveValue(style->paddingLeft());
+ case CSS_PROP_PAGE_BREAK_AFTER:
+ return new CSSPrimitiveValue(style->pageBreakAfter());
+ case CSS_PROP_PAGE_BREAK_BEFORE:
+ return new CSSPrimitiveValue(style->pageBreakBefore());
+ case CSS_PROP_PAGE_BREAK_INSIDE: {
+ EPageBreak pageBreak = style->pageBreakInside();
+ ASSERT(pageBreak != PBALWAYS);
+ if (pageBreak == PBALWAYS)
+ return 0;
+ return new CSSPrimitiveValue(style->pageBreakInside());
+ }
+ case CSS_PROP_POSITION:
+ return new CSSPrimitiveValue(style->position());
+ case CSS_PROP_RIGHT:
+ return getPositionOffsetValue(style, CSS_PROP_RIGHT);
+ case CSS_PROP_TABLE_LAYOUT:
+ return new CSSPrimitiveValue(style->tableLayout());
+ case CSS_PROP_TEXT_ALIGN:
+ return new CSSPrimitiveValue(style->textAlign());
+ case CSS_PROP_TEXT_DECORATION: {
+ String string;
+ if (style->textDecoration() & UNDERLINE)
+ string += "underline";
+ if (style->textDecoration() & OVERLINE) {
+ if (string.length())
+ string += " ";
+ string += "overline";
+ }
+ if (style->textDecoration() & LINE_THROUGH) {
+ if (string.length())
+ string += " ";
+ string += "line-through";
+ }
+ if (style->textDecoration() & BLINK) {
+ if (string.length())
+ string += " ";
+ string += "blink";
+ }
+ if (!string.length())
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ return new CSSPrimitiveValue(string, CSSPrimitiveValue::CSS_STRING);
+ }
+ case CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT: {
+ String string;
+ if (style->textDecorationsInEffect() & UNDERLINE)
+ string += "underline";
+ if (style->textDecorationsInEffect() & OVERLINE) {
+ if (string.length())
+ string += " ";
+ string += "overline";
+ }
+ if (style->textDecorationsInEffect() & LINE_THROUGH) {
+ if (string.length())
+ string += " ";
+ string += "line-through";
+ }
+ if (style->textDecorationsInEffect() & BLINK) {
+ if (string.length())
+ string += " ";
+ string += "blink";
+ }
+ if (!string.length())
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ return new CSSPrimitiveValue(string, CSSPrimitiveValue::CSS_STRING);
+ }
+ case CSS_PROP__WEBKIT_TEXT_FILL_COLOR:
+ return currentColorOrValidColor(style, style->textFillColor());
+ case CSS_PROP_TEXT_INDENT:
+ return new CSSPrimitiveValue(style->textIndent());
+ case CSS_PROP_TEXT_SHADOW:
+ return valueForShadow(style->textShadow());
+ case CSS_PROP__WEBKIT_TEXT_SECURITY:
+ return new CSSPrimitiveValue(style->textSecurity());
+ case CSS_PROP__WEBKIT_TEXT_SIZE_ADJUST:
+ if (style->textSizeAdjust())
+ return new CSSPrimitiveValue(CSS_VAL_AUTO);
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ case CSS_PROP__WEBKIT_TEXT_STROKE_COLOR:
+ return currentColorOrValidColor(style, style->textStrokeColor());
+ case CSS_PROP__WEBKIT_TEXT_STROKE_WIDTH:
+ return new CSSPrimitiveValue(style->textStrokeWidth(), CSSPrimitiveValue::CSS_PX);
+ case CSS_PROP_TEXT_TRANSFORM:
+ return new CSSPrimitiveValue(style->textTransform());
+ case CSS_PROP_TOP:
+ return getPositionOffsetValue(style, CSS_PROP_TOP);
+ case CSS_PROP_UNICODE_BIDI:
+ return new CSSPrimitiveValue(style->unicodeBidi());
+ case CSS_PROP_VERTICAL_ALIGN:
+ switch (style->verticalAlign()) {
+ case BASELINE:
+ return new CSSPrimitiveValue(CSS_VAL_BASELINE);
+ case MIDDLE:
+ return new CSSPrimitiveValue(CSS_VAL_MIDDLE);
+ case SUB:
+ return new CSSPrimitiveValue(CSS_VAL_SUB);
+ case SUPER:
+ return new CSSPrimitiveValue(CSS_VAL_SUPER);
+ case TEXT_TOP:
+ return new CSSPrimitiveValue(CSS_VAL_TEXT_TOP);
+ case TEXT_BOTTOM:
+ return new CSSPrimitiveValue(CSS_VAL_TEXT_BOTTOM);
+ case TOP:
+ return new CSSPrimitiveValue(CSS_VAL_TOP);
+ case BOTTOM:
+ return new CSSPrimitiveValue(CSS_VAL_BOTTOM);
+ case BASELINE_MIDDLE:
+ return new CSSPrimitiveValue(CSS_VAL__WEBKIT_BASELINE_MIDDLE);
+ case LENGTH:
+ return new CSSPrimitiveValue(style->verticalAlignLength());
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+ case CSS_PROP_VISIBILITY:
+ return new CSSPrimitiveValue(style->visibility());
+ case CSS_PROP_WHITE_SPACE:
+ return new CSSPrimitiveValue(style->whiteSpace());
+ case CSS_PROP_WIDOWS:
+ return new CSSPrimitiveValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP_WIDTH:
+ if (renderer)
+ return new CSSPrimitiveValue(sizingBox(renderer).width(), CSSPrimitiveValue::CSS_PX);
+ return new CSSPrimitiveValue(style->width());
+ case CSS_PROP_WORD_BREAK:
+ return new CSSPrimitiveValue(style->wordBreak());
+ case CSS_PROP_WORD_SPACING:
+ return new CSSPrimitiveValue(style->wordSpacing(), CSSPrimitiveValue::CSS_PX);
+ case CSS_PROP_WORD_WRAP:
+ return new CSSPrimitiveValue(style->wordWrap());
+ case CSS_PROP__WEBKIT_LINE_BREAK:
+ return new CSSPrimitiveValue(style->khtmlLineBreak());
+ case CSS_PROP__WEBKIT_NBSP_MODE:
+ return new CSSPrimitiveValue(style->nbspMode());
+ case CSS_PROP__WEBKIT_MATCH_NEAREST_MAIL_BLOCKQUOTE_COLOR:
+ return new CSSPrimitiveValue(style->matchNearestMailBlockquoteColor());
+ case CSS_PROP_RESIZE:
+ return new CSSPrimitiveValue(style->resize());
+ case CSS_PROP_Z_INDEX:
+ if (style->hasAutoZIndex())
+ return new CSSPrimitiveValue(CSS_VAL_AUTO);
+ return new CSSPrimitiveValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP__WEBKIT_BOX_SIZING:
+ if (style->boxSizing() == CONTENT_BOX)
+ return new CSSPrimitiveValue(CSS_VAL_CONTENT_BOX);
+ return new CSSPrimitiveValue(CSS_VAL_BORDER_BOX);
+ case CSS_PROP__WEBKIT_DASHBOARD_REGION:
+ {
+ const Vector<StyleDashboardRegion>& regions = style->dashboardRegions();
+ unsigned count = regions.size();
+ if (count == 1 && regions[0].type == StyleDashboardRegion::None)
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+
+ RefPtr<DashboardRegion> firstRegion;
+ DashboardRegion* previousRegion = 0;
+ for (unsigned i = 0; i < count; i++) {
+ RefPtr<DashboardRegion> region = new DashboardRegion;
+ StyleDashboardRegion styleRegion = regions[i];
+
+ region->m_label = styleRegion.label;
+ LengthBox offset = styleRegion.offset;
+ region->setTop(new CSSPrimitiveValue(offset.top.value(), CSSPrimitiveValue::CSS_PX));
+ region->setRight(new CSSPrimitiveValue(offset.right.value(), CSSPrimitiveValue::CSS_PX));
+ region->setBottom(new CSSPrimitiveValue(offset.bottom.value(), CSSPrimitiveValue::CSS_PX));
+ region->setLeft(new CSSPrimitiveValue(offset.left.value(), CSSPrimitiveValue::CSS_PX));
+ region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle);
+ region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
+
+ if (previousRegion)
+ previousRegion->m_next = region;
+ else
+ firstRegion = region;
+ previousRegion = region.get();
+ }
+ return new CSSPrimitiveValue(firstRegion.release());
+ }
+ case CSS_PROP__WEBKIT_APPEARANCE:
+ return new CSSPrimitiveValue(style->appearance());
+ case CSS_PROP__WEBKIT_FONT_SIZE_DELTA:
+ // Not a real style property -- used by the editing engine -- so has no computed value.
+ break;
+ case CSS_PROP__WEBKIT_MARGIN_BOTTOM_COLLAPSE:
+ return new CSSPrimitiveValue(style->marginBottomCollapse());
+ case CSS_PROP__WEBKIT_MARGIN_TOP_COLLAPSE:
+ return new CSSPrimitiveValue(style->marginTopCollapse());
+ case CSS_PROP__WEBKIT_RTL_ORDERING:
+ if (style->visuallyOrdered())
+ return new CSSPrimitiveValue(CSS_VAL_VISUAL);
+ return new CSSPrimitiveValue(CSS_VAL_LOGICAL);
+ case CSS_PROP__WEBKIT_USER_DRAG:
+ return new CSSPrimitiveValue(style->userDrag());
+ case CSS_PROP__WEBKIT_USER_SELECT:
+ return new CSSPrimitiveValue(style->userSelect());
+ case CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS:
+ return getBorderRadiusCornerValue(style->borderBottomLeftRadius());
+ case CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS:
+ return getBorderRadiusCornerValue(style->borderBottomRightRadius());
+ case CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS:
+ return getBorderRadiusCornerValue(style->borderTopLeftRadius());
+ case CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS:
+ return getBorderRadiusCornerValue(style->borderTopRightRadius());
+ case CSS_PROP_BACKGROUND:
+ case CSS_PROP_BORDER:
+ case CSS_PROP_BORDER_BOTTOM:
+ case CSS_PROP_BORDER_COLOR:
+ case CSS_PROP_BORDER_LEFT:
+ case CSS_PROP_BORDER_RIGHT:
+ case CSS_PROP_BORDER_STYLE:
+ case CSS_PROP_BORDER_TOP:
+ case CSS_PROP_BORDER_WIDTH:
+ case CSS_PROP_CLIP:
+ case CSS_PROP_CONTENT:
+ case CSS_PROP_COUNTER_INCREMENT:
+ case CSS_PROP_COUNTER_RESET:
+ case CSS_PROP_FONT:
+ case CSS_PROP_FONT_STRETCH:
+ case CSS_PROP_LIST_STYLE:
+ case CSS_PROP_MARGIN:
+ case CSS_PROP_OUTLINE:
+ case CSS_PROP_OUTLINE_OFFSET:
+ case CSS_PROP_PADDING:
+ case CSS_PROP_PAGE:
+ case CSS_PROP_QUOTES:
+ case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
+ case CSS_PROP_SCROLLBAR_ARROW_COLOR:
+ case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
+ case CSS_PROP_SCROLLBAR_FACE_COLOR:
+ case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
+ case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
+ case CSS_PROP_SCROLLBAR_TRACK_COLOR:
+ case CSS_PROP_SRC: // Only used in @font-face rules.
+ case CSS_PROP_SIZE:
+ case CSS_PROP_TEXT_LINE_THROUGH:
+ case CSS_PROP_TEXT_LINE_THROUGH_COLOR:
+ case CSS_PROP_TEXT_LINE_THROUGH_MODE:
+ case CSS_PROP_TEXT_LINE_THROUGH_STYLE:
+ case CSS_PROP_TEXT_LINE_THROUGH_WIDTH:
+ case CSS_PROP_TEXT_OVERFLOW:
+ case CSS_PROP_TEXT_OVERLINE:
+ case CSS_PROP_TEXT_OVERLINE_COLOR:
+ case CSS_PROP_TEXT_OVERLINE_MODE:
+ case CSS_PROP_TEXT_OVERLINE_STYLE:
+ case CSS_PROP_TEXT_OVERLINE_WIDTH:
+ case CSS_PROP_TEXT_UNDERLINE:
+ case CSS_PROP_TEXT_UNDERLINE_COLOR:
+ case CSS_PROP_TEXT_UNDERLINE_MODE:
+ case CSS_PROP_TEXT_UNDERLINE_STYLE:
+ case CSS_PROP_TEXT_UNDERLINE_WIDTH:
+ case CSS_PROP_UNICODE_RANGE: // Only used in @font-face rules.
+ case CSS_PROP__WEBKIT_BORDER_IMAGE:
+ case CSS_PROP__WEBKIT_BORDER_RADIUS:
+ case CSS_PROP__WEBKIT_COLUMNS:
+ case CSS_PROP__WEBKIT_COLUMN_RULE:
+ case CSS_PROP__WEBKIT_MARGIN_COLLAPSE:
+ case CSS_PROP__WEBKIT_MARGIN_START:
+ case CSS_PROP__WEBKIT_MARQUEE:
+ case CSS_PROP__WEBKIT_MARQUEE_SPEED:
+ case CSS_PROP__WEBKIT_PADDING_START:
+ case CSS_PROP__WEBKIT_TEXT_STROKE:
+ case CSS_PROP__WEBKIT_TRANSFORM:
+ case CSS_PROP__WEBKIT_TRANSFORM_ORIGIN:
+ case CSS_PROP__WEBKIT_TRANSFORM_ORIGIN_X:
+ case CSS_PROP__WEBKIT_TRANSFORM_ORIGIN_Y:
+ case CSS_PROP__WEBKIT_TRANSITION:
+ case CSS_PROP__WEBKIT_TRANSITION_DURATION:
+ case CSS_PROP__WEBKIT_TRANSITION_PROPERTY:
+ case CSS_PROP__WEBKIT_TRANSITION_REPEAT_COUNT:
+ case CSS_PROP__WEBKIT_TRANSITION_TIMING_FUNCTION:
+ // FIXME: The above are unimplemented.
+ break;
+#if ENABLE(SVG)
+ default:
+ return getSVGPropertyCSSValue(propertyID, DoNotUpdateLayout);
+#endif
+ }
+
+ LOG_ERROR("unimplemented propertyID: %d", propertyID);
+ return 0;
+}
+
+String CSSComputedStyleDeclaration::getPropertyValue(int propertyID) const
+{
+ RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
+ if (value)
+ return value->cssText();
+ 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::length() const
+{
+ Node* node = m_node.get();
+ if (!node)
+ return 0;
+
+ RenderStyle* style = node->computedStyle();
+ if (!style)
+ return 0;
+
+ return numComputedProperties;
+}
+
+String CSSComputedStyleDeclaration::item(unsigned i) const
+{
+ if (i >= length())
+ return String();
+
+ return getPropertyName(static_cast<CSSPropertyID>(computedProperties[i]));
+}
+
+// This is the list of properties we want to copy in the copyInheritableProperties() function.
+// It is the intersection of the list of inherited CSS properties and the
+// properties for which we have a computed implementation in this file.
+const int inheritableProperties[] = {
+ CSS_PROP_BORDER_COLLAPSE,
+ CSS_PROP_COLOR,
+ CSS_PROP_FONT_FAMILY,
+ CSS_PROP_FONT_SIZE,
+ CSS_PROP_FONT_STYLE,
+ CSS_PROP_FONT_VARIANT,
+ CSS_PROP_FONT_WEIGHT,
+ CSS_PROP_LETTER_SPACING,
+ CSS_PROP_LINE_HEIGHT,
+ CSS_PROP_ORPHANS,
+ CSS_PROP_TEXT_ALIGN,
+ CSS_PROP_TEXT_INDENT,
+ CSS_PROP_TEXT_TRANSFORM,
+ CSS_PROP_WHITE_SPACE,
+ CSS_PROP_WIDOWS,
+ CSS_PROP_WORD_SPACING,
+ CSS_PROP__WEBKIT_BORDER_HORIZONTAL_SPACING,
+ CSS_PROP__WEBKIT_BORDER_VERTICAL_SPACING,
+ CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT,
+ CSS_PROP__WEBKIT_TEXT_FILL_COLOR,
+ CSS_PROP__WEBKIT_TEXT_SIZE_ADJUST,
+ CSS_PROP__WEBKIT_TEXT_STROKE_COLOR,
+ CSS_PROP__WEBKIT_TEXT_STROKE_WIDTH,
+};
+
+const unsigned numInheritableProperties = sizeof(inheritableProperties) / sizeof(inheritableProperties[0]);
+
+void CSSComputedStyleDeclaration::removeComputedInheritablePropertiesFrom(CSSMutableStyleDeclaration* declaration)
+{
+ declaration->removePropertiesInSet(inheritableProperties, numInheritableProperties);
+}
+
+PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::copyInheritableProperties() const
+{
+ RefPtr<CSSMutableStyleDeclaration> style = copyPropertiesInSet(inheritableProperties, numInheritableProperties);
+ if (style && m_node && m_node->computedStyle()) {
+ // If a node's text fill color is invalid, then its children use
+ // their font-color as their text fill color (they don't
+ // inherit it). Likewise for stroke color.
+ ExceptionCode ec = 0;
+ if (!m_node->computedStyle()->textFillColor().isValid())
+ style->removeProperty(CSS_PROP__WEBKIT_TEXT_FILL_COLOR, ec);
+ if (!m_node->computedStyle()->textStrokeColor().isValid())
+ style->removeProperty(CSS_PROP__WEBKIT_TEXT_STROKE_COLOR, ec);
+ ASSERT(ec == 0);
+ }
+ return style.release();
+}
+
+PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::copy() const
+{
+ return copyPropertiesInSet(computedProperties, numComputedProperties);
+}
+
+PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::makeMutable()
+{
+ return copy();
+}
+
+PassRefPtr<CSSComputedStyleDeclaration> computedStyle(Node* node)
+{
+ return new CSSComputedStyleDeclaration(node);
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSComputedStyleDeclaration.h b/WebCore/css/CSSComputedStyleDeclaration.h
new file mode 100644
index 0000000..b19455c
--- /dev/null
+++ b/WebCore/css/CSSComputedStyleDeclaration.h
@@ -0,0 +1,78 @@
+/**
+ *
+ * Copyright (C) 2004 Zack Rusin <zack@kde.org>
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef CSSComputedStyleDeclaration_h
+#define CSSComputedStyleDeclaration_h
+
+#include "CSSStyleDeclaration.h"
+#include "Node.h"
+
+namespace WebCore {
+
+class CSSMutableStyleDeclaration;
+class CSSProperty;
+class RenderObject;
+class RenderStyle;
+
+enum EUpdateLayout { DoNotUpdateLayout = false, UpdateLayout = true };
+
+class CSSComputedStyleDeclaration : public CSSStyleDeclaration {
+public:
+ CSSComputedStyleDeclaration(PassRefPtr<Node>);
+ virtual ~CSSComputedStyleDeclaration();
+
+ virtual String cssText() const;
+
+ virtual unsigned length() 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; }
+
+ virtual PassRefPtr<CSSMutableStyleDeclaration> copy() const;
+ virtual PassRefPtr<CSSMutableStyleDeclaration> makeMutable();
+
+ PassRefPtr<CSSValue> getPropertyCSSValue(int propertyID, EUpdateLayout) const;
+#if ENABLE(SVG)
+ PassRefPtr<CSSValue> getSVGPropertyCSSValue(int propertyID, EUpdateLayout) const;
+#endif
+
+ PassRefPtr<CSSMutableStyleDeclaration> copyInheritableProperties() const;
+
+ static void removeComputedInheritablePropertiesFrom(CSSMutableStyleDeclaration*);
+
+private:
+ virtual void setCssText(const String&, ExceptionCode&);
+
+ virtual String removeProperty(int propertyID, ExceptionCode&);
+ virtual void setProperty(int propertyId, const String& value, bool important, ExceptionCode&);
+
+ RefPtr<Node> m_node;
+};
+
+PassRefPtr<CSSComputedStyleDeclaration> computedStyle(Node*);
+
+} // namespace WebCore
+
+#endif // CSSComputedStyleDeclaration_h
diff --git a/WebCore/css/CSSCursorImageValue.cpp b/WebCore/css/CSSCursorImageValue.cpp
new file mode 100644
index 0000000..5c0752a
--- /dev/null
+++ b/WebCore/css/CSSCursorImageValue.cpp
@@ -0,0 +1,130 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * Copyright (C) 2006 Rob Buis <buis@kde.org>
+ * (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
+ *
+ * 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 "CSSCursorImageValue.h"
+
+#include "CachedImage.h"
+#include "DocLoader.h"
+#include "PlatformString.h"
+
+#if ENABLE(SVG)
+#include "SVGCursorElement.h"
+#include "SVGURIReference.h"
+#endif
+
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+#if ENABLE(SVG)
+inline bool isSVGCursorIdentifier(const String& url)
+{
+ KURL kurl(url);
+ return kurl.hasRef();
+}
+
+inline SVGCursorElement* resourceReferencedByCursorElement(const String& fragmentId, Document* document)
+{
+ Element* element = document->getElementById(SVGURIReference::getTarget(fragmentId));
+ if (element && element->hasTagName(SVGNames::cursorTag))
+ return static_cast<SVGCursorElement*>(element);
+
+ return 0;
+}
+#endif
+
+CSSCursorImageValue::CSSCursorImageValue(const String& url, const IntPoint& hotspot, StyleBase* style)
+ : CSSImageValue(url, style)
+ , m_hotspot(hotspot)
+{
+}
+
+CSSCursorImageValue::~CSSCursorImageValue()
+{
+#if ENABLE(SVG)
+ const String& url = getStringValue();
+ if (!isSVGCursorIdentifier(url))
+ return;
+
+ HashSet<SVGElement*>::const_iterator it = m_referencedElements.begin();
+ HashSet<SVGElement*>::const_iterator end = m_referencedElements.end();
+
+ for (; it != end; ++it) {
+ SVGElement* referencedElement = *it;
+ if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, referencedElement->document()))
+ cursorElement->removeClient(referencedElement);
+ }
+#endif
+}
+
+bool CSSCursorImageValue::updateIfSVGCursorIsUsed(Element* element)
+{
+#if ENABLE(SVG)
+ if (!element || !element->isSVGElement())
+ return false;
+
+ const String& url = getStringValue();
+ if (!isSVGCursorIdentifier(url))
+ return false;
+
+ if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, element->document())) {
+ int x = roundf(cursorElement->x().value());
+ if (x != m_hotspot.x())
+ m_hotspot.setX(x);
+
+ int y = roundf(cursorElement->y().value());
+ if (y != m_hotspot.y())
+ m_hotspot.setY(y);
+
+ if (m_image && m_image->url() != element->document()->completeURL(cursorElement->href())) {
+ m_image->deref(this);
+ m_image = 0;
+
+ m_accessedImage = false;
+ }
+
+ SVGElement* svgElement = static_cast<SVGElement*>(element);
+ m_referencedElements.add(svgElement);
+ cursorElement->addClient(svgElement);
+ return true;
+ }
+#endif
+
+ return false;
+}
+
+CachedImage* CSSCursorImageValue::image(DocLoader* loader)
+{
+ String url = getStringValue();
+
+#if ENABLE(SVG)
+ if (isSVGCursorIdentifier(url) && loader && loader->doc()) {
+ if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, loader->doc()))
+ url = cursorElement->href();
+ }
+#endif
+
+ return CSSImageValue::image(loader, url);
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSCursorImageValue.h b/WebCore/css/CSSCursorImageValue.h
new file mode 100644
index 0000000..69d4668
--- /dev/null
+++ b/WebCore/css/CSSCursorImageValue.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * Copyright (C) 2006 Rob Buis <buis@kde.org>
+ *
+ * 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 CSSCursorImageValue_h
+#define CSSCursorImageValue_h
+
+#include "CSSImageValue.h"
+#include "IntPoint.h"
+
+#include <wtf/HashSet.h>
+
+namespace WebCore {
+
+class Element;
+class SVGElement;
+
+class CSSCursorImageValue : public CSSImageValue {
+public:
+ CSSCursorImageValue(const String& url, const IntPoint& hotspot, StyleBase*);
+ virtual ~CSSCursorImageValue();
+
+ IntPoint hotspot() const { return m_hotspot; }
+
+ bool updateIfSVGCursorIsUsed(Element*);
+ virtual CachedImage* image(DocLoader*);
+
+private:
+ IntPoint m_hotspot;
+
+#if ENABLE(SVG)
+ HashSet<SVGElement*> m_referencedElements;
+#endif
+};
+
+} // namespace WebCore
+
+#endif // CSSCursorImageValue_h
diff --git a/WebCore/css/CSSFontFace.cpp b/WebCore/css/CSSFontFace.cpp
new file mode 100644
index 0000000..b98e1db
--- /dev/null
+++ b/WebCore/css/CSSFontFace.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2007, 2008 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 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.
+ */
+
+#include "config.h"
+#include "CSSFontFace.h"
+
+#include "CSSFontFaceSource.h"
+#include "CSSSegmentedFontFace.h"
+#include "FontDescription.h"
+#include "SimpleFontData.h"
+
+namespace WebCore {
+
+CSSFontFace::~CSSFontFace()
+{
+ deleteAllValues(m_sources);
+}
+
+bool CSSFontFace::isLoaded() const
+{
+ unsigned size = m_sources.size();
+ for (unsigned i = 0; i < size; i++) {
+ if (!m_sources[i]->isLoaded())
+ return false;
+ }
+ return true;
+}
+
+bool CSSFontFace::isValid() const
+{
+ unsigned size = m_sources.size();
+ if (!size)
+ return false;
+ for (unsigned i = 0; i < size; i++) {
+ if (m_sources[i]->isValid())
+ return true;
+ }
+ return false;
+}
+
+void CSSFontFace::addSource(CSSFontFaceSource* source)
+{
+ m_sources.append(source);
+ source->setFontFace(this);
+}
+
+void CSSFontFace::fontLoaded(CSSFontFaceSource*)
+{
+ m_segmentedFontFace->fontLoaded(this);
+}
+
+SimpleFontData* CSSFontFace::getFontData(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic)
+{
+ if (!isValid())
+ return 0;
+
+ // If we hit a local font, we know it is valid, and can just return it.
+ SimpleFontData* result = 0;
+ unsigned size = m_sources.size();
+ for (unsigned i = 0; i < size && !result; i++)
+ result = m_sources[i]->getFontData(fontDescription, syntheticBold, syntheticItalic, m_segmentedFontFace->fontSelector());
+ return result;
+}
+
+}
+
diff --git a/WebCore/css/CSSFontFace.h b/WebCore/css/CSSFontFace.h
new file mode 100644
index 0000000..8c26b9f
--- /dev/null
+++ b/WebCore/css/CSSFontFace.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007, 2008 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 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 CSSFontFace_h
+#define CSSFontFace_h
+
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class CSSFontFaceSource;
+class CSSSegmentedFontFace;
+class FontDescription;
+class SimpleFontData;
+
+class CSSFontFace : public RefCounted<CSSFontFace> {
+public:
+ CSSFontFace()
+ : RefCounted<CSSFontFace>(0)
+ , m_segmentedFontFace(0)
+ {
+ }
+
+ virtual ~CSSFontFace();
+
+ void setSegmentedFontFace(CSSSegmentedFontFace* segmentedFontFace) { m_segmentedFontFace = segmentedFontFace; }
+
+ bool isLoaded() const;
+ virtual bool isValid() const;
+
+ virtual void addSource(CSSFontFaceSource*);
+
+ void fontLoaded(CSSFontFaceSource*);
+
+ virtual SimpleFontData* getFontData(const FontDescription&, bool syntheticBold, bool syntheticItalic);
+
+private:
+ CSSSegmentedFontFace* m_segmentedFontFace;
+ Vector<CSSFontFaceSource*> m_sources;
+};
+
+}
+
+#endif
diff --git a/WebCore/css/CSSFontFaceRule.cpp b/WebCore/css/CSSFontFaceRule.cpp
new file mode 100644
index 0000000..b1ffc05
--- /dev/null
+++ b/WebCore/css/CSSFontFaceRule.cpp
@@ -0,0 +1,54 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 "CSSFontFaceRule.h"
+
+#include "CSSMutableStyleDeclaration.h"
+
+namespace WebCore {
+
+CSSFontFaceRule::CSSFontFaceRule(StyleBase* parent)
+ : CSSRule(parent)
+{
+}
+
+CSSFontFaceRule::~CSSFontFaceRule()
+{
+}
+
+void CSSFontFaceRule::setDeclaration(PassRefPtr<CSSMutableStyleDeclaration> style)
+{
+ m_style = style;
+}
+
+String CSSFontFaceRule::cssText() const
+{
+ String result("@font-face");
+ result += " { ";
+ result += m_style->cssText();
+ result += "}";
+ return result;
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSFontFaceRule.h b/WebCore/css/CSSFontFaceRule.h
new file mode 100644
index 0000000..bc551a6
--- /dev/null
+++ b/WebCore/css/CSSFontFaceRule.h
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2006 Apple Computer, Inc.
+ *
+ * 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 CSSFontFaceRule_h
+#define CSSFontFaceRule_h
+
+#include "CSSRule.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSMutableStyleDeclaration;
+
+class CSSFontFaceRule : public CSSRule {
+public:
+ CSSFontFaceRule(StyleBase* parent);
+ virtual ~CSSFontFaceRule();
+
+ virtual bool isFontFaceRule() { return true; }
+
+ CSSMutableStyleDeclaration* style() const { return m_style.get(); }
+
+ // Inherited from CSSRule
+ virtual unsigned short type() const { return FONT_FACE_RULE; }
+
+ virtual String cssText() const;
+
+ void setDeclaration(PassRefPtr<CSSMutableStyleDeclaration>);
+
+protected:
+ RefPtr<CSSMutableStyleDeclaration> m_style;
+};
+
+} // namespace WebCore
+
+#endif // CSSFontFaceRule_h
diff --git a/WebCore/css/CSSFontFaceRule.idl b/WebCore/css/CSSFontFaceRule.idl
new file mode 100644
index 0000000..514c7dd
--- /dev/null
+++ b/WebCore/css/CSSFontFaceRule.idl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [
+ GenerateConstructor,
+ InterfaceUUID=8afa4b1a-39fe-49fb-be6d-4d56e81d9b4a,
+ ImplementationUUID=5a7971d9-5aad-4ed7-be67-3a1644560256
+ ] CSSFontFaceRule : CSSRule {
+ readonly attribute CSSStyleDeclaration style;
+ };
+
+}
diff --git a/WebCore/css/CSSFontFaceSource.cpp b/WebCore/css/CSSFontFaceSource.cpp
new file mode 100644
index 0000000..7202787
--- /dev/null
+++ b/WebCore/css/CSSFontFaceSource.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2007, 2008 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 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.
+ */
+
+#include "config.h"
+#include "CSSFontFaceSource.h"
+
+#include "CachedFont.h"
+#include "CSSFontFace.h"
+#include "CSSFontSelector.h"
+#include "DocLoader.h"
+#include "FontCache.h"
+#include "FontDescription.h"
+#include "GlyphPageTreeNode.h"
+#include "SimpleFontData.h"
+
+#if ENABLE(SVG_FONTS)
+#include "FontCustomPlatformData.h"
+#include "HTMLNames.h"
+#include "SVGFontData.h"
+#include "SVGFontElement.h"
+#include "SVGURIReference.h"
+#endif
+
+namespace WebCore {
+
+CSSFontFaceSource::CSSFontFaceSource(const String& str, CachedFont* font)
+: m_string(str)
+, m_font(font)
+, m_face(0)
+{
+ if (m_font)
+ m_font->ref(this);
+}
+
+CSSFontFaceSource::~CSSFontFaceSource()
+{
+ if (m_font)
+ m_font->deref(this);
+ pruneTable();
+}
+
+void CSSFontFaceSource::pruneTable()
+{
+ if (m_fontDataTable.isEmpty())
+ return;
+ HashMap<int, SimpleFontData*>::iterator end = m_fontDataTable.end();
+ for (HashMap<int, SimpleFontData*>::iterator it = m_fontDataTable.begin(); it != end; ++it)
+ GlyphPageTreeNode::pruneTreeCustomFontData(it->second);
+ deleteAllValues(m_fontDataTable);
+ m_fontDataTable.clear();
+}
+
+bool CSSFontFaceSource::isLoaded() const
+{
+ if (m_font)
+ return m_font->isLoaded();
+ return true;
+}
+
+bool CSSFontFaceSource::isValid() const
+{
+ if (m_font)
+ return !m_font->errorOccurred();
+ return true;
+}
+
+void CSSFontFaceSource::fontLoaded(CachedFont*)
+{
+ pruneTable();
+ if (m_face)
+ m_face->fontLoaded(this);
+}
+
+SimpleFontData* CSSFontFaceSource::getFontData(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic, CSSFontSelector* fontSelector)
+{
+ // If the font hasn't loaded or an error occurred, then we've got nothing.
+ if (!isValid())
+ return 0;
+
+#if ENABLE(SVG_FONTS)
+ if (!m_font && !m_svgFontFaceElement) {
+#else
+ if (!m_font) {
+#endif
+ FontPlatformData* data = FontCache::getCachedFontPlatformData(fontDescription, m_string);
+ SimpleFontData* fontData = FontCache::getCachedFontData(data);
+
+ // We're local. Just return a SimpleFontData from the normal cache.
+ return fontData;
+ }
+
+ // See if we have a mapping in our FontData cache.
+ if (SimpleFontData* cachedData = m_fontDataTable.get(fontDescription.computedPixelSize()))
+ return cachedData;
+
+ OwnPtr<SimpleFontData> fontData;
+
+ // If we are still loading, then we let the system pick a font.
+ if (isLoaded()) {
+ if (m_font) {
+#if ENABLE(SVG_FONTS)
+ if (m_font->isSVGFont()) {
+ // For SVG fonts parse the external SVG document, and extract the <font> element.
+ if (!m_font->ensureSVGFontData())
+ return 0;
+
+ if (!m_externalSVGFontElement)
+ m_externalSVGFontElement = m_font->getSVGFontById(SVGURIReference::getTarget(m_string));
+
+ if (!m_externalSVGFontElement)
+ return 0;
+
+ SVGFontFaceElement* fontFaceElement = 0;
+
+ // Select first <font-face> child
+ for (Node* fontChild = m_externalSVGFontElement->firstChild(); fontChild; fontChild = fontChild->nextSibling()) {
+ if (fontChild->hasTagName(SVGNames::font_faceTag)) {
+ fontFaceElement = static_cast<SVGFontFaceElement*>(fontChild);
+ break;
+ }
+ }
+
+ if (fontFaceElement) {
+ if (!m_svgFontFaceElement) {
+ // We're created using a CSS @font-face rule, that means we're not associated with a SVGFontFaceElement.
+ // Use the imported <font-face> tag as referencing font-face element for these cases.
+ m_svgFontFaceElement = fontFaceElement;
+ }
+
+ SVGFontData* svgFontData = new SVGFontData(fontFaceElement);
+ fontData.set(new SimpleFontData(m_font->platformDataFromCustomData(fontDescription.computedPixelSize(), syntheticBold, syntheticItalic), true, false, svgFontData));
+ }
+ } else
+#endif
+ {
+ // Create new FontPlatformData from our CGFontRef, point size and ATSFontRef.
+ if (!m_font->ensureCustomFontData())
+ return 0;
+
+ fontData.set(new SimpleFontData(m_font->platformDataFromCustomData(fontDescription.computedPixelSize(), syntheticBold, syntheticItalic), true, false));
+ }
+ } else {
+#if ENABLE(SVG_FONTS)
+ // In-Document SVG Fonts
+ if (m_svgFontFaceElement) {
+ SVGFontData* svgFontData = new SVGFontData(m_svgFontFaceElement.get());
+ fontData.set(new SimpleFontData(FontPlatformData(fontDescription.computedPixelSize(), syntheticBold, syntheticItalic), true, false, svgFontData));
+ }
+#endif
+ }
+ } else {
+ // Kick off the load now.
+ m_font->beginLoadIfNeeded(fontSelector->docLoader());
+ FontPlatformData* tempData = FontCache::getCachedFontPlatformData(fontDescription, m_string);
+ if (!tempData)
+ tempData = FontCache::getLastResortFallbackFont(fontDescription);
+ fontData.set(new SimpleFontData(*tempData, true, true));
+ }
+
+ m_fontDataTable.set(fontDescription.computedPixelSize(), fontData.get());
+ return fontData.release();
+}
+
+}
+
diff --git a/WebCore/css/CSSFontFaceSource.h b/WebCore/css/CSSFontFaceSource.h
new file mode 100644
index 0000000..76d6288
--- /dev/null
+++ b/WebCore/css/CSSFontFaceSource.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2007 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 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 CSSFontFaceSource_h
+#define CSSFontFaceSource_h
+
+#include "AtomicString.h"
+#include "CachedResourceClient.h"
+#include <wtf/HashMap.h>
+
+#if ENABLE(SVG_FONTS)
+#include "SVGFontFaceElement.h"
+#endif
+
+namespace WebCore {
+
+class CachedFont;
+class CSSFontFace;
+class CSSFontSelector;
+class FontDescription;
+class SimpleFontData;
+
+class CSSFontFaceSource : public CachedResourceClient {
+public:
+ CSSFontFaceSource(const String&, CachedFont* = 0);
+ virtual ~CSSFontFaceSource();
+
+ bool isLoaded() const;
+ bool isValid() const;
+
+ const AtomicString& string() const { return m_string; }
+
+ void setFontFace(CSSFontFace* face) { m_face = face; }
+
+ virtual void fontLoaded(CachedFont*);
+
+ SimpleFontData* getFontData(const FontDescription&, bool syntheticBold, bool syntheticItalic, CSSFontSelector*);
+
+ void pruneTable();
+
+#if ENABLE(SVG_FONTS)
+ SVGFontFaceElement* svgFontFaceElement() const { return m_svgFontFaceElement.get(); }
+ void setSVGFontFaceElement(SVGFontFaceElement* element) { m_svgFontFaceElement = element; }
+#endif
+
+private:
+ AtomicString m_string; // URI for remote, built-in font name for local.
+ CachedFont* m_font; // For remote fonts, a pointer to our cached resource.
+ CSSFontFace* m_face; // Our owning font face.
+ HashMap<int, SimpleFontData*> m_fontDataTable; // A cache of FontDatas for various pixel sizes.
+
+#if ENABLE(SVG_FONTS)
+ RefPtr<SVGFontFaceElement> m_svgFontFaceElement;
+ RefPtr<SVGFontElement> m_externalSVGFontElement;
+#endif
+};
+
+}
+
+#endif
diff --git a/WebCore/css/CSSFontFaceSrcValue.cpp b/WebCore/css/CSSFontFaceSrcValue.cpp
new file mode 100644
index 0000000..3456532
--- /dev/null
+++ b/WebCore/css/CSSFontFaceSrcValue.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007 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 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.
+ */
+
+#include "config.h"
+#include "CSSFontFaceSrcValue.h"
+
+namespace WebCore {
+
+#if ENABLE(SVG_FONTS)
+bool CSSFontFaceSrcValue::isSVGFontFaceSrc() const
+{
+ return equalIgnoringCase(m_format, "svg");
+}
+#endif
+
+bool CSSFontFaceSrcValue::isSupportedFormat() const
+{
+ // Normally we would just check the format, but in order to avoid conflicts with the old WinIE style of font-face,
+ // we will also check to see if the URL ends with .eot. If so, we'll go ahead and assume that we shouldn't load it.
+ if (m_format.isEmpty()) {
+ // Check for .eot.
+ if (m_resource.endsWith("eot", false))
+ return false;
+ return true;
+ }
+
+ return equalIgnoringCase(m_format, "truetype") || equalIgnoringCase(m_format, "opentype")
+#if ENABLE(SVG_FONTS)
+ || isSVGFontFaceSrc()
+#endif
+ ;
+}
+
+String CSSFontFaceSrcValue::cssText() const
+{
+ String result;
+ if (isLocal())
+ result += "local(";
+ else
+ result += "url(";
+ result += m_resource;
+ result += ")";
+ if (!m_format.isEmpty())
+ result += " format(" + m_format + ")";
+ return result;
+}
+
+}
+
diff --git a/WebCore/css/CSSFontFaceSrcValue.h b/WebCore/css/CSSFontFaceSrcValue.h
new file mode 100644
index 0000000..328f505
--- /dev/null
+++ b/WebCore/css/CSSFontFaceSrcValue.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007 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 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 CSSFontFaceSrcValue_h
+#define CSSFontFaceSrcValue_h
+
+#include "CSSValue.h"
+#include "PlatformString.h"
+
+#if ENABLE(SVG_FONTS)
+#include "SVGFontFaceElement.h"
+#endif
+
+namespace WebCore {
+
+class CSSFontFaceSrcValue : public CSSValue {
+public:
+ CSSFontFaceSrcValue(const String& resource, bool local)
+ :m_resource(resource), m_isLocal(local)
+ {}
+ virtual ~CSSFontFaceSrcValue() {}
+
+ const String& resource() const { return m_resource; }
+ const String& format() const { return m_format; }
+ bool isLocal() const { return m_isLocal; }
+
+ void setFormat(const String& format) { m_format = format; }
+
+ bool isSupportedFormat() const;
+
+#if ENABLE(SVG_FONTS)
+ bool isSVGFontFaceSrc() const;
+
+ SVGFontFaceElement* svgFontFaceElement() const { return m_svgFontFaceElement.get(); }
+ void setSVGFontFaceElement(SVGFontFaceElement* element) { m_svgFontFaceElement = element; }
+#endif
+
+ virtual String cssText() const;
+
+private:
+ String m_resource;
+ String m_format;
+ bool m_isLocal;
+
+#if ENABLE(SVG_FONTS)
+ RefPtr<SVGFontFaceElement> m_svgFontFaceElement;
+#endif
+};
+
+}
+
+#endif
diff --git a/WebCore/css/CSSFontSelector.cpp b/WebCore/css/CSSFontSelector.cpp
new file mode 100644
index 0000000..14002dd
--- /dev/null
+++ b/WebCore/css/CSSFontSelector.cpp
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.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.
+ */
+
+#include "config.h"
+
+#include "CSSFontSelector.h"
+#include "AtomicString.h"
+#include "CachedFont.h"
+#include "CSSFontFace.h"
+#include "CSSFontFaceRule.h"
+#include "CSSFontFaceSource.h"
+#include "CSSFontFaceSrcValue.h"
+#include "CSSMutableStyleDeclaration.h"
+#include "CSSPrimitiveValue.h"
+#include "CSSPropertyNames.h"
+#include "CSSSegmentedFontFace.h"
+#include "CSSUnicodeRangeValue.h"
+#include "CSSValueKeywords.h"
+#include "CSSValueList.h"
+#include "DocLoader.h"
+#include "Document.h"
+#include "FontCache.h"
+#include "FontFamilyValue.h"
+#include "Frame.h"
+#include "NodeList.h"
+#include "RenderObject.h"
+#include "Settings.h"
+#include "SimpleFontData.h"
+
+#if ENABLE(SVG)
+#include "SVGFontFaceElement.h"
+#include "SVGNames.h"
+#endif
+
+namespace WebCore {
+
+CSSFontSelector::CSSFontSelector(Document* document)
+: m_document(document)
+{
+ ASSERT(m_document);
+}
+
+CSSFontSelector::~CSSFontSelector()
+{}
+
+bool CSSFontSelector::isEmpty() const
+{
+ return m_fonts.isEmpty();
+}
+
+DocLoader* CSSFontSelector::docLoader() const
+{
+ return m_document->docLoader();
+}
+
+static String hashForFont(const String& familyName, bool bold, bool italic)
+{
+ String familyHash(familyName);
+ if (bold)
+ familyHash += "-webkit-bold";
+ if (italic)
+ familyHash += "-webkit-italic";
+ return AtomicString(familyHash);
+}
+
+void CSSFontSelector::addFontFaceRule(const CSSFontFaceRule* fontFaceRule)
+{
+ // Obtain the font-family property and the src property. Both must be defined.
+ const CSSMutableStyleDeclaration* style = fontFaceRule->style();
+ RefPtr<CSSValue> fontFamily = style->getPropertyCSSValue(CSS_PROP_FONT_FAMILY);
+ RefPtr<CSSValue> src = style->getPropertyCSSValue(CSS_PROP_SRC);
+ RefPtr<CSSValue> unicodeRange = style->getPropertyCSSValue(CSS_PROP_UNICODE_RANGE);
+ if (!fontFamily || !src || !fontFamily->isValueList() || !src->isValueList() || unicodeRange && !unicodeRange->isValueList())
+ return;
+
+ CSSValueList* familyList = static_cast<CSSValueList*>(fontFamily.get());
+ if (!familyList->length())
+ return;
+
+ CSSValueList* srcList = static_cast<CSSValueList*>(src.get());
+ if (!srcList->length())
+ return;
+
+ CSSValueList* rangeList = static_cast<CSSValueList*>(unicodeRange.get());
+
+ // Create a FontDescription for this font and set up bold/italic info properly.
+ FontDescription fontDescription;
+
+ if (RefPtr<CSSValue> fontStyle = style->getPropertyCSSValue(CSS_PROP_FONT_STYLE))
+ fontDescription.setItalic(static_cast<CSSPrimitiveValue*>(fontStyle.get())->getIdent() != CSS_VAL_NORMAL);
+
+ if (RefPtr<CSSValue> fontWeight = style->getPropertyCSSValue(CSS_PROP_FONT_WEIGHT)) {
+ // FIXME: Need to support weights for real, since we're effectively limiting the number of supported weights to two.
+ // This behavior could also result in the "last kinda bold variant" described winning even if it isn't the best match for bold.
+ switch (static_cast<CSSPrimitiveValue*>(fontWeight.get())->getIdent()) {
+ case CSS_VAL_BOLD:
+ case CSS_VAL_BOLDER:
+ case CSS_VAL_600:
+ case CSS_VAL_700:
+ case CSS_VAL_800:
+ case CSS_VAL_900:
+ fontDescription.setWeight(cBoldWeight);
+ default:
+ break;
+ }
+ }
+
+ if (RefPtr<CSSValue> fontVariant = style->getPropertyCSSValue(CSS_PROP_FONT_VARIANT))
+ fontDescription.setSmallCaps(static_cast<CSSPrimitiveValue*>(fontVariant.get())->getIdent() == CSS_VAL_SMALL_CAPS);
+
+ // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace.
+ CSSFontFace* fontFace = 0;
+
+ int i;
+ int srcLength = srcList->length();
+
+ bool foundLocal = false;
+
+#if ENABLE(SVG_FONTS)
+ bool foundSVGFont = false;
+#endif
+
+ for (i = 0; i < srcLength; i++) {
+ // An item in the list either specifies a string (local font name) or a URL (remote font to download).
+ CSSFontFaceSrcValue* item = static_cast<CSSFontFaceSrcValue*>(srcList->item(i));
+ CSSFontFaceSource* source = 0;
+
+#if ENABLE(SVG_FONTS)
+ foundSVGFont = item->isSVGFontFaceSrc() || item->svgFontFaceElement();
+#endif
+
+ if (!item->isLocal()) {
+ if (item->isSupportedFormat()) {
+ CachedFont* cachedFont = m_document->docLoader()->requestFont(item->resource());
+ if (cachedFont) {
+#if ENABLE(SVG_FONTS)
+ if (foundSVGFont)
+ cachedFont->setSVGFont(true);
+#endif
+ source = new CSSFontFaceSource(item->resource(), cachedFont);
+ }
+ }
+ } else {
+ String family = item->resource();
+
+ // Test the validity of the local font now. We don't want to include this font if it does not exist
+ // on the system. If it *does* exist on the system, then we don't need to look any further.
+ if (FontCache::fontExists(fontDescription, family)
+#if ENABLE(SVG_FONTS)
+ || foundSVGFont
+#endif
+ ) {
+ source = new CSSFontFaceSource(family);
+ foundLocal = true;
+ }
+ }
+
+ if (!fontFace)
+ fontFace = new CSSFontFace();
+
+ if (source) {
+#if ENABLE(SVG_FONTS)
+ source->setSVGFontFaceElement(item->svgFontFaceElement());
+#endif
+ fontFace->addSource(source);
+ }
+
+ // We can just break if we see a local font that is valid.
+ if (foundLocal)
+ break;
+ }
+
+ ASSERT(fontFace);
+
+ if (fontFace && !fontFace->isValid()) {
+ delete fontFace;
+ return;
+ }
+
+ // Hash under every single family name.
+ int familyLength = familyList->length();
+ for (i = 0; i < familyLength; i++) {
+ CSSPrimitiveValue* item = static_cast<CSSPrimitiveValue*>(familyList->item(i));
+ String familyName;
+ if (item->primitiveType() == CSSPrimitiveValue::CSS_STRING)
+ familyName = static_cast<FontFamilyValue*>(item)->familyName();
+ else if (item->primitiveType() == CSSPrimitiveValue::CSS_IDENT) {
+ // 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;
+ switch (item->getIdent()) {
+ case CSS_VAL_SERIF:
+ familyName = "-webkit-serif";
+ break;
+ case CSS_VAL_SANS_SERIF:
+ familyName = "-webkit-sans-serif";
+ break;
+ case CSS_VAL_CURSIVE:
+ familyName = "-webkit-cursive";
+ break;
+ case CSS_VAL_FANTASY:
+ familyName = "-webkit-fantasy";
+ break;
+ case CSS_VAL_MONOSPACE:
+ familyName = "-webkit-monospace";
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (familyName.isEmpty())
+ continue;
+
+#if ENABLE(SVG_FONTS)
+ // SVG allows several <font> elements with the same font-family, differing only
+ // in ie. font-variant. Be sure to pick up the right one - in getFontData below.
+ if (foundSVGFont && fontDescription.smallCaps())
+ familyName += "-webkit-svg-small-caps";
+#endif
+
+ String hash = hashForFont(familyName.lower(), fontDescription.bold(), fontDescription.italic());
+ CSSSegmentedFontFace* segmentedFontFace = m_fonts.get(hash).get();
+ if (!segmentedFontFace) {
+ segmentedFontFace = new CSSSegmentedFontFace(this);
+ m_fonts.set(hash, segmentedFontFace);
+ }
+ if (rangeList) {
+ // A local font matching the font description should come first, so that it gets used for
+ // any character not overlaid by explicit @font-face rules for the family.
+ if (!segmentedFontFace->numRanges() && FontCache::fontExists(fontDescription, familyName)) {
+ CSSFontFace* implicitFontFace = new CSSFontFace();
+ implicitFontFace->addSource(new CSSFontFaceSource(familyName));
+ ASSERT(implicitFontFace->isValid());
+ segmentedFontFace->overlayRange(0, 0x7FFFFFFF, implicitFontFace);
+ }
+
+ unsigned numRanges = rangeList->length();
+ for (unsigned i = 0; i < numRanges; i++) {
+ CSSUnicodeRangeValue* range = static_cast<CSSUnicodeRangeValue*>(rangeList->item(i));
+ segmentedFontFace->overlayRange(range->from(), range->to(), fontFace);
+ }
+ } else
+ segmentedFontFace->overlayRange(0, 0x7FFFFFFF, fontFace);
+ }
+}
+
+void CSSFontSelector::fontLoaded(CSSSegmentedFontFace*)
+{
+ if (m_document->inPageCache())
+ return;
+ m_document->recalcStyle(Document::Force);
+ m_document->renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+}
+
+FontData* CSSFontSelector::getFontData(const FontDescription& fontDescription, const AtomicString& familyName)
+{
+ if (m_fonts.isEmpty() && !familyName.startsWith("-webkit-"))
+ return 0;
+
+ bool bold = fontDescription.bold();
+ bool italic = fontDescription.italic();
+
+ bool syntheticBold = false;
+ bool syntheticItalic = false;
+
+ String family = familyName.string().lower();
+
+#if ENABLE(SVG_FONTS)
+ RefPtr<CSSSegmentedFontFace> face;
+
+ if (fontDescription.smallCaps()) {
+ String testFamily = family + "-webkit-svg-small-caps";
+ face = m_fonts.get(hashForFont(testFamily, bold, italic));
+ } else
+ face = m_fonts.get(hashForFont(family, bold, italic));
+#else
+ RefPtr<CSSSegmentedFontFace> face = m_fonts.get(hashForFont(family, bold, italic));
+#endif
+
+ // If we don't find a face, and if bold/italic are set, we should try other variants.
+ // Bold/italic should try bold first, then italic, then normal (on the assumption that we are better at synthesizing italic than we are
+ // at synthesizing bold).
+ if (!face) {
+ if (bold && italic) {
+ syntheticItalic = true;
+ face = m_fonts.get(hashForFont(family, bold, false));
+ if (!face) {
+ syntheticBold = true;
+ face = m_fonts.get(hashForFont(family, false, italic));
+ }
+ }
+
+ // Bold should try normal.
+ // Italic should try normal.
+ if (!face && (bold || italic)) {
+ syntheticBold = bold;
+ syntheticItalic = italic;
+ face = m_fonts.get(hashForFont(family, false, false));
+ }
+ }
+
+#if ENABLE(SVG_FONTS)
+ // If no face was found, and if we're a SVG Font we may have hit following case:
+ // <font-face> specified font-weight and/or font-style to be ie. bold and italic.
+ // And the font-family requested is non-bold & non-italic. For SVG Fonts we still
+ // have to return the defined font, and not fallback to the system default.
+ if (!face && !bold)
+ face = m_fonts.get(hashForFont(family, true, italic));
+
+ if (!face && !italic)
+ face = m_fonts.get(hashForFont(family, bold, true));
+
+ if (!face && !bold && !italic)
+ face = m_fonts.get(hashForFont(family, true, true));
+#endif
+
+ // If no face was found, then return 0 and let the OS come up with its best match for the name.
+ if (!face) {
+ // If we were handed a generic family, but there was no match, go ahead and return the correct font based off our
+ // settings.
+ const Settings* settings = m_document->frame()->settings();
+ AtomicString genericFamily;
+ if (familyName == "-webkit-serif")
+ genericFamily = settings->serifFontFamily();
+ else if (familyName == "-webkit-sans-serif")
+ genericFamily = settings->sansSerifFontFamily();
+ else if (familyName == "-webkit-cursive")
+ genericFamily = settings->cursiveFontFamily();
+ else if (familyName == "-webkit-fantasy")
+ genericFamily = settings->fantasyFontFamily();
+ else if (familyName == "-webkit-monospace")
+ genericFamily = settings->fixedFontFamily();
+ else if (familyName == "-webkit-standard")
+ genericFamily = settings->standardFontFamily();
+
+ if (!genericFamily.isEmpty())
+ return FontCache::getCachedFontData(FontCache::getCachedFontPlatformData(fontDescription, genericFamily));
+ return 0;
+ }
+
+ // We have a face. Ask it for a font data. If it cannot produce one, it will fail, and the OS will take over.
+ return face->getFontData(fontDescription, syntheticBold, syntheticItalic);
+}
+
+}
diff --git a/WebCore/css/CSSFontSelector.h b/WebCore/css/CSSFontSelector.h
new file mode 100644
index 0000000..51de2f2
--- /dev/null
+++ b/WebCore/css/CSSFontSelector.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007 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 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 CSSFontSelector_h
+#define CSSFontSelector_h
+
+#include "FontSelector.h"
+
+#include "StringHash.h"
+#include <wtf/HashMap.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class AtomicString;
+class CSSFontFaceRule;
+class CSSSegmentedFontFace;
+class Document;
+class DocLoader;
+class FontDescription;
+class String;
+
+class CSSFontSelector : public FontSelector {
+public:
+ CSSFontSelector(Document* doc);
+ virtual ~CSSFontSelector();
+
+ virtual FontData* getFontData(const FontDescription& fontDescription, const AtomicString& familyName);
+
+ void addFontFaceRule(const CSSFontFaceRule*);
+
+ void fontLoaded(CSSSegmentedFontFace*);
+
+ bool isEmpty() const;
+
+ DocLoader* docLoader() const;
+
+protected:
+ Document* m_document; // No need to ref, since we will always get destroyed before the document does.
+ HashMap<String, RefPtr<CSSSegmentedFontFace> > m_fonts;
+};
+
+} // namespace WebCore
+
+#endif // CSSFontSelector_h
diff --git a/WebCore/css/CSSGrammar.y b/WebCore/css/CSSGrammar.y
new file mode 100644
index 0000000..c91ca32
--- /dev/null
+++ b/WebCore/css/CSSGrammar.y
@@ -0,0 +1,1164 @@
+%{
+
+/*
+ * Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+
+#include "CSSMediaRule.h"
+#include "CSSParser.h"
+#include "CSSRuleList.h"
+#include "CSSSelector.h"
+#include "CSSStyleSheet.h"
+#include "Document.h"
+#include "HTMLNames.h"
+#include "MediaList.h"
+#include <stdlib.h>
+#include <string.h>
+
+using namespace WebCore;
+using namespace HTMLNames;
+
+#define YYENABLE_NLS 0
+#define YYLTYPE_IS_TRIVIAL 1
+#define YYMAXDEPTH 10000
+#define YYDEBUG 0
+
+// FIXME: Replace with %parse-param { CSSParser* parser } once we can depend on bison 2.x
+#define YYPARSE_PARAM parser
+
+%}
+
+%pure_parser
+
+%union {
+ bool boolean;
+ char character;
+ int integer;
+ double number;
+ ParseString string;
+
+ CSSRule* rule;
+ CSSRuleList* ruleList;
+ CSSSelector* selector;
+ CSSSelector::Relation relation;
+ MediaList* mediaList;
+ MediaQuery* mediaQuery;
+ MediaQuery::Restrictor mediaQueryRestrictor;
+ MediaQueryExp* mediaQueryExp;
+ Value value;
+ ValueList* valueList;
+ Vector<MediaQueryExp*>* mediaQueryExpList;
+}
+
+%{
+
+static inline int cssyyerror(const char*) { return 1; }
+static int cssyylex(YYSTYPE* yylval) { return CSSParser::current()->lex(yylval); }
+
+%}
+
+%expect 41
+
+%left UNIMPORTANT_TOK
+
+%token WHITESPACE SGML_CD
+
+%token INCLUDES
+%token DASHMATCH
+%token BEGINSWITH
+%token ENDSWITH
+%token CONTAINS
+
+%token <string> STRING
+%right <string> IDENT
+%token <string> NTH
+
+%nonassoc <string> HEX
+%nonassoc <string> IDSEL
+%nonassoc ':'
+%nonassoc '.'
+%nonassoc '['
+%nonassoc <string> '*'
+%nonassoc error
+%left '|'
+
+%token IMPORT_SYM
+%token PAGE_SYM
+%token MEDIA_SYM
+%token FONT_FACE_SYM
+%token CHARSET_SYM
+%token NAMESPACE_SYM
+%token WEBKIT_RULE_SYM
+%token WEBKIT_DECLS_SYM
+%token WEBKIT_VALUE_SYM
+%token WEBKIT_MEDIAQUERY_SYM
+
+%token IMPORTANT_SYM
+%token MEDIA_ONLY
+%token MEDIA_NOT
+%token MEDIA_AND
+
+%token <number> QEMS
+%token <number> EMS
+%token <number> EXS
+%token <number> PXS
+%token <number> CMS
+%token <number> MMS
+%token <number> INS
+%token <number> PTS
+%token <number> PCS
+%token <number> DEGS
+%token <number> RADS
+%token <number> GRADS
+%token <number> MSECS
+%token <number> SECS
+%token <number> HERZ
+%token <number> KHERZ
+%token <string> DIMEN
+%token <number> PERCENTAGE
+%token <number> FLOATTOKEN
+%token <number> INTEGER
+
+%token <string> URI
+%token <string> FUNCTION
+%token <string> NOTFUNCTION
+
+%token <string> UNICODERANGE
+
+%type <relation> combinator
+
+%type <rule> charset
+%type <rule> ruleset
+%type <rule> ruleset_or_import
+%type <rule> media
+%type <rule> import
+%type <rule> page
+%type <rule> font_face
+%type <rule> invalid_rule
+%type <rule> invalid_at
+%type <rule> invalid_import
+%type <rule> rule
+
+%type <string> maybe_ns_prefix
+
+%type <string> namespace_selector
+
+%type <string> string_or_uri
+%type <string> ident_or_string
+%type <string> medium
+%type <string> hexcolor
+
+%type <string> media_feature
+%type <mediaList> media_list
+%type <mediaList> maybe_media_list
+%type <mediaQuery> media_query
+%type <mediaQueryRestrictor> maybe_media_restrictor
+%type <valueList> maybe_media_value
+%type <mediaQueryExp> media_query_exp
+%type <mediaQueryExpList> media_query_exp_list
+%type <mediaQueryExpList> maybe_media_query_exp_list
+
+%type <ruleList> ruleset_list
+
+%type <integer> property
+
+%type <selector> specifier
+%type <selector> specifier_list
+%type <selector> simple_selector
+%type <selector> selector
+%type <selector> selector_list
+%type <selector> selector_with_trailing_whitespace
+%type <selector> class
+%type <selector> attrib
+%type <selector> pseudo
+
+%type <boolean> declaration_list
+%type <boolean> decl_list
+%type <boolean> declaration
+
+%type <boolean> prio
+
+%type <integer> match
+%type <integer> unary_operator
+%type <character> operator
+
+%type <valueList> expr
+%type <value> term
+%type <value> unary_term
+%type <value> function
+
+%type <string> element_name
+%type <string> attr_name
+
+%%
+
+stylesheet:
+ maybe_charset maybe_sgml import_list namespace_list rule_list
+ | webkit_rule maybe_space
+ | webkit_decls maybe_space
+ | webkit_value maybe_space
+ | webkit_mediaquery maybe_space
+ ;
+
+ruleset_or_import:
+ ruleset |
+ import
+;
+
+webkit_rule:
+ WEBKIT_RULE_SYM '{' maybe_space ruleset_or_import maybe_space '}' {
+ static_cast<CSSParser*>(parser)->rule = $4;
+ }
+;
+
+webkit_decls:
+ WEBKIT_DECLS_SYM '{' maybe_space declaration_list '}' {
+ /* can be empty */
+ }
+;
+
+webkit_value:
+ WEBKIT_VALUE_SYM '{' maybe_space expr '}' {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if ($4) {
+ p->valueList = p->sinkFloatingValueList($4);
+ int oldParsedProperties = p->numParsedProperties;
+ if (!p->parseValue(p->id, p->important))
+ p->rollbackLastProperties(p->numParsedProperties - oldParsedProperties);
+ delete p->valueList;
+ p->valueList = 0;
+ }
+ }
+;
+
+webkit_mediaquery:
+ WEBKIT_MEDIAQUERY_SYM WHITESPACE maybe_space media_query '}' {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ p->mediaQuery = p->sinkFloatingMediaQuery($4);
+ }
+;
+
+maybe_space:
+ /* empty */ %prec UNIMPORTANT_TOK
+ | maybe_space WHITESPACE
+ ;
+
+maybe_sgml:
+ /* empty */
+ | maybe_sgml SGML_CD
+ | maybe_sgml WHITESPACE
+ ;
+
+maybe_charset:
+ /* empty */
+ | charset {
+ }
+;
+
+charset:
+ CHARSET_SYM maybe_space STRING maybe_space ';' {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = static_cast<CSSParser*>(parser)->createCharsetRule($3);
+ if ($$ && p->styleElement && p->styleElement->isCSSStyleSheet())
+ p->styleElement->append($$);
+ }
+ | CHARSET_SYM error invalid_block {
+ }
+ | CHARSET_SYM error ';' {
+ }
+;
+
+import_list:
+ /* empty */
+ | import_list import maybe_sgml {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if ($2 && p->styleElement && p->styleElement->isCSSStyleSheet())
+ p->styleElement->append($2);
+ }
+ ;
+
+namespace_list:
+/* empty */
+| namespace_list namespace maybe_sgml
+;
+
+rule_list:
+ /* empty */
+ | rule_list rule maybe_sgml {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if ($2 && p->styleElement && p->styleElement->isCSSStyleSheet())
+ p->styleElement->append($2);
+ }
+ ;
+
+rule:
+ ruleset
+ | media
+ | page
+ | font_face
+ | invalid_rule
+ | invalid_at
+ | invalid_import
+ ;
+
+import:
+ IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list ';' {
+ $$ = static_cast<CSSParser*>(parser)->createImportRule($3, $5);
+ }
+ | IMPORT_SYM error invalid_block {
+ $$ = 0;
+ }
+ | IMPORT_SYM error ';' {
+ $$ = 0;
+ }
+ ;
+
+namespace:
+NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if (p->styleElement && p->styleElement->isCSSStyleSheet())
+ static_cast<CSSStyleSheet*>(p->styleElement)->addNamespace(p, $3, $4);
+}
+| NAMESPACE_SYM error invalid_block
+| NAMESPACE_SYM error ';'
+;
+
+maybe_ns_prefix:
+/* empty */ { $$.characters = 0; }
+| IDENT WHITESPACE { $$ = $1; }
+;
+
+string_or_uri:
+STRING
+| URI
+;
+
+media_feature:
+ IDENT maybe_space {
+ $$ = $1;
+ }
+ ;
+
+maybe_media_value:
+ /*empty*/ {
+ $$ = 0;
+ }
+ | ':' maybe_space expr maybe_space {
+ $$ = $3;
+ }
+ ;
+
+media_query_exp:
+ MEDIA_AND maybe_space '(' maybe_space media_feature maybe_space maybe_media_value ')' maybe_space {
+ $5.lower();
+ $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExp($5, $7);
+ }
+ ;
+
+media_query_exp_list:
+ media_query_exp {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingMediaQueryExpList();
+ $$->append(p->sinkFloatingMediaQueryExp($1));
+ }
+ | media_query_exp_list media_query_exp {
+ $$ = $1;
+ $$->append(static_cast<CSSParser*>(parser)->sinkFloatingMediaQueryExp($2));
+ }
+ ;
+
+maybe_media_query_exp_list:
+ /*empty*/ {
+ $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExpList();
+ }
+ | media_query_exp_list
+ ;
+
+maybe_media_restrictor:
+ /*empty*/ {
+ $$ = MediaQuery::None;
+ }
+ | MEDIA_ONLY {
+ $$ = MediaQuery::Only;
+ }
+ | MEDIA_NOT {
+ $$ = MediaQuery::Not;
+ }
+ ;
+
+media_query:
+ maybe_media_restrictor maybe_space medium maybe_media_query_exp_list {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $3.lower();
+ $$ = p->createFloatingMediaQuery($1, $3, p->sinkFloatingMediaQueryExpList($4));
+ }
+ ;
+
+maybe_media_list:
+ /* empty */ {
+ $$ = static_cast<CSSParser*>(parser)->createMediaList();
+ }
+ | media_list
+ ;
+
+media_list:
+ media_query {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createMediaList();
+ $$->appendMediaQuery(p->sinkFloatingMediaQuery($1));
+ }
+ | media_list ',' maybe_space media_query {
+ $$ = $1;
+ if ($$)
+ $$->appendMediaQuery(static_cast<CSSParser*>(parser)->sinkFloatingMediaQuery($4));
+ }
+ | media_list error {
+ $$ = 0;
+ }
+ ;
+
+media:
+ MEDIA_SYM maybe_space media_list '{' maybe_space ruleset_list '}' {
+ $$ = static_cast<CSSParser*>(parser)->createMediaRule($3, $6);
+ }
+ | MEDIA_SYM maybe_space '{' maybe_space ruleset_list '}' {
+ $$ = static_cast<CSSParser*>(parser)->createMediaRule(0, $5);
+ }
+ ;
+
+ruleset_list:
+ /* empty */ { $$ = 0; }
+ | ruleset_list ruleset maybe_space {
+ $$ = $1;
+ if ($2) {
+ if (!$$)
+ $$ = static_cast<CSSParser*>(parser)->createRuleList();
+ $$->append($2);
+ }
+ }
+ ;
+
+medium:
+ IDENT maybe_space {
+ $$ = $1;
+ }
+ ;
+
+/*
+page:
+ PAGE_SYM maybe_space IDENT? pseudo_page? maybe_space
+ '{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space
+ ;
+
+pseudo_page
+ : ':' IDENT
+ ;
+*/
+
+page:
+ PAGE_SYM error invalid_block {
+ $$ = 0;
+ }
+ | PAGE_SYM error ';' {
+ $$ = 0;
+ }
+ ;
+
+font_face:
+ FONT_FACE_SYM maybe_space
+ '{' maybe_space declaration_list '}' maybe_space {
+ $$ = static_cast<CSSParser*>(parser)->createFontFaceRule();
+ }
+ | FONT_FACE_SYM error invalid_block {
+ $$ = 0;
+ }
+ | FONT_FACE_SYM error ';' {
+ $$ = 0;
+ }
+;
+
+combinator:
+ '+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
+ | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
+ | '>' maybe_space { $$ = CSSSelector::Child; }
+ ;
+
+unary_operator:
+ '-' { $$ = -1; }
+ | '+' { $$ = 1; }
+ ;
+
+ruleset:
+ selector_list '{' maybe_space declaration_list '}' {
+ $$ = static_cast<CSSParser*>(parser)->createStyleRule($1);
+ }
+ ;
+
+selector_list:
+ selector %prec UNIMPORTANT_TOK {
+ $$ = $1;
+ }
+ | selector_list ',' maybe_space selector %prec UNIMPORTANT_TOK {
+ if ($1 && $4) {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = $1;
+ $$->append(p->sinkFloatingSelector($4));
+ } else
+ $$ = 0;
+ }
+ | selector_list error {
+ $$ = 0;
+ }
+ ;
+
+selector_with_trailing_whitespace:
+ selector WHITESPACE {
+ $$ = $1;
+ }
+ ;
+
+selector:
+ simple_selector {
+ $$ = $1;
+ }
+ | selector_with_trailing_whitespace
+ {
+ $$ = $1;
+ }
+ | selector_with_trailing_whitespace simple_selector
+ {
+ $$ = $2;
+ if (!$1)
+ $$ = 0;
+ else if ($$) {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ CSSSelector* end = $$;
+ while (end->m_tagHistory)
+ end = end->m_tagHistory;
+ end->m_relation = CSSSelector::Descendant;
+ end->m_tagHistory = p->sinkFloatingSelector($1);
+ if (Document* doc = p->document())
+ doc->setUsesDescendantRules(true);
+ }
+ }
+ | selector combinator simple_selector {
+ $$ = $3;
+ if (!$1)
+ $$ = 0;
+ else if ($$) {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ CSSSelector* end = $$;
+ while (end->m_tagHistory)
+ end = end->m_tagHistory;
+ end->m_relation = $2;
+ end->m_tagHistory = p->sinkFloatingSelector($1);
+ if ($2 == CSSSelector::Child) {
+ if (Document* doc = p->document())
+ doc->setUsesDescendantRules(true);
+ } else if ($2 == CSSSelector::DirectAdjacent || $2 == CSSSelector::IndirectAdjacent) {
+ if (Document* doc = p->document())
+ doc->setUsesSiblingRules(true);
+ }
+ }
+ }
+ | selector error {
+ $$ = 0;
+ }
+ ;
+
+namespace_selector:
+ /* empty */ '|' { $$.characters = 0; $$.length = 0; }
+ | '*' '|' { static UChar star = '*'; $$.characters = &star; $$.length = 1; }
+ | IDENT '|' { $$ = $1; }
+;
+
+simple_selector:
+ element_name {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_tag = QualifiedName(nullAtom, $1, p->defaultNamespace);
+ }
+ | element_name specifier_list {
+ $$ = $2;
+ if ($$) {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$->m_tag = QualifiedName(nullAtom, $1, p->defaultNamespace);
+ }
+ }
+ | specifier_list {
+ $$ = $1;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if ($$ && p->defaultNamespace != starAtom)
+ $$->m_tag = QualifiedName(nullAtom, starAtom, p->defaultNamespace);
+ }
+ | namespace_selector element_name {
+ AtomicString namespacePrefix = $1;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ if (p->styleElement && p->styleElement->isCSSStyleSheet()) {
+ $$->m_tag = QualifiedName(namespacePrefix, $2,
+ static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
+ } else // FIXME: Shouldn't this case be an error?
+ $$->m_tag = QualifiedName(nullAtom, $2, p->defaultNamespace);
+ }
+ | namespace_selector element_name specifier_list {
+ $$ = $3;
+ if ($$) {
+ AtomicString namespacePrefix = $1;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if (p->styleElement && p->styleElement->isCSSStyleSheet()) {
+ $$->m_tag = QualifiedName(namespacePrefix, $2,
+ static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
+ } else // FIXME: Shouldn't this case be an error?
+ $$->m_tag = QualifiedName(nullAtom, $2, p->defaultNamespace);
+ }
+ }
+ | namespace_selector specifier_list {
+ $$ = $2;
+ if ($$) {
+ AtomicString namespacePrefix = $1;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if (p->styleElement && p->styleElement->isCSSStyleSheet())
+ $$->m_tag = QualifiedName(namespacePrefix,
+ starAtom,
+ static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
+ }
+ }
+ ;
+
+element_name:
+ IDENT {
+ ParseString& str = $1;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ Document* doc = p->document();
+ if (doc && doc->isHTMLDocument())
+ str.lower();
+ $$ = str;
+ }
+ | '*' {
+ static UChar star = '*';
+ $$.characters = &star;
+ $$.length = 1;
+ }
+ ;
+
+specifier_list:
+ specifier {
+ $$ = $1;
+ }
+ | specifier_list specifier {
+ if (!$2)
+ $$ = 0;
+ else if ($1) {
+ $$ = $1;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ CSSSelector* end = $1;
+ while (end->m_tagHistory)
+ end = end->m_tagHistory;
+ end->m_relation = CSSSelector::SubSelector;
+ end->m_tagHistory = p->sinkFloatingSelector($2);
+ }
+ }
+ | specifier_list error {
+ $$ = 0;
+ }
+;
+
+specifier:
+ IDSEL {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_match = CSSSelector::Id;
+ if (!p->strict)
+ $1.lower();
+ $$->m_attr = idAttr;
+ $$->m_value = $1;
+ }
+ | HEX {
+ if ($1.characters[0] >= '0' && $1.characters[0] <= '9') {
+ $$ = 0;
+ } else {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_match = CSSSelector::Id;
+ if (!p->strict)
+ $1.lower();
+ $$->m_attr = idAttr;
+ $$->m_value = $1;
+ }
+ }
+ | class
+ | attrib
+ | pseudo
+ ;
+
+class:
+ '.' IDENT {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_match = CSSSelector::Class;
+ if (!p->strict)
+ $2.lower();
+ $$->m_attr = classAttr;
+ $$->m_value = $2;
+ }
+ ;
+
+attr_name:
+ IDENT maybe_space {
+ ParseString& str = $1;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ Document* doc = p->document();
+ if (doc && doc->isHTMLDocument())
+ str.lower();
+ $$ = str;
+ }
+ ;
+
+attrib:
+ '[' maybe_space attr_name ']' {
+ $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
+ $$->m_attr = QualifiedName(nullAtom, $3, nullAtom);
+ $$->m_match = CSSSelector::Set;
+ }
+ | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space ']' {
+ $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
+ $$->m_attr = QualifiedName(nullAtom, $3, nullAtom);
+ $$->m_match = (CSSSelector::Match)$4;
+ $$->m_value = $6;
+ }
+ | '[' maybe_space namespace_selector attr_name ']' {
+ AtomicString namespacePrefix = $3;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_attr = QualifiedName(namespacePrefix, $4,
+ static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
+ $$->m_match = CSSSelector::Set;
+ }
+ | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space ']' {
+ AtomicString namespacePrefix = $3;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_attr = QualifiedName(namespacePrefix, $4,
+ static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
+ $$->m_match = (CSSSelector::Match)$5;
+ $$->m_value = $7;
+ }
+ ;
+
+match:
+ '=' {
+ $$ = CSSSelector::Exact;
+ }
+ | INCLUDES {
+ $$ = CSSSelector::List;
+ }
+ | DASHMATCH {
+ $$ = CSSSelector::Hyphen;
+ }
+ | BEGINSWITH {
+ $$ = CSSSelector::Begin;
+ }
+ | ENDSWITH {
+ $$ = CSSSelector::End;
+ }
+ | CONTAINS {
+ $$ = CSSSelector::Contain;
+ }
+ ;
+
+ident_or_string:
+ IDENT
+ | STRING
+ ;
+
+pseudo:
+ ':' IDENT {
+ $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
+ $$->m_match = CSSSelector::PseudoClass;
+ $2.lower();
+ $$->m_value = $2;
+ CSSSelector::PseudoType type = $$->pseudoType();
+ if (type == CSSSelector::PseudoUnknown)
+ $$ = 0;
+ else if (type == CSSSelector::PseudoEmpty ||
+ type == CSSSelector::PseudoFirstChild ||
+ type == CSSSelector::PseudoFirstOfType ||
+ type == CSSSelector::PseudoLastChild ||
+ type == CSSSelector::PseudoLastOfType ||
+ type == CSSSelector::PseudoOnlyChild ||
+ type == CSSSelector::PseudoOnlyOfType) {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ Document* doc = p->document();
+ if (doc)
+ doc->setUsesSiblingRules(true);
+ } else if (type == CSSSelector::PseudoFirstLine) {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if (Document* doc = p->document())
+ doc->setUsesFirstLineRules(true);
+ }
+ }
+ | ':' ':' IDENT {
+ $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
+ $$->m_match = CSSSelector::PseudoElement;
+ $3.lower();
+ $$->m_value = $3;
+ CSSSelector::PseudoType type = $$->pseudoType();
+ if (type == CSSSelector::PseudoUnknown)
+ $$ = 0;
+ else if (type == CSSSelector::PseudoFirstLine) {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if (Document* doc = p->document())
+ doc->setUsesFirstLineRules(true);
+ }
+ }
+ // used by :nth-*(ax+b)
+ | ':' FUNCTION NTH ')' {
+ CSSParser *p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_match = CSSSelector::PseudoClass;
+ $$->m_argument = $3;
+ $$->m_value = $2;
+ CSSSelector::PseudoType type = $$->pseudoType();
+ if (type == CSSSelector::PseudoUnknown)
+ $$ = 0;
+ else if (type == CSSSelector::PseudoNthChild ||
+ type == CSSSelector::PseudoNthOfType ||
+ type == CSSSelector::PseudoNthLastChild ||
+ type == CSSSelector::PseudoNthLastOfType) {
+ if (p->document())
+ p->document()->setUsesSiblingRules(true);
+ }
+ }
+ // used by :nth-*
+ | ':' FUNCTION INTEGER ')' {
+ CSSParser *p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_match = CSSSelector::PseudoClass;
+ $$->m_argument = String::number($3);
+ $$->m_value = $2;
+ CSSSelector::PseudoType type = $$->pseudoType();
+ if (type == CSSSelector::PseudoUnknown)
+ $$ = 0;
+ else if (type == CSSSelector::PseudoNthChild ||
+ type == CSSSelector::PseudoNthOfType ||
+ type == CSSSelector::PseudoNthLastChild ||
+ type == CSSSelector::PseudoNthLastOfType) {
+ if (p->document())
+ p->document()->setUsesSiblingRules(true);
+ }
+ }
+ // used by :nth-*(odd/even) and :lang
+ | ':' FUNCTION IDENT ')' {
+ CSSParser *p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_match = CSSSelector::PseudoClass;
+ $$->m_argument = $3;
+ $2.lower();
+ $$->m_value = $2;
+ CSSSelector::PseudoType type = $$->pseudoType();
+ if (type == CSSSelector::PseudoUnknown)
+ $$ = 0;
+ else if (type == CSSSelector::PseudoNthChild ||
+ type == CSSSelector::PseudoNthOfType ||
+ type == CSSSelector::PseudoNthLastChild ||
+ type == CSSSelector::PseudoNthLastOfType) {
+ if (p->document())
+ p->document()->setUsesSiblingRules(true);
+ }
+ }
+ // used by :not
+ | ':' NOTFUNCTION maybe_space simple_selector maybe_space ')' {
+ if (!$4)
+ $$ = 0;
+ else {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingSelector();
+ $$->m_match = CSSSelector::PseudoClass;
+ $$->m_simpleSelector = p->sinkFloatingSelector($4);
+ $2.lower();
+ $$->m_value = $2;
+ }
+ }
+ ;
+
+declaration_list:
+ declaration {
+ $$ = $1;
+ }
+ | decl_list declaration {
+ $$ = $1;
+ if ( $2 )
+ $$ = $2;
+ }
+ | decl_list {
+ $$ = $1;
+ }
+ | error invalid_block_list error {
+ $$ = false;
+ }
+ | error {
+ $$ = false;
+ }
+ | decl_list error {
+ $$ = $1;
+ }
+ ;
+
+decl_list:
+ declaration ';' maybe_space {
+ $$ = $1;
+ }
+ | declaration invalid_block_list ';' maybe_space {
+ $$ = false;
+ }
+ | error ';' maybe_space {
+ $$ = false;
+ }
+ | error invalid_block_list error ';' maybe_space {
+ $$ = false;
+ }
+ | decl_list declaration ';' maybe_space {
+ $$ = $1;
+ if ($2)
+ $$ = $2;
+ }
+ | decl_list error ';' maybe_space {
+ $$ = $1;
+ }
+ | decl_list error invalid_block_list error ';' maybe_space {
+ $$ = $1;
+ }
+ ;
+
+declaration:
+ property ':' maybe_space expr prio {
+ $$ = false;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ if ($1 && $4) {
+ p->valueList = p->sinkFloatingValueList($4);
+ int oldParsedProperties = p->numParsedProperties;
+ $$ = p->parseValue($1, $5);
+ if (!$$)
+ p->rollbackLastProperties(p->numParsedProperties - oldParsedProperties);
+ delete p->valueList;
+ p->valueList = 0;
+ }
+ }
+ |
+ property error {
+ $$ = false;
+ }
+ |
+ property ':' maybe_space error expr prio {
+ /* The default movable type template has letter-spacing: .none; Handle this by looking for
+ error tokens at the start of an expr, recover the expr and then treat as an error, cleaning
+ up and deleting the shifted expr. */
+ $$ = false;
+ }
+ |
+ IMPORTANT_SYM maybe_space {
+ /* Handle this case: div { text-align: center; !important } Just reduce away the stray !important. */
+ $$ = false;
+ }
+ |
+ property ':' maybe_space {
+ /* div { font-family: } Just reduce away this property with no value. */
+ $$ = false;
+ }
+ |
+ property ':' maybe_space error {
+ /* if we come across rules with invalid values like this case: p { weight: *; }, just discard the rule */
+ $$ = false;
+ }
+ ;
+
+property:
+ IDENT maybe_space {
+ $$ = cssPropertyID($1);
+ }
+ ;
+
+prio:
+ IMPORTANT_SYM maybe_space { $$ = true; }
+ | /* empty */ { $$ = false; }
+ ;
+
+expr:
+ term {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = p->createFloatingValueList();
+ $$->addValue(p->sinkFloatingValue($1));
+ }
+ | expr operator term {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ $$ = $1;
+ if ($$) {
+ if ($2) {
+ Value v;
+ v.id = 0;
+ v.unit = Value::Operator;
+ v.iValue = $2;
+ $$->addValue(v);
+ }
+ $$->addValue(p->sinkFloatingValue($3));
+ }
+ }
+ | expr error {
+ $$ = 0;
+ }
+ ;
+
+operator:
+ '/' maybe_space {
+ $$ = '/';
+ }
+ | ',' maybe_space {
+ $$ = ',';
+ }
+ | /* empty */ {
+ $$ = 0;
+ }
+ ;
+
+term:
+ unary_term { $$ = $1; }
+ | unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
+ | STRING maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
+ | IDENT maybe_space {
+ $$.id = cssValueKeywordID($1);
+ $$.unit = CSSPrimitiveValue::CSS_IDENT;
+ $$.string = $1;
+ }
+ /* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */
+ | DIMEN maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION }
+ | unary_operator DIMEN maybe_space { $$.id = 0; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION }
+ | URI maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; }
+ | UNICODERANGE maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE }
+ | hexcolor { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR; }
+ | '#' maybe_space { $$.id = 0; $$.string = ParseString(); $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR; } /* Handle error case: "color: #;" */
+ /* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
+ | function {
+ $$ = $1;
+ }
+ | '%' maybe_space {} /* Handle width: %; */
+ ;
+
+unary_term:
+ INTEGER maybe_space { $$.id = 0; $$.isInt = true; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
+ | FLOATTOKEN maybe_space { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
+ | PERCENTAGE maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PERCENTAGE; }
+ | PXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PX; }
+ | CMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_CM; }
+ | MMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MM; }
+ | INS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_IN; }
+ | PTS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PT; }
+ | PCS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PC; }
+ | DEGS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_DEG; }
+ | RADS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_RAD; }
+ | GRADS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_GRAD; }
+ | MSECS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MS; }
+ | SECS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_S; }
+ | HERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_HZ; }
+ | KHERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_KHZ; }
+ | EMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EMS; }
+ | QEMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = Value::Q_EMS; }
+ | EXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EXS; }
+ ;
+
+
+function:
+ FUNCTION maybe_space expr ')' maybe_space {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ Function* f = p->createFloatingFunction();
+ f->name = $1;
+ f->args = p->sinkFloatingValueList($3);
+ $$.id = 0;
+ $$.unit = Value::Function;
+ $$.function = f;
+ } |
+ FUNCTION maybe_space error {
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ Function* f = p->createFloatingFunction();
+ f->name = $1;
+ f->args = 0;
+ $$.id = 0;
+ $$.unit = Value::Function;
+ $$.function = f;
+ }
+ ;
+/*
+ * There is a constraint on the color that it must
+ * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
+ * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
+ */
+hexcolor:
+ HEX maybe_space { $$ = $1; }
+ | IDSEL maybe_space { $$ = $1; }
+ ;
+
+
+/* error handling rules */
+
+invalid_at:
+ '@' error invalid_block {
+ $$ = 0;
+ }
+ | '@' error ';' {
+ $$ = 0;
+ }
+ ;
+
+invalid_import:
+ import {
+ $$ = 0;
+ }
+ ;
+
+invalid_rule:
+ error invalid_block {
+ $$ = 0;
+ }
+/*
+ Seems like the two rules below are trying too much and violating
+ http://www.hixie.ch/tests/evil/mixed/csserrorhandling.html
+
+ | error ';' {
+ $$ = 0;
+ }
+ | error '}' {
+ $$ = 0;
+ }
+*/
+ ;
+
+invalid_block:
+ '{' error invalid_block_list error '}'
+ | '{' error '}'
+ ;
+
+invalid_block_list:
+ invalid_block
+ | invalid_block_list error invalid_block
+;
+
+%%
diff --git a/WebCore/css/CSSHelper.cpp b/WebCore/css/CSSHelper.cpp
new file mode 100644
index 0000000..aa1186c
--- /dev/null
+++ b/WebCore/css/CSSHelper.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 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 "CSSHelper.h"
+
+#include "PlatformString.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+String parseURL(const String& url)
+{
+ StringImpl* i = url.impl();
+ if (!i)
+ return String();
+
+ int o = 0;
+ int l = i->length();
+
+ while (o < l && (*i)[o] <= ' ') {
+ ++o;
+ --l;
+ }
+ while (l > 0 && (*i)[o + l - 1] <= ' ')
+ --l;
+
+ if (l >= 5
+ && ((*i)[o] == 'u' || (*i)[o] == 'U')
+ && ((*i)[o + 1] == 'r' || (*i)[o + 1] == 'R')
+ && ((*i)[o + 2] == 'l' || (*i)[o + 2] == 'L')
+ && (*i)[o + 3] == '('
+ && (*i)[o + l - 1] == ')') {
+ o += 4;
+ l -= 5;
+ }
+
+ while (o < l && (*i)[o] <= ' ') {
+ ++o;
+ --l;
+ }
+ while (l > 0 && (*i)[o + l - 1] <= ' ')
+ --l;
+
+ if (l >= 2 && (*i)[o] == (*i)[o + l - 1] && ((*i)[o] == '\'' || (*i)[o] == '\"')) {
+ o++;
+ l -= 2;
+ }
+
+ while (o < l && (*i)[o] <= ' ') {
+ ++o;
+ --l;
+ }
+ while (l > 0 && (*i)[o + l - 1] <= ' ')
+ --l;
+
+ Vector<UChar, 2048> buffer(l);
+
+ int nl = 0;
+ for (int k = o; k < o + l; k++) {
+ UChar c = (*i)[k];
+ if (c > '\r')
+ buffer[nl++] = c;
+ }
+
+ return String(buffer.data(), nl);
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSHelper.h b/WebCore/css/CSSHelper.h
new file mode 100644
index 0000000..2a882e4
--- /dev/null
+++ b/WebCore/css/CSSHelper.h
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the CSS implementation for KDE.
+ *
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *
+ * 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 CSSHelper_h
+#define CSSHelper_h
+
+namespace WebCore {
+
+ class String;
+
+ /*
+ * mostly just removes the url("...") brace
+ */
+ String parseURL(const String& url);
+
+ // We always assume 96 CSS pixels in a CSS inch. This is the cold hard truth of the Web.
+ // At high DPI, we may scale a CSS pixel, but the ratio of the CSS pixel to the so-called
+ // "absolute" CSS length units like inch and pt is always fixed and never changes.
+ const float cssPixelsPerInch = 96.0f;
+
+ // Used by animation.
+ const int cAnimateNone = 0;
+ const int cAnimateAll = -2;
+
+} // namespace WebCore
+
+#endif // CSSHelper_h
diff --git a/WebCore/css/CSSImageValue.cpp b/WebCore/css/CSSImageValue.cpp
new file mode 100644
index 0000000..7d917b2
--- /dev/null
+++ b/WebCore/css/CSSImageValue.cpp
@@ -0,0 +1,75 @@
+/*
+ * (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 "CSSImageValue.h"
+
+#include "CSSValueKeywords.h"
+#include "Cache.h"
+#include "CachedImage.h"
+#include "DocLoader.h"
+
+namespace WebCore {
+
+CSSImageValue::CSSImageValue(const String& url, StyleBase* style)
+ : CSSPrimitiveValue(url, CSS_URI)
+ , m_image(0)
+ , m_accessedImage(false)
+{
+}
+
+CSSImageValue::CSSImageValue()
+ : CSSPrimitiveValue(CSS_VAL_NONE)
+ , m_image(0)
+ , m_accessedImage(true)
+{
+}
+
+CSSImageValue::~CSSImageValue()
+{
+ if (m_image)
+ m_image->deref(this);
+}
+
+CachedImage* CSSImageValue::image(DocLoader* loader)
+{
+ return image(loader, getStringValue());
+}
+
+CachedImage* CSSImageValue::image(DocLoader* loader, const String& url)
+{
+ if (!m_accessedImage) {
+ m_accessedImage = true;
+
+ if (loader)
+ m_image = loader->requestImage(url);
+ else {
+ // FIXME: Should find a way to make these images sit in their own memory partition, since they are user agent images.
+ m_image = static_cast<CachedImage*>(cache()->requestResource(0, CachedResource::ImageResource, KURL(url), 0, 0));
+ }
+
+ if (m_image)
+ m_image->ref(this);
+ }
+
+ return m_image;
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSImageValue.h b/WebCore/css/CSSImageValue.h
new file mode 100644
index 0000000..f2b2025
--- /dev/null
+++ b/WebCore/css/CSSImageValue.h
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 CSSImageValue_h
+#define CSSImageValue_h
+
+#include "CSSPrimitiveValue.h"
+#include "CachedResourceClient.h"
+
+namespace WebCore {
+
+class DocLoader;
+
+class CSSImageValue : public CSSPrimitiveValue,
+ public CachedResourceClient {
+public:
+ CSSImageValue();
+ CSSImageValue(const String& url, StyleBase*);
+ virtual ~CSSImageValue();
+
+ virtual CachedImage* image(DocLoader*);
+
+protected:
+ CachedImage* image(DocLoader*, const String& url);
+
+ CachedImage* m_image;
+ bool m_accessedImage;
+};
+
+} // namespace WebCore
+
+#endif // CSSImageValue_h
diff --git a/WebCore/css/CSSImportRule.cpp b/WebCore/css/CSSImportRule.cpp
new file mode 100644
index 0000000..0672826
--- /dev/null
+++ b/WebCore/css/CSSImportRule.cpp
@@ -0,0 +1,129 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 "CSSImportRule.h"
+
+#include "CachedCSSStyleSheet.h"
+#include "CSSStyleSheet.h"
+#include "DocLoader.h"
+#include "Document.h"
+#include "MediaList.h"
+
+namespace WebCore {
+
+CSSImportRule::CSSImportRule(StyleBase* parent, const String& href, MediaList* media)
+ : CSSRule(parent)
+ , m_strHref(href)
+ , m_lstMedia(media)
+ , m_cachedSheet(0)
+ , m_loading(false)
+{
+ if (m_lstMedia)
+ m_lstMedia->setParent(this);
+ else
+ m_lstMedia = new MediaList(this, String());
+}
+
+CSSImportRule::~CSSImportRule()
+{
+ if (m_lstMedia)
+ m_lstMedia->setParent(0);
+ if (m_styleSheet)
+ m_styleSheet->setParent(0);
+ if (m_cachedSheet)
+ m_cachedSheet->deref(this);
+}
+
+void CSSImportRule::setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet* sheet)
+{
+ if (m_styleSheet)
+ m_styleSheet->setParent(0);
+ m_styleSheet = new CSSStyleSheet(this, url, charset);
+
+ CSSStyleSheet* parent = parentStyleSheet();
+ bool strict = !parent || parent->useStrictParsing();
+ m_styleSheet->parseString(sheet->sheetText(strict), strict);
+ m_loading = false;
+
+ checkLoaded();
+}
+
+bool CSSImportRule::isLoading() const
+{
+ return m_loading || (m_styleSheet && m_styleSheet->isLoading());
+}
+
+void CSSImportRule::insertedIntoParent()
+{
+ StyleBase* root = this;
+ StyleBase* parent;
+ while ((parent = root->parent()))
+ root = parent;
+ if (!root->isCSSStyleSheet())
+ return;
+ DocLoader* docLoader = static_cast<CSSStyleSheet*>(root)->docLoader();
+ if (!docLoader)
+ return;
+
+ String absHref = m_strHref;
+ CSSStyleSheet* parentSheet = parentStyleSheet();
+ if (!parentSheet->href().isNull())
+ // use parent styleheet's URL as the base URL
+ absHref = KURL(KURL(parentSheet->href()), m_strHref).string();
+
+ // Check for a cycle in our import chain. If we encounter a stylesheet
+ // in our parent chain with the same URL, then just bail.
+ for (parent = static_cast<StyleBase*>(this)->parent(); parent; parent = parent->parent()) {
+ if (absHref == parent->baseURL())
+ return;
+ }
+
+ m_cachedSheet = docLoader->requestCSSStyleSheet(absHref, parentSheet->charset());
+ if (m_cachedSheet) {
+ // if the import rule is issued dynamically, the sheet may be
+ // removed from the pending sheet count, so let the doc know
+ // the sheet being imported is pending.
+ if (parentSheet && parentSheet->loadCompleted() && parentSheet->doc())
+ parentSheet->doc()->addPendingSheet();
+ m_loading = true;
+ m_cachedSheet->ref(this);
+ }
+}
+
+String CSSImportRule::cssText() const
+{
+ String result = "@import url(\"";
+ result += m_strHref;
+ result += "\")";
+
+ if (m_lstMedia) {
+ result += " ";
+ result += m_lstMedia->mediaText();
+ }
+ result += ";";
+
+ return result;
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSImportRule.h b/WebCore/css/CSSImportRule.h
new file mode 100644
index 0000000..ea40584
--- /dev/null
+++ b/WebCore/css/CSSImportRule.h
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2006 Apple Computer, Inc.
+ *
+ * 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 CSSImportRule_h
+#define CSSImportRule_h
+
+#include "CSSRule.h"
+#include "CachedResourceClient.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class CachedCSSStyleSheet;
+class MediaList;
+
+class CSSImportRule : public CSSRule, public CachedResourceClient {
+public:
+ CSSImportRule(StyleBase* parent, const String& href, MediaList*);
+ virtual ~CSSImportRule();
+
+ virtual bool isImportRule() { return true; }
+
+ String href() const { return m_strHref; }
+ MediaList* media() const { return m_lstMedia.get(); }
+ CSSStyleSheet* styleSheet() const { return m_styleSheet.get(); }
+
+ // Inherited from CSSRule
+ virtual unsigned short type() const { return IMPORT_RULE; }
+
+ virtual String cssText() const;
+
+ // Not part of the CSSOM
+ bool isLoading() const;
+
+ // from CachedResourceClient
+ virtual void setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet*);
+
+ virtual void insertedIntoParent();
+
+protected:
+ String m_strHref;
+ RefPtr<MediaList> m_lstMedia;
+ RefPtr<CSSStyleSheet> m_styleSheet;
+ CachedCSSStyleSheet* m_cachedSheet;
+ bool m_loading;
+};
+
+} // namespace WebCore
+
+#endif // CSSImportRule_h
diff --git a/WebCore/css/CSSImportRule.idl b/WebCore/css/CSSImportRule.idl
new file mode 100644
index 0000000..454553e
--- /dev/null
+++ b/WebCore/css/CSSImportRule.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [
+ GenerateConstructor,
+ InterfaceUUID=8f60b3a2-ebf0-484d-a714-47a9974a6a9e,
+ ImplementationUUID=437ea93c-68e5-4897-85fe-e161653801eb
+ ] CSSImportRule : CSSRule {
+ readonly attribute [ConvertNullStringTo=Null] DOMString href;
+ readonly attribute stylesheets::MediaList media;
+ readonly attribute CSSStyleSheet styleSheet;
+ };
+
+}
diff --git a/WebCore/css/CSSInheritedValue.cpp b/WebCore/css/CSSInheritedValue.cpp
new file mode 100644
index 0000000..08d3db3
--- /dev/null
+++ b/WebCore/css/CSSInheritedValue.cpp
@@ -0,0 +1,40 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 "CSSInheritedValue.h"
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+unsigned short CSSInheritedValue::cssValueType() const
+{
+ return CSS_INHERIT;
+}
+
+String CSSInheritedValue::cssText() const
+{
+ return "inherit";
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSInheritedValue.h b/WebCore/css/CSSInheritedValue.h
new file mode 100644
index 0000000..a2332d2
--- /dev/null
+++ b/WebCore/css/CSSInheritedValue.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 CSSInheritedValue_h
+#define CSSInheritedValue_h
+
+#include "CSSValue.h"
+
+namespace WebCore {
+
+class CSSInheritedValue : public CSSValue {
+public:
+ virtual unsigned short cssValueType() const;
+ virtual String cssText() const;
+};
+
+} // namespace WebCore
+
+#endif // CSSInheritedValue_h
diff --git a/WebCore/css/CSSInitialValue.cpp b/WebCore/css/CSSInitialValue.cpp
new file mode 100644
index 0000000..9c2bb23
--- /dev/null
+++ b/WebCore/css/CSSInitialValue.cpp
@@ -0,0 +1,40 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 "CSSInitialValue.h"
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+unsigned short CSSInitialValue::cssValueType() const
+{
+ return CSS_INITIAL;
+}
+
+String CSSInitialValue::cssText() const
+{
+ return "initial";
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSInitialValue.h b/WebCore/css/CSSInitialValue.h
new file mode 100644
index 0000000..1e04015
--- /dev/null
+++ b/WebCore/css/CSSInitialValue.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 CSSInitialValue_h
+#define CSSInitialValue_h
+
+#include "CSSValue.h"
+
+namespace WebCore {
+
+class CSSInitialValue : public CSSValue {
+public:
+ CSSInitialValue(bool implicit)
+ :m_implicit(implicit)
+ {}
+
+ virtual unsigned short cssValueType() const;
+ virtual String cssText() const;
+
+ virtual bool isImplicitInitialValue() const { return m_implicit; }
+
+private:
+ bool m_implicit;
+};
+
+} // namespace WebCore
+
+#endif // CSSInitialValue_h
diff --git a/WebCore/css/CSSMediaRule.cpp b/WebCore/css/CSSMediaRule.cpp
new file mode 100644
index 0000000..c46d9b7
--- /dev/null
+++ b/WebCore/css/CSSMediaRule.cpp
@@ -0,0 +1,151 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2006 Samuel Weinig (sam@webkit.org)
+ *
+ * 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 "CSSMediaRule.h"
+
+#include "CSSParser.h"
+#include "CSSRuleList.h"
+#include "ExceptionCode.h"
+#include "MediaList.h"
+#include "StyleSheet.h"
+
+namespace WebCore {
+
+CSSMediaRule::CSSMediaRule(StyleBase* parent, MediaList* mediaList, CSSRuleList* ruleList)
+ : CSSRule(parent)
+ , m_lstMedia(mediaList)
+ , m_lstCSSRules(ruleList)
+{
+}
+
+CSSMediaRule::CSSMediaRule(StyleBase* parent)
+ : CSSRule(parent)
+ , m_lstMedia(0)
+ , m_lstCSSRules(new CSSRuleList())
+
+{
+}
+
+CSSMediaRule::CSSMediaRule(StyleBase* parent, const String &media)
+ : CSSRule(parent)
+ , m_lstMedia(new MediaList(this, media))
+ , m_lstCSSRules(new CSSRuleList())
+{
+}
+
+CSSMediaRule::~CSSMediaRule()
+{
+ if (m_lstMedia)
+ m_lstMedia->setParent(0);
+
+ int length = m_lstCSSRules->length();
+ for (int i = 0; i < length; i++)
+ m_lstCSSRules->item(i)->setParent(0);
+}
+
+unsigned CSSMediaRule::append(CSSRule* rule)
+{
+ if (!rule)
+ return 0;
+
+ rule->setParent(this);
+ return m_lstCSSRules->insertRule(rule, m_lstCSSRules->length());
+}
+
+unsigned CSSMediaRule::insertRule(const String& rule, unsigned index, ExceptionCode& ec)
+{
+ if (index > m_lstCSSRules->length()) {
+ // INDEX_SIZE_ERR: Raised if the specified index is not a valid insertion point.
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+
+ CSSParser p(useStrictParsing());
+ RefPtr<CSSRule> newRule = p.parseRule(parentStyleSheet(), rule);
+ if (!newRule) {
+ // SYNTAX_ERR: Raised if the specified rule has a syntax error and is unparsable.
+ ec = SYNTAX_ERR;
+ return 0;
+ }
+
+ if (newRule->isImportRule()) {
+ // FIXME: an HIERARCHY_REQUEST_ERR should also be thrown for a @charset or a nested
+ // @media rule. They are currently not getting parsed, resulting in a SYNTAX_ERR
+ // to get raised above.
+
+ // HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at the specified
+ // index, e.g., if an @import rule is inserted after a standard rule set or other
+ // at-rule.
+ ec = HIERARCHY_REQUEST_ERR;
+ return 0;
+ }
+
+ newRule->setParent(this);
+ unsigned returnedIndex = m_lstCSSRules->insertRule(newRule.get(), index);
+
+ // stylesheet() can only return 0 for computed style declarations.
+ stylesheet()->styleSheetChanged();
+
+ return returnedIndex;
+}
+
+void CSSMediaRule::deleteRule(unsigned index, ExceptionCode& ec)
+{
+ if (index >= m_lstCSSRules->length()) {
+ // INDEX_SIZE_ERR: Raised if the specified index does not correspond to a
+ // rule in the media rule list.
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ m_lstCSSRules->deleteRule(index);
+
+ // stylesheet() can only return 0 for computed style declarations.
+ stylesheet()->styleSheetChanged();
+}
+
+String CSSMediaRule::cssText() const
+{
+ String result = "@media ";
+ if (m_lstMedia) {
+ result += m_lstMedia->mediaText();
+ result += " ";
+ }
+ result += "{ \n";
+
+ if (m_lstCSSRules) {
+ unsigned len = m_lstCSSRules->length();
+ for (unsigned i = 0; i < len; i++) {
+ result += " ";
+ result += m_lstCSSRules->item(i)->cssText();
+ result += "\n";
+ }
+ }
+
+ result += "}";
+ return result;
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSMediaRule.h b/WebCore/css/CSSMediaRule.h
new file mode 100644
index 0000000..f6a7e48
--- /dev/null
+++ b/WebCore/css/CSSMediaRule.h
@@ -0,0 +1,68 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2006 Apple Computer, Inc.
+ * Copyright (C) 2006 Samuel Weinig (sam@webkit.org)
+ *
+ * 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 CSSMediaRule_h
+#define CSSMediaRule_h
+
+#include "CSSRule.h"
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSRuleList;
+class MediaList;
+
+typedef int ExceptionCode;
+
+class CSSMediaRule : public CSSRule {
+public:
+ CSSMediaRule(StyleBase* parent);
+ CSSMediaRule(StyleBase* parent, const String& media);
+ CSSMediaRule(StyleBase* parent, MediaList* mediaList, CSSRuleList* ruleList);
+ virtual ~CSSMediaRule();
+
+ virtual bool isMediaRule() { return true; }
+
+ MediaList* media() const { return m_lstMedia.get(); }
+ CSSRuleList* cssRules() { return m_lstCSSRules.get(); }
+
+ unsigned insertRule(const String& rule, unsigned index, ExceptionCode&);
+ void deleteRule(unsigned index, ExceptionCode&);
+
+ // Inherited from CSSRule
+ virtual unsigned short type() const { return MEDIA_RULE; }
+
+ virtual String cssText() const;
+
+ // Not part of the CSSOM
+ unsigned append(CSSRule*);
+
+protected:
+ RefPtr<MediaList> m_lstMedia;
+ RefPtr<CSSRuleList> m_lstCSSRules;
+};
+
+} // namespace WebCore
+
+#endif // CSSMediaRule_h
diff --git a/WebCore/css/CSSMediaRule.idl b/WebCore/css/CSSMediaRule.idl
new file mode 100644
index 0000000..1347171
--- /dev/null
+++ b/WebCore/css/CSSMediaRule.idl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [
+ GenerateConstructor,
+ InterfaceUUID=9c623c09-2677-4d28-ba90-826da0ae316a,
+ ImplementationUUID=30493ec9-e139-4e9e-ae24-cc8f532006d9
+ ] CSSMediaRule : CSSRule {
+ readonly attribute stylesheets::MediaList media;
+ readonly attribute CSSRuleList cssRules;
+
+ [OldStyleObjC] unsigned long insertRule(in DOMString rule,
+ in unsigned long index)
+ raises(DOMException);
+ void deleteRule(in unsigned long index)
+ raises(DOMException);
+ };
+
+}
diff --git a/WebCore/css/CSSMutableStyleDeclaration.cpp b/WebCore/css/CSSMutableStyleDeclaration.cpp
new file mode 100644
index 0000000..bc354ff
--- /dev/null
+++ b/WebCore/css/CSSMutableStyleDeclaration.cpp
@@ -0,0 +1,729 @@
+/*
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 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 "CSSMutableStyleDeclaration.h"
+
+#include "CSSImageValue.h"
+#include "CSSParser.h"
+#include "CSSProperty.h"
+#include "CSSPropertyNames.h"
+#include "CSSStyleSheet.h"
+#include "CSSValueList.h"
+#include "Document.h"
+#include "ExceptionCode.h"
+#include "StyledElement.h"
+
+using namespace std;
+
+namespace WebCore {
+
+CSSMutableStyleDeclaration::CSSMutableStyleDeclaration()
+ : m_node(0)
+{
+}
+
+CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent)
+ : CSSStyleDeclaration(parent)
+ , m_node(0)
+{
+}
+
+CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const DeprecatedValueList<CSSProperty>& values)
+ : CSSStyleDeclaration(parent)
+ , m_values(values)
+ , m_node(0)
+{
+ // FIXME: This allows duplicate properties.
+}
+
+CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const CSSProperty* const * properties, int numProperties)
+ : CSSStyleDeclaration(parent)
+ , m_node(0)
+{
+ for (int i = 0; i < numProperties; ++i) {
+ ASSERT(properties[i]);
+ m_values.append(*properties[i]);
+ }
+ // FIXME: This allows duplicate properties.
+}
+
+CSSMutableStyleDeclaration& CSSMutableStyleDeclaration::operator=(const CSSMutableStyleDeclaration& other)
+{
+ // don't attach it to the same node, just leave the current m_node value
+ m_values = other.m_values;
+ return *this;
+}
+
+String CSSMutableStyleDeclaration::getPropertyValue(int propertyID) const
+{
+ RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
+ if (value)
+ return value->cssText();
+
+ // Shorthand and 4-values properties
+ switch (propertyID) {
+ case CSS_PROP_BACKGROUND_POSITION: {
+ // FIXME: Is this correct? The code in cssparser.cpp is confusing
+ const int properties[2] = { CSS_PROP_BACKGROUND_POSITION_X,
+ CSS_PROP_BACKGROUND_POSITION_Y };
+ return getLayeredShorthandValue(properties, 2);
+ }
+ case CSS_PROP_BACKGROUND: {
+ const int properties[6] = { CSS_PROP_BACKGROUND_IMAGE, CSS_PROP_BACKGROUND_REPEAT,
+ CSS_PROP_BACKGROUND_ATTACHMENT, CSS_PROP_BACKGROUND_POSITION_X,
+ CSS_PROP_BACKGROUND_POSITION_Y, CSS_PROP_BACKGROUND_COLOR };
+ return getLayeredShorthandValue(properties, 6);
+ }
+ case CSS_PROP_BORDER: {
+ const int properties[3] = { CSS_PROP_BORDER_WIDTH, CSS_PROP_BORDER_STYLE,
+ CSS_PROP_BORDER_COLOR };
+ return getShorthandValue(properties, 3);
+ }
+ case CSS_PROP_BORDER_TOP: {
+ const int properties[3] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_TOP_STYLE,
+ CSS_PROP_BORDER_TOP_COLOR};
+ return getShorthandValue(properties, 3);
+ }
+ case CSS_PROP_BORDER_RIGHT: {
+ const int properties[3] = { CSS_PROP_BORDER_RIGHT_WIDTH, CSS_PROP_BORDER_RIGHT_STYLE,
+ CSS_PROP_BORDER_RIGHT_COLOR};
+ return getShorthandValue(properties, 3);
+ }
+ case CSS_PROP_BORDER_BOTTOM: {
+ const int properties[3] = { CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_BOTTOM_STYLE,
+ CSS_PROP_BORDER_BOTTOM_COLOR};
+ return getShorthandValue(properties, 3);
+ }
+ case CSS_PROP_BORDER_LEFT: {
+ const int properties[3] = { CSS_PROP_BORDER_LEFT_WIDTH, CSS_PROP_BORDER_LEFT_STYLE,
+ CSS_PROP_BORDER_LEFT_COLOR};
+ return getShorthandValue(properties, 3);
+ }
+ case CSS_PROP_OUTLINE: {
+ const int properties[3] = { CSS_PROP_OUTLINE_WIDTH, CSS_PROP_OUTLINE_STYLE,
+ CSS_PROP_OUTLINE_COLOR };
+ return getShorthandValue(properties, 3);
+ }
+ case CSS_PROP_BORDER_COLOR: {
+ const int properties[4] = { CSS_PROP_BORDER_TOP_COLOR, CSS_PROP_BORDER_RIGHT_COLOR,
+ CSS_PROP_BORDER_BOTTOM_COLOR, CSS_PROP_BORDER_LEFT_COLOR };
+ return get4Values(properties);
+ }
+ case CSS_PROP_BORDER_WIDTH: {
+ const int properties[4] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_RIGHT_WIDTH,
+ CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_LEFT_WIDTH };
+ return get4Values(properties);
+ }
+ case CSS_PROP_BORDER_STYLE: {
+ const int properties[4] = { CSS_PROP_BORDER_TOP_STYLE, CSS_PROP_BORDER_RIGHT_STYLE,
+ CSS_PROP_BORDER_BOTTOM_STYLE, CSS_PROP_BORDER_LEFT_STYLE };
+ return get4Values(properties);
+ }
+ case CSS_PROP_MARGIN: {
+ const int properties[4] = { CSS_PROP_MARGIN_TOP, CSS_PROP_MARGIN_RIGHT,
+ CSS_PROP_MARGIN_BOTTOM, CSS_PROP_MARGIN_LEFT };
+ return get4Values(properties);
+ }
+ case CSS_PROP_PADDING: {
+ const int properties[4] = { CSS_PROP_PADDING_TOP, CSS_PROP_PADDING_RIGHT,
+ CSS_PROP_PADDING_BOTTOM, CSS_PROP_PADDING_LEFT };
+ return get4Values(properties);
+ }
+ case CSS_PROP_LIST_STYLE: {
+ const int properties[3] = { CSS_PROP_LIST_STYLE_TYPE, CSS_PROP_LIST_STYLE_POSITION,
+ CSS_PROP_LIST_STYLE_IMAGE };
+ return getShorthandValue(properties, 3);
+ }
+ }
+ return String();
+}
+
+String CSSMutableStyleDeclaration::get4Values( const int* properties ) const
+{
+ String res;
+ for (int i = 0; i < 4; ++i) {
+ if (!isPropertyImplicit(properties[i])) {
+ RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
+
+ // apparently all 4 properties must be specified.
+ if (!value)
+ return String();
+
+ if (!res.isNull())
+ res += " ";
+ res += value->cssText();
+ }
+ }
+ return res;
+}
+
+String CSSMutableStyleDeclaration::getLayeredShorthandValue(const int* properties, unsigned number) const
+{
+ String res;
+ unsigned i;
+ unsigned j;
+
+ // Begin by collecting the properties into an array.
+ Vector< RefPtr<CSSValue> > values(number);
+ unsigned numLayers = 0;
+
+ for (i = 0; i < number; ++i) {
+ values[i] = getPropertyCSSValue(properties[i]);
+ if (values[i]) {
+ if (values[i]->isValueList()) {
+ CSSValueList* valueList = static_cast<CSSValueList*>(values[i].get());
+ numLayers = max(valueList->length(), numLayers);
+ } else
+ numLayers = max(1U, numLayers);
+ }
+ }
+
+ // Now stitch the properties together. Implicit initial values are flagged as such and
+ // can safely be omitted.
+ for (i = 0; i < numLayers; i++) {
+ String layerRes;
+ for (j = 0; j < number; j++) {
+ RefPtr<CSSValue> value;
+ if (values[j]) {
+ if (values[j]->isValueList())
+ value = static_cast<CSSValueList*>(values[j].get())->item(i);
+ else {
+ value = values[j];
+
+ // Color only belongs in the last layer.
+ if (properties[j] == CSS_PROP_BACKGROUND_COLOR) {
+ if (i != numLayers - 1)
+ value = 0;
+ } else if (i != 0) // Other singletons only belong in the first layer.
+ value = 0;
+ }
+ }
+
+ if (value && !value->isImplicitInitialValue()) {
+ if (!layerRes.isNull())
+ layerRes += " ";
+ layerRes += value->cssText();
+ }
+ }
+
+ if (!layerRes.isNull()) {
+ if (!res.isNull())
+ res += ", ";
+ res += layerRes;
+ }
+ }
+
+ return res;
+}
+
+String CSSMutableStyleDeclaration::getShorthandValue(const int* properties, int number) const
+{
+ String res;
+ for (int i = 0; i < number; ++i) {
+ if (!isPropertyImplicit(properties[i])) {
+ RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
+ // FIXME: provide default value if !value
+ if (value) {
+ if (!res.isNull())
+ res += " ";
+ res += value->cssText();
+ }
+ }
+ }
+ return res;
+}
+
+PassRefPtr<CSSValue> CSSMutableStyleDeclaration::getPropertyCSSValue(int propertyID) const
+{
+ DeprecatedValueListConstIterator<CSSProperty> end;
+ for (DeprecatedValueListConstIterator<CSSProperty> it = m_values.fromLast(); it != end; --it) {
+ if (propertyID == (*it).m_id)
+ return (*it).value();
+ }
+ return 0;
+}
+
+struct PropertyLonghand {
+ PropertyLonghand()
+ : m_properties(0)
+ , m_length(0)
+ {
+ }
+
+ PropertyLonghand(const int* firstProperty, unsigned numProperties)
+ : m_properties(firstProperty)
+ , m_length(numProperties)
+ {
+ }
+
+ const int* properties() const { return m_properties; }
+ unsigned length() const { return m_length; }
+
+private:
+ const int* m_properties;
+ unsigned m_length;
+};
+
+static void initShorthandMap(HashMap<int, PropertyLonghand>& shorthandMap)
+{
+ #define SET_SHORTHAND_MAP_ENTRY(map, propID, array) \
+ map.set(propID, PropertyLonghand(array, sizeof(array) / sizeof(array[0])))
+
+ // FIXME: The 'font' property has "shorthand nature" but is not parsed as a shorthand.
+
+ // Do not change the order of the following four shorthands, and keep them together.
+ static const int borderProperties[4][3] = {
+ { CSS_PROP_BORDER_TOP_COLOR, CSS_PROP_BORDER_TOP_STYLE, CSS_PROP_BORDER_TOP_WIDTH },
+ { CSS_PROP_BORDER_RIGHT_COLOR, CSS_PROP_BORDER_RIGHT_STYLE, CSS_PROP_BORDER_RIGHT_WIDTH },
+ { CSS_PROP_BORDER_BOTTOM_COLOR, CSS_PROP_BORDER_BOTTOM_STYLE, CSS_PROP_BORDER_BOTTOM_WIDTH },
+ { CSS_PROP_BORDER_LEFT_COLOR, CSS_PROP_BORDER_LEFT_STYLE, CSS_PROP_BORDER_LEFT_WIDTH }
+ };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_TOP, borderProperties[0]);
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_RIGHT, borderProperties[1]);
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_BOTTOM, borderProperties[2]);
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_LEFT, borderProperties[3]);
+
+ shorthandMap.set(CSS_PROP_BORDER, PropertyLonghand(borderProperties[0], sizeof(borderProperties) / sizeof(borderProperties[0][0])));
+
+ static const int borderColorProperties[] = {
+ CSS_PROP_BORDER_TOP_COLOR,
+ CSS_PROP_BORDER_RIGHT_COLOR,
+ CSS_PROP_BORDER_BOTTOM_COLOR,
+ CSS_PROP_BORDER_LEFT_COLOR
+ };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_COLOR, borderColorProperties);
+
+ static const int borderStyleProperties[] = {
+ CSS_PROP_BORDER_TOP_STYLE,
+ CSS_PROP_BORDER_RIGHT_STYLE,
+ CSS_PROP_BORDER_BOTTOM_STYLE,
+ CSS_PROP_BORDER_LEFT_STYLE
+ };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_STYLE, borderStyleProperties);
+
+ static const int borderWidthProperties[] = {
+ CSS_PROP_BORDER_TOP_WIDTH,
+ CSS_PROP_BORDER_RIGHT_WIDTH,
+ CSS_PROP_BORDER_BOTTOM_WIDTH,
+ CSS_PROP_BORDER_LEFT_WIDTH
+ };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_WIDTH, borderWidthProperties);
+
+ static const int backgroundPositionProperties[] = { CSS_PROP_BACKGROUND_POSITION_X, CSS_PROP_BACKGROUND_POSITION_Y };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BACKGROUND_POSITION, backgroundPositionProperties);
+
+ static const int borderSpacingProperties[] = { CSS_PROP__WEBKIT_BORDER_HORIZONTAL_SPACING, CSS_PROP__WEBKIT_BORDER_VERTICAL_SPACING };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_SPACING, borderSpacingProperties);
+
+ static const int listStyleProperties[] = {
+ CSS_PROP_LIST_STYLE_IMAGE,
+ CSS_PROP_LIST_STYLE_POSITION,
+ CSS_PROP_LIST_STYLE_TYPE
+ };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_LIST_STYLE, listStyleProperties);
+
+ static const int marginProperties[] = {
+ CSS_PROP_MARGIN_TOP,
+ CSS_PROP_MARGIN_RIGHT,
+ CSS_PROP_MARGIN_BOTTOM,
+ CSS_PROP_MARGIN_LEFT
+ };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_MARGIN, marginProperties);
+
+ static const int marginCollapseProperties[] = { CSS_PROP__WEBKIT_MARGIN_TOP_COLLAPSE, CSS_PROP__WEBKIT_MARGIN_BOTTOM_COLLAPSE };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP__WEBKIT_MARGIN_COLLAPSE, marginCollapseProperties);
+
+ static const int marqueeProperties[] = {
+ CSS_PROP__WEBKIT_MARQUEE_DIRECTION,
+ CSS_PROP__WEBKIT_MARQUEE_INCREMENT,
+ CSS_PROP__WEBKIT_MARQUEE_REPETITION,
+ CSS_PROP__WEBKIT_MARQUEE_STYLE,
+ CSS_PROP__WEBKIT_MARQUEE_SPEED
+ };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP__WEBKIT_MARQUEE, marqueeProperties);
+
+ static const int outlineProperties[] = {
+ CSS_PROP_OUTLINE_COLOR,
+ CSS_PROP_OUTLINE_OFFSET,
+ CSS_PROP_OUTLINE_STYLE,
+ CSS_PROP_OUTLINE_WIDTH
+ };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_OUTLINE, outlineProperties);
+
+ static const int paddingProperties[] = {
+ CSS_PROP_PADDING_TOP,
+ CSS_PROP_PADDING_RIGHT,
+ CSS_PROP_PADDING_BOTTOM,
+ CSS_PROP_PADDING_LEFT
+ };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_PADDING, paddingProperties);
+
+ static const int textStrokeProperties[] = { CSS_PROP__WEBKIT_TEXT_STROKE_COLOR, CSS_PROP__WEBKIT_TEXT_STROKE_WIDTH };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP__WEBKIT_TEXT_STROKE, textStrokeProperties);
+
+ static const int backgroundProperties[] = {
+ CSS_PROP_BACKGROUND_ATTACHMENT,
+ CSS_PROP_BACKGROUND_COLOR,
+ CSS_PROP_BACKGROUND_IMAGE,
+ CSS_PROP_BACKGROUND_POSITION_X,
+ CSS_PROP_BACKGROUND_POSITION_Y,
+ CSS_PROP_BACKGROUND_REPEAT,
+ CSS_PROP__WEBKIT_BACKGROUND_SIZE
+ };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BACKGROUND, backgroundProperties);
+
+ static const int columnsProperties[] = { CSS_PROP__WEBKIT_COLUMN_WIDTH, CSS_PROP__WEBKIT_COLUMN_COUNT };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP__WEBKIT_COLUMNS, columnsProperties);
+
+ static const int columnRuleProperties[] = {
+ CSS_PROP__WEBKIT_COLUMN_RULE_COLOR,
+ CSS_PROP__WEBKIT_COLUMN_RULE_STYLE,
+ CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH
+ };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP__WEBKIT_COLUMN_RULE, columnRuleProperties);
+
+ static const int overflowProperties[] = { CSS_PROP_OVERFLOW_X, CSS_PROP_OVERFLOW_Y };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_OVERFLOW, overflowProperties);
+
+ static const int borderRadiusProperties[] = {
+ CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS,
+ CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS,
+ CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS,
+ CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS
+ };
+ SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP__WEBKIT_BORDER_RADIUS, borderRadiusProperties);
+
+ #undef SET_SHORTHAND_MAP_ENTRY
+}
+
+String CSSMutableStyleDeclaration::removeProperty(int propertyID, bool notifyChanged, bool returnText, ExceptionCode& ec)
+{
+ ec = 0;
+
+ static HashMap<int, PropertyLonghand> shorthandMap;
+ if (shorthandMap.isEmpty())
+ initShorthandMap(shorthandMap);
+
+ PropertyLonghand longhand = shorthandMap.get(propertyID);
+ if (longhand.length()) {
+ removePropertiesInSet(longhand.properties(), longhand.length(), notifyChanged);
+ // FIXME: Return an equivalent shorthand when possible.
+ return String();
+ }
+
+ String value;
+
+ DeprecatedValueListIterator<CSSProperty> end;
+ for (DeprecatedValueListIterator<CSSProperty> it = m_values.fromLast(); it != end; --it) {
+ if (propertyID == (*it).m_id) {
+ if (returnText)
+ value = (*it).value()->cssText();
+ m_values.remove(it);
+ if (notifyChanged)
+ setChanged();
+ break;
+ }
+ }
+
+ return value;
+}
+
+void CSSMutableStyleDeclaration::clear()
+{
+ m_values.clear();
+ setChanged();
+}
+
+void CSSMutableStyleDeclaration::setChanged(StyleChangeType changeType)
+{
+ if (m_node) {
+ m_node->setChanged(changeType);
+ // FIXME: Ideally, this should be factored better and there
+ // should be a subclass of CSSMutableStyleDeclaration just
+ // for inline style declarations that handles this
+ if (m_node->isStyledElement() && this == static_cast<StyledElement*>(m_node)->inlineStyleDecl())
+ static_cast<StyledElement*>(m_node)->invalidateStyleAttribute();
+ return;
+ }
+
+ // FIXME: quick&dirty hack for KDE 3.0... make this MUCH better! (Dirk)
+ StyleBase* root = this;
+ while (StyleBase* parent = root->parent())
+ root = parent;
+ if (root->isCSSStyleSheet())
+ static_cast<CSSStyleSheet*>(root)->doc()->updateStyleSelector();
+}
+
+bool CSSMutableStyleDeclaration::getPropertyPriority(int propertyID) const
+{
+ DeprecatedValueListConstIterator<CSSProperty> end;
+ for (DeprecatedValueListConstIterator<CSSProperty> it = m_values.begin(); it != end; ++it) {
+ if (propertyID == (*it).id())
+ return (*it).isImportant();
+ }
+ return false;
+}
+
+int CSSMutableStyleDeclaration::getPropertyShorthand(int propertyID) const
+{
+ DeprecatedValueListConstIterator<CSSProperty> end;
+ for (DeprecatedValueListConstIterator<CSSProperty> it = m_values.begin(); it != end; ++it) {
+ if (propertyID == (*it).id())
+ return (*it).shorthandID();
+ }
+ return false;
+}
+
+bool CSSMutableStyleDeclaration::isPropertyImplicit(int propertyID) const
+{
+ DeprecatedValueListConstIterator<CSSProperty> end;
+ for (DeprecatedValueListConstIterator<CSSProperty> it = m_values.begin(); it != end; ++it) {
+ if (propertyID == (*it).id())
+ return (*it).isImplicit();
+ }
+ return false;
+}
+
+void CSSMutableStyleDeclaration::setProperty(int propertyID, const String& value, bool important, ExceptionCode& ec)
+{
+ setProperty(propertyID, value, important, true, ec);
+}
+
+String CSSMutableStyleDeclaration::removeProperty(int propertyID, ExceptionCode& ec)
+{
+ return removeProperty(propertyID, true, true, ec);
+}
+
+bool CSSMutableStyleDeclaration::setProperty(int propertyID, const String& value, bool important, bool notifyChanged, ExceptionCode& ec)
+{
+ ec = 0;
+
+ // Setting the value to an empty string just removes the property in both IE and Gecko.
+ // Setting it to null seems to produce less consistent results, but we treat it just the same.
+ if (value.isEmpty()) {
+ removeProperty(propertyID, notifyChanged, false, ec);
+ return ec == 0;
+ }
+
+ // When replacing an existing property value, this moves the property to the end of the list.
+ // Firefox preserves the position, and MSIE moves the property to the beginning.
+ CSSParser parser(useStrictParsing());
+ bool success = parser.parseValue(this, propertyID, value, important);
+ if (!success) {
+ // CSS DOM requires raising SYNTAX_ERR here, but this is too dangerous for compatibility,
+ // see <http://bugs.webkit.org/show_bug.cgi?id=7296>.
+ } else if (notifyChanged)
+ setChanged(InlineStyleChange);
+ ASSERT(!ec);
+ return success;
+}
+
+bool CSSMutableStyleDeclaration::setProperty(int propertyID, int value, bool important, bool notifyChanged)
+{
+ removeProperty(propertyID);
+ m_values.append(CSSProperty(propertyID, new CSSPrimitiveValue(value), important));
+ if (notifyChanged)
+ setChanged();
+ return true;
+}
+
+void CSSMutableStyleDeclaration::setStringProperty(int propertyId, const String &value, CSSPrimitiveValue::UnitTypes type, bool important)
+{
+ removeProperty(propertyId);
+ m_values.append(CSSProperty(propertyId, new CSSPrimitiveValue(value, type), important));
+ setChanged();
+}
+
+void CSSMutableStyleDeclaration::setImageProperty(int propertyId, const String& url, bool important)
+{
+ removeProperty(propertyId);
+ m_values.append(CSSProperty(propertyId, new CSSImageValue(url, this), important));
+ setChanged();
+}
+
+void CSSMutableStyleDeclaration::parseDeclaration(const String& styleDeclaration)
+{
+ m_values.clear();
+ CSSParser parser(useStrictParsing());
+ parser.parseDeclaration(this, styleDeclaration);
+ setChanged();
+}
+
+void CSSMutableStyleDeclaration::addParsedProperties(const CSSProperty * const * properties, int numProperties)
+{
+ for (int i = 0; i < numProperties; ++i) {
+ // Only add properties that have no !important counterpart present
+ if (!getPropertyPriority(properties[i]->id()) || properties[i]->isImportant()) {
+ removeProperty(properties[i]->id(), false);
+ ASSERT(properties[i]);
+ m_values.append(*properties[i]);
+ }
+ }
+ // FIXME: This probably should have a call to setChanged() if something changed. We may also wish to add
+ // a notifyChanged argument to this function to follow the model of other functions in this class.
+}
+
+void CSSMutableStyleDeclaration::setLengthProperty(int propertyId, const String& value, bool important, bool /*multiLength*/)
+{
+ bool parseMode = useStrictParsing();
+ setStrictParsing(false);
+ setProperty(propertyId, value, important);
+ setStrictParsing(parseMode);
+}
+
+unsigned CSSMutableStyleDeclaration::length() const
+{
+ return m_values.count();
+}
+
+String CSSMutableStyleDeclaration::item(unsigned i) const
+{
+ if (i >= m_values.count())
+ return String();
+ return getPropertyName(static_cast<CSSPropertyID>(m_values[i].id()));
+}
+
+String CSSMutableStyleDeclaration::cssText() const
+{
+ String result = "";
+
+ const CSSProperty* positionXProp = 0;
+ const CSSProperty* positionYProp = 0;
+
+ DeprecatedValueListConstIterator<CSSProperty> end;
+ for (DeprecatedValueListConstIterator<CSSProperty> it = m_values.begin(); it != end; ++it) {
+ const CSSProperty& prop = *it;
+ if (prop.id() == CSS_PROP_BACKGROUND_POSITION_X)
+ positionXProp = &prop;
+ else if (prop.id() == CSS_PROP_BACKGROUND_POSITION_Y)
+ positionYProp = &prop;
+ else
+ result += prop.cssText();
+ }
+
+ // FIXME: This is a not-so-nice way to turn x/y positions into single background-position in output.
+ // It is required because background-position-x/y are non-standard properties and WebKit generated output
+ // would not work in Firefox (<rdar://problem/5143183>)
+ // It would be a better solution if background-position was CSS_PAIR.
+ if (positionXProp && positionYProp && positionXProp->isImportant() == positionYProp->isImportant()) {
+ String positionValue;
+ const int properties[2] = { CSS_PROP_BACKGROUND_POSITION_X, CSS_PROP_BACKGROUND_POSITION_Y };
+ if (positionXProp->value()->isValueList() || positionYProp->value()->isValueList())
+ positionValue = getLayeredShorthandValue(properties, 2);
+ else
+ positionValue = positionXProp->value()->cssText() + " " + positionYProp->value()->cssText();
+ result += "background-position: " + positionValue + (positionXProp->isImportant() ? " !important" : "") + "; ";
+ } else {
+ if (positionXProp)
+ result += positionXProp->cssText();
+ if (positionYProp)
+ result += positionYProp->cssText();
+ }
+
+ return result;
+}
+
+void CSSMutableStyleDeclaration::setCssText(const String& text, ExceptionCode& ec)
+{
+ ec = 0;
+ m_values.clear();
+ CSSParser parser(useStrictParsing());
+ parser.parseDeclaration(this, text);
+ // FIXME: Detect syntax errors and set ec.
+ setChanged();
+}
+
+void CSSMutableStyleDeclaration::merge(CSSMutableStyleDeclaration* other, bool argOverridesOnConflict)
+{
+ DeprecatedValueListConstIterator<CSSProperty> end;
+ for (DeprecatedValueListConstIterator<CSSProperty> it = other->valuesIterator(); it != end; ++it) {
+ const CSSProperty& property = *it;
+ RefPtr<CSSValue> value = getPropertyCSSValue(property.id());
+ if (value) {
+ if (!argOverridesOnConflict)
+ continue;
+ removeProperty(property.id());
+ }
+ m_values.append(property);
+ }
+ // FIXME: This probably should have a call to setChanged() if something changed. We may also wish to add
+ // a notifyChanged argument to this function to follow the model of other functions in this class.
+}
+
+// This is the list of properties we want to copy in the copyBlockProperties() function.
+// It is the list of CSS properties that apply specially to block-level elements.
+static const int blockProperties[] = {
+ CSS_PROP_ORPHANS,
+ CSS_PROP_OVERFLOW, // This can be also be applied to replaced elements
+ CSS_PROP__WEBKIT_COLUMN_COUNT,
+ CSS_PROP__WEBKIT_COLUMN_GAP,
+ CSS_PROP__WEBKIT_COLUMN_RULE_COLOR,
+ CSS_PROP__WEBKIT_COLUMN_RULE_STYLE,
+ CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH,
+ CSS_PROP__WEBKIT_COLUMN_BREAK_BEFORE,
+ CSS_PROP__WEBKIT_COLUMN_BREAK_AFTER,
+ CSS_PROP__WEBKIT_COLUMN_BREAK_INSIDE,
+ CSS_PROP__WEBKIT_COLUMN_WIDTH,
+ CSS_PROP_PAGE_BREAK_AFTER,
+ CSS_PROP_PAGE_BREAK_BEFORE,
+ CSS_PROP_PAGE_BREAK_INSIDE,
+ CSS_PROP_TEXT_ALIGN,
+ CSS_PROP_TEXT_INDENT,
+ CSS_PROP_WIDOWS
+};
+
+const unsigned numBlockProperties = sizeof(blockProperties) / sizeof(blockProperties[0]);
+
+PassRefPtr<CSSMutableStyleDeclaration> CSSMutableStyleDeclaration::copyBlockProperties() const
+{
+ return copyPropertiesInSet(blockProperties, numBlockProperties);
+}
+
+void CSSMutableStyleDeclaration::removeBlockProperties()
+{
+ removePropertiesInSet(blockProperties, numBlockProperties);
+}
+
+void CSSMutableStyleDeclaration::removePropertiesInSet(const int* set, unsigned length, bool notifyChanged)
+{
+ bool changed = false;
+ for (unsigned i = 0; i < length; i++) {
+ RefPtr<CSSValue> value = getPropertyCSSValue(set[i]);
+ if (value) {
+ m_values.remove(CSSProperty(set[i], value.release(), false));
+ changed = true;
+ }
+ }
+ if (changed && notifyChanged)
+ setChanged();
+}
+
+PassRefPtr<CSSMutableStyleDeclaration> CSSMutableStyleDeclaration::makeMutable()
+{
+ return this;
+}
+
+PassRefPtr<CSSMutableStyleDeclaration> CSSMutableStyleDeclaration::copy() const
+{
+ return new CSSMutableStyleDeclaration(0, m_values);
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSMutableStyleDeclaration.h b/WebCore/css/CSSMutableStyleDeclaration.h
new file mode 100644
index 0000000..b193d8d
--- /dev/null
+++ b/WebCore/css/CSSMutableStyleDeclaration.h
@@ -0,0 +1,116 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 CSSMutableStyleDeclaration_h
+#define CSSMutableStyleDeclaration_h
+
+#include "CSSStyleDeclaration.h"
+#include "CSSPrimitiveValue.h"
+#include "DeprecatedValueList.h"
+#include "Node.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class CSSProperty;
+class Node;
+
+class CSSMutableStyleDeclaration : public CSSStyleDeclaration {
+public:
+ CSSMutableStyleDeclaration();
+ CSSMutableStyleDeclaration(CSSRule* parentRule);
+ CSSMutableStyleDeclaration(CSSRule* parentRule, const DeprecatedValueList<CSSProperty>&);
+ CSSMutableStyleDeclaration(CSSRule* parentRule, const CSSProperty* const *, int numProperties);
+
+ CSSMutableStyleDeclaration& operator=(const CSSMutableStyleDeclaration&);
+
+ void setNode(Node* node) { m_node = node; }
+
+ virtual String cssText() const;
+ virtual void setCssText(const String&, ExceptionCode&);
+
+ virtual unsigned length() 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;
+ virtual bool isPropertyImplicit(int propertyID) const;
+
+ virtual void setProperty(int propertyId, const String& value, bool important, ExceptionCode&);
+ virtual String removeProperty(int propertyID, ExceptionCode&);
+
+ virtual PassRefPtr<CSSMutableStyleDeclaration> copy() const;
+ virtual PassRefPtr<CSSMutableStyleDeclaration> makeMutable();
+
+ DeprecatedValueListConstIterator<CSSProperty> valuesIterator() const { return m_values.begin(); }
+
+ bool setProperty(int propertyID, int value, bool important = false, bool notifyChanged = true);
+ bool setProperty(int propertyID, const String& value, bool important, bool notifyChanged, ExceptionCode&);
+ bool setProperty(int propertyId, const String& value, bool important = false, bool notifyChanged = true)
+ {
+ ExceptionCode ec;
+ return setProperty(propertyId, value, important, notifyChanged, ec);
+ }
+
+ String removeProperty(int propertyID, bool notifyChanged, bool returnText, ExceptionCode&);
+ void removeProperty(int propertyID, bool notifyChanged = true)
+ {
+ ExceptionCode ec;
+ removeProperty(propertyID, notifyChanged, false, ec);
+ }
+
+ void clear();
+
+ void setChanged(StyleChangeType changeType = FullStyleChange);
+
+ // setLengthProperty treats integers as pixels! (Needed for conversion of HTML attributes.)
+ void setLengthProperty(int propertyId, const String& value, bool important, bool multiLength = false);
+ void setStringProperty(int propertyId, const String& value, CSSPrimitiveValue::UnitTypes, bool important = false); // parsed string value
+ void setImageProperty(int propertyId, const String& url, bool important = false);
+
+ // The following parses an entire new style declaration.
+ void parseDeclaration(const String& styleDeclaration);
+
+ // Besides adding the properties, this also removes any existing properties with these IDs.
+ // It does no notification since it's called by the parser.
+ void addParsedProperties(const CSSProperty* const *, int numProperties);
+
+ PassRefPtr<CSSMutableStyleDeclaration> copyBlockProperties() const;
+ void removeBlockProperties();
+ void removePropertiesInSet(const int* set, unsigned length, bool notifyChanged = true);
+
+ void merge(CSSMutableStyleDeclaration*, bool argOverridesOnConflict = true);
+
+private:
+ String getShorthandValue(const int* properties, int number) const;
+ String getLayeredShorthandValue(const int* properties, unsigned number) const;
+ String get4Values(const int* properties) const;
+
+ DeprecatedValueList<CSSProperty> m_values;
+ Node* m_node;
+};
+
+} // namespace WebCore
+
+#endif // CSSMutableStyleDeclaration_h
diff --git a/WebCore/css/CSSNamespace.h b/WebCore/css/CSSNamespace.h
new file mode 100644
index 0000000..9194be8
--- /dev/null
+++ b/WebCore/css/CSSNamespace.h
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the CSS implementation for KDE.
+ *
+ * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * 1999 Waldo Bastian (bastian@kde.org)
+ * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ *
+ * 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 CSSNamespace_h
+#define CSSNamespace_h
+
+#include "AtomicString.h"
+
+namespace WebCore {
+
+ struct CSSNamespace {
+ AtomicString m_prefix;
+ AtomicString m_uri;
+ CSSNamespace* m_parent;
+
+ CSSNamespace(const AtomicString& prefix, const AtomicString& uri, CSSNamespace* parent)
+ : m_prefix(prefix)
+ , m_uri(uri)
+ , m_parent(parent)
+ {
+ }
+ ~CSSNamespace() { delete m_parent; }
+
+ const AtomicString& uri() { return m_uri; }
+ const AtomicString& prefix() { return m_prefix; }
+
+ CSSNamespace* namespaceForPrefix(const AtomicString& prefix)
+ {
+ if (prefix == m_prefix)
+ return this;
+ if (m_parent)
+ return m_parent->namespaceForPrefix(prefix);
+ return 0;
+ }
+ };
+
+} // namespace WebCore
+
+#endif // CSSNamespace_h
diff --git a/WebCore/css/CSSPageRule.cpp b/WebCore/css/CSSPageRule.cpp
new file mode 100644
index 0000000..4e95473
--- /dev/null
+++ b/WebCore/css/CSSPageRule.cpp
@@ -0,0 +1,57 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 "CSSPageRule.h"
+
+#include "CSSMutableStyleDeclaration.h"
+
+namespace WebCore {
+
+CSSPageRule::CSSPageRule(StyleBase* parent)
+ : CSSRule(parent)
+{
+}
+
+CSSPageRule::~CSSPageRule()
+{
+}
+
+String CSSPageRule::selectorText() const
+{
+ // FIXME: Implement!
+ return String();
+}
+
+void CSSPageRule::setSelectorText(const String& /*selectorText*/, ExceptionCode& /*ec*/)
+{
+ // FIXME: Implement!
+}
+
+String CSSPageRule::cssText() const
+{
+ // FIXME: Implement!
+ return String();
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSPageRule.h b/WebCore/css/CSSPageRule.h
new file mode 100644
index 0000000..afa78c1
--- /dev/null
+++ b/WebCore/css/CSSPageRule.h
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2006 Apple Computer, Inc.
+ *
+ * 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 CSSPageRule_h
+#define CSSPageRule_h
+
+#include "CSSRule.h"
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSMutableStyleDeclaration;
+
+typedef int ExceptionCode;
+
+class CSSPageRule : public CSSRule {
+public:
+ CSSPageRule(StyleBase* parent);
+ virtual ~CSSPageRule();
+
+ virtual bool isPageRule() { return true; }
+
+ String selectorText() const;
+ void setSelectorText(const String&, ExceptionCode&);
+
+ CSSMutableStyleDeclaration* style() const { return m_style.get(); }
+
+ // Inherited from CSSRule
+ virtual unsigned short type() const { return PAGE_RULE; }
+
+ virtual String cssText() const;
+
+protected:
+ RefPtr<CSSMutableStyleDeclaration> m_style;
+};
+
+} // namespace WebCore
+
+#endif // CSSPageRule_h
diff --git a/WebCore/css/CSSPageRule.idl b/WebCore/css/CSSPageRule.idl
new file mode 100644
index 0000000..3ad570e
--- /dev/null
+++ b/WebCore/css/CSSPageRule.idl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [
+ GenerateConstructor,
+ InterfaceUUID=4e8d9d26-65ca-483f-a6d4-be1a25905056,
+ ImplementationUUID=d8e40379-8b0e-4dce-b1f8-636dcf055a5f
+ ] CSSPageRule : CSSRule {
+
+ attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString selectorText
+ setter raises(DOMException);
+
+ readonly attribute CSSStyleDeclaration style;
+
+ };
+
+}
diff --git a/WebCore/css/CSSParser.cpp b/WebCore/css/CSSParser.cpp
new file mode 100644
index 0000000..91c4c50
--- /dev/null
+++ b/WebCore/css/CSSParser.cpp
@@ -0,0 +1,4035 @@
+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
+ * Copyright (C) 2004, 2005, 2006, 2007, 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 "CSSParser.h"
+
+#include "CString.h"
+#include "CSSTimingFunctionValue.h"
+#include "CSSBorderImageValue.h"
+#include "CSSCharsetRule.h"
+#include "CSSCursorImageValue.h"
+#include "CSSHelper.h"
+#include "CSSImageValue.h"
+#include "CSSFontFaceRule.h"
+#include "CSSFontFaceSrcValue.h"
+#include "CSSImportRule.h"
+#include "CSSInheritedValue.h"
+#include "CSSInitialValue.h"
+#include "CSSMediaRule.h"
+#include "CSSMutableStyleDeclaration.h"
+#include "CSSPrimitiveValue.h"
+#include "CSSProperty.h"
+#include "CSSPropertyNames.h"
+#include "CSSQuirkPrimitiveValue.h"
+#include "CSSRuleList.h"
+#include "CSSSelector.h"
+#include "CSSStyleRule.h"
+#include "CSSStyleSheet.h"
+#include "CSSTransformValue.h"
+#include "CSSUnicodeRangeValue.h"
+#include "CSSValueKeywords.h"
+#include "CSSValueList.h"
+#include "Counter.h"
+#include "DashboardRegion.h"
+#include "Document.h"
+#include "FloatConversion.h"
+#include "FontFamilyValue.h"
+#include "FontValue.h"
+#include "MediaList.h"
+#include "MediaQueryExp.h"
+#include "Pair.h"
+#include "ShadowValue.h"
+#include <kjs/dtoa.h>
+
+#define YYDEBUG 0
+
+#if YYDEBUG > 0
+extern int cssyydebug;
+#endif
+
+extern int cssyyparse(void* parser);
+
+using namespace std;
+using namespace WTF;
+
+#include "CSSPropertyNames.c"
+#include "CSSValueKeywords.c"
+
+namespace WebCore {
+
+static bool equal(const ParseString& a, const char* b)
+{
+ for (int i = 0; i < a.length; ++i) {
+ if (!b[i])
+ return false;
+ if (a.characters[i] != b[i])
+ return false;
+ }
+ return !b[a.length];
+}
+
+static bool equalIgnoringCase(const ParseString& a, const char* b)
+{
+ for (int i = 0; i < a.length; ++i) {
+ if (!b[i])
+ return false;
+ ASSERT(!isASCIIUpper(b[i]));
+ if (toASCIILower(a.characters[i]) != b[i])
+ return false;
+ }
+ return !b[a.length];
+}
+
+static bool hasPrefix(const char* string, unsigned length, const char* prefix)
+{
+ for (unsigned i = 0; i < length; ++i) {
+ if (!prefix[i])
+ return true;
+ if (string[i] != prefix[i])
+ return false;
+ }
+ return false;
+}
+
+ValueList::~ValueList()
+{
+ size_t numValues = m_values.size();
+ for (size_t i = 0; i < numValues; i++)
+ if (m_values[i].unit == Value::Function)
+ delete m_values[i].function;
+}
+
+namespace {
+ class ShorthandScope {
+ public:
+ ShorthandScope(CSSParser* parser, int propId) : m_parser(parser)
+ {
+ if (!(m_parser->m_inParseShorthand++))
+ m_parser->m_currentShorthand = propId;
+ }
+ ~ShorthandScope()
+ {
+ if (!(--m_parser->m_inParseShorthand))
+ m_parser->m_currentShorthand = 0;
+ }
+
+ private:
+ CSSParser* m_parser;
+ };
+}
+
+CSSParser* CSSParser::currentParser = 0;
+
+CSSParser::CSSParser(bool strictParsing)
+ : m_floatingMediaQuery(0)
+ , m_floatingMediaQueryExp(0)
+ , m_floatingMediaQueryExpList(0)
+{
+#ifdef CSS_DEBUG
+ kdDebug(6080) << "CSSParser::CSSParser this=" << this << endl;
+#endif
+ strict = strictParsing;
+
+ parsedProperties = (CSSProperty **)fastMalloc(32 * sizeof(CSSProperty *));
+ numParsedProperties = 0;
+ maxParsedProperties = 32;
+
+ data = 0;
+ valueList = 0;
+ id = 0;
+ important = false;
+ m_inParseShorthand = 0;
+ m_currentShorthand = 0;
+ m_implicitShorthand = false;
+
+ defaultNamespace = starAtom;
+
+ yy_start = 1;
+
+#if YYDEBUG > 0
+ cssyydebug = 1;
+#endif
+}
+
+CSSParser::~CSSParser()
+{
+ clearProperties();
+ fastFree(parsedProperties);
+
+ delete valueList;
+
+ fastFree(data);
+
+ if (m_floatingMediaQueryExpList) {
+ deleteAllValues(*m_floatingMediaQueryExpList);
+ delete m_floatingMediaQueryExpList;
+ }
+ delete m_floatingMediaQueryExp;
+ delete m_floatingMediaQuery;
+ deleteAllValues(m_floatingSelectors);
+ deleteAllValues(m_floatingValueLists);
+ deleteAllValues(m_floatingFunctions);
+}
+
+void ParseString::lower()
+{
+ // FIXME: If we need Unicode lowercasing here, then we probably want the real kind
+ // that can potentially change the length of the string rather than the character
+ // by character kind. If we don't need Unicode lowercasing, it would be good to
+ // simplify this function.
+
+ if (charactersAreAllASCII(characters, length)) {
+ // Fast case for all-ASCII.
+ for (int i = 0; i < length; i++)
+ characters[i] = toASCIILower(characters[i]);
+ } else {
+ for (int i = 0; i < length; i++)
+ characters[i] = Unicode::toLower(characters[i]);
+ }
+}
+
+void CSSParser::setupParser(const char* prefix, const String& string, const char* suffix)
+{
+ int length = string.length() + strlen(prefix) + strlen(suffix) + 2;
+
+ if (data)
+ fastFree(data);
+
+ data = static_cast<UChar*>(fastMalloc(length * sizeof(UChar)));
+ for (unsigned i = 0; i < strlen(prefix); i++)
+ data[i] = prefix[i];
+
+ memcpy(data + 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++)
+ data[i] = suffix[i - start];
+
+ data[length - 1] = 0;
+ data[length - 2] = 0;
+
+ yy_hold_char = 0;
+ yyleng = 0;
+ yytext = yy_c_buf_p = data;
+ yy_hold_char = *yy_c_buf_p;
+}
+
+void CSSParser::parseSheet(CSSStyleSheet* sheet, const String& string)
+{
+ styleElement = sheet;
+ defaultNamespace = starAtom; // Reset the default namespace.
+
+ setupParser("", string, "");
+
+ CSSParser* old = currentParser;
+ currentParser = this;
+ cssyyparse(this);
+ currentParser = old;
+
+ rule = 0;
+}
+
+PassRefPtr<CSSRule> CSSParser::parseRule(CSSStyleSheet *sheet, const String &string)
+{
+ styleElement = sheet;
+
+ setupParser("@-webkit-rule{", string, "} ");
+
+ CSSParser* old = currentParser;
+ currentParser = this;
+ cssyyparse(this);
+ currentParser = old;
+
+ return rule.release();
+}
+
+bool CSSParser::parseValue(CSSMutableStyleDeclaration *declaration, int _id, const String &string, bool _important)
+{
+ styleElement = declaration->stylesheet();
+
+ setupParser("@-webkit-value{", string, "} ");
+
+ id = _id;
+ important = _important;
+
+ CSSParser* old = currentParser;
+ currentParser = this;
+ cssyyparse(this);
+ currentParser = old;
+
+ rule = 0;
+
+ bool ok = false;
+ if (numParsedProperties) {
+ ok = true;
+ declaration->addParsedProperties(parsedProperties, numParsedProperties);
+ clearProperties();
+ }
+
+ return ok;
+}
+
+// color will only be changed when string contains a valid css color, making it
+// possible to set up a default color.
+bool CSSParser::parseColor(RGBA32& color, const String &string, bool strict)
+{
+ color = 0;
+ CSSParser parser(true);
+
+ // First try creating a color specified by name or the "#" syntax.
+ if (!parser.parseColor(string, color, strict)) {
+ RefPtr<CSSMutableStyleDeclaration> dummyStyleDeclaration(new CSSMutableStyleDeclaration);
+
+ // Now try to create a color from the rgb() or rgba() syntax.
+ if (parser.parseColor(dummyStyleDeclaration.get(), string)) {
+ CSSValue* value = parser.parsedProperties[0]->value();
+ if (value->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) {
+ CSSPrimitiveValue *primitiveValue = static_cast<CSSPrimitiveValue *>(value);
+ color = primitiveValue->getRGBColorValue();
+ }
+ } else
+ return false;
+ }
+
+ return true;
+}
+
+bool CSSParser::parseColor(CSSMutableStyleDeclaration *declaration, const String &string)
+{
+ styleElement = declaration->stylesheet();
+
+ setupParser("@-webkit-decls{color:", string, "} ");
+
+ CSSParser* old = currentParser;
+ currentParser = this;
+ cssyyparse(this);
+ currentParser = old;
+
+ rule = 0;
+
+ bool ok = false;
+ if (numParsedProperties && parsedProperties[0]->m_id == CSS_PROP_COLOR)
+ ok = true;
+
+ return ok;
+}
+
+bool CSSParser::parseDeclaration(CSSMutableStyleDeclaration *declaration, const String &string)
+{
+ styleElement = declaration->stylesheet();
+
+ setupParser("@-webkit-decls{", string, "} ");
+
+ CSSParser* old = currentParser;
+ currentParser = this;
+ cssyyparse(this);
+ currentParser = old;
+
+ rule = 0;
+
+ bool ok = false;
+ if (numParsedProperties) {
+ ok = true;
+ declaration->addParsedProperties(parsedProperties, numParsedProperties);
+ clearProperties();
+ }
+
+ return ok;
+}
+
+bool CSSParser::parseMediaQuery(MediaList* queries, const String& string)
+{
+ if (string.isEmpty() || string.isNull()) {
+ return true;
+ }
+
+ mediaQuery = 0;
+ // can't use { because tokenizer state switches from mediaquery to initial state when it sees { token.
+ // instead insert one " " (which is WHITESPACE in CSSGrammar.y)
+ setupParser ("@-webkit-mediaquery ", string, "} ");
+
+ CSSParser* old = currentParser;
+ currentParser = this;
+ cssyyparse(this);
+ currentParser = old;
+
+ bool ok = false;
+ if (mediaQuery) {
+ ok = true;
+ queries->appendMediaQuery(mediaQuery);
+ mediaQuery = 0;
+ }
+
+ return ok;
+}
+
+
+void CSSParser::addProperty(int propId, PassRefPtr<CSSValue> value, bool important)
+{
+ CSSProperty *prop = new CSSProperty(propId, value, important, m_currentShorthand, m_implicitShorthand);
+ if (numParsedProperties >= maxParsedProperties) {
+ maxParsedProperties += 32;
+ parsedProperties = (CSSProperty **)fastRealloc(parsedProperties,
+ maxParsedProperties*sizeof(CSSProperty *));
+ }
+ parsedProperties[numParsedProperties++] = prop;
+}
+
+void CSSParser::rollbackLastProperties(int num)
+{
+ ASSERT(num >= 0);
+ ASSERT(numParsedProperties >= num);
+
+ for (int i = 0; i < num; ++i)
+ delete parsedProperties[--numParsedProperties];
+}
+
+void CSSParser::clearProperties()
+{
+ for (int i = 0; i < numParsedProperties; i++)
+ delete parsedProperties[i];
+ numParsedProperties = 0;
+}
+
+Document *CSSParser::document() const
+{
+ StyleBase *root = styleElement;
+ Document *doc = 0;
+ while (root->parent())
+ root = root->parent();
+ if (root->isCSSStyleSheet())
+ doc = static_cast<CSSStyleSheet*>(root)->doc();
+ return doc;
+}
+
+bool CSSParser::validUnit(Value* value, Units unitflags, bool strict)
+{
+ if (unitflags & FNonNeg && value->fValue < 0)
+ return false;
+
+ bool b = false;
+ switch(value->unit) {
+ case CSSPrimitiveValue::CSS_NUMBER:
+ b = (unitflags & FNumber);
+ if (!b && ((unitflags & (FLength | FAngle)) && (value->fValue == 0 || !strict))) {
+ value->unit = (unitflags & FLength) ? CSSPrimitiveValue::CSS_PX : CSSPrimitiveValue::CSS_DEG;
+ b = true;
+ }
+ if (!b && (unitflags & FInteger) && value->isInt)
+ b = true;
+ break;
+ case CSSPrimitiveValue::CSS_PERCENTAGE:
+ b = (unitflags & FPercent);
+ break;
+ case Value::Q_EMS:
+ 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:
+ b = (unitflags & FLength);
+ break;
+ case CSSPrimitiveValue::CSS_MS:
+ case CSSPrimitiveValue::CSS_S:
+ b = (unitflags & FTime);
+ break;
+ case CSSPrimitiveValue::CSS_DEG:
+ case CSSPrimitiveValue::CSS_RAD:
+ case CSSPrimitiveValue::CSS_GRAD:
+ b = (unitflags & FAngle);
+ break;
+ case CSSPrimitiveValue::CSS_HZ:
+ case CSSPrimitiveValue::CSS_KHZ:
+ case CSSPrimitiveValue::CSS_DIMENSION:
+ default:
+ break;
+ }
+ return b;
+}
+
+static int unitFromString(Value* value)
+{
+ if (value->unit != CSSPrimitiveValue::CSS_IDENT || value->id)
+ return 0;
+
+ if (equal(value->string, "em"))
+ return CSSPrimitiveValue::CSS_EMS;
+ if (equal(value->string, "ex"))
+ return CSSPrimitiveValue::CSS_EXS;
+ if (equal(value->string, "px"))
+ return CSSPrimitiveValue::CSS_PX;
+ if (equal(value->string, "cm"))
+ return CSSPrimitiveValue::CSS_CM;
+ if (equal(value->string, "mm"))
+ return CSSPrimitiveValue::CSS_MM;
+ if (equal(value->string, "in"))
+ return CSSPrimitiveValue::CSS_IN;
+ if (equal(value->string, "pt"))
+ return CSSPrimitiveValue::CSS_PT;
+ if (equal(value->string, "pc"))
+ return CSSPrimitiveValue::CSS_PC;
+ if (equal(value->string, "deg"))
+ return CSSPrimitiveValue::CSS_DEG;
+ if (equal(value->string, "rad"))
+ return CSSPrimitiveValue::CSS_RAD;
+ if (equal(value->string, "grad"))
+ return CSSPrimitiveValue::CSS_GRAD;
+ if (equal(value->string, "ms"))
+ return CSSPrimitiveValue::CSS_MS;
+ if (equal(value->string, "s"))
+ return CSSPrimitiveValue::CSS_S;
+ if (equal(value->string, "Hz"))
+ return CSSPrimitiveValue::CSS_HZ;
+ if (equal(value->string, "kHz"))
+ return CSSPrimitiveValue::CSS_KHZ;
+
+ return 0;
+}
+
+void CSSParser::checkForOrphanedUnits()
+{
+ if (strict || inShorthand())
+ return;
+
+ // The purpose of this code is to implement the WinIE quirk that allows unit types to be separated from their numeric values
+ // by whitespace, so e.g., width: 20 px instead of width:20px. This is invalid CSS, so we don't do this in strict mode.
+ Value* numericVal = 0;
+ unsigned size = valueList->size();
+ for (unsigned i = 0; i < size; i++) {
+ Value* value = valueList->valueAt(i);
+ if (numericVal) {
+ // Change the unit type of the numeric val to match.
+ int unit = unitFromString(value);
+ if (unit) {
+ numericVal->unit = unit;
+ numericVal = 0;
+
+ // Now delete the bogus unit value.
+ valueList->deleteValueAt(i);
+ i--; // We're safe even though |i| is unsigned, since we only hit this code if we had a previous numeric value (so |i| is always > 0 here).
+ size--;
+ continue;
+ }
+ }
+
+ numericVal = (value->unit == CSSPrimitiveValue::CSS_NUMBER) ? value : 0;
+ }
+}
+
+bool CSSParser::parseValue(int propId, bool important)
+{
+ if (!valueList)
+ return false;
+
+ Value *value = valueList->current();
+
+ if (!value)
+ return false;
+
+ int id = value->id;
+
+ int num = inShorthand() ? 1 : valueList->size();
+
+ if (id == CSS_VAL_INHERIT) {
+ if (num != 1)
+ return false;
+ addProperty(propId, new CSSInheritedValue(), important);
+ return true;
+ }
+ else if (id == CSS_VAL_INITIAL) {
+ if (num != 1)
+ return false;
+ addProperty(propId, new CSSInitialValue(false), important);
+ return true;
+ }
+
+ bool valid_primitive = false;
+ RefPtr<CSSValue> parsedValue;
+
+ // In quirks mode, we will look for units that have been incorrectly separated from the number they belong to
+ // by a space. We go ahead and associate the unit with the number even though it is invalid CSS.
+ checkForOrphanedUnits();
+
+ switch (static_cast<CSSPropertyID>(propId)) {
+ /* The comment to the left defines all valid value of this properties as defined
+ * in CSS 2, Appendix F. Property index
+ */
+
+ /* All the CSS properties are not supported by the renderer at the moment.
+ * Note that all the CSS2 Aural properties are only checked, if CSS_AURAL is defined
+ * (see parseAuralValues). As we don't support them at all this seems reasonable.
+ */
+
+ case CSS_PROP_SIZE: // <length>{1,2} | auto | portrait | landscape | inherit
+ case CSS_PROP_QUOTES: // [<string> <string>]+ | none | inherit
+ if (id)
+ valid_primitive = true;
+ break;
+ case CSS_PROP_UNICODE_BIDI: // normal | embed | bidi-override | inherit
+ if (id == CSS_VAL_NORMAL ||
+ id == CSS_VAL_EMBED ||
+ id == CSS_VAL_BIDI_OVERRIDE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_POSITION: // static | relative | absolute | fixed | inherit
+ if (id == CSS_VAL_STATIC ||
+ id == CSS_VAL_RELATIVE ||
+ id == CSS_VAL_ABSOLUTE ||
+ id == CSS_VAL_FIXED)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_PAGE_BREAK_AFTER: // auto | always | avoid | left | right | inherit
+ case CSS_PROP_PAGE_BREAK_BEFORE:
+ case CSS_PROP__WEBKIT_COLUMN_BREAK_AFTER:
+ case CSS_PROP__WEBKIT_COLUMN_BREAK_BEFORE:
+ if (id == CSS_VAL_AUTO ||
+ id == CSS_VAL_ALWAYS ||
+ id == CSS_VAL_AVOID ||
+ id == CSS_VAL_LEFT ||
+ id == CSS_VAL_RIGHT)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_PAGE_BREAK_INSIDE: // avoid | auto | inherit
+ case CSS_PROP__WEBKIT_COLUMN_BREAK_INSIDE:
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_AVOID)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_EMPTY_CELLS: // show | hide | inherit
+ if (id == CSS_VAL_SHOW ||
+ id == CSS_VAL_HIDE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_CONTENT: // [ <string> | <uri> | <counter> | attr(X) | open-quote |
+ // close-quote | no-open-quote | no-close-quote ]+ | inherit
+ return parseContent(propId, important);
+ break;
+
+ case CSS_PROP_WHITE_SPACE: // normal | pre | nowrap | inherit
+ if (id == CSS_VAL_NORMAL ||
+ id == CSS_VAL_PRE ||
+ id == CSS_VAL_PRE_WRAP ||
+ id == CSS_VAL_PRE_LINE ||
+ id == CSS_VAL_NOWRAP)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_CLIP: // <shape> | auto | inherit
+ if (id == CSS_VAL_AUTO)
+ valid_primitive = true;
+ else if (value->unit == Value::Function)
+ return parseShape(propId, important);
+ break;
+
+ /* Start of supported CSS properties with validation. This is needed for parseShorthand to work
+ * correctly and allows optimization in WebCore::applyRule(..)
+ */
+ case CSS_PROP_CAPTION_SIDE: // top | bottom | left | right | inherit
+ if (id == CSS_VAL_LEFT || id == CSS_VAL_RIGHT ||
+ id == CSS_VAL_TOP || id == CSS_VAL_BOTTOM)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_BORDER_COLLAPSE: // collapse | separate | inherit
+ if (id == CSS_VAL_COLLAPSE || id == CSS_VAL_SEPARATE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_VISIBILITY: // visible | hidden | collapse | inherit
+ if (id == CSS_VAL_VISIBLE || id == CSS_VAL_HIDDEN || id == CSS_VAL_COLLAPSE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_OVERFLOW: {
+ ShorthandScope scope(this, propId);
+ if (num != 1 || !parseValue(CSS_PROP_OVERFLOW_X, important))
+ return false;
+ CSSValue* value = parsedProperties[numParsedProperties - 1]->value();
+ addProperty(CSS_PROP_OVERFLOW_Y, value, important);
+ return true;
+ }
+ case CSS_PROP_OVERFLOW_X:
+ case CSS_PROP_OVERFLOW_Y: // visible | hidden | scroll | auto | marquee | overlay | inherit
+ if (id == CSS_VAL_VISIBLE || id == CSS_VAL_HIDDEN || id == CSS_VAL_SCROLL || id == CSS_VAL_AUTO ||
+ id == CSS_VAL_OVERLAY || id == CSS_VAL__WEBKIT_MARQUEE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_LIST_STYLE_POSITION: // inside | outside | inherit
+ if (id == CSS_VAL_INSIDE || id == CSS_VAL_OUTSIDE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_LIST_STYLE_TYPE:
+ // disc | circle | square | decimal | decimal-leading-zero | lower-roman |
+ // upper-roman | lower-greek | lower-alpha | lower-latin | upper-alpha |
+ // upper-latin | hebrew | armenian | georgian | cjk-ideographic | hiragana |
+ // katakana | hiragana-iroha | katakana-iroha | none | inherit
+ if ((id >= CSS_VAL_DISC && id <= CSS_VAL_KATAKANA_IROHA) || id == CSS_VAL_NONE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_DISPLAY:
+ // inline | block | list-item | run-in | inline-block | table |
+ // inline-table | table-row-group | table-header-group | table-footer-group | table-row |
+ // table-column-group | table-column | table-cell | table-caption | box | inline-box | none | inherit
+ if ((id >= CSS_VAL_INLINE && id <= CSS_VAL__WEBKIT_INLINE_BOX) || id == CSS_VAL_NONE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_DIRECTION: // ltr | rtl | inherit
+ if (id == CSS_VAL_LTR || id == CSS_VAL_RTL)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_TEXT_TRANSFORM: // capitalize | uppercase | lowercase | none | inherit
+ if ((id >= CSS_VAL_CAPITALIZE && id <= CSS_VAL_LOWERCASE) || id == CSS_VAL_NONE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_FLOAT: // left | right | none | inherit + center for buggy CSS
+ if (id == CSS_VAL_LEFT || id == CSS_VAL_RIGHT ||
+ id == CSS_VAL_NONE || id == CSS_VAL_CENTER)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_CLEAR: // none | left | right | both | inherit
+ if (id == CSS_VAL_NONE || id == CSS_VAL_LEFT ||
+ id == CSS_VAL_RIGHT|| id == CSS_VAL_BOTH)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_TEXT_ALIGN:
+ // left | right | center | justify | webkit_left | webkit_right | webkit_center | start | end | <string> | inherit
+ if ((id >= CSS_VAL__WEBKIT_AUTO && id <= CSS_VAL__WEBKIT_CENTER) || id == CSS_VAL_START || id == CSS_VAL_END ||
+ value->unit == CSSPrimitiveValue::CSS_STRING)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_OUTLINE_STYLE: // <border-style> | auto | inherit
+ if (id == CSS_VAL_AUTO) {
+ valid_primitive = true;
+ break;
+ } // Fall through!
+ case CSS_PROP_BORDER_TOP_STYLE: //// <border-style> | inherit
+ case CSS_PROP_BORDER_RIGHT_STYLE: // Defined as: none | hidden | dotted | dashed |
+ case CSS_PROP_BORDER_BOTTOM_STYLE: // solid | double | groove | ridge | inset | outset
+ case CSS_PROP_BORDER_LEFT_STYLE:
+ case CSS_PROP__WEBKIT_COLUMN_RULE_STYLE:
+ if (id >= CSS_VAL_NONE && id <= CSS_VAL_DOUBLE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_FONT_WEIGHT: // normal | bold | bolder | lighter | 100 | 200 | 300 | 400 |
+ // 500 | 600 | 700 | 800 | 900 | inherit
+ if (id >= CSS_VAL_NORMAL && id <= CSS_VAL_900) {
+ // Allready correct id
+ valid_primitive = true;
+ } else if (validUnit(value, FInteger|FNonNeg, false)) {
+ int weight = (int)value->fValue;
+ if ((weight % 100))
+ break;
+ weight /= 100;
+ if (weight >= 1 && weight <= 9) {
+ id = CSS_VAL_100 + weight - 1;
+ valid_primitive = true;
+ }
+ }
+ break;
+
+ case CSS_PROP_BORDER_SPACING: {
+ const int properties[2] = { CSS_PROP__WEBKIT_BORDER_HORIZONTAL_SPACING,
+ CSS_PROP__WEBKIT_BORDER_VERTICAL_SPACING };
+ if (num == 1) {
+ ShorthandScope scope(this, CSS_PROP_BORDER_SPACING);
+ if (!parseValue(properties[0], important))
+ return false;
+ CSSValue* value = parsedProperties[numParsedProperties-1]->value();
+ addProperty(properties[1], value, important);
+ return true;
+ }
+ else if (num == 2) {
+ ShorthandScope scope(this, CSS_PROP_BORDER_SPACING);
+ if (!parseValue(properties[0], important) || !parseValue(properties[1], important))
+ return false;
+ return true;
+ }
+ return false;
+ }
+ case CSS_PROP__WEBKIT_BORDER_HORIZONTAL_SPACING:
+ case CSS_PROP__WEBKIT_BORDER_VERTICAL_SPACING:
+ valid_primitive = validUnit(value, FLength|FNonNeg, strict);
+ break;
+ case CSS_PROP_SCROLLBAR_FACE_COLOR: // IE5.5
+ case CSS_PROP_SCROLLBAR_SHADOW_COLOR: // IE5.5
+ case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR: // IE5.5
+ case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR: // IE5.5
+ case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR: // IE5.5
+ case CSS_PROP_SCROLLBAR_TRACK_COLOR: // IE5.5
+ case CSS_PROP_SCROLLBAR_ARROW_COLOR: // IE5.5
+ if (strict)
+ break;
+ /* nobreak */
+ case CSS_PROP_OUTLINE_COLOR: // <color> | invert | inherit
+ // Outline color has "invert" as additional keyword.
+ // Also, we want to allow the special focus color even in strict parsing mode.
+ if (propId == CSS_PROP_OUTLINE_COLOR && (id == CSS_VAL_INVERT || id == CSS_VAL__WEBKIT_FOCUS_RING_COLOR)) {
+ valid_primitive = true;
+ break;
+ }
+ /* nobreak */
+ case CSS_PROP_BACKGROUND_COLOR: // <color> | inherit
+ case CSS_PROP_BORDER_TOP_COLOR: // <color> | inherit
+ case CSS_PROP_BORDER_RIGHT_COLOR: // <color> | inherit
+ case CSS_PROP_BORDER_BOTTOM_COLOR: // <color> | inherit
+ case CSS_PROP_BORDER_LEFT_COLOR: // <color> | inherit
+ case CSS_PROP_COLOR: // <color> | inherit
+ case CSS_PROP_TEXT_LINE_THROUGH_COLOR: // CSS3 text decoration colors
+ case CSS_PROP_TEXT_UNDERLINE_COLOR:
+ case CSS_PROP_TEXT_OVERLINE_COLOR:
+ case CSS_PROP__WEBKIT_COLUMN_RULE_COLOR:
+ case CSS_PROP__WEBKIT_TEXT_FILL_COLOR:
+ case CSS_PROP__WEBKIT_TEXT_STROKE_COLOR:
+ if (id == CSS_VAL__WEBKIT_TEXT)
+ valid_primitive = true; // Always allow this, even when strict parsing is on,
+ // since we use this in our UA sheets.
+ else if (id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT || id == CSS_VAL_MENU ||
+ (id >= CSS_VAL__WEBKIT_FOCUS_RING_COLOR && id < CSS_VAL__WEBKIT_TEXT && !strict)) {
+ valid_primitive = true;
+ } else {
+ parsedValue = parseColor();
+ if (parsedValue)
+ valueList->next();
+ }
+ break;
+
+ case CSS_PROP_CURSOR: {
+ // [<uri>,]* [ auto | crosshair | default | pointer | progress | move | e-resize | ne-resize |
+ // nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize | ew-resize |
+ // ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | text | wait | help ] ] | inherit
+ RefPtr<CSSValueList> list;
+ while (value && value->unit == CSSPrimitiveValue::CSS_URI) {
+ if (!list)
+ list = new CSSValueList;
+ String uri = parseURL(value->string);
+ Vector<int> coords;
+ value = valueList->next();
+ while (value && value->unit == CSSPrimitiveValue::CSS_NUMBER) {
+ coords.append(int(value->fValue));
+ value = valueList->next();
+ }
+ IntPoint hotspot;
+ int nrcoords = coords.size();
+ if (nrcoords > 0 && nrcoords != 2) {
+ if (strict) // only support hotspot pairs in strict mode
+ return false;
+ } else if(strict && nrcoords == 2)
+ hotspot = IntPoint(coords[0], coords[1]);
+ if (strict || coords.size() == 0) {
+ if (!uri.isEmpty()) {
+ list->append(new CSSCursorImageValue(KURL(styleElement->baseURL(), uri).string(),
+ hotspot, styleElement));
+ }
+ }
+ if ((strict && !value) || (value && !(value->unit == Value::Operator && value->iValue == ',')))
+ return false;
+ value = valueList->next(); // comma
+ }
+ if (list) {
+ if (!value) { // no value after url list (MSIE 5 compatibility)
+ if (list->length() != 1)
+ return false;
+ } else if (!strict && value->id == CSS_VAL_HAND) // MSIE 5 compatibility :/
+ list->append(new CSSPrimitiveValue(CSS_VAL_POINTER));
+ else if (value && ((value->id >= CSS_VAL_AUTO && value->id <= CSS_VAL_ALL_SCROLL) || value->id == CSS_VAL_COPY || value->id == CSS_VAL_NONE))
+ list->append(new CSSPrimitiveValue(value->id));
+ valueList->next();
+ parsedValue = list.release();
+ break;
+ }
+ id = value->id;
+ if (!strict && value->id == CSS_VAL_HAND) { // MSIE 5 compatibility :/
+ id = CSS_VAL_POINTER;
+ valid_primitive = true;
+ } else if ((value->id >= CSS_VAL_AUTO && value->id <= CSS_VAL_ALL_SCROLL) || value->id == CSS_VAL_COPY || value->id == CSS_VAL_NONE)
+ valid_primitive = true;
+ break;
+ }
+
+ case CSS_PROP_BACKGROUND_ATTACHMENT:
+ case CSS_PROP__WEBKIT_BACKGROUND_CLIP:
+ case CSS_PROP__WEBKIT_BACKGROUND_COMPOSITE:
+ case CSS_PROP_BACKGROUND_IMAGE:
+ case CSS_PROP__WEBKIT_BACKGROUND_ORIGIN:
+ case CSS_PROP_BACKGROUND_POSITION:
+ case CSS_PROP_BACKGROUND_POSITION_X:
+ case CSS_PROP_BACKGROUND_POSITION_Y:
+ case CSS_PROP__WEBKIT_BACKGROUND_SIZE:
+ case CSS_PROP_BACKGROUND_REPEAT: {
+ RefPtr<CSSValue> val1;
+ RefPtr<CSSValue> val2;
+ int propId1, propId2;
+ if (parseBackgroundProperty(propId, propId1, propId2, val1, val2)) {
+ addProperty(propId1, val1.release(), important);
+ if (val2)
+ addProperty(propId2, val2.release(), important);
+ return true;
+ }
+ return false;
+ }
+ case CSS_PROP_LIST_STYLE_IMAGE: // <uri> | none | inherit
+ if (id == CSS_VAL_NONE) {
+ parsedValue = new CSSImageValue();
+ valueList->next();
+ }
+ else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ // ### allow string in non strict mode?
+ String uri = parseURL(value->string);
+ if (!uri.isEmpty()) {
+ parsedValue = new CSSImageValue(KURL(styleElement->baseURL(), uri).string(), styleElement);
+ valueList->next();
+ }
+ }
+ break;
+
+ case CSS_PROP__WEBKIT_TEXT_STROKE_WIDTH:
+ case CSS_PROP_OUTLINE_WIDTH: // <border-width> | inherit
+ case CSS_PROP_BORDER_TOP_WIDTH: //// <border-width> | inherit
+ case CSS_PROP_BORDER_RIGHT_WIDTH: // Which is defined as
+ case CSS_PROP_BORDER_BOTTOM_WIDTH: // thin | medium | thick | <length>
+ case CSS_PROP_BORDER_LEFT_WIDTH:
+ case CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH:
+ if (id == CSS_VAL_THIN || id == CSS_VAL_MEDIUM || id == CSS_VAL_THICK)
+ valid_primitive = true;
+ else
+ valid_primitive = validUnit(value, FLength, strict);
+ break;
+
+ case CSS_PROP_LETTER_SPACING: // normal | <length> | inherit
+ case CSS_PROP_WORD_SPACING: // normal | <length> | inherit
+ if (id == CSS_VAL_NORMAL)
+ valid_primitive = true;
+ else
+ valid_primitive = validUnit(value, FLength, strict);
+ break;
+
+ case CSS_PROP_WORD_BREAK: // normal | break-all | break-word (this is a custom extension)
+ if (id == CSS_VAL_NORMAL || id == CSS_VAL_BREAK_ALL || id == CSS_VAL_BREAK_WORD)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_WORD_WRAP: // normal | break-word
+ if (id == CSS_VAL_NORMAL || id == CSS_VAL_BREAK_WORD)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_TEXT_INDENT: // <length> | <percentage> | inherit
+ case CSS_PROP_PADDING_TOP: //// <padding-width> | inherit
+ case CSS_PROP_PADDING_RIGHT: // Which is defined as
+ case CSS_PROP_PADDING_BOTTOM: // <length> | <percentage>
+ case CSS_PROP_PADDING_LEFT: ////
+ case CSS_PROP__WEBKIT_PADDING_START:
+ valid_primitive = (!id && validUnit(value, FLength|FPercent, strict));
+ break;
+
+ case CSS_PROP_MAX_HEIGHT: // <length> | <percentage> | none | inherit
+ case CSS_PROP_MAX_WIDTH: // <length> | <percentage> | none | inherit
+ if (id == CSS_VAL_NONE || id == CSS_VAL_INTRINSIC || id == CSS_VAL_MIN_INTRINSIC) {
+ valid_primitive = true;
+ break;
+ }
+ /* nobreak */
+ case CSS_PROP_MIN_HEIGHT: // <length> | <percentage> | inherit
+ case CSS_PROP_MIN_WIDTH: // <length> | <percentage> | inherit
+ if (id == CSS_VAL_INTRINSIC || id == CSS_VAL_MIN_INTRINSIC)
+ valid_primitive = true;
+ else
+ valid_primitive = (!id && validUnit(value, FLength|FPercent|FNonNeg, strict));
+ break;
+
+ case CSS_PROP_FONT_SIZE:
+ // <absolute-size> | <relative-size> | <length> | <percentage> | inherit
+ if (id >= CSS_VAL_XX_SMALL && id <= CSS_VAL_LARGER)
+ valid_primitive = true;
+ else
+ valid_primitive = (validUnit(value, FLength|FPercent, strict));
+ break;
+
+ case CSS_PROP_FONT_STYLE: // normal | italic | oblique | inherit
+ if (id == CSS_VAL_NORMAL || id == CSS_VAL_ITALIC || id == CSS_VAL_OBLIQUE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_FONT_VARIANT: // normal | small-caps | inherit
+ if (id == CSS_VAL_NORMAL || id == CSS_VAL_SMALL_CAPS)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_VERTICAL_ALIGN:
+ // baseline | sub | super | top | text-top | middle | bottom | text-bottom |
+ // <percentage> | <length> | inherit
+
+ if (id >= CSS_VAL_BASELINE && id <= CSS_VAL__WEBKIT_BASELINE_MIDDLE)
+ valid_primitive = true;
+ else
+ valid_primitive = (!id && validUnit(value, FLength|FPercent, strict));
+ break;
+
+ case CSS_PROP_HEIGHT: // <length> | <percentage> | auto | inherit
+ case CSS_PROP_WIDTH: // <length> | <percentage> | auto | inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_INTRINSIC || id == CSS_VAL_MIN_INTRINSIC)
+ valid_primitive = true;
+ else
+ // ### handle multilength case where we allow relative units
+ valid_primitive = (!id && validUnit(value, FLength|FPercent|FNonNeg, strict));
+ break;
+
+ case CSS_PROP_BOTTOM: // <length> | <percentage> | auto | inherit
+ case CSS_PROP_LEFT: // <length> | <percentage> | auto | inherit
+ case CSS_PROP_RIGHT: // <length> | <percentage> | auto | inherit
+ case CSS_PROP_TOP: // <length> | <percentage> | auto | inherit
+ case CSS_PROP_MARGIN_TOP: //// <margin-width> | inherit
+ case CSS_PROP_MARGIN_RIGHT: // Which is defined as
+ case CSS_PROP_MARGIN_BOTTOM: // <length> | <percentage> | auto | inherit
+ case CSS_PROP_MARGIN_LEFT: ////
+ case CSS_PROP__WEBKIT_MARGIN_START:
+ if (id == CSS_VAL_AUTO)
+ valid_primitive = true;
+ else
+ valid_primitive = (!id && validUnit(value, FLength|FPercent, strict));
+ break;
+
+ case CSS_PROP_Z_INDEX: // auto | <integer> | inherit
+ if (id == CSS_VAL_AUTO) {
+ valid_primitive = true;
+ break;
+ }
+ /* nobreak */
+ case CSS_PROP_ORPHANS: // <integer> | inherit
+ case CSS_PROP_WIDOWS: // <integer> | inherit
+ // ### not supported later on
+ valid_primitive = (!id && validUnit(value, FInteger, false));
+ break;
+
+ case CSS_PROP_LINE_HEIGHT: // normal | <number> | <length> | <percentage> | inherit
+ if (id == CSS_VAL_NORMAL)
+ valid_primitive = true;
+ else
+ valid_primitive = (!id && validUnit(value, FNumber|FLength|FPercent, strict));
+ break;
+ case CSS_PROP_COUNTER_INCREMENT: // [ <identifier> <integer>? ]+ | none | inherit
+ if (id != CSS_VAL_NONE)
+ return parseCounter(propId, 1, important);
+ valid_primitive = true;
+ break;
+ case CSS_PROP_COUNTER_RESET: // [ <identifier> <integer>? ]+ | none | inherit
+ if (id != CSS_VAL_NONE)
+ return parseCounter(propId, 0, important);
+ valid_primitive = true;
+ break;
+ case CSS_PROP_FONT_FAMILY:
+ // [[ <family-name> | <generic-family> ],]* [<family-name> | <generic-family>] | inherit
+ {
+ parsedValue = parseFontFamily();
+ break;
+ }
+
+ case CSS_PROP_TEXT_DECORATION:
+ case CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT:
+ // none | [ underline || overline || line-through || blink ] | inherit
+ if (id == CSS_VAL_NONE) {
+ valid_primitive = true;
+ } else {
+ RefPtr<CSSValueList> list(new CSSValueList);
+ bool is_valid = true;
+ while(is_valid && value) {
+ switch (value->id) {
+ case CSS_VAL_BLINK:
+ break;
+ case CSS_VAL_UNDERLINE:
+ case CSS_VAL_OVERLINE:
+ case CSS_VAL_LINE_THROUGH:
+ list->append(new CSSPrimitiveValue(value->id));
+ break;
+ default:
+ is_valid = false;
+ }
+ value = valueList->next();
+ }
+ if (list->length() && is_valid) {
+ parsedValue = list.release();
+ valueList->next();
+ }
+ }
+ break;
+
+ case CSS_PROP_TABLE_LAYOUT: // auto | fixed | inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_FIXED)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_SRC: // Only used within @font-face, so cannot use inherit | initial or be !important. This is a list of urls or local references.
+ return parseFontFaceSrc();
+
+ case CSS_PROP_UNICODE_RANGE:
+ return parseFontFaceUnicodeRange();
+
+ /* CSS3 properties */
+ case CSS_PROP__WEBKIT_APPEARANCE:
+ if ((id >= CSS_VAL_CHECKBOX && id <= CSS_VAL_TEXTAREA) || id == CSS_VAL_NONE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP__WEBKIT_BINDING:
+#if ENABLE(XBL)
+ if (id == CSS_VAL_NONE)
+ valid_primitive = true;
+ else {
+ RefPtr<CSSValueList> values(new CSSValueList());
+ Value* val;
+ RefPtr<CSSValue> parsedValue;
+ while ((val = valueList->current())) {
+ if (val->unit == CSSPrimitiveValue::CSS_URI) {
+ String value = parseURL(val->string);
+ parsedValue = new CSSPrimitiveValue(KURL(styleElement->baseURL(), value).string(),
+ CSSPrimitiveValue::CSS_URI);
+ }
+ if (!parsedValue)
+ break;
+
+ // FIXME: We can't use release() here since we might hit this path twice
+ // but that logic seems wrong to me to begin with, we convert all non-uri values
+ // into the last seen URI value!?
+ // -webkit-binding: url(foo.xml), 1, 2; (if that were valid) is treated as:
+ // -webkit-binding: url(foo.xml), url(foo.xml), url(foo.xml); !?
+ values->append(parsedValue.get());
+ valueList->next();
+ }
+ if (!values->length())
+ return false;
+
+ addProperty(propId, values.release(), important);
+ valueList->next();
+ return true;
+ }
+#endif
+ break;
+ case CSS_PROP__WEBKIT_BORDER_IMAGE:
+ if (id == CSS_VAL_NONE)
+ valid_primitive = true;
+ else
+ return parseBorderImage(propId, important);
+ break;
+ case CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS:
+ case CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS:
+ case CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS:
+ case CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS:
+ case CSS_PROP__WEBKIT_BORDER_RADIUS: {
+ if (num != 1 && num != 2)
+ return false;
+ valid_primitive = validUnit(value, FLength, strict);
+ if (!valid_primitive)
+ return false;
+ RefPtr<CSSPrimitiveValue> parsedValue1 = new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ RefPtr<CSSPrimitiveValue> parsedValue2;
+ if (num == 2) {
+ value = valueList->next();
+ valid_primitive = validUnit(value, FLength, strict);
+ if (!valid_primitive)
+ return false;
+ parsedValue2 = new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ } else
+ parsedValue2 = parsedValue1;
+
+ RefPtr<Pair> pair = new Pair(parsedValue1.release(), parsedValue2.release());
+ RefPtr<CSSPrimitiveValue> val = new CSSPrimitiveValue(pair.release());
+ if (propId == CSS_PROP__WEBKIT_BORDER_RADIUS) {
+ const int properties[4] = { CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS,
+ CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS,
+ CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS,
+ CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS };
+ for (int i = 0; i < 4; i++)
+ addProperty(properties[i], val.get(), important);
+ } else
+ addProperty(propId, val.release(), important);
+ return true;
+ }
+ case CSS_PROP_OUTLINE_OFFSET:
+ valid_primitive = validUnit(value, FLength, strict);
+ break;
+ case CSS_PROP_TEXT_SHADOW: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3
+ case CSS_PROP__WEBKIT_BOX_SHADOW:
+ if (id == CSS_VAL_NONE)
+ valid_primitive = true;
+ else
+ return parseShadow(propId, important);
+ break;
+ case CSS_PROP_OPACITY:
+ valid_primitive = validUnit(value, FNumber, strict);
+ break;
+ case CSS_PROP__WEBKIT_BOX_ALIGN:
+ if (id == CSS_VAL_STRETCH || id == CSS_VAL_START || id == CSS_VAL_END ||
+ id == CSS_VAL_CENTER || id == CSS_VAL_BASELINE)
+ valid_primitive = true;
+ break;
+ case CSS_PROP__WEBKIT_BOX_DIRECTION:
+ if (id == CSS_VAL_NORMAL || id == CSS_VAL_REVERSE)
+ valid_primitive = true;
+ break;
+ case CSS_PROP__WEBKIT_BOX_LINES:
+ if (id == CSS_VAL_SINGLE || id == CSS_VAL_MULTIPLE)
+ valid_primitive = true;
+ break;
+ case CSS_PROP__WEBKIT_BOX_ORIENT:
+ if (id == CSS_VAL_HORIZONTAL || id == CSS_VAL_VERTICAL ||
+ id == CSS_VAL_INLINE_AXIS || id == CSS_VAL_BLOCK_AXIS)
+ valid_primitive = true;
+ break;
+ case CSS_PROP__WEBKIT_BOX_PACK:
+ if (id == CSS_VAL_START || id == CSS_VAL_END ||
+ id == CSS_VAL_CENTER || id == CSS_VAL_JUSTIFY)
+ valid_primitive = true;
+ break;
+ case CSS_PROP__WEBKIT_BOX_FLEX:
+ valid_primitive = validUnit(value, FNumber, strict);
+ break;
+ case CSS_PROP__WEBKIT_BOX_FLEX_GROUP:
+ case CSS_PROP__WEBKIT_BOX_ORDINAL_GROUP:
+ valid_primitive = validUnit(value, FInteger|FNonNeg, true);
+ break;
+ case CSS_PROP__WEBKIT_BOX_SIZING:
+ valid_primitive = id == CSS_VAL_BORDER_BOX || id == CSS_VAL_CONTENT_BOX;
+ break;
+ case CSS_PROP__WEBKIT_MARQUEE: {
+ const int properties[5] = { CSS_PROP__WEBKIT_MARQUEE_DIRECTION, CSS_PROP__WEBKIT_MARQUEE_INCREMENT,
+ CSS_PROP__WEBKIT_MARQUEE_REPETITION,
+ CSS_PROP__WEBKIT_MARQUEE_STYLE, CSS_PROP__WEBKIT_MARQUEE_SPEED };
+ return parseShorthand(propId, properties, 5, important);
+ }
+ case CSS_PROP__WEBKIT_MARQUEE_DIRECTION:
+ if (id == CSS_VAL_FORWARDS || id == CSS_VAL_BACKWARDS || id == CSS_VAL_AHEAD ||
+ id == CSS_VAL_REVERSE || id == CSS_VAL_LEFT || id == CSS_VAL_RIGHT || id == CSS_VAL_DOWN ||
+ id == CSS_VAL_UP || id == CSS_VAL_AUTO)
+ valid_primitive = true;
+ break;
+ case CSS_PROP__WEBKIT_MARQUEE_INCREMENT:
+ if (id == CSS_VAL_SMALL || id == CSS_VAL_LARGE || id == CSS_VAL_MEDIUM)
+ valid_primitive = true;
+ else
+ valid_primitive = validUnit(value, FLength|FPercent, strict);
+ break;
+ case CSS_PROP__WEBKIT_MARQUEE_STYLE:
+ if (id == CSS_VAL_NONE || id == CSS_VAL_SLIDE || id == CSS_VAL_SCROLL || id == CSS_VAL_ALTERNATE)
+ valid_primitive = true;
+ break;
+ case CSS_PROP__WEBKIT_MARQUEE_REPETITION:
+ if (id == CSS_VAL_INFINITE)
+ valid_primitive = true;
+ else
+ valid_primitive = validUnit(value, FInteger|FNonNeg, strict);
+ break;
+ case CSS_PROP__WEBKIT_MARQUEE_SPEED:
+ if (id == CSS_VAL_NORMAL || id == CSS_VAL_SLOW || id == CSS_VAL_FAST)
+ valid_primitive = true;
+ else
+ valid_primitive = validUnit(value, FTime|FInteger|FNonNeg, strict);
+ break;
+ case CSS_PROP__WEBKIT_USER_DRAG: // auto | none | element
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_NONE || id == CSS_VAL_ELEMENT)
+ valid_primitive = true;
+ break;
+ case CSS_PROP__WEBKIT_USER_MODIFY: // read-only | read-write
+ if (id == CSS_VAL_READ_ONLY || id == CSS_VAL_READ_WRITE || id == CSS_VAL_READ_WRITE_PLAINTEXT_ONLY)
+ valid_primitive = true;
+ break;
+ case CSS_PROP__WEBKIT_USER_SELECT: // auto | none | text
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_NONE || id == CSS_VAL_TEXT)
+ valid_primitive = true;
+ break;
+ case CSS_PROP_TEXT_OVERFLOW: // clip | ellipsis
+ if (id == CSS_VAL_CLIP || id == CSS_VAL_ELLIPSIS)
+ valid_primitive = true;
+ break;
+ case CSS_PROP__WEBKIT_TRANSFORM:
+ if (id == CSS_VAL_NONE)
+ valid_primitive = true;
+ else {
+ PassRefPtr<CSSValue> val = parseTransform();
+ if (val) {
+ addProperty(propId, val, important);
+ return true;
+ }
+ return false;
+ }
+ break;
+ case CSS_PROP__WEBKIT_TRANSFORM_ORIGIN:
+ case CSS_PROP__WEBKIT_TRANSFORM_ORIGIN_X:
+ case CSS_PROP__WEBKIT_TRANSFORM_ORIGIN_Y: {
+ RefPtr<CSSValue> val1;
+ RefPtr<CSSValue> val2;
+ int propId1, propId2;
+ if (parseTransformOrigin(propId, propId1, propId2, val1, val2)) {
+ addProperty(propId1, val1.release(), important);
+ if (val2)
+ addProperty(propId2, val2.release(), important);
+ return true;
+ }
+ return false;
+ }
+ case CSS_PROP__WEBKIT_TRANSITION_DURATION:
+ case CSS_PROP__WEBKIT_TRANSITION_REPEAT_COUNT:
+ case CSS_PROP__WEBKIT_TRANSITION_TIMING_FUNCTION:
+ case CSS_PROP__WEBKIT_TRANSITION_PROPERTY: {
+ RefPtr<CSSValue> val;
+ if (parseTransitionProperty(propId, val)) {
+ addProperty(propId, val.release(), important);
+ return true;
+ }
+ return false;
+ }
+ case CSS_PROP__WEBKIT_MARGIN_COLLAPSE: {
+ const int properties[2] = { CSS_PROP__WEBKIT_MARGIN_TOP_COLLAPSE,
+ CSS_PROP__WEBKIT_MARGIN_BOTTOM_COLLAPSE };
+ if (num == 1) {
+ ShorthandScope scope(this, CSS_PROP__WEBKIT_MARGIN_COLLAPSE);
+ if (!parseValue(properties[0], important))
+ return false;
+ CSSValue* value = parsedProperties[numParsedProperties-1]->value();
+ addProperty(properties[1], value, important);
+ return true;
+ }
+ else if (num == 2) {
+ ShorthandScope scope(this, CSS_PROP__WEBKIT_MARGIN_COLLAPSE);
+ if (!parseValue(properties[0], important) || !parseValue(properties[1], important))
+ return false;
+ return true;
+ }
+ return false;
+ }
+ case CSS_PROP__WEBKIT_MARGIN_TOP_COLLAPSE:
+ case CSS_PROP__WEBKIT_MARGIN_BOTTOM_COLLAPSE:
+ if (id == CSS_VAL_COLLAPSE || id == CSS_VAL_SEPARATE || id == CSS_VAL_DISCARD)
+ valid_primitive = true;
+ break;
+ case CSS_PROP_TEXT_LINE_THROUGH_MODE:
+ case CSS_PROP_TEXT_OVERLINE_MODE:
+ case CSS_PROP_TEXT_UNDERLINE_MODE:
+ if (id == CSS_VAL_CONTINUOUS || id == CSS_VAL_SKIP_WHITE_SPACE)
+ valid_primitive = true;
+ break;
+ case CSS_PROP_TEXT_LINE_THROUGH_STYLE:
+ case CSS_PROP_TEXT_OVERLINE_STYLE:
+ case CSS_PROP_TEXT_UNDERLINE_STYLE:
+ if (id == CSS_VAL_NONE || id == CSS_VAL_SOLID || id == CSS_VAL_DOUBLE ||
+ id == CSS_VAL_DASHED || id == CSS_VAL_DOT_DASH || id == CSS_VAL_DOT_DOT_DASH ||
+ id == CSS_VAL_WAVE)
+ valid_primitive = true;
+ break;
+ case CSS_PROP_TEXT_LINE_THROUGH_WIDTH:
+ case CSS_PROP_TEXT_OVERLINE_WIDTH:
+ case CSS_PROP_TEXT_UNDERLINE_WIDTH:
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_NORMAL || id == CSS_VAL_THIN ||
+ id == CSS_VAL_MEDIUM || id == CSS_VAL_THICK)
+ valid_primitive = true;
+ else
+ valid_primitive = !id && validUnit(value, FNumber|FLength|FPercent, strict);
+ break;
+ case CSS_PROP_RESIZE: // none | both | horizontal | vertical | auto
+ if (id == CSS_VAL_NONE || id == CSS_VAL_BOTH || id == CSS_VAL_HORIZONTAL || id == CSS_VAL_VERTICAL || id == CSS_VAL_AUTO)
+ valid_primitive = true;
+ break;
+ case CSS_PROP__WEBKIT_COLUMN_COUNT:
+ if (id == CSS_VAL_AUTO)
+ valid_primitive = true;
+ else
+ valid_primitive = !id && validUnit(value, FInteger | FNonNeg, false);
+ break;
+ case CSS_PROP__WEBKIT_COLUMN_GAP: // normal | <length>
+ if (id == CSS_VAL_NORMAL)
+ valid_primitive = true;
+ else
+ valid_primitive = validUnit(value, FLength, strict);
+ break;
+ case CSS_PROP__WEBKIT_COLUMN_WIDTH: // auto | <length>
+ if (id == CSS_VAL_AUTO)
+ valid_primitive = true;
+ else // Always parse this property in strict mode, since it would be ambiguous otherwise when used in the 'columns' shorthand property.
+ valid_primitive = validUnit(value, FLength, true);
+ break;
+ // End of CSS3 properties
+
+ // Apple specific properties. These will never be standardized and are purely to
+ // support custom WebKit-based Apple applications.
+ case CSS_PROP__WEBKIT_LINE_CLAMP:
+ valid_primitive = (!id && validUnit(value, FPercent, false));
+ break;
+ case CSS_PROP__WEBKIT_TEXT_SIZE_ADJUST:
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_NONE)
+ valid_primitive = true;
+ break;
+ case CSS_PROP__WEBKIT_RTL_ORDERING:
+ if (id == CSS_VAL_LOGICAL || id == CSS_VAL_VISUAL)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP__WEBKIT_FONT_SIZE_DELTA: // <length>
+ valid_primitive = validUnit(value, FLength, strict);
+ break;
+
+ case CSS_PROP__WEBKIT_NBSP_MODE: // normal | space
+ if (id == CSS_VAL_NORMAL || id == CSS_VAL_SPACE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP__WEBKIT_LINE_BREAK: // normal | after-white-space
+ if (id == CSS_VAL_NORMAL || id == CSS_VAL_AFTER_WHITE_SPACE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP__WEBKIT_MATCH_NEAREST_MAIL_BLOCKQUOTE_COLOR: // normal | match
+ if (id == CSS_VAL_NORMAL || id == CSS_VAL_MATCH)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP__WEBKIT_HIGHLIGHT:
+ if (id == CSS_VAL_NONE || value->unit == CSSPrimitiveValue::CSS_STRING)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP__WEBKIT_BORDER_FIT:
+ if (id == CSS_VAL_BORDER || id == CSS_VAL_LINES)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP__WEBKIT_TEXT_SECURITY:
+ // disc | circle | square | none | inherit
+ if (id == CSS_VAL_DISC || id == CSS_VAL_CIRCLE || id == CSS_VAL_SQUARE|| id == CSS_VAL_NONE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP__WEBKIT_DASHBOARD_REGION: // <dashboard-region> | <dashboard-region>
+ if (value->unit == Value::Function || id == CSS_VAL_NONE)
+ return parseDashboardRegions(propId, important);
+ break;
+ // End Apple-specific properties
+
+ /* shorthand properties */
+ case CSS_PROP_BACKGROUND:
+ // ['background-color' || 'background-image' || 'background-size' || 'background-repeat' ||
+ // 'background-attachment' || 'background-position'] | inherit
+ return parseBackgroundShorthand(important);
+ case CSS_PROP_BORDER:
+ // [ 'border-width' || 'border-style' || <color> ] | inherit
+ {
+ const int properties[3] = { CSS_PROP_BORDER_WIDTH, CSS_PROP_BORDER_STYLE,
+ CSS_PROP_BORDER_COLOR };
+ return parseShorthand(propId, properties, 3, important);
+ }
+ case CSS_PROP_BORDER_TOP:
+ // [ 'border-top-width' || 'border-style' || <color> ] | inherit
+ {
+ const int properties[3] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_TOP_STYLE,
+ CSS_PROP_BORDER_TOP_COLOR};
+ return parseShorthand(propId, properties, 3, important);
+ }
+ case CSS_PROP_BORDER_RIGHT:
+ // [ 'border-right-width' || 'border-style' || <color> ] | inherit
+ {
+ const int properties[3] = { CSS_PROP_BORDER_RIGHT_WIDTH, CSS_PROP_BORDER_RIGHT_STYLE,
+ CSS_PROP_BORDER_RIGHT_COLOR };
+ return parseShorthand(propId, properties, 3, important);
+ }
+ case CSS_PROP_BORDER_BOTTOM:
+ // [ 'border-bottom-width' || 'border-style' || <color> ] | inherit
+ {
+ const int properties[3] = { CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_BOTTOM_STYLE,
+ CSS_PROP_BORDER_BOTTOM_COLOR };
+ return parseShorthand(propId, properties, 3, important);
+ }
+ case CSS_PROP_BORDER_LEFT:
+ // [ 'border-left-width' || 'border-style' || <color> ] | inherit
+ {
+ const int properties[3] = { CSS_PROP_BORDER_LEFT_WIDTH, CSS_PROP_BORDER_LEFT_STYLE,
+ CSS_PROP_BORDER_LEFT_COLOR };
+ return parseShorthand(propId, properties, 3, important);
+ }
+ case CSS_PROP_OUTLINE:
+ // [ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit
+ {
+ const int properties[3] = { CSS_PROP_OUTLINE_WIDTH, CSS_PROP_OUTLINE_STYLE,
+ CSS_PROP_OUTLINE_COLOR };
+ return parseShorthand(propId, properties, 3, important);
+ }
+ case CSS_PROP_BORDER_COLOR:
+ // <color>{1,4} | inherit
+ {
+ const int properties[4] = { CSS_PROP_BORDER_TOP_COLOR, CSS_PROP_BORDER_RIGHT_COLOR,
+ CSS_PROP_BORDER_BOTTOM_COLOR, CSS_PROP_BORDER_LEFT_COLOR };
+ return parse4Values(propId, properties, important);
+ }
+ case CSS_PROP_BORDER_WIDTH:
+ // <border-width>{1,4} | inherit
+ {
+ const int properties[4] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_RIGHT_WIDTH,
+ CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_LEFT_WIDTH };
+ return parse4Values(propId, properties, important);
+ }
+ case CSS_PROP_BORDER_STYLE:
+ // <border-style>{1,4} | inherit
+ {
+ const int properties[4] = { CSS_PROP_BORDER_TOP_STYLE, CSS_PROP_BORDER_RIGHT_STYLE,
+ CSS_PROP_BORDER_BOTTOM_STYLE, CSS_PROP_BORDER_LEFT_STYLE };
+ return parse4Values(propId, properties, important);
+ }
+ case CSS_PROP_MARGIN:
+ // <margin-width>{1,4} | inherit
+ {
+ const int properties[4] = { CSS_PROP_MARGIN_TOP, CSS_PROP_MARGIN_RIGHT,
+ CSS_PROP_MARGIN_BOTTOM, CSS_PROP_MARGIN_LEFT };
+ return parse4Values(propId, properties, important);
+ }
+ case CSS_PROP_PADDING:
+ // <padding-width>{1,4} | inherit
+ {
+ const int properties[4] = { CSS_PROP_PADDING_TOP, CSS_PROP_PADDING_RIGHT,
+ CSS_PROP_PADDING_BOTTOM, CSS_PROP_PADDING_LEFT };
+ return parse4Values(propId, properties, important);
+ }
+ case CSS_PROP_FONT:
+ // [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]?
+ // 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit
+ if (id >= CSS_VAL_CAPTION && id <= CSS_VAL_STATUS_BAR)
+ valid_primitive = true;
+ else
+ return parseFont(important);
+ break;
+ case CSS_PROP_LIST_STYLE:
+ {
+ const int properties[3] = { CSS_PROP_LIST_STYLE_TYPE, CSS_PROP_LIST_STYLE_POSITION,
+ CSS_PROP_LIST_STYLE_IMAGE };
+ return parseShorthand(propId, properties, 3, important);
+ }
+ case CSS_PROP__WEBKIT_COLUMNS: {
+ const int properties[2] = { CSS_PROP__WEBKIT_COLUMN_WIDTH, CSS_PROP__WEBKIT_COLUMN_COUNT };
+ return parseShorthand(propId, properties, 2, important);
+ }
+ case CSS_PROP__WEBKIT_COLUMN_RULE: {
+ const int properties[3] = { CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH, CSS_PROP__WEBKIT_COLUMN_RULE_STYLE,
+ CSS_PROP__WEBKIT_COLUMN_RULE_COLOR };
+ return parseShorthand(propId, properties, 3, important);
+ }
+ case CSS_PROP__WEBKIT_TEXT_STROKE: {
+ const int properties[2] = { CSS_PROP__WEBKIT_TEXT_STROKE_WIDTH, CSS_PROP__WEBKIT_TEXT_STROKE_COLOR };
+ return parseShorthand(propId, properties, 2, important);
+ }
+ case CSS_PROP__WEBKIT_TRANSITION:
+ return parseTransitionShorthand(important);
+ case CSS_PROP_INVALID:
+ return false;
+ case CSS_PROP_FONT_STRETCH:
+ case CSS_PROP_PAGE:
+ case CSS_PROP_TEXT_LINE_THROUGH:
+ case CSS_PROP_TEXT_OVERLINE:
+ case CSS_PROP_TEXT_UNDERLINE:
+ return false;
+#if ENABLE(SVG)
+ default:
+ return parseSVGValue(propId, important);
+#endif
+ }
+
+ if (valid_primitive) {
+ if (id != 0)
+ parsedValue = new CSSPrimitiveValue(id);
+ else if (value->unit == CSSPrimitiveValue::CSS_STRING)
+ parsedValue = new CSSPrimitiveValue(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
+ else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
+ parsedValue = new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+ else if (value->unit >= Value::Q_EMS)
+ parsedValue = new CSSQuirkPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_EMS);
+ valueList->next();
+ }
+ if (parsedValue) {
+ if (!valueList->current() || inShorthand()) {
+ addProperty(propId, parsedValue.release(), important);
+ return true;
+ }
+ }
+ return false;
+}
+
+void CSSParser::addBackgroundValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval)
+{
+ if (lval) {
+ if (lval->isValueList())
+ static_cast<CSSValueList*>(lval.get())->append(rval);
+ else {
+ PassRefPtr<CSSValue> oldlVal(lval.release());
+ PassRefPtr<CSSValueList> list(new CSSValueList());
+ list->append(oldlVal);
+ list->append(rval);
+ lval = list;
+ }
+ }
+ else
+ lval = rval;
+}
+
+bool CSSParser::parseBackgroundShorthand(bool important)
+{
+ // Position must come before color in this array because a plain old "0" is a legal color
+ // in quirks mode but it's usually the X coordinate of a position.
+ // FIXME: Add CSS_PROP__KHTML_BACKGROUND_SIZE to the shorthand.
+ const int properties[] = { CSS_PROP_BACKGROUND_IMAGE, CSS_PROP_BACKGROUND_REPEAT,
+ CSS_PROP_BACKGROUND_ATTACHMENT, CSS_PROP_BACKGROUND_POSITION, CSS_PROP__WEBKIT_BACKGROUND_CLIP,
+ CSS_PROP__WEBKIT_BACKGROUND_ORIGIN, CSS_PROP_BACKGROUND_COLOR };
+ const int numProperties = sizeof(properties) / sizeof(properties[0]);
+
+ ShorthandScope scope(this, CSS_PROP_BACKGROUND);
+
+ bool parsedProperty[numProperties] = { false }; // compiler will repeat false as necessary
+ RefPtr<CSSValue> values[numProperties];
+ RefPtr<CSSValue> positionYValue;
+ int i;
+
+ while (valueList->current()) {
+ Value* val = valueList->current();
+ if (val->unit == Value::Operator && val->iValue == ',') {
+ // We hit the end. Fill in all remaining values with the initial value.
+ valueList->next();
+ for (i = 0; i < numProperties; ++i) {
+ if (properties[i] == CSS_PROP_BACKGROUND_COLOR && parsedProperty[i])
+ // Color is not allowed except as the last item in a list. Reject the entire
+ // property.
+ return false;
+
+ if (!parsedProperty[i] && properties[i] != CSS_PROP_BACKGROUND_COLOR) {
+ addBackgroundValue(values[i], new CSSInitialValue(true));
+ if (properties[i] == CSS_PROP_BACKGROUND_POSITION)
+ addBackgroundValue(positionYValue, new CSSInitialValue(true));
+ }
+ parsedProperty[i] = false;
+ }
+ if (!valueList->current())
+ break;
+ }
+
+ bool found = false;
+ for (i = 0; !found && i < numProperties; ++i) {
+ if (!parsedProperty[i]) {
+ RefPtr<CSSValue> val1;
+ RefPtr<CSSValue> val2;
+ int propId1, propId2;
+ if (parseBackgroundProperty(properties[i], propId1, propId2, val1, val2)) {
+ parsedProperty[i] = found = true;
+ addBackgroundValue(values[i], val1.release());
+ if (properties[i] == CSS_PROP_BACKGROUND_POSITION)
+ addBackgroundValue(positionYValue, val2.release());
+ }
+ }
+ }
+
+ // if we didn't find at least one match, this is an
+ // invalid shorthand and we have to ignore it
+ if (!found)
+ return false;
+ }
+
+ // Fill in any remaining properties with the initial value.
+ for (i = 0; i < numProperties; ++i) {
+ if (!parsedProperty[i]) {
+ addBackgroundValue(values[i], new CSSInitialValue(true));
+ if (properties[i] == CSS_PROP_BACKGROUND_POSITION)
+ addBackgroundValue(positionYValue, new CSSInitialValue(true));
+ }
+ }
+
+ // Now add all of the properties we found.
+ for (i = 0; i < numProperties; i++) {
+ if (properties[i] == CSS_PROP_BACKGROUND_POSITION) {
+ addProperty(CSS_PROP_BACKGROUND_POSITION_X, values[i].release(), important);
+ // it's OK to call positionYValue.release() since we only see CSS_PROP_BACKGROUND_POSITION once
+ addProperty(CSS_PROP_BACKGROUND_POSITION_Y, positionYValue.release(), important);
+ } else
+ addProperty(properties[i], values[i].release(), important);
+ }
+
+ return true;
+}
+
+void CSSParser::addTransitionValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval)
+{
+ if (lval) {
+ if (lval->isValueList())
+ static_cast<CSSValueList*>(lval.get())->append(rval);
+ else {
+ PassRefPtr<CSSValue> oldVal(lval.release());
+ PassRefPtr<CSSValueList> list(new CSSValueList());
+ list->append(oldVal);
+ list->append(rval);
+ lval = list;
+ }
+ }
+ else
+ lval = rval;
+}
+
+bool CSSParser::parseTransitionShorthand(bool important)
+{
+ const int properties[] = { CSS_PROP__WEBKIT_TRANSITION_PROPERTY, CSS_PROP__WEBKIT_TRANSITION_DURATION,
+ CSS_PROP__WEBKIT_TRANSITION_TIMING_FUNCTION, CSS_PROP__WEBKIT_TRANSITION_REPEAT_COUNT };
+ const int numProperties = sizeof(properties) / sizeof(properties[0]);
+
+ ShorthandScope scope(this, CSS_PROP__WEBKIT_TRANSITION);
+
+ bool parsedProperty[numProperties] = { false }; // compiler will repeat false as necessary
+ RefPtr<CSSValue> values[numProperties];
+
+ int i;
+ while (valueList->current()) {
+ Value* val = valueList->current();
+ if (val->unit == Value::Operator && val->iValue == ',') {
+ // We hit the end. Fill in all remaining values with the initial value.
+ valueList->next();
+ for (i = 0; i < numProperties; ++i) {
+ if (!parsedProperty[i])
+ addTransitionValue(values[i], new CSSInitialValue(true));
+ parsedProperty[i] = false;
+ }
+ if (!valueList->current())
+ break;
+ }
+
+ bool found = false;
+ for (i = 0; !found && i < numProperties; ++i) {
+ if (!parsedProperty[i]) {
+ RefPtr<CSSValue> val;
+ if (parseTransitionProperty(properties[i], val)) {
+ parsedProperty[i] = found = true;
+ addTransitionValue(values[i], val.release());
+ }
+ }
+ }
+
+ // if we didn't find at least one match, this is an
+ // invalid shorthand and we have to ignore it
+ if (!found)
+ return false;
+ }
+
+ // Fill in any remaining properties with the initial value.
+ for (i = 0; i < numProperties; ++i) {
+ if (!parsedProperty[i])
+ addTransitionValue(values[i], new CSSInitialValue(true));
+ }
+
+ // Now add all of the properties we found.
+ for (i = 0; i < numProperties; i++)
+ addProperty(properties[i], values[i].release(), important);
+
+ return true;
+}
+
+bool CSSParser::parseShorthand(int propId, const int *properties, int numProperties, bool important)
+{
+ // We try to match as many properties as possible
+ // We set up an array of booleans to mark which property has been found,
+ // and we try to search for properties until it makes no longer any sense.
+ ShorthandScope scope(this, propId);
+
+ bool found = false;
+ bool fnd[6]; // Trust me ;)
+ for (int i = 0; i < numProperties; i++)
+ fnd[i] = false;
+
+ while (valueList->current()) {
+ found = false;
+ for (int propIndex = 0; !found && propIndex < numProperties; ++propIndex) {
+ if (!fnd[propIndex]) {
+ if (parseValue(properties[propIndex], important))
+ fnd[propIndex] = found = true;
+ }
+ }
+
+ // if we didn't find at least one match, this is an
+ // invalid shorthand and we have to ignore it
+ if (!found)
+ return false;
+ }
+
+ // Fill in any remaining properties with the initial value.
+ m_implicitShorthand = true;
+ for (int i = 0; i < numProperties; ++i) {
+ if (!fnd[i])
+ addProperty(properties[i], new CSSInitialValue(true), important);
+ }
+ m_implicitShorthand = false;
+
+ return true;
+}
+
+bool CSSParser::parse4Values(int propId, const int *properties, bool important)
+{
+ /* From the CSS 2 specs, 8.3
+ * If there is only one value, it applies to all sides. If there are two values, the top and
+ * bottom margins are set to the first value and the right and left margins are set to the second.
+ * If there are three values, the top is set to the first value, the left and right are set to the
+ * second, and the bottom is set to the third. If there are four values, they apply to the top,
+ * right, bottom, and left, respectively.
+ */
+
+ int num = inShorthand() ? 1 : valueList->size();
+
+ ShorthandScope scope(this, propId);
+
+ // the order is top, right, bottom, left
+ switch (num) {
+ case 1: {
+ if (!parseValue(properties[0], important))
+ return false;
+ CSSValue *value = parsedProperties[numParsedProperties-1]->value();
+ m_implicitShorthand = true;
+ addProperty(properties[1], value, important);
+ addProperty(properties[2], value, important);
+ addProperty(properties[3], value, important);
+ m_implicitShorthand = false;
+ break;
+ }
+ case 2: {
+ if (!parseValue(properties[0], important) || !parseValue(properties[1], important))
+ return false;
+ CSSValue *value = parsedProperties[numParsedProperties-2]->value();
+ m_implicitShorthand = true;
+ addProperty(properties[2], value, important);
+ value = parsedProperties[numParsedProperties-2]->value();
+ addProperty(properties[3], value, important);
+ m_implicitShorthand = false;
+ break;
+ }
+ case 3: {
+ if (!parseValue(properties[0], important) || !parseValue(properties[1], important) || !parseValue(properties[2], important))
+ return false;
+ CSSValue *value = parsedProperties[numParsedProperties-2]->value();
+ m_implicitShorthand = true;
+ addProperty(properties[3], value, important);
+ m_implicitShorthand = false;
+ break;
+ }
+ case 4: {
+ if (!parseValue(properties[0], important) || !parseValue(properties[1], important) ||
+ !parseValue(properties[2], important) || !parseValue(properties[3], important))
+ return false;
+ break;
+ }
+ default: {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// [ <string> | <uri> | <counter> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
+// in CSS 2.1 this got somewhat reduced:
+// [ <string> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
+bool CSSParser::parseContent(int propId, bool important)
+{
+ RefPtr<CSSValueList> values = new CSSValueList;
+
+ while (Value* val = valueList->current()) {
+ RefPtr<CSSValue> parsedValue;
+ if (val->unit == CSSPrimitiveValue::CSS_URI) {
+ // url
+ String value = parseURL(val->string);
+ parsedValue = new CSSImageValue(KURL(styleElement->baseURL(), value).string(), styleElement);
+ } else if (val->unit == Value::Function) {
+ // attr(X) | counter(X [,Y]) | counters(X, Y, [,Z])
+ ValueList* args = val->function->args;
+ if (!args)
+ return false;
+ if (equalIgnoringCase(val->function->name, "attr(")) {
+ if (args->size() != 1)
+ return false;
+ Value* a = args->current();
+ String attrName = a->string;
+ if (document()->isHTMLDocument())
+ attrName = attrName.lower();
+ parsedValue = new CSSPrimitiveValue(attrName, CSSPrimitiveValue::CSS_ATTR);
+ } else if (equalIgnoringCase(val->function->name, "counter(")) {
+ parsedValue = parseCounterContent(args, false);
+ if (!parsedValue) return false;
+ } else if (equalIgnoringCase(val->function->name, "counters(")) {
+ parsedValue = parseCounterContent(args, true);
+ if (!parsedValue)
+ return false;
+ } else
+ return false;
+ } else if (val->unit == CSSPrimitiveValue::CSS_IDENT) {
+ // open-quote
+ // close-quote
+ // no-open-quote
+ // no-close-quote
+ // FIXME: These are not yet implemented (http://bugs.webkit.org/show_bug.cgi?id=6503).
+ } else if (val->unit == CSSPrimitiveValue::CSS_STRING) {
+ parsedValue = new CSSPrimitiveValue(val->string, CSSPrimitiveValue::CSS_STRING);
+ }
+ if (!parsedValue)
+ break;
+ values->append(parsedValue.release());
+ valueList->next();
+ }
+
+ if (values->length()) {
+ addProperty(propId, values.release(), important);
+ valueList->next();
+ return true;
+ }
+
+ return false;
+}
+
+PassRefPtr<CSSValue> CSSParser::parseBackgroundColor()
+{
+ int id = valueList->current()->id;
+ if (id == CSS_VAL__WEBKIT_TEXT || (id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT) || id == CSS_VAL_MENU ||
+ (id >= CSS_VAL_GREY && id < CSS_VAL__WEBKIT_TEXT && !strict))
+ return new CSSPrimitiveValue(id);
+ return parseColor();
+}
+
+bool CSSParser::parseBackgroundImage(RefPtr<CSSValue>& value)
+{
+ if (valueList->current()->id == CSS_VAL_NONE) {
+ value = new CSSImageValue();
+ return true;
+ }
+ if (valueList->current()->unit == CSSPrimitiveValue::CSS_URI) {
+ String uri = parseURL(valueList->current()->string);
+ if (!uri.isEmpty())
+ value = new CSSImageValue(KURL(styleElement->baseURL(), uri).string(), styleElement);
+ return true;
+ }
+ return false;
+}
+
+PassRefPtr<CSSValue> CSSParser::parseBackgroundPositionXY(bool& xFound, bool& yFound)
+{
+ int id = valueList->current()->id;
+ if (id == CSS_VAL_LEFT || id == CSS_VAL_TOP || id == CSS_VAL_RIGHT || id == CSS_VAL_BOTTOM || id == CSS_VAL_CENTER) {
+ int percent = 0;
+ if (id == CSS_VAL_LEFT || id == CSS_VAL_RIGHT) {
+ if (xFound)
+ return 0;
+ xFound = true;
+ if (id == CSS_VAL_RIGHT)
+ percent = 100;
+ }
+ else if (id == CSS_VAL_TOP || id == CSS_VAL_BOTTOM) {
+ if (yFound)
+ return 0;
+ yFound = true;
+ if (id == CSS_VAL_BOTTOM)
+ percent = 100;
+ }
+ else if (id == CSS_VAL_CENTER)
+ // Center is ambiguous, so we're not sure which position we've found yet, an x or a y.
+ percent = 50;
+ return new CSSPrimitiveValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+ }
+ if (validUnit(valueList->current(), FPercent|FLength, strict))
+ return new CSSPrimitiveValue(valueList->current()->fValue,
+ (CSSPrimitiveValue::UnitTypes)valueList->current()->unit);
+
+ return 0;
+}
+
+void CSSParser::parseBackgroundPosition(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2)
+{
+ Value* value = valueList->current();
+
+ // Parse the first value. We're just making sure that it is one of the valid keywords or a percentage/length.
+ bool value1IsX = false, value1IsY = false;
+ value1 = parseBackgroundPositionXY(value1IsX, value1IsY);
+ if (!value1)
+ return;
+
+ // It only takes one value for background-position to be correctly parsed if it was specified in a shorthand (since we
+ // can assume that any other values belong to the rest of the shorthand). If we're not parsing a shorthand, though, the
+ // value was explicitly specified for our property.
+ value = valueList->next();
+
+ // First check for the comma. If so, we are finished parsing this value or value pair.
+ if (value && value->unit == Value::Operator && value->iValue == ',')
+ value = 0;
+
+ bool value2IsX = false, value2IsY = false;
+ if (value) {
+ value2 = parseBackgroundPositionXY(value2IsX, value2IsY);
+ if (value2)
+ valueList->next();
+ else {
+ if (!inShorthand()) {
+ value1.clear();
+ return;
+ }
+ }
+ }
+
+ if (!value2)
+ // Only one value was specified. If that value was not a keyword, then it sets the x position, and the y position
+ // is simply 50%. This is our default.
+ // For keywords, the keyword was either an x-keyword (left/right), a y-keyword (top/bottom), or an ambiguous keyword (center).
+ // For left/right/center, the default of 50% in the y is still correct.
+ value2 = new CSSPrimitiveValue(50, CSSPrimitiveValue::CSS_PERCENTAGE);
+
+ if (value1IsY || value2IsX)
+ value1.swap(value2);
+}
+
+PassRefPtr<CSSValue> CSSParser::parseBackgroundSize()
+{
+ Value* value = valueList->current();
+ CSSPrimitiveValue* parsedValue1;
+
+ if (value->id == CSS_VAL_AUTO)
+ parsedValue1 = new CSSPrimitiveValue(0, CSSPrimitiveValue::CSS_UNKNOWN);
+ else {
+ if (!validUnit(value, FLength|FPercent, strict))
+ return 0;
+ parsedValue1 = new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ }
+
+ CSSPrimitiveValue* parsedValue2 = parsedValue1;
+ if ((value = valueList->next())) {
+ if (value->id == CSS_VAL_AUTO)
+ parsedValue2 = new CSSPrimitiveValue(0, CSSPrimitiveValue::CSS_UNKNOWN);
+ else {
+ if (!validUnit(value, FLength|FPercent, strict)) {
+ delete parsedValue1;
+ return 0;
+ }
+ parsedValue2 = new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ }
+ }
+
+ Pair* pair = new Pair(parsedValue1, parsedValue2);
+ return new CSSPrimitiveValue(pair);
+}
+
+bool CSSParser::parseBackgroundProperty(int propId, int& propId1, int& propId2,
+ RefPtr<CSSValue>& retValue1, RefPtr<CSSValue>& retValue2)
+{
+ RefPtr<CSSValueList> values;
+ RefPtr<CSSValueList> values2;
+ Value* val;
+ RefPtr<CSSValue> value;
+ RefPtr<CSSValue> value2;
+
+ bool allowComma = false;
+
+ retValue1 = retValue2 = 0;
+ propId1 = propId;
+ propId2 = propId;
+ if (propId == CSS_PROP_BACKGROUND_POSITION) {
+ propId1 = CSS_PROP_BACKGROUND_POSITION_X;
+ propId2 = CSS_PROP_BACKGROUND_POSITION_Y;
+ }
+
+ while ((val = valueList->current())) {
+ RefPtr<CSSValue> currValue;
+ RefPtr<CSSValue> currValue2;
+
+ if (allowComma) {
+ if (val->unit != Value::Operator || val->iValue != ',')
+ return false;
+ valueList->next();
+ allowComma = false;
+ } else {
+ switch (propId) {
+ case CSS_PROP_BACKGROUND_ATTACHMENT:
+ if (val->id == CSS_VAL_SCROLL || val->id == CSS_VAL_FIXED) {
+ currValue = new CSSPrimitiveValue(val->id);
+ valueList->next();
+ }
+ break;
+ case CSS_PROP_BACKGROUND_COLOR:
+ currValue = parseBackgroundColor();
+ if (currValue)
+ valueList->next();
+ break;
+ case CSS_PROP_BACKGROUND_IMAGE:
+ if (parseBackgroundImage(currValue))
+ valueList->next();
+ break;
+ case CSS_PROP__WEBKIT_BACKGROUND_CLIP:
+ case CSS_PROP__WEBKIT_BACKGROUND_ORIGIN:
+ if (val->id == CSS_VAL_BORDER || val->id == CSS_VAL_PADDING || val->id == CSS_VAL_CONTENT) {
+ currValue = new CSSPrimitiveValue(val->id);
+ valueList->next();
+ }
+ break;
+ case CSS_PROP_BACKGROUND_POSITION:
+ parseBackgroundPosition(currValue, currValue2);
+ // unlike the other functions, parseBackgroundPosition advances the valueList pointer
+ break;
+ case CSS_PROP_BACKGROUND_POSITION_X: {
+ bool xFound = false, yFound = true;
+ currValue = parseBackgroundPositionXY(xFound, yFound);
+ if (currValue)
+ valueList->next();
+ break;
+ }
+ case CSS_PROP_BACKGROUND_POSITION_Y: {
+ bool xFound = true, yFound = false;
+ currValue = parseBackgroundPositionXY(xFound, yFound);
+ if (currValue)
+ valueList->next();
+ break;
+ }
+ case CSS_PROP__WEBKIT_BACKGROUND_COMPOSITE:
+ if ((val->id >= CSS_VAL_CLEAR && val->id <= CSS_VAL_PLUS_LIGHTER) || val->id == CSS_VAL_HIGHLIGHT) {
+ currValue = new CSSPrimitiveValue(val->id);
+ valueList->next();
+ }
+ break;
+ case CSS_PROP_BACKGROUND_REPEAT:
+ if (val->id >= CSS_VAL_REPEAT && val->id <= CSS_VAL_NO_REPEAT) {
+ currValue = new CSSPrimitiveValue(val->id);
+ valueList->next();
+ }
+ break;
+ case CSS_PROP__WEBKIT_BACKGROUND_SIZE:
+ currValue = parseBackgroundSize();
+ if (currValue)
+ valueList->next();
+ break;
+ }
+ if (!currValue)
+ return false;
+
+ if (value && !values) {
+ values = new CSSValueList();
+ values->append(value.release());
+ }
+
+ if (value2 && !values2) {
+ values2 = new CSSValueList();
+ values2->append(value2.release());
+ }
+
+ if (values)
+ values->append(currValue.release());
+ else
+ value = currValue.release();
+ if (currValue2) {
+ if (values2)
+ values2->append(currValue2.release());
+ else
+ value2 = currValue2.release();
+ }
+ allowComma = true;
+ }
+
+ // When parsing the 'background' shorthand property, we let it handle building up the lists for all
+ // properties.
+ if (inShorthand())
+ break;
+ }
+
+ if (values && values->length()) {
+ retValue1 = values.release();
+ if (values2 && values2->length())
+ retValue2 = values2.release();
+ return true;
+ }
+ if (value) {
+ retValue1 = value.release();
+ retValue2 = value2.release();
+ return true;
+ }
+ return false;
+}
+
+PassRefPtr<CSSValue> CSSParser::parseTransitionDuration()
+{
+ Value* value = valueList->current();
+ if (validUnit(value, FTime, strict))
+ return new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ return 0;
+}
+
+PassRefPtr<CSSValue> CSSParser::parseTransitionRepeatCount()
+{
+ Value* value = valueList->current();
+ if (value->id == CSS_VAL_INFINITE)
+ return new CSSPrimitiveValue(value->id);
+ if (validUnit(value, FInteger|FNonNeg, strict))
+ return new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ return 0;
+}
+
+bool CSSParser::parseTimingFunctionValue(ValueList*& args, double& result)
+{
+ Value* v = args->current();
+ if (!validUnit(v, FNumber, strict))
+ return false;
+ result = v->fValue;
+ if (result < 0 || result > 1.0)
+ return false;
+ v = args->next();
+ if (!v)
+ // The last number in the function has no comma after it, so we're done.
+ return true;
+ if (v->unit != Value::Operator && v->iValue != ',')
+ return false;
+ v = args->next();
+ return true;
+}
+
+PassRefPtr<CSSValue> CSSParser::parseTransitionTimingFunction()
+{
+ Value* value = valueList->current();
+ if (value->id == CSS_VAL_AUTO || value->id == CSS_VAL_LINEAR || value->id == CSS_VAL_EASE_IN || value->id == CSS_VAL_EASE_OUT || value->id == CSS_VAL_EASE_IN_OUT)
+ return new CSSPrimitiveValue(value->id);
+
+ // We must be a function.
+ if (value->unit != Value::Function)
+ return 0;
+
+ // The only timing function we accept for now is a cubic bezier function. 4 points must be specified.
+ ValueList* args = value->function->args;
+ if (!equalIgnoringCase(value->function->name, "cubic-bezier(") || !args || args->size() != 7)
+ return 0;
+
+ // There are two points specified. The values must be between 0 and 1.
+ double x1, y1, x2, y2;
+
+ if (!parseTimingFunctionValue(args, x1))
+ return 0;
+ if (!parseTimingFunctionValue(args, y1))
+ return 0;
+ if (!parseTimingFunctionValue(args, x2))
+ return 0;
+ if (!parseTimingFunctionValue(args, y2))
+ return 0;
+
+ return new CSSTimingFunctionValue(x1, y1, x2, y2);
+}
+
+PassRefPtr<CSSValue> CSSParser::parseTransitionProperty()
+{
+ Value* value = valueList->current();
+ if (value->unit != CSSPrimitiveValue::CSS_IDENT)
+ return 0;
+ int result = cssPropertyID(value->string);
+ if (result)
+ return new CSSPrimitiveValue(result);
+ if (equalIgnoringCase(value->string, "all"))
+ return new CSSPrimitiveValue(cAnimateAll);
+ if (equalIgnoringCase(value->string, "none"))
+ return new CSSPrimitiveValue(cAnimateNone);
+ return 0;
+}
+
+bool CSSParser::parseTransitionProperty(int propId, RefPtr<CSSValue>& result)
+{
+ RefPtr<CSSValueList> values;
+ Value* val;
+ RefPtr<CSSValue> value;
+ bool allowComma = false;
+
+ result = 0;
+
+ while ((val = valueList->current())) {
+ RefPtr<CSSValue> currValue;
+ if (allowComma) {
+ if (val->unit != Value::Operator || val->iValue != ',')
+ return false;
+ valueList->next();
+ allowComma = false;
+ }
+ else {
+ switch (propId) {
+ case CSS_PROP__WEBKIT_TRANSITION_DURATION:
+ currValue = parseTransitionDuration();
+ if (currValue)
+ valueList->next();
+ break;
+ case CSS_PROP__WEBKIT_TRANSITION_REPEAT_COUNT:
+ currValue = parseTransitionRepeatCount();
+ if (currValue)
+ valueList->next();
+ break;
+ case CSS_PROP__WEBKIT_TRANSITION_TIMING_FUNCTION:
+ currValue = parseTransitionTimingFunction();
+ if (currValue)
+ valueList->next();
+ break;
+ case CSS_PROP__WEBKIT_TRANSITION_PROPERTY:
+ currValue = parseTransitionProperty();
+ if (currValue)
+ valueList->next();
+ break;
+ }
+
+ if (!currValue)
+ return false;
+
+ if (value && !values) {
+ values = new CSSValueList();
+ values->append(value.release());
+ }
+
+ if (values)
+ values->append(currValue.release());
+ else
+ value = currValue.release();
+
+ allowComma = true;
+ }
+
+ // When parsing the 'transition' shorthand property, we let it handle building up the lists for all
+ // properties.
+ if (inShorthand())
+ break;
+ }
+
+ if (values && values->length()) {
+ result = values.release();
+ return true;
+ }
+ if (value) {
+ result = value.release();
+ return true;
+ }
+ return false;
+}
+
+#define DASHBOARD_REGION_NUM_PARAMETERS 6
+#define DASHBOARD_REGION_SHORT_NUM_PARAMETERS 2
+
+static Value *skipCommaInDashboardRegion (ValueList *args)
+{
+ if (args->size() == (DASHBOARD_REGION_NUM_PARAMETERS*2-1) ||
+ args->size() == (DASHBOARD_REGION_SHORT_NUM_PARAMETERS*2-1)) {
+ Value *current = args->current();
+ if (current->unit == Value::Operator && current->iValue == ',')
+ return args->next();
+ }
+ return args->current();
+}
+
+bool CSSParser::parseDashboardRegions(int propId, bool important)
+{
+ bool valid = true;
+
+ Value *value = valueList->current();
+
+ if (value->id == CSS_VAL_NONE) {
+ if (valueList->next())
+ return false;
+ addProperty(propId, new CSSPrimitiveValue(value->id), important);
+ return valid;
+ }
+
+ RefPtr<DashboardRegion> firstRegion = new DashboardRegion;
+ DashboardRegion* region = 0;
+
+ while (value) {
+ if (region == 0) {
+ region = firstRegion.get();
+ } else {
+ RefPtr<DashboardRegion> nextRegion = new DashboardRegion();
+ region->m_next = nextRegion;
+ region = nextRegion.get();
+ }
+
+ if (value->unit != Value::Function) {
+ valid = false;
+ break;
+ }
+
+ // Commas count as values, so allow:
+ // dashboard-region(label, type, t, r, b, l) or dashboard-region(label type t r b l)
+ // dashboard-region(label, type, t, r, b, l) or dashboard-region(label type t r b l)
+ // also allow
+ // dashboard-region(label, type) or dashboard-region(label type)
+ // dashboard-region(label, type) or dashboard-region(label type)
+ ValueList* args = value->function->args;
+ if (!equalIgnoringCase(value->function->name, "dashboard-region(") || !args) {
+ valid = false;
+ break;
+ }
+
+ int numArgs = args->size();
+ if ((numArgs != DASHBOARD_REGION_NUM_PARAMETERS && numArgs != (DASHBOARD_REGION_NUM_PARAMETERS*2-1)) &&
+ (numArgs != DASHBOARD_REGION_SHORT_NUM_PARAMETERS && numArgs != (DASHBOARD_REGION_SHORT_NUM_PARAMETERS*2-1))){
+ valid = false;
+ break;
+ }
+
+ // First arg is a label.
+ Value* arg = args->current();
+ if (arg->unit != CSSPrimitiveValue::CSS_IDENT) {
+ valid = false;
+ break;
+ }
+
+ region->m_label = arg->string;
+
+ // Second arg is a type.
+ arg = args->next();
+ arg = skipCommaInDashboardRegion (args);
+ if (arg->unit != CSSPrimitiveValue::CSS_IDENT) {
+ valid = false;
+ break;
+ }
+
+ if (equalIgnoringCase(arg->string, "circle"))
+ region->m_isCircle = true;
+ else if (equalIgnoringCase(arg->string, "rectangle"))
+ region->m_isRectangle = true;
+ else {
+ valid = false;
+ break;
+ }
+
+ region->m_geometryType = arg->string;
+
+ if (numArgs == DASHBOARD_REGION_SHORT_NUM_PARAMETERS || numArgs == (DASHBOARD_REGION_SHORT_NUM_PARAMETERS*2-1)) {
+ // This originally used CSS_VAL_INVALID by accident. It might be more logical to use something else.
+ CSSPrimitiveValue *amount = new CSSPrimitiveValue(CSS_VAL_INVALID);
+
+ region->setTop(amount);
+ region->setRight(amount);
+ region->setBottom(amount);
+ region->setLeft(amount);
+ }
+ else {
+ // Next four arguments must be offset numbers
+ int i;
+ for (i = 0; i < 4; i++) {
+ arg = args->next();
+ arg = skipCommaInDashboardRegion (args);
+
+ valid = arg->id == CSS_VAL_AUTO || validUnit(arg, FLength, strict);
+ if (!valid)
+ break;
+
+ CSSPrimitiveValue *amount = arg->id == CSS_VAL_AUTO ?
+ new CSSPrimitiveValue(CSS_VAL_AUTO) :
+ new CSSPrimitiveValue(arg->fValue, (CSSPrimitiveValue::UnitTypes) arg->unit);
+
+ if (i == 0)
+ region->setTop(amount);
+ else if (i == 1)
+ region->setRight(amount);
+ else if (i == 2)
+ region->setBottom(amount);
+ else
+ region->setLeft(amount);
+ }
+ }
+
+ if (args->next())
+ return false;
+
+ value = valueList->next();
+ }
+
+ if (valid)
+ addProperty(propId, new CSSPrimitiveValue(firstRegion.release()), important);
+
+ return valid;
+}
+
+PassRefPtr<CSSValue> CSSParser::parseCounterContent(ValueList* args, bool counters)
+{
+ unsigned numArgs = args->size();
+ if (counters && numArgs != 3 && numArgs != 5)
+ return 0;
+ if (!counters && numArgs != 1 && numArgs != 3)
+ return 0;
+
+ Value* i = args->current();
+ RefPtr<CSSPrimitiveValue> identifier = new CSSPrimitiveValue(i->string, CSSPrimitiveValue::CSS_STRING);
+
+ RefPtr<CSSPrimitiveValue> separator;
+ if (!counters)
+ separator = new CSSPrimitiveValue(String(), CSSPrimitiveValue::CSS_STRING);
+ else {
+ i = args->next();
+ if (i->unit != Value::Operator || i->iValue != ',')
+ return 0;
+
+ i = args->next();
+ if (i->unit != CSSPrimitiveValue::CSS_STRING)
+ return 0;
+
+ separator = new CSSPrimitiveValue(i->string, (CSSPrimitiveValue::UnitTypes) i->unit);
+ }
+
+ RefPtr<CSSPrimitiveValue> listStyle;
+ i = args->next();
+ if (!i) // Make the list style default decimal
+ listStyle = new CSSPrimitiveValue(CSS_VAL_DECIMAL - CSS_VAL_DISC, CSSPrimitiveValue::CSS_NUMBER);
+ else {
+ if (i->unit != Value::Operator || i->iValue != ',')
+ return 0;
+
+ i = args->next();
+ if (i->unit != CSSPrimitiveValue::CSS_IDENT)
+ return 0;
+
+ short ls = 0;
+ if (i->id == CSS_VAL_NONE)
+ ls = CSS_VAL_KATAKANA_IROHA - CSS_VAL_DISC + 1;
+ else if (i->id >= CSS_VAL_DISC && i->id <= CSS_VAL_KATAKANA_IROHA)
+ ls = i->id - CSS_VAL_DISC;
+ else
+ return 0;
+
+ listStyle = new CSSPrimitiveValue(ls, (CSSPrimitiveValue::UnitTypes) i->unit);
+ }
+
+ return new CSSPrimitiveValue(new Counter(identifier.release(), listStyle.release(), separator.release()));
+}
+
+bool CSSParser::parseShape(int propId, bool important)
+{
+ Value* value = valueList->current();
+ ValueList* args = value->function->args;
+ if (!equalIgnoringCase(value->function->name, "rect(") || !args)
+ return false;
+
+ // rect(t, r, b, l) || rect(t r b l)
+ if (args->size() != 4 && args->size() != 7)
+ return false;
+ Rect *rect = new Rect();
+ bool valid = true;
+ int i = 0;
+ Value *a = args->current();
+ while (a) {
+ valid = a->id == CSS_VAL_AUTO || validUnit(a, FLength, strict);
+ if (!valid)
+ break;
+ CSSPrimitiveValue *length = a->id == CSS_VAL_AUTO ?
+ new CSSPrimitiveValue(CSS_VAL_AUTO) :
+ new CSSPrimitiveValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
+ if (i == 0)
+ rect->setTop(length);
+ else if (i == 1)
+ rect->setRight(length);
+ else if (i == 2)
+ rect->setBottom(length);
+ else
+ rect->setLeft(length);
+ a = args->next();
+ if (a && args->size() == 7) {
+ if (a->unit == Value::Operator && a->iValue == ',') {
+ a = args->next();
+ } else {
+ valid = false;
+ break;
+ }
+ }
+ i++;
+ }
+ if (valid) {
+ addProperty(propId, new CSSPrimitiveValue(rect), important);
+ valueList->next();
+ return true;
+ }
+ delete rect;
+ return false;
+}
+
+// [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? 'font-family'
+bool CSSParser::parseFont(bool important)
+{
+ bool valid = true;
+ Value *value = valueList->current();
+ RefPtr<FontValue> font = new FontValue;
+ // optional font-style, font-variant and font-weight
+ while (value) {
+ int id = value->id;
+ if (id) {
+ if (id == CSS_VAL_NORMAL) {
+ // do nothing, it's the inital value for all three
+ } else if (id == CSS_VAL_ITALIC || id == CSS_VAL_OBLIQUE) {
+ if (font->style)
+ return false;
+ font->style = new CSSPrimitiveValue(id);
+ } else if (id == CSS_VAL_SMALL_CAPS) {
+ if (font->variant)
+ return false;
+ font->variant = new CSSPrimitiveValue(id);
+ } else if (id >= CSS_VAL_BOLD && id <= CSS_VAL_LIGHTER) {
+ if (font->weight)
+ return false;
+ font->weight = new CSSPrimitiveValue(id);
+ } else {
+ valid = false;
+ }
+ } else if (!font->weight && validUnit(value, FInteger|FNonNeg, true)) {
+ int weight = (int)value->fValue;
+ int val = 0;
+ if (weight == 100)
+ val = CSS_VAL_100;
+ else if (weight == 200)
+ val = CSS_VAL_200;
+ else if (weight == 300)
+ val = CSS_VAL_300;
+ else if (weight == 400)
+ val = CSS_VAL_400;
+ else if (weight == 500)
+ val = CSS_VAL_500;
+ else if (weight == 600)
+ val = CSS_VAL_600;
+ else if (weight == 700)
+ val = CSS_VAL_700;
+ else if (weight == 800)
+ val = CSS_VAL_800;
+ else if (weight == 900)
+ val = CSS_VAL_900;
+
+ if (val)
+ font->weight = new CSSPrimitiveValue(val);
+ else
+ valid = false;
+ } else {
+ valid = false;
+ }
+ if (!valid)
+ break;
+ value = valueList->next();
+ }
+ if (!value)
+ return false;
+
+ // set undefined values to default
+ if (!font->style)
+ font->style = new CSSPrimitiveValue(CSS_VAL_NORMAL);
+ if (!font->variant)
+ font->variant = new CSSPrimitiveValue(CSS_VAL_NORMAL);
+ if (!font->weight)
+ font->weight = new CSSPrimitiveValue(CSS_VAL_NORMAL);
+
+ // now a font size _must_ come
+ // <absolute-size> | <relative-size> | <length> | <percentage> | inherit
+ if (value->id >= CSS_VAL_XX_SMALL && value->id <= CSS_VAL_LARGER)
+ font->size = new CSSPrimitiveValue(value->id);
+ else if (validUnit(value, FLength|FPercent, strict))
+ font->size = new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+ value = valueList->next();
+ if (!font->size || !value)
+ return false;
+
+ if (value->unit == Value::Operator && value->iValue == '/') {
+ // line-height
+ value = valueList->next();
+ if (!value)
+ return false;
+ if (value->id == CSS_VAL_NORMAL) {
+ // default value, nothing to do
+ } else if (validUnit(value, FNumber|FLength|FPercent, strict))
+ font->lineHeight = new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+ else
+ return false;
+ value = valueList->next();
+ if (!value)
+ return false;
+ }
+
+ if (!font->lineHeight)
+ font->lineHeight = new CSSPrimitiveValue(CSS_VAL_NORMAL);
+
+ // font family must come now
+ font->family = parseFontFamily();
+
+ if (valueList->current() || !font->family)
+ return false;
+
+ addProperty(CSS_PROP_FONT, font.release(), important);
+ return true;
+}
+
+PassRefPtr<CSSValueList> CSSParser::parseFontFamily()
+{
+ CSSValueList* list = new CSSValueList;
+ Value* value = valueList->current();
+ FontFamilyValue* currFamily = 0;
+ while (value) {
+ Value* nextValue = valueList->next();
+ bool nextValBreaksFont = !nextValue ||
+ (nextValue->unit == Value::Operator && nextValue->iValue == ',');
+ bool nextValIsFontName = nextValue &&
+ ((nextValue->id >= CSS_VAL_SERIF && nextValue->id <= CSS_VAL__WEBKIT_BODY) ||
+ (nextValue->unit == CSSPrimitiveValue::CSS_STRING || nextValue->unit == CSSPrimitiveValue::CSS_IDENT));
+
+ if (value->id >= CSS_VAL_SERIF && value->id <= CSS_VAL__WEBKIT_BODY) {
+ if (currFamily)
+ currFamily->appendSpaceSeparated(value->string.characters, value->string.length);
+ else if (nextValBreaksFont || !nextValIsFontName)
+ list->append(new CSSPrimitiveValue(value->id));
+ else
+ list->append(currFamily = new FontFamilyValue(value->string));
+ }
+ else if (value->unit == CSSPrimitiveValue::CSS_STRING) {
+ // Strings never share in a family name.
+ currFamily = 0;
+ list->append(new FontFamilyValue(value->string));
+ }
+ else if (value->unit == CSSPrimitiveValue::CSS_IDENT) {
+ if (currFamily)
+ currFamily->appendSpaceSeparated(value->string.characters, value->string.length);
+ else if (nextValBreaksFont || !nextValIsFontName)
+ list->append(new FontFamilyValue(value->string));
+ else
+ list->append(currFamily = new FontFamilyValue(value->string));
+ }
+ else {
+ break;
+ }
+
+ if (!nextValue)
+ break;
+
+ if (nextValBreaksFont) {
+ value = valueList->next();
+ currFamily = 0;
+ }
+ else if (nextValIsFontName)
+ value = nextValue;
+ else
+ break;
+ }
+ if (!list->length()) {
+ delete list;
+ list = 0;
+ }
+ return list;
+}
+
+bool CSSParser::parseFontFaceSrc()
+{
+ RefPtr<CSSValueList> values(new CSSValueList());
+ Value* val;
+ bool expectComma = false;
+ bool allowFormat = false;
+ bool failed = false;
+ RefPtr<CSSFontFaceSrcValue> uriValue;
+ while ((val = valueList->current())) {
+ RefPtr<CSSFontFaceSrcValue> parsedValue;
+ if (val->unit == CSSPrimitiveValue::CSS_URI && !expectComma) {
+ String value = parseURL(val->string);
+ parsedValue = new CSSFontFaceSrcValue(KURL(styleElement->baseURL(), value).string(), false);
+ uriValue = parsedValue;
+ allowFormat = true;
+ expectComma = true;
+ } else if (val->unit == Value::Function) {
+ // There are two allowed functions: local() and format().
+ ValueList* args = val->function->args;
+ if (args && args->size() == 1) {
+ if (equalIgnoringCase(val->function->name, "local(") && !expectComma) {
+ expectComma = true;
+ allowFormat = false;
+ Value* a = args->current();
+ uriValue.clear();
+ parsedValue = new CSSFontFaceSrcValue(a->string, true);
+ } else if (equalIgnoringCase(val->function->name, "format(") && allowFormat && uriValue) {
+ expectComma = true;
+ allowFormat = false;
+ uriValue->setFormat(args->current()->string);
+ uriValue.clear();
+ valueList->next();
+ continue;
+ }
+ }
+ } else if (val->unit == Value::Operator && val->iValue == ',' && expectComma) {
+ expectComma = false;
+ allowFormat = false;
+ uriValue.clear();
+ valueList->next();
+ continue;
+ }
+
+ if (parsedValue)
+ values->append(parsedValue.release());
+ else {
+ failed = true;
+ break;
+ }
+ valueList->next();
+ }
+
+ if (values->length() && !failed) {
+ addProperty(CSS_PROP_SRC, values.release(), important);
+ valueList->next();
+ return true;
+ }
+
+ return false;
+}
+
+bool CSSParser::parseFontFaceUnicodeRange()
+{
+ CSSValueList* values = new CSSValueList();
+ Value* currentValue;
+ bool failed = false;
+ while ((currentValue = valueList->current())) {
+ if (valueList->current()->unit != CSSPrimitiveValue::CSS_UNICODE_RANGE) {
+ failed = true;
+ break;
+ }
+
+ String rangeString = valueList->current()->string;
+ UChar32 from = 0;
+ UChar32 to = 0;
+ unsigned length = rangeString.length();
+
+ if (length < 3) {
+ failed = true;
+ break;
+ }
+
+ unsigned i = 2;
+ while (i < length) {
+ UChar c = rangeString[i];
+ if (c == '-' || c == '?')
+ break;
+ from *= 16;
+ if (c >= '0' && c <= '9')
+ from += c - '0';
+ else if (c >= 'A' && c <= 'F')
+ from += 10 + c - 'A';
+ else if (c >= 'a' && c <= 'f')
+ from += 10 + c - 'a';
+ else {
+ failed = true;
+ break;
+ }
+ i++;
+ }
+ if (failed)
+ break;
+
+ if (i == length)
+ to = from;
+ else if (rangeString[i] == '?') {
+ unsigned span = 1;
+ while (i < length && rangeString[i] == '?') {
+ span *= 16;
+ from *= 16;
+ i++;
+ }
+ if (i < length)
+ failed = true;
+ to = from + span - 1;
+ } else {
+ if (length < i + 2) {
+ failed = true;
+ break;
+ }
+ i++;
+ while (i < length) {
+ UChar c = rangeString[i];
+ to *= 16;
+ if (c >= '0' && c <= '9')
+ to += c - '0';
+ else if (c >= 'A' && c <= 'F')
+ to += 10 + c - 'A';
+ else if (c >= 'a' && c <= 'f')
+ to += 10 + c - 'a';
+ else {
+ failed = true;
+ break;
+ }
+ i++;
+ }
+ if (failed)
+ break;
+ }
+ values->append(new CSSUnicodeRangeValue(from, to));
+ valueList->next();
+ }
+ if (failed || !values->length()) {
+ delete values;
+ return false;
+ }
+ addProperty(CSS_PROP_UNICODE_RANGE, values, important);
+ return true;
+}
+
+bool CSSParser::parseColor(const String &name, RGBA32& rgb, bool strict)
+{
+ if (!strict && Color::parseHexColor(name, rgb))
+ return true;
+
+ // try a little harder
+ Color tc;
+ tc.setNamedColor(name);
+ if (tc.isValid()) {
+ rgb = tc.rgb();
+ return true;
+ }
+
+ return false;
+}
+
+bool CSSParser::parseColorParameters(Value* value, int* colorArray, bool parseAlpha)
+{
+ ValueList* args = value->function->args;
+ Value* v = args->current();
+ // Get the first value
+ if (!validUnit(v, FInteger | FPercent, true))
+ return false;
+ colorArray[0] = static_cast<int>(v->fValue * (v->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 256.0 / 100.0 : 1.0));
+ for (int i = 1; i < 3; i++) {
+ v = args->next();
+ if (v->unit != Value::Operator && v->iValue != ',')
+ return false;
+ v = args->next();
+ if (!validUnit(v, FInteger | FPercent, true))
+ return false;
+ colorArray[i] = static_cast<int>(v->fValue * (v->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 256.0 / 100.0 : 1.0));
+ }
+ if (parseAlpha) {
+ v = args->next();
+ if (v->unit != Value::Operator && v->iValue != ',')
+ return false;
+ v = args->next();
+ if (!validUnit(v, FNumber, true))
+ return false;
+ colorArray[3] = static_cast<int>(max(0.0, min(1.0, v->fValue)) * 255);
+ }
+ return true;
+}
+
+// CSS3 sepcification defines the format of a HSL color as
+// hsl(<number>, <percent>, <percent>)
+// and with alpha, the format is
+// hsla(<number>, <percent>, <percent>, <number>)
+// The first value, HUE, is in an angle with a value between 0 and 360
+bool CSSParser::parseHSLParameters(Value* value, double* colorArray, bool parseAlpha)
+{
+ ValueList* args = value->function->args;
+ Value* v = args->current();
+ // Get the first value
+ 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;
+ for (int i = 1; i < 3; i++) {
+ v = args->next();
+ if (v->unit != Value::Operator && v->iValue != ',')
+ return false;
+ 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
+ }
+ if (parseAlpha) {
+ v = args->next();
+ if (v->unit != Value::Operator && v->iValue != ',')
+ return false;
+ v = args->next();
+ if (!validUnit(v, FNumber, true))
+ return false;
+ colorArray[3] = max(0.0, min(1.0, v->fValue));
+ }
+ return true;
+}
+
+PassRefPtr<CSSPrimitiveValue> CSSParser::parseColor(Value* value)
+{
+ RGBA32 c = Color::transparent;
+ if (!parseColorFromValue(value ? value : valueList->current(), c))
+ return 0;
+ return new CSSPrimitiveValue(c);
+}
+
+bool CSSParser::parseColorFromValue(Value* value, RGBA32& c, bool svg)
+{
+ if (!strict && value->unit == CSSPrimitiveValue::CSS_NUMBER &&
+ value->fValue >= 0. && value->fValue < 1000000.) {
+ String str = String::format("%06d", (int)(value->fValue+.5));
+ if (!CSSParser::parseColor(str, c, strict))
+ return false;
+ } else if (value->unit == CSSPrimitiveValue::CSS_RGBCOLOR ||
+ value->unit == CSSPrimitiveValue::CSS_IDENT ||
+ (!strict && value->unit == CSSPrimitiveValue::CSS_DIMENSION)) {
+ if (!CSSParser::parseColor(value->string, c, strict && value->unit == CSSPrimitiveValue::CSS_IDENT))
+ return false;
+ } else if (value->unit == Value::Function &&
+ value->function->args != 0 &&
+ value->function->args->size() == 5 /* rgb + two commas */ &&
+ equalIgnoringCase(value->function->name, "rgb(")) {
+ int colorValues[3];
+ if (!parseColorParameters(value, colorValues, false))
+ return false;
+ c = makeRGB(colorValues[0], colorValues[1], colorValues[2]);
+ } else if (!svg) {
+ if (value->unit == Value::Function &&
+ value->function->args != 0 &&
+ value->function->args->size() == 7 /* rgba + three commas */ &&
+ equalIgnoringCase(value->function->name, "rgba(")) {
+ int colorValues[4];
+ if (!parseColorParameters(value, colorValues, true))
+ return false;
+ c = makeRGBA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
+ } else if (value->unit == Value::Function &&
+ value->function->args != 0 &&
+ value->function->args->size() == 5 /* hsl + two commas */ &&
+ equalIgnoringCase(value->function->name, "hsl(")) {
+ double colorValues[3];
+ if (!parseHSLParameters(value, colorValues, false))
+ return false;
+ c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], 1.0);
+ } else if (value->unit == Value::Function &&
+ value->function->args != 0 &&
+ value->function->args->size() == 7 /* hsla + three commas */ &&
+ equalIgnoringCase(value->function->name, "hsla(")) {
+ double colorValues[4];
+ if (!parseHSLParameters(value, colorValues, true))
+ return false;
+ c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
+ } else
+ return false;
+ } else
+ return false;
+
+ return true;
+}
+
+// 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()
+ : allowX(true)
+ , allowY(false)
+ , allowBlur(false)
+ , allowColor(true)
+ , allowBreak(true)
+ {}
+
+ bool allowLength() { return allowX || allowY || allowBlur; }
+
+ void commitValue() {
+ // Handle the ,, case gracefully by doing nothing.
+ if (x || y || blur || color) {
+ if (!values)
+ values = new CSSValueList();
+
+ // Construct the current shadow value and add it to the list.
+ values->append(new ShadowValue(x.release(), y.release(), blur.release(), color.release()));
+ }
+
+ // Now reset for the next shadow value.
+ x = y = blur = color = 0;
+ allowX = allowColor = allowBreak = true;
+ allowY = allowBlur = false;
+ }
+
+ void commitLength(Value* v) {
+ RefPtr<CSSPrimitiveValue> val = new CSSPrimitiveValue(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
+
+ if (allowX) {
+ x = val.release();
+ allowX = false; allowY = true; allowColor = false; allowBreak = false;
+ }
+ else if (allowY) {
+ y = val.release();
+ allowY = false; allowBlur = true; allowColor = true; allowBreak = true;
+ }
+ else if (allowBlur) {
+ blur = val.release();
+ allowBlur = false;
+ }
+ }
+
+ void commitColor(PassRefPtr<CSSPrimitiveValue> val) {
+ color = val;
+ allowColor = false;
+ if (allowX)
+ allowBreak = false;
+ else
+ allowBlur = false;
+ }
+
+ RefPtr<CSSValueList> values;
+ RefPtr<CSSPrimitiveValue> x;
+ RefPtr<CSSPrimitiveValue> y;
+ RefPtr<CSSPrimitiveValue> blur;
+ RefPtr<CSSPrimitiveValue> color;
+
+ bool allowX;
+ bool allowY;
+ bool allowBlur;
+ bool allowColor;
+ bool allowBreak;
+};
+
+bool CSSParser::parseShadow(int propId, bool important)
+{
+ ShadowParseContext context;
+ Value* val;
+ while ((val = valueList->current())) {
+ // Check for a comma break first.
+ if (val->unit == Value::Operator) {
+ if (val->iValue != ',' || !context.allowBreak)
+ // Other operators aren't legal or we aren't done with the current shadow
+ // value. Treat as invalid.
+ return false;
+
+ // The value is good. Commit it.
+ context.commitValue();
+ }
+ // Check to see if we're a length.
+ else if (validUnit(val, FLength, true)) {
+ // We required a length and didn't get one. Invalid.
+ if (!context.allowLength())
+ return false;
+
+ // A length is allowed here. Construct the value and add it.
+ context.commitLength(val);
+ }
+ else {
+ // The only other type of value that's ok is a color value.
+ RefPtr<CSSPrimitiveValue> parsedColor;
+ bool isColor = (val->id >= CSS_VAL_AQUA && val->id <= CSS_VAL_WINDOWTEXT || val->id == CSS_VAL_MENU ||
+ (val->id >= CSS_VAL__WEBKIT_FOCUS_RING_COLOR && val->id <= CSS_VAL__WEBKIT_TEXT && !strict));
+ if (isColor) {
+ if (!context.allowColor)
+ return false;
+ parsedColor = new CSSPrimitiveValue(val->id);
+ }
+
+ if (!parsedColor)
+ // It's not built-in. Try to parse it as a color.
+ parsedColor = parseColor(val);
+
+ if (!parsedColor || !context.allowColor)
+ return false; // This value is not a color or length and is invalid or
+ // it is a color, but a color isn't allowed at this point.
+
+ context.commitColor(parsedColor.release());
+ }
+
+ valueList->next();
+ }
+
+ if (context.allowBreak) {
+ context.commitValue();
+ if (context.values->length()) {
+ addProperty(propId, context.values.release(), important);
+ valueList->next();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+struct BorderImageParseContext
+{
+ BorderImageParseContext()
+ : m_allowBreak(false)
+ , m_allowNumber(false)
+ , m_allowSlash(false)
+ , m_allowWidth(false)
+ , m_allowRule(false)
+ , m_borderTop(0)
+ , m_borderRight(0)
+ , m_borderBottom(0)
+ , m_borderLeft(0)
+ , m_horizontalRule(0)
+ , m_verticalRule(0)
+ {}
+
+ bool allowBreak() const { return m_allowBreak; }
+ bool allowNumber() const { return m_allowNumber; }
+ bool allowSlash() const { return m_allowSlash; }
+ bool allowWidth() const { return m_allowWidth; }
+ bool allowRule() const { return m_allowRule; }
+
+ void commitImage(CSSImageValue* image) { m_image = image; m_allowNumber = true; }
+ void commitNumber(Value* v) {
+ PassRefPtr<CSSPrimitiveValue> val = new CSSPrimitiveValue(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
+ if (!m_top)
+ m_top = val;
+ else if (!m_right)
+ m_right = val;
+ else if (!m_bottom)
+ m_bottom = val;
+ else {
+ ASSERT(!m_left);
+ m_left = val;
+ }
+
+ m_allowBreak = m_allowSlash = m_allowRule = true;
+ m_allowNumber = !m_left;
+ }
+ void commitSlash() { m_allowBreak = m_allowSlash = m_allowNumber = false; m_allowWidth = true; }
+ void commitWidth(Value* val) {
+ if (!m_borderTop)
+ m_borderTop = val;
+ else if (!m_borderRight)
+ m_borderRight = val;
+ else if (!m_borderBottom)
+ m_borderBottom = val;
+ else {
+ ASSERT(!m_borderLeft);
+ m_borderLeft = val;
+ }
+
+ m_allowBreak = m_allowRule = true;
+ m_allowWidth = !m_borderLeft;
+ }
+ void commitRule(int keyword) {
+ if (!m_horizontalRule)
+ m_horizontalRule = keyword;
+ else if (!m_verticalRule)
+ m_verticalRule = keyword;
+ m_allowRule = !m_verticalRule;
+ }
+ void commitBorderImage(CSSParser* p, int propId, bool important) {
+ // We need to clone and repeat values for any omissions.
+ if (!m_right) {
+ m_right = new CSSPrimitiveValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+ m_bottom = new CSSPrimitiveValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+ m_left = new CSSPrimitiveValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+ }
+ if (!m_bottom) {
+ m_bottom = new CSSPrimitiveValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+ m_left = new CSSPrimitiveValue(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
+ }
+ if (!m_left)
+ m_left = new CSSPrimitiveValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+
+ // Now build a rect value to hold all four of our primitive values.
+ RefPtr<Rect> rect = new Rect;
+ rect->setTop(m_top);
+ rect->setRight(m_right);
+ rect->setBottom(m_bottom);
+ rect->setLeft(m_left);
+
+ // Fill in STRETCH as the default if it wasn't specified.
+ if (!m_horizontalRule)
+ m_horizontalRule = CSS_VAL_STRETCH;
+
+ // The vertical rule should match the horizontal rule if unspecified.
+ if (!m_verticalRule)
+ m_verticalRule = m_horizontalRule;
+
+ // Make our new border image value now and add it as the result.
+ CSSBorderImageValue* borderImage = new CSSBorderImageValue(m_image, rect.release(), m_horizontalRule, m_verticalRule);
+ p->addProperty(propId, borderImage, important);
+
+ // Now we have to deal with the border widths. The best way to deal with these is to actually put these values into a value
+ // list and then make our parsing machinery do the parsing.
+ if (m_borderTop) {
+ ValueList newList;
+ newList.addValue(*m_borderTop);
+ if (m_borderRight)
+ newList.addValue(*m_borderRight);
+ if (m_borderBottom)
+ newList.addValue(*m_borderBottom);
+ if (m_borderLeft)
+ newList.addValue(*m_borderLeft);
+ p->valueList = &newList;
+ p->parseValue(CSS_PROP_BORDER_WIDTH, important);
+ p->valueList = 0;
+ }
+ }
+
+ bool m_allowBreak;
+ bool m_allowNumber;
+ bool m_allowSlash;
+ bool m_allowWidth;
+ bool m_allowRule;
+
+ RefPtr<CSSImageValue> m_image;
+
+ RefPtr<CSSPrimitiveValue> m_top;
+ RefPtr<CSSPrimitiveValue> m_right;
+ RefPtr<CSSPrimitiveValue> m_bottom;
+ RefPtr<CSSPrimitiveValue> m_left;
+
+ Value* m_borderTop;
+ Value* m_borderRight;
+ Value* m_borderBottom;
+ Value* m_borderLeft;
+
+ int m_horizontalRule;
+ int m_verticalRule;
+};
+
+bool CSSParser::parseBorderImage(int propId, bool important)
+{
+ // Look for an image initially. If the first value is not a URI, then we're done.
+ BorderImageParseContext context;
+ Value* val = valueList->current();
+ if (val->unit != CSSPrimitiveValue::CSS_URI)
+ return false;
+
+ String uri = parseURL(val->string);
+ if (uri.isEmpty())
+ return false;
+
+ context.commitImage(new CSSImageValue(KURL(styleElement->baseURL(), uri).string(), styleElement));
+ while ((val = valueList->next())) {
+ if (context.allowNumber() && validUnit(val, FInteger|FNonNeg|FPercent, true)) {
+ context.commitNumber(val);
+ } else if (context.allowSlash() && val->unit == Value::Operator && val->iValue == '/') {
+ context.commitSlash();
+ } else if (context.allowWidth() &&
+ (val->id == CSS_VAL_THIN || val->id == CSS_VAL_MEDIUM || val->id == CSS_VAL_THICK || validUnit(val, FLength, strict))) {
+ context.commitWidth(val);
+ } else if (context.allowRule() &&
+ (val->id == CSS_VAL_STRETCH || val->id == CSS_VAL_ROUND || val->id == CSS_VAL_REPEAT)) {
+ context.commitRule(val->id);
+ } else {
+ // Something invalid was encountered.
+ return false;
+ }
+ }
+
+ if (context.allowBreak()) {
+ // Need to fully commit as a single value.
+ context.commitBorderImage(this, propId, important);
+ return true;
+ }
+
+ return false;
+}
+
+bool CSSParser::parseCounter(int propId, int defaultValue, bool important)
+{
+ enum { ID, VAL } state = ID;
+
+ RefPtr<CSSValueList> list = new CSSValueList;
+ RefPtr<CSSPrimitiveValue> counterName;
+
+ while (true) {
+ Value* val = valueList->current();
+ switch (state) {
+ case ID:
+ if (val && val->unit == CSSPrimitiveValue::CSS_IDENT) {
+ counterName = new CSSPrimitiveValue(val->string, CSSPrimitiveValue::CSS_STRING);
+ state = VAL;
+ valueList->next();
+ continue;
+ }
+ break;
+ case VAL: {
+ int i = defaultValue;
+ if (val && val->unit == CSSPrimitiveValue::CSS_NUMBER) {
+ i = (int)val->fValue;
+ valueList->next();
+ }
+
+ list->append(new CSSPrimitiveValue(new Pair(counterName.release(),
+ new CSSPrimitiveValue(i, CSSPrimitiveValue::CSS_NUMBER))));
+ state = ID;
+ continue;
+ }
+ }
+ break;
+ }
+
+ if (list->length() > 0) {
+ addProperty(propId, list.release(), important);
+ return true;
+ }
+
+ return false;
+}
+
+class TransformOperationInfo {
+public:
+ TransformOperationInfo(const ParseString& name)
+ : m_type(CSSTransformValue::UnknownTransformOperation)
+ , m_argCount(1)
+ , m_allowSingleArgument(false)
+ , m_unit(CSSParser::FUnknown)
+ {
+ if (equalIgnoringCase(name, "scale(") || equalIgnoringCase(name, "scaleX(") || equalIgnoringCase(name, "scaleY(")) {
+ m_unit = CSSParser::FNumber;
+ if (equalIgnoringCase(name, "scale("))
+ m_type = CSSTransformValue::ScaleTransformOperation;
+ else if (equalIgnoringCase(name, "scaleX("))
+ m_type = CSSTransformValue::ScaleXTransformOperation;
+ else
+ m_type = CSSTransformValue::ScaleYTransformOperation;
+ } else if (equalIgnoringCase(name, "rotate(")) {
+ m_type = CSSTransformValue::RotateTransformOperation;
+ m_unit = CSSParser::FAngle;
+ } else if (equalIgnoringCase(name, "skew(") || equalIgnoringCase(name, "skewX(") || equalIgnoringCase(name, "skewY(")) {
+ m_unit = CSSParser::FAngle;
+ if (equalIgnoringCase(name, "skew("))
+ m_type = CSSTransformValue::SkewTransformOperation;
+ else if (equalIgnoringCase(name, "skewX("))
+ m_type = CSSTransformValue::SkewXTransformOperation;
+ else
+ m_type = CSSTransformValue::SkewYTransformOperation;
+ } else if (equalIgnoringCase(name, "translate(") || equalIgnoringCase(name, "translateX(") || equalIgnoringCase(name, "translateY(")) {
+ m_unit = CSSParser::FLength | CSSParser::FPercent;
+ if (equalIgnoringCase(name, "translate("))
+ m_type = CSSTransformValue::TranslateTransformOperation;
+ else if (equalIgnoringCase(name, "translateX("))
+ m_type = CSSTransformValue::TranslateXTransformOperation;
+ else
+ m_type = CSSTransformValue::TranslateYTransformOperation;
+ } else if (equalIgnoringCase(name, "matrix(")) {
+ m_type = CSSTransformValue::MatrixTransformOperation;
+ m_argCount = 11;
+ m_unit = CSSParser::FNumber;
+ }
+
+ if (equalIgnoringCase(name, "scale(") || equalIgnoringCase(name, "skew(") || equalIgnoringCase(name, "translate(")) {
+ m_allowSingleArgument = true;
+ m_argCount = 3;
+ }
+ }
+
+ CSSTransformValue::TransformOperationType type() const { return m_type; }
+ unsigned argCount() const { return m_argCount; }
+ CSSParser::Units unit() const { return m_unit; }
+
+ bool unknown() const { return m_type == CSSTransformValue::UnknownTransformOperation; }
+ bool hasCorrectArgCount(unsigned argCount) { return m_argCount == argCount || (m_allowSingleArgument && argCount == 1); }
+
+private:
+ CSSTransformValue::TransformOperationType m_type;
+ unsigned m_argCount;
+ bool m_allowSingleArgument;
+ CSSParser::Units m_unit;
+};
+
+PassRefPtr<CSSValue> CSSParser::parseTransform()
+{
+ if (!valueList)
+ return 0;
+
+ // The transform is a list of functional primitives that specify transform operations. We collect a list
+ // of CSSTransformValues, where each value specifies a single operation.
+ RefPtr<CSSValueList> list = new CSSValueList;
+ for (Value* value = valueList->current(); value; value = valueList->next()) {
+ if (value->unit != Value::Function || !value->function)
+ return 0;
+
+ // Every primitive requires at least one argument.
+ ValueList* args = value->function->args;
+ if (!args)
+ return 0;
+
+ // See if the specified primitive is one we understand.
+ TransformOperationInfo info(value->function->name);
+ if (info.unknown())
+ return 0;
+
+ if (!info.hasCorrectArgCount(args->size()))
+ return 0;
+
+ // Create the new CSSTransformValue for this operation and add it to our list.
+ CSSTransformValue* transformValue = new CSSTransformValue(info.type());
+ list->append(transformValue);
+
+ // Snag our values.
+ Value* a = args->current();
+ unsigned argNumber = 0;
+ while (a) {
+ CSSParser::Units unit = info.unit();
+
+ if (!validUnit(a, unit, true))
+ return 0;
+
+ // Add the value to the current transform operation.
+ transformValue->addValue(new CSSPrimitiveValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit));
+
+ a = args->next();
+ if (!a)
+ break;
+ if (a->unit != Value::Operator || a->iValue != ',')
+ return 0;
+ a = args->next();
+
+ argNumber++;
+ }
+ }
+
+ return list.release();
+}
+
+bool CSSParser::parseTransformOrigin(int propId, int& propId1, int& propId2, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2)
+{
+ propId1 = propId;
+ propId2 = propId;
+ if (propId == CSS_PROP__WEBKIT_TRANSFORM_ORIGIN) {
+ propId1 = CSS_PROP__WEBKIT_TRANSFORM_ORIGIN_X;
+ propId2 = CSS_PROP__WEBKIT_TRANSFORM_ORIGIN_Y;
+ }
+
+ switch (propId) {
+ case CSS_PROP__WEBKIT_TRANSFORM_ORIGIN:
+ parseBackgroundPosition(value, value2);
+ // Unlike the other functions, parseBackgroundPosition advances the valueList pointer
+ break;
+ case CSS_PROP__WEBKIT_TRANSFORM_ORIGIN_X: {
+ bool xFound = false, yFound = true;
+ value = parseBackgroundPositionXY(xFound, yFound);
+ if (value)
+ valueList->next();
+ break;
+ }
+ case CSS_PROP__WEBKIT_TRANSFORM_ORIGIN_Y: {
+ bool xFound = true, yFound = false;
+ value = parseBackgroundPositionXY(xFound, yFound);
+ if (value)
+ valueList->next();
+ break;
+ }
+ }
+
+ return value;
+}
+
+#ifdef CSS_DEBUG
+
+static inline int yyerror(const char *str)
+{
+ kdDebug(6080) << "CSS parse error " << str << endl;
+ return 1;
+}
+
+#else
+
+static inline int yyerror(const char*) { return 1; }
+
+#endif
+
+#define END_TOKEN 0
+
+#include "CSSGrammar.h"
+
+int CSSParser::lex(void* yylvalWithoutType)
+{
+ YYSTYPE* yylval = static_cast<YYSTYPE*>(yylvalWithoutType);
+ int token = lex();
+ int length;
+ UChar* t = text(&length);
+
+ switch(token) {
+ case WHITESPACE:
+ case SGML_CD:
+ case INCLUDES:
+ case DASHMATCH:
+ break;
+
+ case URI:
+ case STRING:
+ case IDENT:
+ case NTH:
+ case HEX:
+ case IDSEL:
+ case DIMEN:
+ case UNICODERANGE:
+ case FUNCTION:
+ case NOTFUNCTION:
+ 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 IMPORTANT_SYM:
+ break;
+
+ case QEMS:
+ length--;
+ case GRADS:
+ length--;
+ case DEGS:
+ case RADS:
+ case KHERZ:
+ length--;
+ case MSECS:
+ case HERZ:
+ 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);
+ break;
+
+ default:
+ break;
+ }
+
+ return token;
+}
+
+static inline int toHex(char c)
+{
+ if ('0' <= c && c <= '9')
+ return c - '0';
+ if ('a' <= c && c <= 'f')
+ return c - 'a' + 10;
+ if ('A' <= c && c<= 'F')
+ return c - 'A' + 10;
+ return 0;
+}
+
+UChar* CSSParser::text(int *length)
+{
+ UChar* start = yytext;
+ int l = yyleng;
+ switch(yyTok) {
+ case STRING:
+ l--;
+ /* nobreak */
+ case HEX:
+ case IDSEL:
+ start++;
+ l--;
+ break;
+ case URI:
+ // "url("{w}{string}{w}")"
+ // "url("{w}{url}{w}")"
+
+ // strip "url(" and ")"
+ start += 4;
+ l -= 5;
+ // strip {w}
+ while (l &&
+ (*start == ' ' || *start == '\t' || *start == '\r' ||
+ *start == '\n' || *start == '\f')) {
+ start++; l--;
+ }
+ if (*start == '"' || *start == '\'') {
+ start++; l--;
+ }
+ while (l &&
+ (start[l-1] == ' ' || start[l-1] == '\t' || start[l-1] == '\r' ||
+ start[l-1] == '\n' || start[l-1] == '\f')) {
+ l--;
+ }
+ if (l && (start[l-1] == '\"' || start[l-1] == '\''))
+ l--;
+
+ default:
+ break;
+ }
+
+ // process escapes
+ UChar* out = start;
+ UChar* escape = 0;
+
+ for (int i = 0; i < l; i++) {
+ UChar* current = start + i;
+ if (escape == current - 1) {
+ if ((*current >= '0' && *current <= '9') ||
+ (*current >= 'a' && *current <= 'f') ||
+ (*current >= 'A' && *current <= 'F'))
+ continue;
+ if (yyTok == STRING &&
+ (*current == '\n' || *current == '\r' || *current == '\f')) {
+ // ### handle \r\n case
+ if (*current != '\r')
+ escape = 0;
+ continue;
+ }
+ // in all other cases copy the char to output
+ // ###
+ *out++ = *current;
+ escape = 0;
+ continue;
+ }
+ if (escape == current - 2 && yyTok == STRING &&
+ *(current-1) == '\r' && *current == '\n') {
+ escape = 0;
+ continue;
+ }
+ if (escape > current - 7 &&
+ ((*current >= '0' && *current <= '9') ||
+ (*current >= 'a' && *current <= 'f') ||
+ (*current >= 'A' && *current <= 'F')))
+ continue;
+ if (escape) {
+ // add escaped char
+ unsigned uc = 0;
+ escape++;
+ while (escape < current) {
+ uc *= 16;
+ uc += toHex(*escape);
+ escape++;
+ }
+ // can't handle chars outside ucs2
+ if (uc > 0xffff)
+ uc = 0xfffd;
+ *out++ = uc;
+ escape = 0;
+ if (*current == ' ' ||
+ *current == '\t' ||
+ *current == '\r' ||
+ *current == '\n' ||
+ *current == '\f')
+ continue;
+ }
+ if (!escape && *current == '\\') {
+ escape = current;
+ continue;
+ }
+ *out++ = *current;
+ }
+ if (escape) {
+ // add escaped char
+ unsigned uc = 0;
+ escape++;
+ while (escape < start+l) {
+ uc *= 16;
+ uc += toHex(*escape);
+ escape++;
+ }
+ // can't handle chars outside ucs2
+ if (uc > 0xffff)
+ uc = 0xfffd;
+ *out++ = uc;
+ }
+
+ *length = out - start;
+ return start;
+}
+
+CSSSelector* CSSParser::createFloatingSelector()
+{
+ CSSSelector* selector = new CSSSelector;
+ m_floatingSelectors.add(selector);
+ return selector;
+}
+
+CSSSelector* CSSParser::sinkFloatingSelector(CSSSelector* selector)
+{
+ if (selector) {
+ ASSERT(m_floatingSelectors.contains(selector));
+ m_floatingSelectors.remove(selector);
+ }
+ return selector;
+}
+
+ValueList* CSSParser::createFloatingValueList()
+{
+ ValueList* list = new ValueList;
+ m_floatingValueLists.add(list);
+ return list;
+}
+
+ValueList* CSSParser::sinkFloatingValueList(ValueList* list)
+{
+ if (list) {
+ ASSERT(m_floatingValueLists.contains(list));
+ m_floatingValueLists.remove(list);
+ }
+ return list;
+}
+
+Function* CSSParser::createFloatingFunction()
+{
+ Function* function = new Function;
+ m_floatingFunctions.add(function);
+ return function;
+}
+
+Function* CSSParser::sinkFloatingFunction(Function* function)
+{
+ if (function) {
+ ASSERT(m_floatingFunctions.contains(function));
+ m_floatingFunctions.remove(function);
+ }
+ return function;
+}
+
+Value& CSSParser::sinkFloatingValue(Value& value)
+{
+ if (value.unit == Value::Function) {
+ ASSERT(m_floatingFunctions.contains(value.function));
+ m_floatingFunctions.remove(value.function);
+ }
+ return value;
+}
+
+MediaQueryExp* CSSParser::createFloatingMediaQueryExp(const AtomicString& mediaFeature, ValueList* values)
+{
+ delete m_floatingMediaQueryExp;
+ m_floatingMediaQueryExp = new MediaQueryExp(mediaFeature, values);
+ return m_floatingMediaQueryExp;
+}
+
+MediaQueryExp* CSSParser::sinkFloatingMediaQueryExp(MediaQueryExp* e)
+{
+ ASSERT(e == m_floatingMediaQueryExp);
+ m_floatingMediaQueryExp = 0;
+ return e;
+}
+
+Vector<MediaQueryExp*>* CSSParser::createFloatingMediaQueryExpList()
+{
+ if (m_floatingMediaQueryExpList) {
+ deleteAllValues(*m_floatingMediaQueryExpList);
+ delete m_floatingMediaQueryExpList;
+ }
+ m_floatingMediaQueryExpList = new Vector<MediaQueryExp*>;
+ return m_floatingMediaQueryExpList;
+}
+
+Vector<MediaQueryExp*>* CSSParser::sinkFloatingMediaQueryExpList(Vector<MediaQueryExp*>* l)
+{
+ ASSERT(l == m_floatingMediaQueryExpList);
+ m_floatingMediaQueryExpList = 0;
+ return l;
+}
+
+MediaQuery* CSSParser::createFloatingMediaQuery(MediaQuery::Restrictor r, const String& mediaType, Vector<MediaQueryExp*>* exprs)
+{
+ delete m_floatingMediaQuery;
+ m_floatingMediaQuery = new MediaQuery(r, mediaType, exprs);
+ return m_floatingMediaQuery;
+}
+
+MediaQuery* CSSParser::sinkFloatingMediaQuery(MediaQuery* mq)
+{
+ ASSERT(mq == m_floatingMediaQuery);
+ m_floatingMediaQuery = 0;
+ return mq;
+}
+
+MediaList* CSSParser::createMediaList()
+{
+ MediaList* list = new MediaList;
+ m_parsedStyleObjects.append(list);
+ return list;
+}
+
+CSSRule* CSSParser::createCharsetRule(const ParseString& charset)
+{
+ if (!styleElement)
+ return 0;
+ if (!styleElement->isCSSStyleSheet())
+ return 0;
+ CSSCharsetRule* rule = new CSSCharsetRule(styleElement, charset);
+ m_parsedStyleObjects.append(rule);
+ return rule;
+}
+
+CSSRule* CSSParser::createImportRule(const ParseString& url, MediaList* media)
+{
+ if (!media)
+ return 0;
+ if (!styleElement)
+ return 0;
+ if (!styleElement->isCSSStyleSheet())
+ return 0;
+ CSSImportRule* rule = new CSSImportRule(styleElement, url, media);
+ m_parsedStyleObjects.append(rule);
+ return rule;
+}
+
+CSSRule* CSSParser::createMediaRule(MediaList* media, CSSRuleList* rules)
+{
+ if (!media)
+ return 0;
+ if (!rules)
+ return 0;
+ if (!styleElement)
+ return 0;
+ if (!styleElement->isCSSStyleSheet())
+ return 0;
+ CSSMediaRule* rule = new CSSMediaRule(styleElement, media, rules);
+ m_parsedStyleObjects.append(rule);
+ return rule;
+}
+
+CSSRuleList* CSSParser::createRuleList()
+{
+ CSSRuleList* list = new CSSRuleList;
+ m_parsedRuleLists.append(list);
+ return list;
+}
+
+CSSRule* CSSParser::createStyleRule(CSSSelector* selector)
+{
+ CSSStyleRule* rule = 0;
+ if (selector) {
+ rule = new CSSStyleRule(styleElement);
+ m_parsedStyleObjects.append(rule);
+ rule->setSelector(sinkFloatingSelector(selector));
+ rule->setDeclaration(new CSSMutableStyleDeclaration(rule, parsedProperties, numParsedProperties));
+ }
+ clearProperties();
+ return rule;
+}
+
+CSSRule* CSSParser::createFontFaceRule()
+{
+ CSSFontFaceRule* rule = new CSSFontFaceRule(styleElement);
+ m_parsedStyleObjects.append(rule);
+ rule->setDeclaration(new CSSMutableStyleDeclaration(rule, parsedProperties, numParsedProperties));
+ clearProperties();
+ return rule;
+}
+
+static int cssPropertyID(const UChar* propertyName, unsigned length)
+{
+ if (!length)
+ return 0;
+ if (length > maxCSSPropertyNameLength)
+ return 0;
+
+ char buffer[maxCSSPropertyNameLength + 1 + 1]; // 1 to turn "apple"/"khtml" into "webkit", 1 for null character
+
+ for (unsigned i = 0; i != length; ++i) {
+ UChar c = propertyName[i];
+ if (c == 0 || c >= 0x7F)
+ return 0; // illegal character
+ buffer[i] = toASCIILower(c);
+ }
+ buffer[length] = '\0';
+
+ const char* name = buffer;
+ if (buffer[0] == '-') {
+ // If the prefix is -apple- or -khtml-, change it to -webkit-.
+ // This makes the string one character longer.
+ if (hasPrefix(buffer, length, "-apple-") || hasPrefix(buffer, length, "-khtml-")) {
+ memmove(buffer + 7, buffer + 6, length + 1 - 6);
+ memcpy(buffer, "-webkit", 7);
+ ++length;
+ }
+
+ // Honor -webkit-opacity as a synonym for opacity.
+ // This was the only syntax that worked in Safari 1.1, and may be in use on some websites and widgets.
+ if (strcmp(buffer, "-webkit-opacity") == 0) {
+ const char * const opacity = "opacity";
+ name = opacity;
+ length = strlen(opacity);
+ }
+ }
+
+ const props* hashTableEntry = findProp(name, length);
+ return hashTableEntry ? hashTableEntry->id : 0;
+}
+
+int cssPropertyID(const String& string)
+{
+ return cssPropertyID(string.characters(), string.length());
+}
+
+int cssPropertyID(const ParseString& string)
+{
+ return cssPropertyID(string.characters, string.length);
+}
+
+int cssValueKeywordID(const ParseString& string)
+{
+ unsigned length = string.length;
+ if (!length)
+ return 0;
+ if (length > maxCSSValueKeywordLength)
+ return 0;
+
+ char buffer[maxCSSValueKeywordLength + 1 + 1]; // 1 to turn "apple"/"khtml" into "webkit", 1 for null character
+
+ for (unsigned i = 0; i != length; ++i) {
+ UChar c = string.characters[i];
+ if (c == 0 || c >= 0x7F)
+ return 0; // illegal character
+ buffer[i] = WTF::toASCIILower(c);
+ }
+ buffer[length] = '\0';
+
+ if (buffer[0] == '-') {
+ // If the prefix is -apple- or -khtml-, change it to -webkit-.
+ // This makes the string one character longer.
+ if (hasPrefix(buffer, length, "-apple-") || hasPrefix(buffer, length, "-khtml-")) {
+ memmove(buffer + 7, buffer + 6, length + 1 - 6);
+ memcpy(buffer, "-webkit", 7);
+ ++length;
+ }
+ }
+
+ const css_value* hashTableEntry = findValue(buffer, length);
+ return hashTableEntry ? hashTableEntry->id : 0;
+}
+
+#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/WebCore/css/CSSParser.h b/WebCore/css/CSSParser.h
new file mode 100644
index 0000000..250961d
--- /dev/null
+++ b/WebCore/css/CSSParser.h
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 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 CSSParser_h
+#define CSSParser_h
+
+#include "AtomicString.h"
+#include "Color.h"
+#include "MediaQuery.h"
+#include <wtf/HashSet.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class CSSMutableStyleDeclaration;
+ class CSSPrimitiveValue;
+ class CSSProperty;
+ class CSSRule;
+ class CSSRuleList;
+ class CSSSelector;
+ class CSSStyleSheet;
+ class CSSValue;
+ class CSSValueList;
+ class Document;
+ class MediaList;
+ class MediaList;
+ class MediaQueryExp;
+ class StyleBase;
+ class StyleList;
+ struct Function;
+
+ struct ParseString {
+ UChar* characters;
+ int length;
+
+ void lower();
+
+ operator String() const { return String(characters, length); }
+ operator AtomicString() const { return AtomicString(characters, length); }
+ };
+
+ struct Value {
+ int id;
+ bool isInt;
+ union {
+ double fValue;
+ int iValue;
+ ParseString string;
+ Function* function;
+ };
+ enum {
+ Operator = 0x100000,
+ Function = 0x100001,
+ Q_EMS = 0x100002
+ };
+ int unit;
+ };
+
+ class ValueList {
+ public:
+ ValueList() : m_current(0) { }
+ ~ValueList();
+
+ void addValue(const Value& v) { m_values.append(v); }
+ unsigned size() const { return m_values.size(); }
+ Value* current() { return m_current < m_values.size() ? &m_values[m_current] : 0; }
+ Value* next() { ++m_current; return current(); }
+
+ Value* valueAt(unsigned i) { return i < m_values.size() ? &m_values[i] : 0; }
+ void deleteValueAt(unsigned i) { m_values.remove(i); }
+
+ private:
+ Vector<Value, 16> m_values;
+ unsigned m_current;
+ };
+
+ struct Function {
+ ParseString name;
+ ValueList* args;
+
+ ~Function() { delete args; }
+ };
+
+ class CSSParser {
+ public:
+ CSSParser(bool strictParsing = true);
+ ~CSSParser();
+
+ void parseSheet(CSSStyleSheet*, const String&);
+ PassRefPtr<CSSRule> parseRule(CSSStyleSheet*, const String&);
+ bool parseValue(CSSMutableStyleDeclaration*, int propId, const String&, bool important);
+ static bool parseColor(RGBA32& color, const String&, bool strict = false);
+ bool parseColor(CSSMutableStyleDeclaration*, const String&);
+ bool parseDeclaration(CSSMutableStyleDeclaration*, const String&);
+ bool parseMediaQuery(MediaList*, const String&);
+
+ static CSSParser* current() { return currentParser; }
+
+ Document* document() const;
+
+ void addProperty(int propId, PassRefPtr<CSSValue>, bool important);
+ void rollbackLastProperties(int num);
+ bool hasProperties() const { return numParsedProperties > 0; }
+
+ bool parseValue(int propId, bool important);
+ bool parseShorthand(int propId, const int* properties, int numProperties, bool important);
+ bool parse4Values(int propId, const int* properties, bool important);
+ bool parseContent(int propId, bool important);
+
+ PassRefPtr<CSSValue> parseBackgroundColor();
+ bool parseBackgroundImage(RefPtr<CSSValue>&);
+ PassRefPtr<CSSValue> parseBackgroundPositionXY(bool& xFound, bool& yFound);
+ void parseBackgroundPosition(RefPtr<CSSValue>&, RefPtr<CSSValue>&);
+ PassRefPtr<CSSValue> parseBackgroundSize();
+
+ bool parseBackgroundProperty(int propId, int& propId1, int& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
+ bool parseBackgroundShorthand(bool important);
+
+ void addBackgroundValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval);
+
+ void addTransitionValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval);
+ PassRefPtr<CSSValue> parseTransitionDuration();
+ PassRefPtr<CSSValue> parseTransitionRepeatCount();
+ PassRefPtr<CSSValue> parseTransitionTimingFunction();
+ bool parseTimingFunctionValue(ValueList*& args, double& result);
+ PassRefPtr<CSSValue> parseTransitionProperty();
+ bool parseTransitionProperty(int propId, RefPtr<CSSValue>&);
+ bool parseTransitionShorthand(bool important);
+
+ bool parseDashboardRegions(int propId, bool important);
+
+ bool parseShape(int propId, bool important);
+
+ bool parseFont(bool important);
+ PassRefPtr<CSSValueList> parseFontFamily();
+
+ bool parseCounter(int propId, int defaultValue, bool important);
+ PassRefPtr<CSSValue> parseCounterContent(ValueList* args, bool counters);
+
+ bool parseColorParameters(Value*, int* colorValues, bool parseAlpha);
+ bool parseHSLParameters(Value*, double* colorValues, bool parseAlpha);
+ PassRefPtr<CSSPrimitiveValue> parseColor(Value* = 0);
+ bool parseColorFromValue(Value*, RGBA32&, bool = false);
+
+ static bool parseColor(const String&, RGBA32& rgb, bool strict);
+
+ bool parseFontFaceSrc();
+ bool parseFontFaceUnicodeRange();
+
+#if ENABLE(SVG)
+ bool parseSVGValue(int propId, bool important);
+ PassRefPtr<CSSValue> parseSVGPaint();
+ PassRefPtr<CSSValue> parseSVGColor();
+ PassRefPtr<CSSValue> parseSVGStrokeDasharray();
+#endif
+
+ // CSS3 Parsing Routines (for properties specific to CSS3)
+ bool parseShadow(int propId, bool important);
+ bool parseBorderImage(int propId, bool important);
+
+ PassRefPtr<CSSValue> parseTransform();
+ bool parseTransformOrigin(int propId, int& propId1, int& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
+
+ int yyparse();
+
+ CSSSelector* createFloatingSelector();
+ CSSSelector* sinkFloatingSelector(CSSSelector*);
+
+ ValueList* createFloatingValueList();
+ ValueList* sinkFloatingValueList(ValueList*);
+
+ Function* createFloatingFunction();
+ Function* sinkFloatingFunction(Function*);
+
+ Value& sinkFloatingValue(Value&);
+
+ MediaList* createMediaList();
+ CSSRule* createCharsetRule(const ParseString&);
+ CSSRule* createImportRule(const ParseString&, MediaList*);
+ CSSRule* createMediaRule(MediaList*, CSSRuleList*);
+ CSSRuleList* createRuleList();
+ CSSRule* createStyleRule(CSSSelector*);
+ CSSRule* createFontFaceRule();
+
+ MediaQueryExp* createFloatingMediaQueryExp(const AtomicString&, ValueList*);
+ MediaQueryExp* sinkFloatingMediaQueryExp(MediaQueryExp*);
+ Vector<MediaQueryExp*>* createFloatingMediaQueryExpList();
+ Vector<MediaQueryExp*>* sinkFloatingMediaQueryExpList(Vector<MediaQueryExp*>*);
+ MediaQuery* createFloatingMediaQuery(MediaQuery::Restrictor, const String&, Vector<MediaQueryExp*>*);
+ MediaQuery* sinkFloatingMediaQuery(MediaQuery*);
+
+ public:
+ bool strict;
+ bool important;
+ int id;
+ StyleList* styleElement;
+ RefPtr<CSSRule> rule;
+ MediaQuery* mediaQuery;
+ ValueList* valueList;
+ CSSProperty** parsedProperties;
+ int numParsedProperties;
+ int maxParsedProperties;
+
+ int m_inParseShorthand;
+ int m_currentShorthand;
+ bool m_implicitShorthand;
+
+ AtomicString defaultNamespace;
+
+ static CSSParser* currentParser;
+
+ // tokenizer methods and data
+ public:
+ int lex(void* yylval);
+ int token() { return yyTok; }
+ UChar* text(int* length);
+ int lex();
+
+ private:
+ void clearProperties();
+
+ void setupParser(const char* prefix, const String&, const char* suffix);
+
+ bool inShorthand() const { return m_inParseShorthand; }
+
+ void checkForOrphanedUnits();
+
+ UChar* 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;
+
+ Vector<RefPtr<StyleBase> > m_parsedStyleObjects;
+ Vector<RefPtr<CSSRuleList> > m_parsedRuleLists;
+ HashSet<CSSSelector*> m_floatingSelectors;
+ HashSet<ValueList*> m_floatingValueLists;
+ HashSet<Function*> m_floatingFunctions;
+
+ MediaQuery* m_floatingMediaQuery;
+ MediaQueryExp* m_floatingMediaQueryExp;
+ Vector<MediaQueryExp*>* m_floatingMediaQueryExpList;
+
+ // defines units allowed for a certain property, used in parseUnit
+ enum Units {
+ FUnknown = 0x0000,
+ FInteger = 0x0001,
+ FNumber = 0x0002, // Real Numbers
+ FPercent = 0x0004,
+ FLength = 0x0008,
+ FAngle = 0x0010,
+ FTime = 0x0020,
+ FFrequency = 0x0040,
+ FRelative = 0x0100,
+ FNonNeg = 0x0200
+ };
+
+ friend inline Units operator|(Units a, Units b)
+ {
+ return static_cast<Units>(static_cast<unsigned>(a) | static_cast<unsigned>(b));
+ }
+
+ static bool validUnit(Value*, Units, bool strict);
+
+ friend class TransformOperationInfo;
+ };
+
+ int cssPropertyID(const ParseString&);
+ int cssPropertyID(const String&);
+ int cssValueKeywordID(const ParseString&);
+
+} // namespace WebCore
+
+#endif // CSSParser_h
diff --git a/WebCore/css/CSSPrimitiveValue.cpp b/WebCore/css/CSSPrimitiveValue.cpp
new file mode 100644
index 0000000..b3d94ab
--- /dev/null
+++ b/WebCore/css/CSSPrimitiveValue.cpp
@@ -0,0 +1,703 @@
+/*
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 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 "CSSPrimitiveValue.h"
+
+#include "CSSHelper.h"
+#include "CSSValueKeywords.h"
+#include "Color.h"
+#include "Counter.h"
+#include "DashboardRegion.h"
+#include "ExceptionCode.h"
+#include "Pair.h"
+#include "RenderStyle.h"
+#include <wtf/ASCIICType.h>
+
+using namespace WTF;
+
+namespace WebCore {
+
+// "ident" from the CSS tokenizer, minus backslash-escape sequences
+static bool isCSSTokenizerIdentifier(const String& string)
+{
+ const UChar* p = string.characters();
+ const UChar* end = p + string.length();
+
+ // -?
+ if (p != end && p[0] == '-')
+ ++p;
+
+ // {nmstart}
+ if (p == end || !(p[0] == '_' || p[0] >= 128 || isASCIIAlpha(p[0])))
+ return false;
+ ++p;
+
+ // {nmchar}*
+ for (; p != end; ++p) {
+ if (!(p[0] == '_' || p[0] == '-' || p[0] >= 128 || isASCIIAlphanumeric(p[0])))
+ return false;
+ }
+
+ return true;
+}
+
+// "url" from the CSS tokenizer, minus backslash-escape sequences
+static bool isCSSTokenizerURL(const String& string)
+{
+ const UChar* p = string.characters();
+ const UChar* end = p + string.length();
+
+ for (; p != end; ++p) {
+ UChar c = p[0];
+ switch (c) {
+ case '!':
+ case '#':
+ case '$':
+ case '%':
+ case '&':
+ break;
+ default:
+ if (c < '*')
+ return false;
+ if (c <= '~')
+ break;
+ if (c < 128)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// We use single quotes for now because markup.cpp uses double quotes.
+static String quoteString(const String& string)
+{
+ // FIXME: Also need to escape characters like '\n'.
+ String s = string;
+ s.replace('\\', "\\\\");
+ s.replace('\'', "\\'");
+ return "'" + s + "'";
+}
+
+static String quoteStringIfNeeded(const String& string)
+{
+ return isCSSTokenizerIdentifier(string) ? string : quoteString(string);
+}
+
+static String quoteURLIfNeeded(const String& string)
+{
+ return isCSSTokenizerURL(string) ? string : quoteString(string);
+}
+
+CSSPrimitiveValue::CSSPrimitiveValue()
+ : m_type(0)
+{
+}
+
+CSSPrimitiveValue::CSSPrimitiveValue(int ident)
+ : m_type(CSS_IDENT)
+{
+ m_value.ident = ident;
+}
+
+CSSPrimitiveValue::CSSPrimitiveValue(double num, UnitTypes type)
+ : m_type(type)
+{
+ m_value.num = num;
+}
+
+CSSPrimitiveValue::CSSPrimitiveValue(const String& str, UnitTypes type)
+ : m_type(type)
+{
+ if ((m_value.string = str.impl()))
+ m_value.string->ref();
+}
+
+CSSPrimitiveValue::CSSPrimitiveValue(RGBA32 color)
+ : m_type(CSS_RGBCOLOR)
+{
+ m_value.rgbcolor = color;
+}
+
+CSSPrimitiveValue::CSSPrimitiveValue(const Length& length)
+{
+ switch (length.type()) {
+ case Auto:
+ m_type = CSS_IDENT;
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case WebCore::Fixed:
+ m_type = CSS_PX;
+ m_value.num = length.value();
+ break;
+ case Intrinsic:
+ m_type = CSS_IDENT;
+ m_value.ident = CSS_VAL_INTRINSIC;
+ break;
+ case MinIntrinsic:
+ m_type = CSS_IDENT;
+ m_value.ident = CSS_VAL_MIN_INTRINSIC;
+ break;
+ case Percent:
+ m_type = CSS_PERCENTAGE;
+ m_value.num = length.percent();
+ break;
+ case Relative:
+ case Static:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void CSSPrimitiveValue::init(PassRefPtr<Counter> c)
+{
+ m_type = CSS_COUNTER;
+ m_value.counter = c.releaseRef();
+}
+
+void CSSPrimitiveValue::init(PassRefPtr<Rect> r)
+{
+ m_type = CSS_RECT;
+ m_value.rect = r.releaseRef();
+}
+
+void CSSPrimitiveValue::init(PassRefPtr<DashboardRegion> r)
+{
+ m_type = CSS_DASHBOARD_REGION;
+ m_value.region = r.releaseRef();
+}
+
+void CSSPrimitiveValue::init(PassRefPtr<Pair> p)
+{
+ m_type = CSS_PAIR;
+ m_value.pair = p.releaseRef();
+}
+
+CSSPrimitiveValue::~CSSPrimitiveValue()
+{
+ cleanup();
+}
+
+void CSSPrimitiveValue::cleanup()
+{
+ switch (m_type) {
+ case CSS_STRING:
+ case CSS_URI:
+ case CSS_ATTR:
+ if (m_value.string)
+ m_value.string->deref();
+ break;
+ case CSS_COUNTER:
+ m_value.counter->deref();
+ break;
+ case CSS_RECT:
+ m_value.rect->deref();
+ break;
+ case CSS_PAIR:
+ m_value.pair->deref();
+ break;
+ case CSS_DASHBOARD_REGION:
+ if (m_value.region)
+ m_value.region->deref();
+ break;
+ default:
+ break;
+ }
+
+ m_type = 0;
+}
+
+int CSSPrimitiveValue::computeLengthInt(RenderStyle* style)
+{
+ double result = computeLengthDouble(style);
+
+ // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We
+ // need to go ahead and round if we're really close to the next integer value.
+ result += result < 0 ? -0.01 : +0.01;
+
+ if (result > INT_MAX || result < INT_MIN)
+ return 0;
+ return static_cast<int>(result);
+}
+
+int CSSPrimitiveValue::computeLengthInt(RenderStyle* style, double multiplier)
+{
+ double result = multiplier * computeLengthDouble(style);
+
+ // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We
+ // need to go ahead and round if we're really close to the next integer value.
+ result += result < 0 ? -0.01 : +0.01;
+
+ if (result > INT_MAX || result < INT_MIN)
+ return 0;
+ return static_cast<int>(result);
+}
+
+const int intMaxForLength = 0x7ffffff; // max value for a 28-bit int
+const int intMinForLength = (-0x7ffffff - 1); // min value for a 28-bit int
+
+// Lengths expect an int that is only 28-bits, so we have to check for a different overflow.
+int CSSPrimitiveValue::computeLengthIntForLength(RenderStyle* style)
+{
+ double result = computeLengthDouble(style);
+
+ // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We
+ // need to go ahead and round if we're really close to the next integer value.
+ result += result < 0 ? -0.01 : +0.01;
+
+ if (result > intMaxForLength || result < intMinForLength)
+ return 0;
+ return static_cast<int>(result);
+}
+
+// Lengths expect an int that is only 28-bits, so we have to check for a different overflow.
+int CSSPrimitiveValue::computeLengthIntForLength(RenderStyle* style, double multiplier)
+{
+ double result = multiplier * computeLengthDouble(style);
+
+ // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We
+ // need to go ahead and round if we're really close to the next integer value.
+ result += result < 0 ? -0.01 : +0.01;
+
+ if (result > intMaxForLength || result < intMinForLength)
+ return 0;
+ return static_cast<int>(result);
+}
+
+short CSSPrimitiveValue::computeLengthShort(RenderStyle* style)
+{
+ double result = computeLengthDouble(style);
+
+ // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We
+ // need to go ahead and round if we're really close to the next integer value.
+ result += result < 0 ? -0.01 : +0.01;
+
+ if (result > SHRT_MAX || result < SHRT_MIN)
+ return 0;
+ return static_cast<short>(result);
+}
+
+short CSSPrimitiveValue::computeLengthShort(RenderStyle* style, double multiplier)
+{
+ double result = multiplier * computeLengthDouble(style);
+
+ // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We
+ // need to go ahead and round if we're really close to the next integer value.
+ result += result < 0 ? -0.01 : +0.01;
+
+ if (result > SHRT_MAX || result < SHRT_MIN)
+ return 0;
+ return static_cast<short>(result);
+}
+
+float CSSPrimitiveValue::computeLengthFloat(RenderStyle* style, bool applyZoomFactor)
+{
+ return static_cast<float>(computeLengthDouble(style, applyZoomFactor));
+}
+
+double CSSPrimitiveValue::computeLengthDouble(RenderStyle* style, bool applyZoomFactor)
+{
+ unsigned short type = primitiveType();
+
+ double factor = 1.0;
+ switch (type) {
+ case CSS_EMS:
+ factor = applyZoomFactor ? style->fontDescription().computedSize() : style->fontDescription().specifiedSize();
+ break;
+ case CSS_EXS:
+ // FIXME: We have a bug right now where the zoom will be applied multiple times to EX units.
+ // We really need to compute EX using fontMetrics for the original specifiedSize and not use
+ // our actual constructed rendering font.
+ factor = style->font().xHeight();
+ break;
+ case CSS_PX:
+ break;
+ case CSS_CM:
+ factor = cssPixelsPerInch / 2.54; // (2.54 cm/in)
+ break;
+ case CSS_MM:
+ factor = cssPixelsPerInch / 25.4;
+ break;
+ case CSS_IN:
+ factor = cssPixelsPerInch;
+ break;
+ case CSS_PT:
+ factor = cssPixelsPerInch / 72.0;
+ break;
+ case CSS_PC:
+ // 1 pc == 12 pt
+ factor = cssPixelsPerInch * 12.0 / 72.0;
+ break;
+ default:
+ return -1.0;
+ }
+
+ return getDoubleValue() * factor;
+}
+
+void CSSPrimitiveValue::setFloatValue(unsigned short unitType, double floatValue, ExceptionCode& ec)
+{
+ ec = 0;
+
+ // FIXME: check if property supports this type
+ if (m_type > CSS_DIMENSION) {
+ ec = SYNTAX_ERR;
+ return;
+ }
+
+ cleanup();
+
+ //if(m_type > CSS_DIMENSION) throw DOMException(INVALID_ACCESS_ERR);
+ m_value.num = floatValue;
+ m_type = unitType;
+}
+
+double scaleFactorForConversion(unsigned short unitType)
+{
+ double factor = 1.0;
+ switch (unitType) {
+ case CSSPrimitiveValue::CSS_PX:
+ break;
+ case CSSPrimitiveValue::CSS_CM:
+ factor = cssPixelsPerInch / 2.54; // (2.54 cm/in)
+ break;
+ case CSSPrimitiveValue::CSS_MM:
+ factor = cssPixelsPerInch / 25.4;
+ break;
+ case CSSPrimitiveValue::CSS_IN:
+ factor = cssPixelsPerInch;
+ break;
+ case CSSPrimitiveValue::CSS_PT:
+ factor = cssPixelsPerInch / 72.0;
+ break;
+ case CSSPrimitiveValue::CSS_PC:
+ factor = cssPixelsPerInch * 12.0 / 72.0; // 1 pc == 12 pt
+ break;
+ default:
+ break;
+ }
+
+ return factor;
+}
+
+double CSSPrimitiveValue::getDoubleValue(unsigned short unitType, ExceptionCode& ec)
+{
+ ec = 0;
+ if (m_type < CSS_NUMBER || m_type > CSS_DIMENSION || unitType < CSS_NUMBER || unitType > CSS_DIMENSION) {
+ ec = INVALID_ACCESS_ERR;
+ return 0.0;
+ }
+
+ if (unitType == m_type || unitType < CSS_PX || unitType > CSS_PC)
+ return m_value.num;
+
+ double convertedValue = m_value.num;
+
+ // First convert the value from m_type into CSSPixels
+ double factor = scaleFactorForConversion(m_type);
+ convertedValue *= factor;
+
+ // Now convert from CSSPixels to the specified unitType
+ factor = scaleFactorForConversion(unitType);
+ convertedValue /= factor;
+
+ return convertedValue;
+}
+
+double CSSPrimitiveValue::getDoubleValue(unsigned short unitType)
+{
+ if (m_type < CSS_NUMBER || m_type > CSS_DIMENSION || unitType < CSS_NUMBER || unitType > CSS_DIMENSION)
+ return 0;
+
+ if (unitType == m_type || unitType < CSS_PX || unitType > CSS_PC)
+ return m_value.num;
+
+ double convertedValue = m_value.num;
+
+ // First convert the value from m_type into CSSPixels
+ double factor = scaleFactorForConversion(m_type);
+ convertedValue *= factor;
+
+ // Now convert from CSSPixels to the specified unitType
+ factor = scaleFactorForConversion(unitType);
+ convertedValue /= factor;
+
+ return convertedValue;
+}
+
+
+void CSSPrimitiveValue::setStringValue(unsigned short stringType, const String& stringValue, ExceptionCode& ec)
+{
+ ec = 0;
+
+ //if(m_type < CSS_STRING) throw DOMException(INVALID_ACCESS_ERR);
+ //if(m_type > CSS_ATTR) throw DOMException(INVALID_ACCESS_ERR);
+ if (m_type < CSS_STRING || m_type > CSS_ATTR) {
+ ec = SYNTAX_ERR;
+ return;
+ }
+
+ cleanup();
+
+ if (stringType != CSS_IDENT) {
+ m_value.string = stringValue.impl();
+ m_value.string->ref();
+ m_type = stringType;
+ }
+ // FIXME: parse ident
+}
+
+String CSSPrimitiveValue::getStringValue(ExceptionCode& ec) const
+{
+ ec = 0;
+ switch (m_type) {
+ case CSS_STRING:
+ case CSS_ATTR:
+ case CSS_URI:
+ return m_value.string;
+ case CSS_IDENT:
+ return getValueName(m_value.ident);
+ default:
+ ec = INVALID_ACCESS_ERR;
+ break;
+ }
+
+ return String();
+}
+
+String CSSPrimitiveValue::getStringValue() const
+{
+ switch (m_type) {
+ case CSS_STRING:
+ case CSS_ATTR:
+ case CSS_URI:
+ return m_value.string;
+ case CSS_IDENT:
+ return getValueName(m_value.ident);
+ default:
+ break;
+ }
+
+ return String();
+}
+
+Counter* CSSPrimitiveValue::getCounterValue(ExceptionCode& ec) const
+{
+ ec = 0;
+ if (m_type != CSS_COUNTER) {
+ ec = INVALID_ACCESS_ERR;
+ return 0;
+ }
+
+ return m_value.counter;
+}
+
+Rect* CSSPrimitiveValue::getRectValue(ExceptionCode& ec) const
+{
+ ec = 0;
+ if (m_type != CSS_RECT) {
+ ec = INVALID_ACCESS_ERR;
+ return 0;
+ }
+
+ return m_value.rect;
+}
+
+unsigned CSSPrimitiveValue::getRGBColorValue(ExceptionCode& ec) const
+{
+ ec = 0;
+ if (m_type != CSS_RGBCOLOR) {
+ ec = INVALID_ACCESS_ERR;
+ return 0;
+ }
+
+ return m_value.rgbcolor;
+}
+
+Pair* CSSPrimitiveValue::getPairValue(ExceptionCode& ec) const
+{
+ ec = 0;
+ if (m_type != CSS_PAIR) {
+ ec = INVALID_ACCESS_ERR;
+ return 0;
+ }
+
+ return m_value.pair;
+}
+
+unsigned short CSSPrimitiveValue::cssValueType() const
+{
+ return CSS_PRIMITIVE_VALUE;
+}
+
+bool CSSPrimitiveValue::parseString(const String& /*string*/, bool /*strict*/)
+{
+ // FIXME
+ return false;
+}
+
+int CSSPrimitiveValue::getIdent()
+{
+ if (m_type != CSS_IDENT)
+ return 0;
+ return m_value.ident;
+}
+
+String CSSPrimitiveValue::cssText() const
+{
+ // FIXME: return the original value instead of a generated one (e.g. color
+ // name if it was specified) - check what spec says about this
+ String text;
+ switch (m_type) {
+ case CSS_UNKNOWN:
+ // FIXME
+ break;
+ case CSS_NUMBER:
+ text = String::number(m_value.num);
+ break;
+ case CSS_PERCENTAGE:
+ text = String::format("%.6lg%%", m_value.num);
+ break;
+ case CSS_EMS:
+ text = String::format("%.6lgem", m_value.num);
+ break;
+ case CSS_EXS:
+ text = String::format("%.6lgex", m_value.num);
+ break;
+ case CSS_PX:
+ text = String::format("%.6lgpx", m_value.num);
+ break;
+ case CSS_CM:
+ text = String::format("%.6lgcm", m_value.num);
+ break;
+ case CSS_MM:
+ text = String::format("%.6lgmm", m_value.num);
+ break;
+ case CSS_IN:
+ text = String::format("%.6lgin", m_value.num);
+ break;
+ case CSS_PT:
+ text = String::format("%.6lgpt", m_value.num);
+ break;
+ case CSS_PC:
+ text = String::format("%.6lgpc", m_value.num);
+ break;
+ case CSS_DEG:
+ text = String::format("%.6lgdeg", m_value.num);
+ break;
+ case CSS_RAD:
+ text = String::format("%.6lgrad", m_value.num);
+ break;
+ case CSS_GRAD:
+ text = String::format("%.6lggrad", m_value.num);
+ break;
+ case CSS_MS:
+ text = String::format("%.6lgms", m_value.num);
+ break;
+ case CSS_S:
+ text = String::format("%.6lgs", m_value.num);
+ break;
+ case CSS_HZ:
+ text = String::format("%.6lghz", m_value.num);
+ break;
+ case CSS_KHZ:
+ text = String::format("%.6lgkhz", m_value.num);
+ break;
+ case CSS_DIMENSION:
+ // FIXME
+ break;
+ case CSS_STRING:
+ text = quoteStringIfNeeded(m_value.string);
+ break;
+ case CSS_URI:
+ text = "url(" + quoteURLIfNeeded(m_value.string) + ")";
+ break;
+ case CSS_IDENT:
+ text = getValueName(m_value.ident);
+ break;
+ case CSS_ATTR:
+ // FIXME
+ break;
+ case CSS_COUNTER:
+ text = "counter(";
+ text += String::number(m_value.num);
+ text += ")";
+ // FIXME: Add list-style and separator
+ break;
+ case CSS_RECT: {
+ Rect* rectVal = getRectValue();
+ text = "rect(";
+ text += rectVal->top()->cssText() + " ";
+ text += rectVal->right()->cssText() + " ";
+ text += rectVal->bottom()->cssText() + " ";
+ text += rectVal->left()->cssText() + ")";
+ break;
+ }
+ case CSS_RGBCOLOR: {
+ Color color(m_value.rgbcolor);
+ text = (color.alpha() < 0xFF) ? "rgba(" : "rgb(";
+ text += String::number(color.red()) + ", ";
+ text += String::number(color.green()) + ", ";
+ text += String::number(color.blue());
+ if (color.alpha() < 0xFF)
+ text += ", " + String::number(static_cast<float>(color.alpha()) / 0xFF);
+ text += ")";
+ break;
+ }
+ case CSS_PAIR:
+ text = m_value.pair->first()->cssText();
+ text += " ";
+ text += m_value.pair->second()->cssText();
+ break;
+ case CSS_DASHBOARD_REGION:
+ for (DashboardRegion* region = getDashboardRegionValue(); region; region = region->m_next.get()) {
+ if (!text.isEmpty())
+ text.append(' ');
+ text += "dashboard-region(";
+ text += region->m_label;
+ if (region->m_isCircle)
+ text += " circle";
+ else if (region->m_isRectangle)
+ text += " rectangle";
+ else
+ break;
+ if (region->top()->m_type == CSS_IDENT && region->top()->getIdent() == CSS_VAL_INVALID) {
+ ASSERT(region->right()->m_type == CSS_IDENT);
+ ASSERT(region->bottom()->m_type == CSS_IDENT);
+ ASSERT(region->left()->m_type == CSS_IDENT);
+ ASSERT(region->right()->getIdent() == CSS_VAL_INVALID);
+ ASSERT(region->bottom()->getIdent() == CSS_VAL_INVALID);
+ ASSERT(region->left()->getIdent() == CSS_VAL_INVALID);
+ } else {
+ text.append(' ');
+ text += region->top()->cssText() + " ";
+ text += region->right()->cssText() + " ";
+ text += region->bottom()->cssText() + " ";
+ text += region->left()->cssText();
+ }
+ text += ")";
+ }
+ break;
+ }
+ return text;
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSPrimitiveValue.h b/WebCore/css/CSSPrimitiveValue.h
new file mode 100644
index 0000000..d81e7cf
--- /dev/null
+++ b/WebCore/css/CSSPrimitiveValue.h
@@ -0,0 +1,180 @@
+/*
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
+ *
+ * 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 CSSPrimitiveValue_h
+#define CSSPrimitiveValue_h
+
+#include "CSSValue.h"
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class Counter;
+class DashboardRegion;
+struct Length;
+class Pair;
+class Rect;
+class RenderStyle;
+class StringImpl;
+
+typedef int ExceptionCode;
+
+class CSSPrimitiveValue : public CSSValue {
+public:
+ enum UnitTypes {
+ CSS_UNKNOWN = 0,
+ CSS_NUMBER = 1,
+ CSS_PERCENTAGE = 2,
+ CSS_EMS = 3,
+ CSS_EXS = 4,
+ CSS_PX = 5,
+ CSS_CM = 6,
+ CSS_MM = 7,
+ CSS_IN = 8,
+ CSS_PT = 9,
+ CSS_PC = 10,
+ CSS_DEG = 11,
+ CSS_RAD = 12,
+ CSS_GRAD = 13,
+ CSS_MS = 14,
+ CSS_S = 15,
+ CSS_HZ = 16,
+ CSS_KHZ = 17,
+ CSS_DIMENSION = 18,
+ CSS_STRING = 19,
+ CSS_URI = 20,
+ CSS_IDENT = 21,
+ CSS_ATTR = 22,
+ CSS_COUNTER = 23,
+ CSS_RECT = 24,
+ CSS_RGBCOLOR = 25,
+ CSS_PAIR = 100, // We envision this being exposed as a means of getting computed style values for pairs (border-spacing/radius, background-position, etc.)
+ CSS_DASHBOARD_REGION = 101, // FIXME: What on earth is this doing as a primitive value? It should not be!
+ CSS_UNICODE_RANGE = 102
+ };
+
+ // FIXME: int vs. unsigned overloading is too tricky for color vs. ident
+ CSSPrimitiveValue();
+ CSSPrimitiveValue(int ident);
+ CSSPrimitiveValue(double, UnitTypes);
+ CSSPrimitiveValue(const String&, UnitTypes);
+ CSSPrimitiveValue(unsigned color); // RGB value
+ CSSPrimitiveValue(const Length&);
+ template<typename T> CSSPrimitiveValue(T); // Defined in CSSPrimitiveValueMappings.h
+ template<typename T> CSSPrimitiveValue(T* val) { init(PassRefPtr<T>(val)); }
+ template<typename T> CSSPrimitiveValue(PassRefPtr<T> val) { init(val); }
+
+ virtual ~CSSPrimitiveValue();
+
+ void cleanup();
+
+ unsigned short primitiveType() const { return m_type; }
+
+ /*
+ * 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.
+ *
+ * The metrics have to be a bit different for screen and printer output.
+ * For screen output we assume 1 inch == 72 px, for printer we assume 300 dpi
+ *
+ * this is screen/printer dependent, so we probably need a config option for this,
+ * and some tool to calibrate.
+ */
+ int computeLengthInt(RenderStyle*);
+ int computeLengthInt(RenderStyle*, double multiplier);
+ int computeLengthIntForLength(RenderStyle*);
+ int computeLengthIntForLength(RenderStyle*, double multiplier);
+ short computeLengthShort(RenderStyle*);
+ short computeLengthShort(RenderStyle*, double multiplier);
+ float computeLengthFloat(RenderStyle*, bool applyZoomFactor = true);
+ double computeLengthDouble(RenderStyle*, bool applyZoomFactor = true);
+
+ // use with care!!!
+ void setPrimitiveType(unsigned short type) { m_type = type; }
+
+ double getDoubleValue(unsigned short unitType, ExceptionCode&);
+ double getDoubleValue(unsigned short unitType);
+ double getDoubleValue() const { return m_value.num; }
+
+ void setFloatValue(unsigned short unitType, double floatValue, ExceptionCode&);
+ float getFloatValue(unsigned short unitType, ExceptionCode& ec) { return static_cast<float>(getDoubleValue(unitType, ec)); }
+ float getFloatValue(unsigned short unitType) { return static_cast<float>(getDoubleValue(unitType)); }
+ float getFloatValue() const { return static_cast<float>(m_value.num); }
+
+ int getIntValue(unsigned short unitType, ExceptionCode& ec) { return static_cast<int>(getDoubleValue(unitType, ec)); }
+ int getIntValue(unsigned short unitType) { return static_cast<int>(getDoubleValue(unitType)); }
+ int getIntValue() const { return static_cast<int>(m_value.num); }
+
+ void setStringValue(unsigned short stringType, const String& stringValue, ExceptionCode&);
+ String getStringValue(ExceptionCode&) const;
+ String getStringValue() const;
+
+ Counter* getCounterValue(ExceptionCode&) const;
+ Counter* getCounterValue() const { return m_type != CSS_COUNTER ? 0 : m_value.counter; }
+
+ Rect* getRectValue(ExceptionCode&) const;
+ Rect* getRectValue() const { return m_type != CSS_RECT ? 0 : m_value.rect; }
+
+ unsigned getRGBColorValue(ExceptionCode&) const;
+ unsigned getRGBColorValue() const { return m_type != CSS_RGBCOLOR ? 0 : m_value.rgbcolor; }
+
+ Pair* getPairValue(ExceptionCode&) const;
+ Pair* getPairValue() const { return m_type != CSS_PAIR ? 0 : m_value.pair; }
+
+ DashboardRegion* getDashboardRegionValue() const { return m_type != CSS_DASHBOARD_REGION ? 0 : m_value.region; }
+
+ virtual bool isPrimitiveValue() const { return true; }
+
+ virtual unsigned short cssValueType() const;
+
+ int getIdent();
+ template<typename T> operator T() const; // Defined in CSSPrimitiveValueMappings.h
+
+ virtual bool parseString(const String&, bool = false);
+ virtual String cssText() const;
+
+ virtual bool isQuirkValue() { return false; }
+
+protected:
+ int m_type;
+ union {
+ int ident;
+ double num;
+ StringImpl* string;
+ Counter* counter;
+ Rect* rect;
+ unsigned rgbcolor;
+ Pair* pair;
+ DashboardRegion* region;
+ } m_value;
+
+private:
+ template<typename T> operator T*(); // compile-time guard
+
+ void init(PassRefPtr<Counter>);
+ void init(PassRefPtr<Rect>);
+ void init(PassRefPtr<Pair>);
+ void init(PassRefPtr<DashboardRegion>); // FIXME: Why is dashboard region a primitive value? This makes no sense.
+};
+
+} // namespace WebCore
+
+#endif // CSSPrimitiveValue_h
diff --git a/WebCore/css/CSSPrimitiveValue.idl b/WebCore/css/CSSPrimitiveValue.idl
new file mode 100644
index 0000000..b049c29
--- /dev/null
+++ b/WebCore/css/CSSPrimitiveValue.idl
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 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.
+ */
+
+module css {
+
+ interface [
+ GenerateConstructor,
+ InterfaceUUID=a286b0cb-4ff0-4482-aa6e-7c5fb39afaba,
+ ImplementationUUID=c310c84d-480f-4bbb-9187-28e00956ac47
+ ] CSSPrimitiveValue : CSSValue {
+
+ // UnitTypes
+ const unsigned short CSS_UNKNOWN = 0;
+ const unsigned short CSS_NUMBER = 1;
+ const unsigned short CSS_PERCENTAGE = 2;
+ const unsigned short CSS_EMS = 3;
+ const unsigned short CSS_EXS = 4;
+ const unsigned short CSS_PX = 5;
+ const unsigned short CSS_CM = 6;
+ const unsigned short CSS_MM = 7;
+ const unsigned short CSS_IN = 8;
+ const unsigned short CSS_PT = 9;
+ const unsigned short CSS_PC = 10;
+ const unsigned short CSS_DEG = 11;
+ const unsigned short CSS_RAD = 12;
+ const unsigned short CSS_GRAD = 13;
+ const unsigned short CSS_MS = 14;
+ const unsigned short CSS_S = 15;
+ const unsigned short CSS_HZ = 16;
+ const unsigned short CSS_KHZ = 17;
+ const unsigned short CSS_DIMENSION = 18;
+ const unsigned short CSS_STRING = 19;
+ const unsigned short CSS_URI = 20;
+ const unsigned short CSS_IDENT = 21;
+ const unsigned short CSS_ATTR = 22;
+ const unsigned short CSS_COUNTER = 23;
+ const unsigned short CSS_RECT = 24;
+ const unsigned short CSS_RGBCOLOR = 25;
+
+ readonly attribute unsigned short primitiveType;
+
+ [OldStyleObjC] void setFloatValue(in unsigned short unitType,
+ in float floatValue)
+ raises(DOMException);
+ float getFloatValue(in unsigned short unitType)
+ raises(DOMException);
+ [OldStyleObjC] void setStringValue(in unsigned short stringType,
+ in DOMString stringValue)
+ raises(DOMException);
+ DOMString getStringValue()
+ raises(DOMException);
+ Counter getCounterValue()
+ raises(DOMException);
+ Rect getRectValue()
+ raises(DOMException);
+#if !defined(LANGUAGE_COM)
+ RGBColor getRGBColorValue()
+ raises(DOMException);
+#endif
+
+ };
+
+}
diff --git a/WebCore/css/CSSPrimitiveValueMappings.h b/WebCore/css/CSSPrimitiveValueMappings.h
new file mode 100644
index 0000000..3feb19f
--- /dev/null
+++ b/WebCore/css/CSSPrimitiveValueMappings.h
@@ -0,0 +1,2212 @@
+/*
+ * Copyright (C) 2007 Alexey Proskuryakov <ap@nypop.com>.
+ * Copyright (C) 2008 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 THE AUTHOR ``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 AUTHOR 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 CSSPrimitiveValueMappings_h
+#define CSSPrimitiveValueMappings_h
+
+#include "CSSPrimitiveValue.h"
+#include "CSSValueKeywords.h"
+#include "RenderStyle.h"
+
+namespace WebCore {
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EBorderStyle e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case BNONE:
+ m_value.ident = CSS_VAL_NONE;
+ break;
+ case BHIDDEN:
+ m_value.ident = CSS_VAL_HIDDEN;
+ break;
+ case INSET:
+ m_value.ident = CSS_VAL_INSET;
+ break;
+ case GROOVE:
+ m_value.ident = CSS_VAL_GROOVE;
+ break;
+ case RIDGE:
+ m_value.ident = CSS_VAL_RIDGE;
+ break;
+ case OUTSET:
+ m_value.ident = CSS_VAL_OUTSET;
+ break;
+ case DOTTED:
+ m_value.ident = CSS_VAL_DOTTED;
+ break;
+ case DASHED:
+ m_value.ident = CSS_VAL_DASHED;
+ break;
+ case SOLID:
+ m_value.ident = CSS_VAL_SOLID;
+ break;
+ case DOUBLE:
+ m_value.ident = CSS_VAL_DOUBLE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EBorderStyle() const
+{
+ return (EBorderStyle)(m_value.ident - CSS_VAL_NONE);
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(CompositeOperator e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case CompositeClear:
+ m_value.ident = CSS_VAL_CLEAR;
+ break;
+ case CompositeCopy:
+ m_value.ident = CSS_VAL_COPY;
+ break;
+ case CompositeSourceOver:
+ m_value.ident = CSS_VAL_SOURCE_OVER;
+ break;
+ case CompositeSourceIn:
+ m_value.ident = CSS_VAL_SOURCE_IN;
+ break;
+ case CompositeSourceOut:
+ m_value.ident = CSS_VAL_SOURCE_OUT;
+ break;
+ case CompositeSourceAtop:
+ m_value.ident = CSS_VAL_SOURCE_ATOP;
+ break;
+ case CompositeDestinationOver:
+ m_value.ident = CSS_VAL_DESTINATION_OVER;
+ break;
+ case CompositeDestinationIn:
+ m_value.ident = CSS_VAL_DESTINATION_IN;
+ break;
+ case CompositeDestinationOut:
+ m_value.ident = CSS_VAL_DESTINATION_OUT;
+ break;
+ case CompositeDestinationAtop:
+ m_value.ident = CSS_VAL_DESTINATION_ATOP;
+ break;
+ case CompositeXOR:
+ m_value.ident = CSS_VAL_XOR;
+ break;
+ case CompositePlusDarker:
+ m_value.ident = CSS_VAL_PLUS_DARKER;
+ break;
+ case CompositeHighlight:
+ m_value.ident = CSS_VAL_HIGHLIGHT;
+ break;
+ case CompositePlusLighter:
+ m_value.ident = CSS_VAL_PLUS_LIGHTER;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator CompositeOperator() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_CLEAR:
+ return CompositeClear;
+ case CSS_VAL_COPY:
+ return CompositeCopy;
+ case CSS_VAL_SOURCE_OVER:
+ return CompositeSourceOver;
+ case CSS_VAL_SOURCE_IN:
+ return CompositeSourceIn;
+ case CSS_VAL_SOURCE_OUT:
+ return CompositeSourceOut;
+ case CSS_VAL_SOURCE_ATOP:
+ return CompositeSourceAtop;
+ case CSS_VAL_DESTINATION_OVER:
+ return CompositeDestinationOver;
+ case CSS_VAL_DESTINATION_IN:
+ return CompositeDestinationIn;
+ case CSS_VAL_DESTINATION_OUT:
+ return CompositeDestinationOut;
+ case CSS_VAL_DESTINATION_ATOP:
+ return CompositeDestinationAtop;
+ case CSS_VAL_XOR:
+ return CompositeXOR;
+ case CSS_VAL_PLUS_DARKER:
+ return CompositePlusDarker;
+ case CSS_VAL_HIGHLIGHT:
+ return CompositeHighlight;
+ case CSS_VAL_PLUS_LIGHTER:
+ return CompositePlusLighter;
+ default:
+ ASSERT_NOT_REACHED();
+ return CompositeClear;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EAppearance e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case NoAppearance:
+ m_value.ident = CSS_VAL_NONE;
+ break;
+ case CheckboxAppearance:
+ m_value.ident = CSS_VAL_CHECKBOX;
+ break;
+ case RadioAppearance:
+ m_value.ident = CSS_VAL_RADIO;
+ break;
+ case PushButtonAppearance:
+ m_value.ident = CSS_VAL_PUSH_BUTTON;
+ break;
+ case SquareButtonAppearance:
+ m_value.ident = CSS_VAL_SQUARE_BUTTON;
+ break;
+ case ButtonAppearance:
+ m_value.ident = CSS_VAL_BUTTON;
+ break;
+ case ButtonBevelAppearance:
+ m_value.ident = CSS_VAL_BUTTON_BEVEL;
+ break;
+ case ListboxAppearance:
+ m_value.ident = CSS_VAL_LISTBOX;
+ break;
+ case ListItemAppearance:
+ m_value.ident = CSS_VAL_LISTITEM;
+ break;
+ case MediaFullscreenButtonAppearance:
+ m_value.ident = CSS_VAL_MEDIA_FULLSCREEN_BUTTON;
+ break;
+ case MediaPlayButtonAppearance:
+ m_value.ident = CSS_VAL_MEDIA_PLAY_BUTTON;
+ break;
+ case MediaMuteButtonAppearance:
+ m_value.ident = CSS_VAL_MEDIA_MUTE_BUTTON;
+ break;
+ case MediaSeekBackButtonAppearance:
+ m_value.ident = CSS_VAL_MEDIA_SEEK_BACK_BUTTON;
+ break;
+ case MediaSeekForwardButtonAppearance:
+ m_value.ident = CSS_VAL_MEDIA_SEEK_FORWARD_BUTTON;
+ break;
+ case MediaSliderAppearance:
+ m_value.ident = CSS_VAL_MEDIA_SLIDER;
+ break;
+ case MediaSliderThumbAppearance:
+ m_value.ident = CSS_VAL_MEDIA_SLIDERTHUMB;
+ break;
+ case MenulistAppearance:
+ m_value.ident = CSS_VAL_MENULIST;
+ break;
+ case MenulistButtonAppearance:
+ m_value.ident = CSS_VAL_MENULIST_BUTTON;
+ break;
+ case MenulistTextAppearance:
+ m_value.ident = CSS_VAL_MENULIST_TEXT;
+ break;
+ case MenulistTextFieldAppearance:
+ m_value.ident = CSS_VAL_MENULIST_TEXTFIELD;
+ break;
+ case ScrollbarButtonUpAppearance:
+ m_value.ident = CSS_VAL_SCROLLBARBUTTON_UP;
+ break;
+ case ScrollbarButtonDownAppearance:
+ m_value.ident = CSS_VAL_SCROLLBARBUTTON_DOWN;
+ break;
+ case ScrollbarButtonLeftAppearance:
+ m_value.ident = CSS_VAL_SCROLLBARBUTTON_LEFT;
+ break;
+ case ScrollbarButtonRightAppearance:
+ m_value.ident = CSS_VAL_SCROLLBARBUTTON_RIGHT;
+ break;
+ case ScrollbarTrackHorizontalAppearance:
+ m_value.ident = CSS_VAL_SCROLLBARTRACK_HORIZONTAL;
+ break;
+ case ScrollbarTrackVerticalAppearance:
+ m_value.ident = CSS_VAL_SCROLLBARTRACK_VERTICAL;
+ break;
+ case ScrollbarThumbHorizontalAppearance:
+ m_value.ident = CSS_VAL_SCROLLBARTHUMB_HORIZONTAL;
+ break;
+ case ScrollbarThumbVerticalAppearance:
+ m_value.ident = CSS_VAL_SCROLLBARTHUMB_VERTICAL;
+ break;
+ case ScrollbarGripperHorizontalAppearance:
+ m_value.ident = CSS_VAL_SCROLLBARGRIPPER_HORIZONTAL;
+ break;
+ case ScrollbarGripperVerticalAppearance:
+ m_value.ident = CSS_VAL_SCROLLBARGRIPPER_VERTICAL;
+ break;
+ case SliderHorizontalAppearance:
+ m_value.ident = CSS_VAL_SLIDER_HORIZONTAL;
+ break;
+ case SliderVerticalAppearance:
+ m_value.ident = CSS_VAL_SLIDER_VERTICAL;
+ break;
+ case SliderThumbHorizontalAppearance:
+ m_value.ident = CSS_VAL_SLIDERTHUMB_HORIZONTAL;
+ break;
+ case SliderThumbVerticalAppearance:
+ m_value.ident = CSS_VAL_SLIDERTHUMB_VERTICAL;
+ break;
+ case CaretAppearance:
+ m_value.ident = CSS_VAL_CARET;
+ break;
+ case SearchFieldAppearance:
+ m_value.ident = CSS_VAL_SEARCHFIELD;
+ break;
+ case SearchFieldDecorationAppearance:
+ m_value.ident = CSS_VAL_SEARCHFIELD_DECORATION;
+ break;
+ case SearchFieldResultsDecorationAppearance:
+ m_value.ident = CSS_VAL_SEARCHFIELD_RESULTS_DECORATION;
+ break;
+ case SearchFieldResultsButtonAppearance:
+ m_value.ident = CSS_VAL_SEARCHFIELD_RESULTS_BUTTON;
+ break;
+ case SearchFieldCancelButtonAppearance:
+ m_value.ident = CSS_VAL_SEARCHFIELD_CANCEL_BUTTON;
+ break;
+ case TextFieldAppearance:
+ m_value.ident = CSS_VAL_TEXTFIELD;
+ break;
+ case TextAreaAppearance:
+ m_value.ident = CSS_VAL_TEXTAREA;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EAppearance() const
+{
+ if (m_value.ident == CSS_VAL_NONE)
+ return NoAppearance;
+ else
+ return EAppearance(m_value.ident - CSS_VAL_CHECKBOX + 1);
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EBackgroundBox e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case BGBORDER:
+ m_value.ident = CSS_VAL_BORDER;
+ break;
+ case BGPADDING:
+ m_value.ident = CSS_VAL_PADDING;
+ break;
+ case BGCONTENT:
+ m_value.ident = CSS_VAL_CONTENT;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EBackgroundBox() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_BORDER:
+ return BGBORDER;
+ case CSS_VAL_PADDING:
+ return BGPADDING;
+ case CSS_VAL_CONTENT:
+ return BGCONTENT;
+ default:
+ ASSERT_NOT_REACHED();
+ return BGBORDER;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EBackgroundRepeat e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case REPEAT:
+ m_value.ident = CSS_VAL_REPEAT;
+ break;
+ case REPEAT_X:
+ m_value.ident = CSS_VAL_REPEAT_X;
+ break;
+ case REPEAT_Y:
+ m_value.ident = CSS_VAL_REPEAT_Y;
+ break;
+ case NO_REPEAT:
+ m_value.ident = CSS_VAL_NO_REPEAT;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EBackgroundRepeat() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_REPEAT:
+ return REPEAT;
+ case CSS_VAL_REPEAT_X:
+ return REPEAT_X;
+ case CSS_VAL_REPEAT_Y:
+ return REPEAT_Y;
+ case CSS_VAL_NO_REPEAT:
+ return NO_REPEAT;
+ default:
+ ASSERT_NOT_REACHED();
+ return REPEAT;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EBoxAlignment e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case BSTRETCH:
+ m_value.ident = CSS_VAL_STRETCH;
+ break;
+ case BSTART:
+ m_value.ident = CSS_VAL_START;
+ break;
+ case BCENTER:
+ m_value.ident = CSS_VAL_CENTER;
+ break;
+ case BEND:
+ m_value.ident = CSS_VAL_END;
+ break;
+ case BBASELINE:
+ m_value.ident = CSS_VAL_BASELINE;
+ break;
+ case BJUSTIFY:
+ m_value.ident = CSS_VAL_JUSTIFY;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EBoxAlignment() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_STRETCH:
+ return BSTRETCH;
+ case CSS_VAL_START:
+ return BSTART;
+ case CSS_VAL_END:
+ return BEND;
+ case CSS_VAL_CENTER:
+ return BCENTER;
+ case CSS_VAL_BASELINE:
+ return BBASELINE;
+ case CSS_VAL_JUSTIFY:
+ return BJUSTIFY;
+ default:
+ ASSERT_NOT_REACHED();
+ return BSTRETCH;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EBoxDirection e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case BNORMAL:
+ m_value.ident = CSS_VAL_NORMAL;
+ break;
+ case BREVERSE:
+ m_value.ident = CSS_VAL_REVERSE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EBoxDirection() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_NORMAL:
+ return BNORMAL;
+ case CSS_VAL_REVERSE:
+ return BREVERSE;
+ default:
+ ASSERT_NOT_REACHED();
+ return BNORMAL;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EBoxLines e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case SINGLE:
+ m_value.ident = CSS_VAL_SINGLE;
+ break;
+ case MULTIPLE:
+ m_value.ident = CSS_VAL_MULTIPLE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EBoxLines() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_SINGLE:
+ return SINGLE;
+ case CSS_VAL_MULTIPLE:
+ return MULTIPLE;
+ default:
+ ASSERT_NOT_REACHED();
+ return SINGLE;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EBoxOrient e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case HORIZONTAL:
+ m_value.ident = CSS_VAL_HORIZONTAL;
+ break;
+ case VERTICAL:
+ m_value.ident = CSS_VAL_VERTICAL;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EBoxOrient() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_HORIZONTAL:
+ case CSS_VAL_INLINE_AXIS:
+ return HORIZONTAL;
+ case CSS_VAL_VERTICAL:
+ return VERTICAL;
+ default:
+ ASSERT_NOT_REACHED();
+ return HORIZONTAL;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ECaptionSide e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case CAPLEFT:
+ m_value.ident = CSS_VAL_LEFT;
+ break;
+ case CAPRIGHT:
+ m_value.ident = CSS_VAL_RIGHT;
+ break;
+ case CAPTOP:
+ m_value.ident = CSS_VAL_TOP;
+ break;
+ case CAPBOTTOM:
+ m_value.ident = CSS_VAL_BOTTOM;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator ECaptionSide() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_LEFT:
+ return CAPLEFT;
+ case CSS_VAL_RIGHT:
+ return CAPRIGHT;
+ case CSS_VAL_TOP:
+ return CAPTOP;
+ case CSS_VAL_BOTTOM:
+ return CAPBOTTOM;
+ default:
+ ASSERT_NOT_REACHED();
+ return CAPTOP;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EClear e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case CNONE:
+ m_value.ident = CSS_VAL_NONE;
+ break;
+ case CLEFT:
+ m_value.ident = CSS_VAL_LEFT;
+ break;
+ case CRIGHT:
+ m_value.ident = CSS_VAL_RIGHT;
+ break;
+ case CBOTH:
+ m_value.ident = CSS_VAL_BOTH;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EClear() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_NONE:
+ return CNONE;
+ case CSS_VAL_LEFT:
+ return CLEFT;
+ case CSS_VAL_RIGHT:
+ return CRIGHT;
+ case CSS_VAL_BOTH:
+ return CBOTH;
+ default:
+ ASSERT_NOT_REACHED();
+ return CNONE;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ECursor e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case CURSOR_AUTO:
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case CURSOR_CROSS:
+ m_value.ident = CSS_VAL_CROSSHAIR;
+ break;
+ case CURSOR_DEFAULT:
+ m_value.ident = CSS_VAL_DEFAULT;
+ break;
+ case CURSOR_POINTER:
+ m_value.ident = CSS_VAL_POINTER;
+ break;
+ case CURSOR_MOVE:
+ m_value.ident = CSS_VAL_MOVE;
+ break;
+ case CURSOR_CELL:
+ m_value.ident = CSS_VAL_CELL;
+ break;
+ case CURSOR_VERTICAL_TEXT:
+ m_value.ident = CSS_VAL_VERTICAL_TEXT;
+ break;
+ case CURSOR_CONTEXT_MENU:
+ m_value.ident = CSS_VAL_CONTEXT_MENU;
+ break;
+ case CURSOR_ALIAS:
+ m_value.ident = CSS_VAL_ALIAS;
+ break;
+ case CURSOR_COPY:
+ m_value.ident = CSS_VAL_COPY;
+ break;
+ case CURSOR_NONE:
+ m_value.ident = CSS_VAL_NONE;
+ break;
+ case CURSOR_PROGRESS:
+ m_value.ident = CSS_VAL_PROGRESS;
+ break;
+ case CURSOR_NO_DROP:
+ m_value.ident = CSS_VAL_NO_DROP;
+ break;
+ case CURSOR_NOT_ALLOWED:
+ m_value.ident = CSS_VAL_NOT_ALLOWED;
+ break;
+ case CURSOR_WEBKIT_ZOOM_IN:
+ m_value.ident = CSS_VAL__WEBKIT_ZOOM_IN;
+ break;
+ case CURSOR_WEBKIT_ZOOM_OUT:
+ m_value.ident = CSS_VAL__WEBKIT_ZOOM_OUT;
+ break;
+ case CURSOR_E_RESIZE:
+ m_value.ident = CSS_VAL_E_RESIZE;
+ break;
+ case CURSOR_NE_RESIZE:
+ m_value.ident = CSS_VAL_NE_RESIZE;
+ break;
+ case CURSOR_NW_RESIZE:
+ m_value.ident = CSS_VAL_NW_RESIZE;
+ break;
+ case CURSOR_N_RESIZE:
+ m_value.ident = CSS_VAL_N_RESIZE;
+ break;
+ case CURSOR_SE_RESIZE:
+ m_value.ident = CSS_VAL_SE_RESIZE;
+ break;
+ case CURSOR_SW_RESIZE:
+ m_value.ident = CSS_VAL_SW_RESIZE;
+ break;
+ case CURSOR_S_RESIZE:
+ m_value.ident = CSS_VAL_S_RESIZE;
+ break;
+ case CURSOR_W_RESIZE:
+ m_value.ident = CSS_VAL_W_RESIZE;
+ break;
+ case CURSOR_EW_RESIZE:
+ m_value.ident = CSS_VAL_EW_RESIZE;
+ break;
+ case CURSOR_NS_RESIZE:
+ m_value.ident = CSS_VAL_NS_RESIZE;
+ break;
+ case CURSOR_NESW_RESIZE:
+ m_value.ident = CSS_VAL_NESW_RESIZE;
+ break;
+ case CURSOR_NWSE_RESIZE:
+ m_value.ident = CSS_VAL_NWSE_RESIZE;
+ break;
+ case CURSOR_COL_RESIZE:
+ m_value.ident = CSS_VAL_COL_RESIZE;
+ break;
+ case CURSOR_ROW_RESIZE:
+ m_value.ident = CSS_VAL_ROW_RESIZE;
+ break;
+ case CURSOR_TEXT:
+ m_value.ident = CSS_VAL_TEXT;
+ break;
+ case CURSOR_WAIT:
+ m_value.ident = CSS_VAL_WAIT;
+ break;
+ case CURSOR_HELP:
+ m_value.ident = CSS_VAL_HELP;
+ break;
+ case CURSOR_ALL_SCROLL:
+ m_value.ident = CSS_VAL_ALL_SCROLL;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator ECursor() const
+{
+ if (m_value.ident == CSS_VAL_COPY)
+ return CURSOR_COPY;
+ if (m_value.ident == CSS_VAL_NONE)
+ return CURSOR_NONE;
+ return static_cast<ECursor>(m_value.ident - CSS_VAL_AUTO);
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EDisplay e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case INLINE:
+ m_value.ident = CSS_VAL_INLINE;
+ break;
+ case BLOCK:
+ m_value.ident = CSS_VAL_BLOCK;
+ break;
+ case LIST_ITEM:
+ m_value.ident = CSS_VAL_LIST_ITEM;
+ break;
+ case RUN_IN:
+ m_value.ident = CSS_VAL_RUN_IN;
+ break;
+ case COMPACT:
+ m_value.ident = CSS_VAL_COMPACT;
+ break;
+ case INLINE_BLOCK:
+ m_value.ident = CSS_VAL_INLINE_BLOCK;
+ break;
+ case TABLE:
+ m_value.ident = CSS_VAL_TABLE;
+ break;
+ case INLINE_TABLE:
+ m_value.ident = CSS_VAL_INLINE_TABLE;
+ break;
+ case TABLE_ROW_GROUP:
+ m_value.ident = CSS_VAL_TABLE_ROW_GROUP;
+ break;
+ case TABLE_HEADER_GROUP:
+ m_value.ident = CSS_VAL_TABLE_HEADER_GROUP;
+ break;
+ case TABLE_FOOTER_GROUP:
+ m_value.ident = CSS_VAL_TABLE_FOOTER_GROUP;
+ break;
+ case TABLE_ROW:
+ m_value.ident = CSS_VAL_TABLE_ROW;
+ break;
+ case TABLE_COLUMN_GROUP:
+ m_value.ident = CSS_VAL_TABLE_COLUMN_GROUP;
+ break;
+ case TABLE_COLUMN:
+ m_value.ident = CSS_VAL_TABLE_COLUMN;
+ break;
+ case TABLE_CELL:
+ m_value.ident = CSS_VAL_TABLE_CELL;
+ break;
+ case TABLE_CAPTION:
+ m_value.ident = CSS_VAL_TABLE_CAPTION;
+ break;
+ case BOX:
+ m_value.ident = CSS_VAL__WEBKIT_BOX;
+ break;
+ case INLINE_BOX:
+ m_value.ident = CSS_VAL__WEBKIT_INLINE_BOX;
+ break;
+ case NONE:
+ m_value.ident = CSS_VAL_NONE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EDisplay() const
+{
+ if (m_value.ident == CSS_VAL_NONE)
+ return NONE;
+ return static_cast<EDisplay>(m_value.ident - CSS_VAL_INLINE);
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EEmptyCell e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case SHOW:
+ m_value.ident = CSS_VAL_SHOW;
+ break;
+ case HIDE:
+ m_value.ident = CSS_VAL_HIDE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EEmptyCell() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_SHOW:
+ return SHOW;
+ case CSS_VAL_HIDE:
+ return HIDE;
+ default:
+ ASSERT_NOT_REACHED();
+ return SHOW;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EFloat e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case FNONE:
+ m_value.ident = CSS_VAL_NONE;
+ break;
+ case FLEFT:
+ m_value.ident = CSS_VAL_LEFT;
+ break;
+ case FRIGHT:
+ m_value.ident = CSS_VAL_RIGHT;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EFloat() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_LEFT:
+ return FLEFT;
+ case CSS_VAL_RIGHT:
+ return FRIGHT;
+ case CSS_VAL_NONE:
+ case CSS_VAL_CENTER: // Non-standard CSS value
+ return FNONE;
+ default:
+ ASSERT_NOT_REACHED();
+ return FNONE;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EKHTMLLineBreak e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case LBNORMAL:
+ m_value.ident = CSS_VAL_NORMAL;
+ break;
+ case AFTER_WHITE_SPACE:
+ m_value.ident = CSS_VAL_AFTER_WHITE_SPACE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EKHTMLLineBreak() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_AFTER_WHITE_SPACE:
+ return AFTER_WHITE_SPACE;
+ case CSS_VAL_NORMAL:
+ return LBNORMAL;
+ default:
+ ASSERT_NOT_REACHED();
+ return LBNORMAL;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EListStylePosition e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case OUTSIDE:
+ m_value.ident = CSS_VAL_OUTSIDE;
+ break;
+ case INSIDE:
+ m_value.ident = CSS_VAL_INSIDE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EListStylePosition() const
+{
+ return (EListStylePosition)(m_value.ident - CSS_VAL_OUTSIDE);
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EListStyleType e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case LNONE:
+ m_value.ident = CSS_VAL_NONE;
+ break;
+ case DISC:
+ m_value.ident = CSS_VAL_DISC;
+ break;
+ case CIRCLE:
+ m_value.ident = CSS_VAL_CIRCLE;
+ break;
+ case SQUARE:
+ m_value.ident = CSS_VAL_SQUARE;
+ break;
+ case LDECIMAL:
+ m_value.ident = CSS_VAL_DECIMAL;
+ break;
+ case DECIMAL_LEADING_ZERO:
+ m_value.ident = CSS_VAL_DECIMAL_LEADING_ZERO;
+ break;
+ case LOWER_ROMAN:
+ m_value.ident = CSS_VAL_LOWER_ROMAN;
+ break;
+ case UPPER_ROMAN:
+ m_value.ident = CSS_VAL_UPPER_ROMAN;
+ break;
+ case LOWER_GREEK:
+ m_value.ident = CSS_VAL_LOWER_GREEK;
+ break;
+ case LOWER_ALPHA:
+ m_value.ident = CSS_VAL_LOWER_ALPHA;
+ break;
+ case LOWER_LATIN:
+ m_value.ident = CSS_VAL_LOWER_LATIN;
+ break;
+ case UPPER_ALPHA:
+ m_value.ident = CSS_VAL_UPPER_ALPHA;
+ break;
+ case UPPER_LATIN:
+ m_value.ident = CSS_VAL_UPPER_LATIN;
+ break;
+ case HEBREW:
+ m_value.ident = CSS_VAL_HEBREW;
+ break;
+ case ARMENIAN:
+ m_value.ident = CSS_VAL_ARMENIAN;
+ break;
+ case GEORGIAN:
+ m_value.ident = CSS_VAL_GEORGIAN;
+ break;
+ case CJK_IDEOGRAPHIC:
+ m_value.ident = CSS_VAL_CJK_IDEOGRAPHIC;
+ break;
+ case HIRAGANA:
+ m_value.ident = CSS_VAL_HIRAGANA;
+ break;
+ case KATAKANA:
+ m_value.ident = CSS_VAL_KATAKANA;
+ break;
+ case HIRAGANA_IROHA:
+ m_value.ident = CSS_VAL_HIRAGANA_IROHA;
+ break;
+ case KATAKANA_IROHA:
+ m_value.ident = CSS_VAL_KATAKANA_IROHA;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EListStyleType() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_NONE:
+ return LNONE;
+ default:
+ return static_cast<EListStyleType>(m_value.ident - CSS_VAL_DISC);
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EMarginCollapse e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case MCOLLAPSE:
+ m_value.ident = CSS_VAL_COLLAPSE;
+ break;
+ case MSEPARATE:
+ m_value.ident = CSS_VAL_SEPARATE;
+ break;
+ case MDISCARD:
+ m_value.ident = CSS_VAL_DISCARD;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EMarginCollapse() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_COLLAPSE:
+ return MCOLLAPSE;
+ case CSS_VAL_SEPARATE:
+ return MSEPARATE;
+ case CSS_VAL_DISCARD:
+ return MDISCARD;
+ default:
+ ASSERT_NOT_REACHED();
+ return MCOLLAPSE;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EMarqueeBehavior e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case MNONE:
+ m_value.ident = CSS_VAL_NONE;
+ break;
+ case MSCROLL:
+ m_value.ident = CSS_VAL_SCROLL;
+ break;
+ case MSLIDE:
+ m_value.ident = CSS_VAL_SLIDE;
+ break;
+ case MALTERNATE:
+ m_value.ident = CSS_VAL_ALTERNATE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EMarqueeBehavior() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_NONE:
+ return MNONE;
+ case CSS_VAL_SCROLL:
+ return MSCROLL;
+ case CSS_VAL_SLIDE:
+ return MSLIDE;
+ case CSS_VAL_ALTERNATE:
+ return MALTERNATE;
+ default:
+ ASSERT_NOT_REACHED();
+ return MNONE;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EMarqueeDirection e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case MFORWARD:
+ m_value.ident = CSS_VAL_FORWARDS;
+ break;
+ case MBACKWARD:
+ m_value.ident = CSS_VAL_BACKWARDS;
+ break;
+ case MAUTO:
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case MUP:
+ m_value.ident = CSS_VAL_UP;
+ break;
+ case MDOWN:
+ m_value.ident = CSS_VAL_DOWN;
+ break;
+ case MLEFT:
+ m_value.ident = CSS_VAL_LEFT;
+ break;
+ case MRIGHT:
+ m_value.ident = CSS_VAL_RIGHT;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EMarqueeDirection() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_FORWARDS:
+ return MFORWARD;
+ case CSS_VAL_BACKWARDS:
+ return MBACKWARD;
+ case CSS_VAL_AUTO:
+ return MAUTO;
+ case CSS_VAL_AHEAD:
+ case CSS_VAL_UP: // We don't support vertical languages, so AHEAD just maps to UP.
+ return MUP;
+ case CSS_VAL_REVERSE:
+ case CSS_VAL_DOWN: // REVERSE just maps to DOWN, since we don't do vertical text.
+ return MDOWN;
+ case CSS_VAL_LEFT:
+ return MLEFT;
+ case CSS_VAL_RIGHT:
+ return MRIGHT;
+ default:
+ ASSERT_NOT_REACHED();
+ return MAUTO;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EMatchNearestMailBlockquoteColor e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case BCNORMAL:
+ m_value.ident = CSS_VAL_NORMAL;
+ break;
+ case MATCH:
+ m_value.ident = CSS_VAL_MATCH;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EMatchNearestMailBlockquoteColor() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_NORMAL:
+ return BCNORMAL;
+ case CSS_VAL_MATCH:
+ return MATCH;
+ default:
+ ASSERT_NOT_REACHED();
+ return BCNORMAL;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ENBSPMode e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case NBNORMAL:
+ m_value.ident = CSS_VAL_NORMAL;
+ break;
+ case SPACE:
+ m_value.ident = CSS_VAL_SPACE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator ENBSPMode() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_SPACE:
+ return SPACE;
+ case CSS_VAL_NORMAL:
+ return NBNORMAL;
+ default:
+ ASSERT_NOT_REACHED();
+ return NBNORMAL;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EOverflow e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case OVISIBLE:
+ m_value.ident = CSS_VAL_VISIBLE;
+ break;
+ case OHIDDEN:
+ m_value.ident = CSS_VAL_HIDDEN;
+ break;
+ case OSCROLL:
+ m_value.ident = CSS_VAL_SCROLL;
+ break;
+ case OAUTO:
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case OMARQUEE:
+ m_value.ident = CSS_VAL__WEBKIT_MARQUEE;
+ break;
+ case OOVERLAY:
+ m_value.ident = CSS_VAL_OVERLAY;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EOverflow() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_VISIBLE:
+ return OVISIBLE;
+ case CSS_VAL_HIDDEN:
+ return OHIDDEN;
+ case CSS_VAL_SCROLL:
+ return OSCROLL;
+ case CSS_VAL_AUTO:
+ return OAUTO;
+ case CSS_VAL__WEBKIT_MARQUEE:
+ return OMARQUEE;
+ case CSS_VAL_OVERLAY:
+ return OOVERLAY;
+ default:
+ ASSERT_NOT_REACHED();
+ return OVISIBLE;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EPageBreak e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case PBAUTO:
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case PBALWAYS:
+ m_value.ident = CSS_VAL_ALWAYS;
+ break;
+ case PBAVOID:
+ m_value.ident = CSS_VAL_AVOID;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EPageBreak() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_AUTO:
+ return PBAUTO;
+ case CSS_VAL_LEFT:
+ case CSS_VAL_RIGHT:
+ case CSS_VAL_ALWAYS:
+ return PBALWAYS; // CSS2.1: "Conforming user agents may map left/right to always."
+ case CSS_VAL_AVOID:
+ return PBAVOID;
+ default:
+ ASSERT_NOT_REACHED();
+ return PBAUTO;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EPosition e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case StaticPosition:
+ m_value.ident = CSS_VAL_STATIC;
+ break;
+ case RelativePosition:
+ m_value.ident = CSS_VAL_RELATIVE;
+ break;
+ case AbsolutePosition:
+ m_value.ident = CSS_VAL_ABSOLUTE;
+ break;
+ case FixedPosition:
+ m_value.ident = CSS_VAL_FIXED;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EPosition() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_STATIC:
+ return StaticPosition;
+ case CSS_VAL_RELATIVE:
+ return RelativePosition;
+ case CSS_VAL_ABSOLUTE:
+ return AbsolutePosition;
+ case CSS_VAL_FIXED:
+ return FixedPosition;
+ default:
+ ASSERT_NOT_REACHED();
+ return StaticPosition;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EResize e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case RESIZE_BOTH:
+ m_value.ident = CSS_VAL_BOTH;
+ break;
+ case RESIZE_HORIZONTAL:
+ m_value.ident = CSS_VAL_HORIZONTAL;
+ break;
+ case RESIZE_VERTICAL:
+ m_value.ident = CSS_VAL_VERTICAL;
+ break;
+ case RESIZE_NONE:
+ m_value.ident = CSS_VAL_NONE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EResize() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_BOTH:
+ return RESIZE_BOTH;
+ case CSS_VAL_HORIZONTAL:
+ return RESIZE_HORIZONTAL;
+ case CSS_VAL_VERTICAL:
+ return RESIZE_VERTICAL;
+ case CSS_VAL_AUTO:
+ ASSERT_NOT_REACHED(); // Depends on settings, thus should be handled by the caller.
+ return RESIZE_NONE;
+ case CSS_VAL_NONE:
+ return RESIZE_NONE;
+ default:
+ ASSERT_NOT_REACHED();
+ return RESIZE_NONE;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ETableLayout e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case TAUTO:
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case TFIXED:
+ m_value.ident = CSS_VAL_FIXED;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator ETableLayout() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_FIXED:
+ return TFIXED;
+ case CSS_VAL_AUTO:
+ return TAUTO;
+ default:
+ ASSERT_NOT_REACHED();
+ return TAUTO;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ETextAlign e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case TAAUTO:
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case LEFT:
+ m_value.ident = CSS_VAL_LEFT;
+ break;
+ case RIGHT:
+ m_value.ident = CSS_VAL_RIGHT;
+ break;
+ case CENTER:
+ m_value.ident = CSS_VAL_CENTER;
+ break;
+ case JUSTIFY:
+ m_value.ident = CSS_VAL_JUSTIFY;
+ break;
+ case WEBKIT_LEFT:
+ m_value.ident = CSS_VAL__WEBKIT_LEFT;
+ break;
+ case WEBKIT_RIGHT:
+ m_value.ident = CSS_VAL__WEBKIT_RIGHT;
+ break;
+ case WEBKIT_CENTER:
+ m_value.ident = CSS_VAL__WEBKIT_CENTER;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator ETextAlign() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_START:
+ case CSS_VAL_END:
+ ASSERT_NOT_REACHED(); // Depends on direction, thus should be handled by the caller.
+ return LEFT;
+ default:
+ return static_cast<ETextAlign>(m_value.ident - CSS_VAL__WEBKIT_AUTO);
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ETextSecurity e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case TSNONE:
+ m_value.ident = CSS_VAL_NONE;
+ break;
+ case TSDISC:
+ m_value.ident = CSS_VAL_DISC;
+ break;
+ case TSCIRCLE:
+ m_value.ident = CSS_VAL_CIRCLE;
+ break;
+ case TSSQUARE:
+ m_value.ident = CSS_VAL_SQUARE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator ETextSecurity() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_NONE:
+ return TSNONE;
+ case CSS_VAL_DISC:
+ return TSDISC;
+ case CSS_VAL_CIRCLE:
+ return TSCIRCLE;
+ case CSS_VAL_SQUARE:
+ return TSSQUARE;
+ default:
+ ASSERT_NOT_REACHED();
+ return TSNONE;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ETextTransform e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case CAPITALIZE:
+ m_value.ident = CSS_VAL_CAPITALIZE;
+ break;
+ case UPPERCASE:
+ m_value.ident = CSS_VAL_UPPERCASE;
+ break;
+ case LOWERCASE:
+ m_value.ident = CSS_VAL_LOWERCASE;
+ break;
+ case TTNONE:
+ m_value.ident = CSS_VAL_NONE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator ETextTransform() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_CAPITALIZE:
+ return CAPITALIZE;
+ case CSS_VAL_UPPERCASE:
+ return UPPERCASE;
+ case CSS_VAL_LOWERCASE:
+ return LOWERCASE;
+ case CSS_VAL_NONE:
+ return TTNONE;
+ default:
+ ASSERT_NOT_REACHED();
+ return TTNONE;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EUnicodeBidi e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case UBNormal:
+ m_value.ident = CSS_VAL_NORMAL;
+ break;
+ case Embed:
+ m_value.ident = CSS_VAL_EMBED;
+ break;
+ case Override:
+ m_value.ident = CSS_VAL_BIDI_OVERRIDE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EUnicodeBidi() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_NORMAL:
+ return UBNormal;
+ case CSS_VAL_EMBED:
+ return Embed;
+ case CSS_VAL_BIDI_OVERRIDE:
+ return Override;
+ default:
+ ASSERT_NOT_REACHED();
+ return UBNormal;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EUserDrag e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case DRAG_AUTO:
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case DRAG_NONE:
+ m_value.ident = CSS_VAL_NONE;
+ break;
+ case DRAG_ELEMENT:
+ m_value.ident = CSS_VAL_ELEMENT;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EUserDrag() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_AUTO:
+ return DRAG_AUTO;
+ case CSS_VAL_NONE:
+ return DRAG_NONE;
+ case CSS_VAL_ELEMENT:
+ return DRAG_ELEMENT;
+ default:
+ ASSERT_NOT_REACHED();
+ return DRAG_AUTO;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EUserModify e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case READ_ONLY:
+ m_value.ident = CSS_VAL_READ_ONLY;
+ break;
+ case READ_WRITE:
+ m_value.ident = CSS_VAL_READ_WRITE;
+ break;
+ case READ_WRITE_PLAINTEXT_ONLY:
+ m_value.ident = CSS_VAL_READ_WRITE_PLAINTEXT_ONLY;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EUserModify() const
+{
+ return static_cast<EUserModify>(m_value.ident - CSS_VAL_READ_ONLY);
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EUserSelect e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case SELECT_NONE:
+ m_value.ident = CSS_VAL_NONE;
+ break;
+ case SELECT_TEXT:
+ m_value.ident = CSS_VAL_TEXT;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EUserSelect() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_AUTO:
+ return SELECT_TEXT;
+ case CSS_VAL_NONE:
+ return SELECT_NONE;
+ case CSS_VAL_TEXT:
+ return SELECT_TEXT;
+ default:
+ ASSERT_NOT_REACHED();
+ return SELECT_TEXT;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EVisibility e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case VISIBLE:
+ m_value.ident = CSS_VAL_VISIBLE;
+ break;
+ case HIDDEN:
+ m_value.ident = CSS_VAL_HIDDEN;
+ break;
+ case COLLAPSE:
+ m_value.ident = CSS_VAL_COLLAPSE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EVisibility() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_HIDDEN:
+ return HIDDEN;
+ case CSS_VAL_VISIBLE:
+ return VISIBLE;
+ case CSS_VAL_COLLAPSE:
+ return COLLAPSE;
+ default:
+ ASSERT_NOT_REACHED();
+ return VISIBLE;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EWhiteSpace e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case NORMAL:
+ m_value.ident = CSS_VAL_NORMAL;
+ break;
+ case PRE:
+ m_value.ident = CSS_VAL_PRE;
+ break;
+ case PRE_WRAP:
+ m_value.ident = CSS_VAL_PRE_WRAP;
+ break;
+ case PRE_LINE:
+ m_value.ident = CSS_VAL_PRE_LINE;
+ break;
+ case NOWRAP:
+ m_value.ident = CSS_VAL_NOWRAP;
+ break;
+ case KHTML_NOWRAP:
+ m_value.ident = CSS_VAL__WEBKIT_NOWRAP;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EWhiteSpace() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL__WEBKIT_NOWRAP:
+ return KHTML_NOWRAP;
+ case CSS_VAL_NOWRAP:
+ return NOWRAP;
+ case CSS_VAL_PRE:
+ return PRE;
+ case CSS_VAL_PRE_WRAP:
+ return PRE_WRAP;
+ case CSS_VAL_PRE_LINE:
+ return PRE_LINE;
+ case CSS_VAL_NORMAL:
+ return NORMAL;
+ default:
+ ASSERT_NOT_REACHED();
+ return NORMAL;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EWordBreak e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case NormalWordBreak:
+ m_value.ident = CSS_VAL_NORMAL;
+ break;
+ case BreakAllWordBreak:
+ m_value.ident = CSS_VAL_BREAK_ALL;
+ break;
+ case BreakWordBreak:
+ m_value.ident = CSS_VAL_BREAK_WORD;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EWordBreak() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_BREAK_ALL:
+ return BreakAllWordBreak;
+ case CSS_VAL_BREAK_WORD:
+ return BreakWordBreak;
+ case CSS_VAL_NORMAL:
+ return NormalWordBreak;
+ default:
+ ASSERT_NOT_REACHED();
+ return NormalWordBreak;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EWordWrap e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case NormalWordWrap:
+ m_value.ident = CSS_VAL_NORMAL;
+ break;
+ case BreakWordWrap:
+ m_value.ident = CSS_VAL_BREAK_WORD;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EWordWrap() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_BREAK_WORD:
+ return BreakWordWrap;
+ case CSS_VAL_NORMAL:
+ return NormalWordWrap;
+ default:
+ ASSERT_NOT_REACHED();
+ return NormalWordWrap;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextDirection e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case LTR:
+ m_value.ident = CSS_VAL_LTR;
+ break;
+ case RTL:
+ m_value.ident = CSS_VAL_RTL;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator TextDirection() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_LTR:
+ return LTR;
+ case CSS_VAL_RTL:
+ return RTL;
+ default:
+ ASSERT_NOT_REACHED();
+ return LTR;
+ }
+}
+
+#if ENABLE(SVG)
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineCap e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case ButtCap:
+ m_value.ident = CSS_VAL_BUTT;
+ break;
+ case RoundCap:
+ m_value.ident = CSS_VAL_ROUND;
+ break;
+ case SquareCap:
+ m_value.ident = CSS_VAL_SQUARE;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator LineCap() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_BUTT:
+ return ButtCap;
+ case CSS_VAL_ROUND:
+ return RoundCap;
+ case CSS_VAL_SQUARE:
+ return SquareCap;
+ default:
+ ASSERT_NOT_REACHED();
+ return ButtCap;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineJoin e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case MiterJoin:
+ m_value.ident = CSS_VAL_MITER;
+ break;
+ case RoundJoin:
+ m_value.ident = CSS_VAL_ROUND;
+ break;
+ case BevelJoin:
+ m_value.ident = CSS_VAL_BEVEL;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator LineJoin() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_MITER:
+ return MiterJoin;
+ case CSS_VAL_ROUND:
+ return RoundJoin;
+ case CSS_VAL_BEVEL:
+ return BevelJoin;
+ default:
+ ASSERT_NOT_REACHED();
+ return MiterJoin;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(WindRule e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case RULE_NONZERO:
+ m_value.ident = CSS_VAL_NONZERO;
+ break;
+ case RULE_EVENODD:
+ m_value.ident = CSS_VAL_EVENODD;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator WindRule() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_NONZERO:
+ return RULE_NONZERO;
+ case CSS_VAL_EVENODD:
+ return RULE_EVENODD;
+ default:
+ ASSERT_NOT_REACHED();
+ return RULE_NONZERO;
+ }
+}
+
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EAlignmentBaseline e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case AB_AUTO:
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case AB_BASELINE:
+ m_value.ident = CSS_VAL_BASELINE;
+ break;
+ case AB_BEFORE_EDGE:
+ m_value.ident = CSS_VAL_BEFORE_EDGE;
+ break;
+ case AB_TEXT_BEFORE_EDGE:
+ m_value.ident = CSS_VAL_TEXT_BEFORE_EDGE;
+ break;
+ case AB_MIDDLE:
+ m_value.ident = CSS_VAL_MIDDLE;
+ break;
+ case AB_CENTRAL:
+ m_value.ident = CSS_VAL_CENTRAL;
+ break;
+ case AB_AFTER_EDGE:
+ m_value.ident = CSS_VAL_AFTER_EDGE;
+ break;
+ case AB_TEXT_AFTER_EDGE:
+ m_value.ident = CSS_VAL_TEXT_AFTER_EDGE;
+ break;
+ case AB_IDEOGRAPHIC:
+ m_value.ident = CSS_VAL_IDEOGRAPHIC;
+ break;
+ case AB_ALPHABETIC:
+ m_value.ident = CSS_VAL_ALPHABETIC;
+ break;
+ case AB_HANGING:
+ m_value.ident = CSS_VAL_HANGING;
+ break;
+ case AB_MATHEMATICAL:
+ m_value.ident = CSS_VAL_MATHEMATICAL;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EAlignmentBaseline() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_AUTO:
+ return AB_AUTO;
+ case CSS_VAL_BASELINE:
+ return AB_BASELINE;
+ case CSS_VAL_BEFORE_EDGE:
+ return AB_BEFORE_EDGE;
+ case CSS_VAL_TEXT_BEFORE_EDGE:
+ return AB_TEXT_BEFORE_EDGE;
+ case CSS_VAL_MIDDLE:
+ return AB_MIDDLE;
+ case CSS_VAL_CENTRAL:
+ return AB_CENTRAL;
+ case CSS_VAL_AFTER_EDGE:
+ return AB_AFTER_EDGE;
+ case CSS_VAL_TEXT_AFTER_EDGE:
+ return AB_TEXT_AFTER_EDGE;
+ case CSS_VAL_IDEOGRAPHIC:
+ return AB_IDEOGRAPHIC;
+ case CSS_VAL_ALPHABETIC:
+ return AB_ALPHABETIC;
+ case CSS_VAL_HANGING:
+ return AB_HANGING;
+ case CSS_VAL_MATHEMATICAL:
+ return AB_MATHEMATICAL;
+ default:
+ ASSERT_NOT_REACHED();
+ return AB_AUTO;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EColorInterpolation e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case CI_AUTO:
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case CI_SRGB:
+ m_value.ident = CSS_VAL_SRGB;
+ break;
+ case CI_LINEARRGB:
+ m_value.ident = CSS_VAL_LINEARRGB;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EColorInterpolation() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_SRGB:
+ return CI_SRGB;
+ case CSS_VAL_LINEARRGB:
+ return CI_LINEARRGB;
+ case CSS_VAL_AUTO:
+ return CI_AUTO;
+ default:
+ ASSERT_NOT_REACHED();
+ return CI_AUTO;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EColorRendering e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case CR_AUTO:
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case CR_OPTIMIZESPEED:
+ m_value.ident = CSS_VAL_OPTIMIZESPEED;
+ break;
+ case CR_OPTIMIZEQUALITY:
+ m_value.ident = CSS_VAL_OPTIMIZEQUALITY;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EColorRendering() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_OPTIMIZESPEED:
+ return CR_OPTIMIZESPEED;
+ case CSS_VAL_OPTIMIZEQUALITY:
+ return CR_OPTIMIZEQUALITY;
+ case CSS_VAL_AUTO:
+ return CR_AUTO;
+ default:
+ ASSERT_NOT_REACHED();
+ return CR_AUTO;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EDominantBaseline e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case DB_AUTO:
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case DB_USE_SCRIPT:
+ m_value.ident = CSS_VAL_USE_SCRIPT;
+ break;
+ case DB_NO_CHANGE:
+ m_value.ident = CSS_VAL_NO_CHANGE;
+ break;
+ case DB_RESET_SIZE:
+ m_value.ident = CSS_VAL_RESET_SIZE;
+ break;
+ case DB_CENTRAL:
+ m_value.ident = CSS_VAL_CENTRAL;
+ break;
+ case DB_MIDDLE:
+ m_value.ident = CSS_VAL_MIDDLE;
+ break;
+ case DB_TEXT_BEFORE_EDGE:
+ m_value.ident = CSS_VAL_TEXT_BEFORE_EDGE;
+ break;
+ case DB_TEXT_AFTER_EDGE:
+ m_value.ident = CSS_VAL_TEXT_AFTER_EDGE;
+ break;
+ case DB_IDEOGRAPHIC:
+ m_value.ident = CSS_VAL_IDEOGRAPHIC;
+ break;
+ case DB_ALPHABETIC:
+ m_value.ident = CSS_VAL_ALPHABETIC;
+ break;
+ case DB_HANGING:
+ m_value.ident = CSS_VAL_HANGING;
+ break;
+ case DB_MATHEMATICAL:
+ m_value.ident = CSS_VAL_MATHEMATICAL;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EDominantBaseline() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_AUTO:
+ return DB_AUTO;
+ case CSS_VAL_USE_SCRIPT:
+ return DB_USE_SCRIPT;
+ case CSS_VAL_NO_CHANGE:
+ return DB_NO_CHANGE;
+ case CSS_VAL_RESET_SIZE:
+ return DB_RESET_SIZE;
+ case CSS_VAL_IDEOGRAPHIC:
+ return DB_IDEOGRAPHIC;
+ case CSS_VAL_ALPHABETIC:
+ return DB_ALPHABETIC;
+ case CSS_VAL_HANGING:
+ return DB_HANGING;
+ case CSS_VAL_MATHEMATICAL:
+ return DB_MATHEMATICAL;
+ case CSS_VAL_CENTRAL:
+ return DB_CENTRAL;
+ case CSS_VAL_MIDDLE:
+ return DB_MIDDLE;
+ case CSS_VAL_TEXT_AFTER_EDGE:
+ return DB_TEXT_AFTER_EDGE;
+ case CSS_VAL_TEXT_BEFORE_EDGE:
+ return DB_TEXT_BEFORE_EDGE;
+ default:
+ ASSERT_NOT_REACHED();
+ return DB_AUTO;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EImageRendering e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case IR_AUTO:
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case IR_OPTIMIZESPEED:
+ m_value.ident = CSS_VAL_OPTIMIZESPEED;
+ break;
+ case IR_OPTIMIZEQUALITY:
+ m_value.ident = CSS_VAL_OPTIMIZEQUALITY;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EImageRendering() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_AUTO:
+ return IR_AUTO;
+ case CSS_VAL_OPTIMIZESPEED:
+ return IR_OPTIMIZESPEED;
+ case CSS_VAL_OPTIMIZEQUALITY:
+ return IR_OPTIMIZEQUALITY;
+ default:
+ ASSERT_NOT_REACHED();
+ return IR_AUTO;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EPointerEvents e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case PE_NONE:
+ m_value.ident = CSS_VAL_NONE;
+ break;
+ case PE_STROKE:
+ m_value.ident = CSS_VAL_STROKE;
+ break;
+ case PE_FILL:
+ m_value.ident = CSS_VAL_FILL;
+ break;
+ case PE_PAINTED:
+ m_value.ident = CSS_VAL_PAINTED;
+ break;
+ case PE_VISIBLE:
+ m_value.ident = CSS_VAL_VISIBLE;
+ break;
+ case PE_VISIBLE_STROKE:
+ m_value.ident = CSS_VAL_VISIBLESTROKE;
+ break;
+ case PE_VISIBLE_FILL:
+ m_value.ident = CSS_VAL_VISIBLEFILL;
+ break;
+ case PE_VISIBLE_PAINTED:
+ m_value.ident = CSS_VAL_VISIBLEPAINTED;
+ break;
+ case PE_ALL:
+ m_value.ident = CSS_VAL_ALL;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EPointerEvents() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_ALL:
+ return PE_ALL;
+ case CSS_VAL_NONE:
+ return PE_NONE;
+ case CSS_VAL_VISIBLEPAINTED:
+ return PE_VISIBLE_PAINTED;
+ case CSS_VAL_VISIBLEFILL:
+ return PE_VISIBLE_FILL;
+ case CSS_VAL_VISIBLESTROKE:
+ return PE_VISIBLE_STROKE;
+ case CSS_VAL_VISIBLE:
+ return PE_VISIBLE;
+ case CSS_VAL_PAINTED:
+ return PE_PAINTED;
+ case CSS_VAL_FILL:
+ return PE_FILL;
+ case CSS_VAL_STROKE:
+ return PE_STROKE;
+ default:
+ ASSERT_NOT_REACHED();
+ return PE_ALL;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EShapeRendering e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case IR_AUTO:
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case IR_OPTIMIZESPEED:
+ m_value.ident = CSS_VAL_OPTIMIZESPEED;
+ break;
+ case SR_CRISPEDGES:
+ m_value.ident = CSS_VAL_CRISPEDGES;
+ break;
+ case SR_GEOMETRICPRECISION:
+ m_value.ident = CSS_VAL_GEOMETRICPRECISION;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EShapeRendering() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_AUTO:
+ return SR_AUTO;
+ case CSS_VAL_OPTIMIZESPEED:
+ return SR_OPTIMIZESPEED;
+ case CSS_VAL_CRISPEDGES:
+ return SR_CRISPEDGES;
+ case CSS_VAL_GEOMETRICPRECISION:
+ return SR_GEOMETRICPRECISION;
+ default:
+ ASSERT_NOT_REACHED();
+ return SR_AUTO;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ETextAnchor e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case TA_START:
+ m_value.ident = CSS_VAL_START;
+ break;
+ case TA_MIDDLE:
+ m_value.ident = CSS_VAL_MIDDLE;
+ break;
+ case TA_END:
+ m_value.ident = CSS_VAL_END;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator ETextAnchor() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_START:
+ return TA_START;
+ case CSS_VAL_MIDDLE:
+ return TA_MIDDLE;
+ case CSS_VAL_END:
+ return TA_END;
+ default:
+ ASSERT_NOT_REACHED();
+ return TA_START;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ETextRendering e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case TR_AUTO:
+ m_value.ident = CSS_VAL_AUTO;
+ break;
+ case TR_OPTIMIZESPEED:
+ m_value.ident = CSS_VAL_OPTIMIZESPEED;
+ break;
+ case TR_OPTIMIZELEGIBILITY:
+ m_value.ident = CSS_VAL_OPTIMIZELEGIBILITY;
+ break;
+ case TR_GEOMETRICPRECISION:
+ m_value.ident = CSS_VAL_GEOMETRICPRECISION;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator ETextRendering() const
+{
+ switch (m_value.ident) {
+ case CSS_VAL_AUTO:
+ return TR_AUTO;
+ case CSS_VAL_OPTIMIZESPEED:
+ return TR_OPTIMIZESPEED;
+ case CSS_VAL_OPTIMIZELEGIBILITY:
+ return TR_OPTIMIZELEGIBILITY;
+ case CSS_VAL_GEOMETRICPRECISION:
+ return TR_GEOMETRICPRECISION;
+ default:
+ ASSERT_NOT_REACHED();
+ return TR_AUTO;
+ }
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EWritingMode e)
+ : m_type(CSS_IDENT)
+{
+ switch (e) {
+ case WM_LRTB:
+ m_value.ident = CSS_VAL_LR_TB;
+ break;
+ case WM_LR:
+ m_value.ident = CSS_VAL_LR;
+ break;
+ case WM_RLTB:
+ m_value.ident = CSS_VAL_RL_TB;
+ break;
+ case WM_RL:
+ m_value.ident = CSS_VAL_RL;
+ break;
+ case WM_TBRL:
+ m_value.ident = CSS_VAL_TB_RL;
+ break;
+ case WM_TB:
+ m_value.ident = CSS_VAL_TB;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator EWritingMode() const
+{
+ return static_cast<EWritingMode>(m_value.ident - CSS_VAL_LR_TB);
+}
+
+#endif
+
+}
+
+#endif
diff --git a/WebCore/css/CSSProperty.cpp b/WebCore/css/CSSProperty.cpp
new file mode 100644
index 0000000..d25ddf6
--- /dev/null
+++ b/WebCore/css/CSSProperty.cpp
@@ -0,0 +1,41 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 "CSSProperty.h"
+
+#include "CSSPropertyNames.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+String CSSProperty::cssText() const
+{
+ return String(getPropertyName(static_cast<CSSPropertyID>(id()))) + ": " + m_value->cssText() + (isImportant() ? " !important" : "") + "; ";
+}
+
+bool operator==(const CSSProperty& a, const CSSProperty& b)
+{
+ return a.m_id == b.m_id && a.m_important == b.m_important && a.m_value == b.m_value;
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSProperty.h b/WebCore/css/CSSProperty.h
new file mode 100644
index 0000000..0b06da3
--- /dev/null
+++ b/WebCore/css/CSSProperty.h
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 CSSProperty_h
+#define CSSProperty_h
+
+#include "CSSValue.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSProperty {
+public:
+ CSSProperty(int propID, PassRefPtr<CSSValue> value, bool important = false, int shorthandID = 0, bool implicit = false)
+ : m_id(propID)
+ , m_shorthandID(shorthandID)
+ , m_important(important)
+ , m_implicit(implicit)
+ , m_value(value)
+ {
+ }
+
+ CSSProperty& operator=(const CSSProperty& other)
+ {
+ m_id = other.m_id;
+ m_shorthandID = other.m_shorthandID;
+ m_important = other.m_important;
+ m_value = other.m_value;
+ return *this;
+ }
+
+ int id() const { return m_id; }
+ int shorthandID() const { return m_shorthandID; }
+
+ bool isImportant() const { return m_important; }
+ bool isImplicit() const { return m_implicit; }
+
+ CSSValue* value() const { return m_value.get(); }
+
+ String cssText() const;
+
+ friend bool operator==(const CSSProperty&, const CSSProperty&);
+
+ // make sure the following fits in 4 bytes.
+ int m_id;
+ int m_shorthandID; // If this property was set as part of a shorthand, gives the shorthand.
+ bool m_important : 1;
+ bool m_implicit : 1; // Whether or not the property was set implicitly as the result of a shorthand.
+
+ RefPtr<CSSValue> m_value;
+};
+
+} // namespace WebCore
+
+#endif // CSSProperty_h
diff --git a/WebCore/css/CSSPropertyNames.in b/WebCore/css/CSSPropertyNames.in
new file mode 100644
index 0000000..03f8ca2
--- /dev/null
+++ b/WebCore/css/CSSPropertyNames.in
@@ -0,0 +1,217 @@
+#
+# CSS property names
+#
+# Some properties are used internally, but are not part of CSS. They are used to get
+# HTML4 compatibility in the rendering engine.
+#
+# Microsoft extensions are documented here:
+# http://msdn.microsoft.com/workshop/author/css/reference/attributes.asp
+#
+
+background
+background-attachment
+background-color
+background-image
+background-position
+background-position-x
+background-position-y
+background-repeat
+border
+border-bottom
+border-bottom-color
+border-bottom-style
+border-bottom-width
+border-collapse
+border-color
+border-left
+border-left-color
+border-left-style
+border-left-width
+border-right
+border-right-color
+border-right-style
+border-right-width
+border-spacing
+border-style
+border-top
+border-top-color
+border-top-style
+border-top-width
+border-width
+bottom
+caption-side
+clear
+clip
+color
+content
+counter-increment
+counter-reset
+cursor
+direction
+display
+empty-cells
+float
+font
+font-family
+font-size
+font-stretch
+font-style
+font-variant
+font-weight
+height
+left
+letter-spacing
+line-height
+list-style
+list-style-image
+list-style-position
+list-style-type
+margin
+margin-bottom
+margin-left
+margin-right
+margin-top
+max-height
+max-width
+min-height
+min-width
+opacity
+orphans
+outline
+outline-color
+outline-offset
+outline-style
+outline-width
+overflow
+overflow-x
+overflow-y
+padding
+padding-bottom
+padding-left
+padding-right
+padding-top
+page
+page-break-after
+page-break-before
+page-break-inside
+position
+quotes
+resize
+right
+scrollbar-3dlight-color
+scrollbar-arrow-color
+scrollbar-darkshadow-color
+scrollbar-face-color
+scrollbar-highlight-color
+scrollbar-shadow-color
+scrollbar-track-color
+size
+src
+table-layout
+text-align
+text-decoration
+text-indent
+text-line-through
+text-line-through-color
+text-line-through-mode
+text-line-through-style
+text-line-through-width
+text-overflow
+text-overline
+text-overline-color
+text-overline-mode
+text-overline-style
+text-overline-width
+text-shadow
+text-transform
+text-underline
+text-underline-color
+text-underline-mode
+text-underline-style
+text-underline-width
+top
+unicode-bidi
+unicode-range
+vertical-align
+visibility
+white-space
+widows
+width
+word-break
+word-spacing
+word-wrap
+z-index
+-webkit-transition
+-webkit-transition-duration
+-webkit-transition-property
+-webkit-transition-repeat-count
+-webkit-transition-timing-function
+-webkit-appearance
+-webkit-background-clip
+-webkit-background-composite
+-webkit-background-origin
+-webkit-background-size
+-webkit-binding
+-webkit-border-bottom-left-radius
+-webkit-border-bottom-right-radius
+-webkit-border-fit
+-webkit-border-horizontal-spacing
+-webkit-border-image
+-webkit-border-radius
+-webkit-border-top-left-radius
+-webkit-border-top-right-radius
+-webkit-border-vertical-spacing
+-webkit-box-align
+-webkit-box-direction
+-webkit-box-flex
+-webkit-box-flex-group
+-webkit-box-lines
+-webkit-box-ordinal-group
+-webkit-box-orient
+-webkit-box-pack
+-webkit-box-shadow
+-webkit-box-sizing
+-webkit-column-break-after
+-webkit-column-break-before
+-webkit-column-break-inside
+-webkit-column-count
+-webkit-column-gap
+-webkit-column-rule
+-webkit-column-rule-color
+-webkit-column-rule-style
+-webkit-column-rule-width
+-webkit-column-width
+-webkit-columns
+-webkit-dashboard-region
+-webkit-font-size-delta
+-webkit-highlight
+-webkit-line-break
+-webkit-line-clamp
+-webkit-margin-bottom-collapse
+-webkit-margin-collapse
+-webkit-margin-start
+-webkit-margin-top-collapse
+-webkit-marquee
+-webkit-marquee-direction
+-webkit-marquee-increment
+-webkit-marquee-repetition
+-webkit-marquee-speed
+-webkit-marquee-style
+-webkit-match-nearest-mail-blockquote-color
+-webkit-nbsp-mode
+-webkit-padding-start
+-webkit-rtl-ordering
+-webkit-text-decorations-in-effect
+-webkit-text-fill-color
+-webkit-text-security
+-webkit-text-size-adjust
+-webkit-text-stroke
+-webkit-text-stroke-color
+-webkit-text-stroke-width
+-webkit-transform
+-webkit-transform-origin
+-webkit-transform-origin-x
+-webkit-transform-origin-y
+-webkit-user-drag
+-webkit-user-modify
+-webkit-user-select
diff --git a/WebCore/css/CSSQuirkPrimitiveValue.h b/WebCore/css/CSSQuirkPrimitiveValue.h
new file mode 100644
index 0000000..3655ca5
--- /dev/null
+++ b/WebCore/css/CSSQuirkPrimitiveValue.h
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 CSSQuirkPrimitiveValue_h
+#define CSSQuirkPrimitiveValue_h
+
+#include "CSSPrimitiveValue.h"
+
+namespace WebCore {
+
+// This value is used to handle quirky margins in reflow roots (body, td, and th) like WinIE.
+// The basic idea is that a stylesheet can use the value __qem (for quirky em) instead of em
+// in a stylesheet. When the quirky value is used, if you're in quirks mode, the margin will
+// collapse away inside a table cell.
+class CSSQuirkPrimitiveValue : public CSSPrimitiveValue {
+public:
+ CSSQuirkPrimitiveValue(double num, UnitTypes type)
+ : CSSPrimitiveValue(num, type)
+ {
+ }
+
+ virtual bool isQuirkValue() { return true; }
+};
+
+} // namespace WebCore
+
+#endif // CSSQuirkPrimitiveValue_h
diff --git a/WebCore/css/CSSRule.cpp b/WebCore/css/CSSRule.cpp
new file mode 100644
index 0000000..0b141b1
--- /dev/null
+++ b/WebCore/css/CSSRule.cpp
@@ -0,0 +1,52 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2005, 2006, 2007 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 "CSSRule.h"
+
+#include "CSSStyleSheet.h"
+
+namespace WebCore {
+
+CSSStyleSheet* CSSRule::parentStyleSheet() const
+{
+ return (parent() && parent()->isCSSStyleSheet()) ? static_cast<CSSStyleSheet*>(parent()) : 0;
+}
+
+CSSRule* CSSRule::parentRule() const
+{
+ return (parent() && parent()->isRule()) ? static_cast<CSSRule*>(parent()) : 0;
+}
+
+String CSSRule::cssText() const
+{
+ // FIXME: Implement!
+ return String();
+}
+
+void CSSRule::setCssText(String /*cssText*/, ExceptionCode& /*ec*/)
+{
+ // FIXME: Implement!
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSRule.h b/WebCore/css/CSSRule.h
new file mode 100644
index 0000000..ad865b3
--- /dev/null
+++ b/WebCore/css/CSSRule.h
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2006, 2007 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 CSSRule_h
+#define CSSRule_h
+
+#include "StyleBase.h"
+
+namespace WebCore {
+
+class CSSStyleSheet;
+
+typedef int ExceptionCode;
+
+class CSSRule : public StyleBase {
+public:
+ enum CSSRuleType {
+ UNKNOWN_RULE,
+ STYLE_RULE,
+ CHARSET_RULE,
+ IMPORT_RULE,
+ MEDIA_RULE,
+ FONT_FACE_RULE,
+ PAGE_RULE
+ };
+
+ CSSRule(StyleBase* parent)
+ : StyleBase(parent)
+ {
+ }
+
+ virtual bool isRule() { return true; }
+
+ virtual unsigned short type() const = 0;
+
+ CSSStyleSheet* parentStyleSheet() const;
+ CSSRule* parentRule() const;
+
+ virtual String cssText() const;
+ void setCssText(String, ExceptionCode&);
+};
+
+} // namespace WebCore
+
+#endif // CSSRule_h
diff --git a/WebCore/css/CSSRule.idl b/WebCore/css/CSSRule.idl
new file mode 100644
index 0000000..d36c059
--- /dev/null
+++ b/WebCore/css/CSSRule.idl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [
+ GenerateConstructor,
+ ObjCCustomInternalImpl,
+ InterfaceUUID=548139b4-31ab-4978-b1d5-cfcfdfbaea0e,
+ ImplementationUUID=0268e673-2489-4743-9a3a-197dae4b4d9c
+ ] CSSRule {
+
+ // RuleType
+ const unsigned short UNKNOWN_RULE = 0;
+ const unsigned short STYLE_RULE = 1;
+ const unsigned short CHARSET_RULE = 2;
+ const unsigned short IMPORT_RULE = 3;
+ const unsigned short MEDIA_RULE = 4;
+ const unsigned short FONT_FACE_RULE = 5;
+ const unsigned short PAGE_RULE = 6;
+
+ readonly attribute unsigned short type;
+
+ attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString cssText
+ setter raises (DOMException);
+
+ readonly attribute CSSStyleSheet parentStyleSheet;
+ readonly attribute CSSRule parentRule;
+
+ };
+
+}
diff --git a/WebCore/css/CSSRuleList.cpp b/WebCore/css/CSSRuleList.cpp
new file mode 100644
index 0000000..89058fd
--- /dev/null
+++ b/WebCore/css/CSSRuleList.cpp
@@ -0,0 +1,100 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 "CSSRuleList.h"
+
+#include "CSSRule.h"
+#include "StyleList.h"
+
+namespace WebCore {
+
+CSSRuleList::CSSRuleList()
+ : RefCounted<CSSRuleList>(0)
+{
+}
+
+CSSRuleList::CSSRuleList(StyleList* list, bool omitCharsetRules)
+ : RefCounted<CSSRuleList>(0)
+{
+ m_list = list;
+ if (list && omitCharsetRules) {
+ m_list = 0;
+ unsigned len = list->length();
+ for (unsigned i = 0; i < len; ++i) {
+ StyleBase* style = list->item(i);
+ if (style->isRule() && !style->isCharsetRule())
+ append(static_cast<CSSRule*>(style));
+ }
+ }
+}
+
+CSSRuleList::~CSSRuleList()
+{
+ CSSRule* rule;
+ while (!m_lstCSSRules.isEmpty() && (rule = m_lstCSSRules.take(0)))
+ rule->deref();
+}
+
+unsigned CSSRuleList::length() const
+{
+ return m_list ? m_list->length() : m_lstCSSRules.count();
+}
+
+CSSRule* CSSRuleList::item(unsigned index)
+{
+ if (m_list) {
+ StyleBase* rule = m_list->item(index);
+ ASSERT(!rule || rule->isRule());
+ return static_cast<CSSRule*>(rule);
+ }
+ return m_lstCSSRules.at(index);
+}
+
+void CSSRuleList::deleteRule(unsigned index)
+{
+ ASSERT(!m_list);
+ CSSRule* rule = m_lstCSSRules.take(index);
+ if (rule)
+ rule->deref();
+ // FIXME: Throw INDEX_SIZE_ERR exception here if !rule
+}
+
+void CSSRuleList::append(CSSRule* rule)
+{
+ insertRule(rule, m_lstCSSRules.count()) ;
+}
+
+unsigned CSSRuleList::insertRule(CSSRule* rule, unsigned index)
+{
+ ASSERT(!m_list);
+ if (rule && m_lstCSSRules.insert(index, rule)) {
+ rule->ref();
+ return index;
+ }
+
+ // FIXME: Should throw INDEX_SIZE_ERR exception instead!
+ return 0;
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSRuleList.h b/WebCore/css/CSSRuleList.h
new file mode 100644
index 0000000..721696f
--- /dev/null
+++ b/WebCore/css/CSSRuleList.h
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2006 Apple Computer, Inc.
+ *
+ * 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 CSSRuleList_h
+#define CSSRuleList_h
+
+#include "DeprecatedPtrList.h"
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSRule;
+class StyleList;
+
+class CSSRuleList : public RefCounted<CSSRuleList> {
+public:
+ CSSRuleList();
+ CSSRuleList(StyleList*, bool omitCharsetRules = false);
+ ~CSSRuleList();
+
+ unsigned length() const;
+ CSSRule* item(unsigned index);
+
+ // FIXME: Not part of the DOM. Only used by media rules. We should be able to remove them if we changed media rules to work
+ // as StyleLists instead.
+ unsigned insertRule(CSSRule*, unsigned index);
+ void deleteRule(unsigned index);
+ void append(CSSRule*);
+
+protected:
+ RefPtr<StyleList> m_list;
+ DeprecatedPtrList<CSSRule> m_lstCSSRules; // FIXME: Want to eliminate, but used by IE rules() extension and still used by media rules.
+};
+
+} // namespace WebCore
+
+#endif // CSSRuleList_h
diff --git a/WebCore/css/CSSRuleList.idl b/WebCore/css/CSSRuleList.idl
new file mode 100644
index 0000000..224d6a1
--- /dev/null
+++ b/WebCore/css/CSSRuleList.idl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006, 2007 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 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.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [
+ GenerateConstructor,
+ HasIndexGetter,
+ InterfaceUUID=64c346a0-1e34-49d3-9472-57ec8e0fdccb,
+ ImplementationUUID=971a28e0-d0da-4570-9b71-e39fc2cf9a1b
+ ] CSSRuleList {
+ readonly attribute unsigned long length;
+ CSSRule item(in unsigned long index);
+ };
+
+}
diff --git a/WebCore/css/CSSSegmentedFontFace.cpp b/WebCore/css/CSSSegmentedFontFace.cpp
new file mode 100644
index 0000000..8ecfea9
--- /dev/null
+++ b/WebCore/css/CSSSegmentedFontFace.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2008 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 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.
+ */
+
+#include "config.h"
+#include "CSSSegmentedFontFace.h"
+
+#include "CSSFontFace.h"
+#include "CSSFontSelector.h"
+#include "FontDescription.h"
+#include "SegmentedFontData.h"
+#include "SimpleFontData.h"
+
+namespace WebCore {
+
+CSSSegmentedFontFace::CSSSegmentedFontFace(CSSFontSelector* fontSelector)
+ : RefCounted<CSSSegmentedFontFace>(0)
+ , m_fontSelector(fontSelector)
+{
+}
+
+CSSSegmentedFontFace::~CSSSegmentedFontFace()
+{
+ pruneTable();
+}
+
+void CSSSegmentedFontFace::pruneTable()
+{
+ // Make sure the glyph page tree prunes out all uses of this custom font.
+ if (m_fontDataTable.isEmpty())
+ return;
+ HashMap<unsigned, SegmentedFontData*>::iterator end = m_fontDataTable.end();
+ for (HashMap<unsigned, SegmentedFontData*>::iterator it = m_fontDataTable.begin(); it != end; ++it)
+ GlyphPageTreeNode::pruneTreeCustomFontData(it->second);
+ deleteAllValues(m_fontDataTable);
+ m_fontDataTable.clear();
+}
+
+bool CSSSegmentedFontFace::isLoaded() const
+{
+ unsigned size = m_ranges.size();
+ for (unsigned i = 0; i < size; i++) {
+ if (!m_ranges[i].fontFace()->isLoaded())
+ return false;
+ }
+ return true;
+}
+
+bool CSSSegmentedFontFace::isValid() const
+{
+ unsigned size = m_ranges.size();
+ for (unsigned i = 0; i < size; i++) {
+ if (!m_ranges[i].fontFace()->isValid())
+ return false;
+ }
+ return true;
+}
+
+void CSSSegmentedFontFace::fontLoaded(CSSFontFace*)
+{
+ pruneTable();
+ m_fontSelector->fontLoaded(this);
+}
+
+void CSSSegmentedFontFace::overlayRange(UChar32 from, UChar32 to, PassRefPtr<CSSFontFace> fontFace)
+{
+ pruneTable();
+ fontFace->setSegmentedFontFace(this);
+
+ unsigned size = m_ranges.size();
+ if (size) {
+ Vector<FontFaceRange, 8> oldRanges = m_ranges;
+ m_ranges.clear();
+ for (unsigned i = 0; i < size; i++) {
+ const FontFaceRange& range = oldRanges[i];
+ if (range.from() > to || range.to() < from)
+ m_ranges.append(range);
+ else if (range.from() < from) {
+ m_ranges.append(FontFaceRange(range.from(), from - 1, range.fontFace()));
+ if (range.to() > to)
+ m_ranges.append(FontFaceRange(to + 1, range.to(), range.fontFace()));
+ } else if (range.to() > to)
+ m_ranges.append(FontFaceRange(to + 1, range.to(), range.fontFace()));
+ }
+ }
+ m_ranges.append(FontFaceRange(from, to, fontFace));
+}
+
+FontData* CSSSegmentedFontFace::getFontData(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic)
+{
+ if (!isValid())
+ return 0;
+
+ unsigned hashKey = fontDescription.computedPixelSize() << 2 | (syntheticBold ? 0 : 2) | (syntheticItalic ? 0 : 1);
+
+ SegmentedFontData* fontData = m_fontDataTable.get(hashKey);
+ if (fontData)
+ return fontData;
+
+ fontData = new SegmentedFontData();
+
+ unsigned size = m_ranges.size();
+ for (unsigned i = 0; i < size; i++) {
+ if (const FontData* rangeFontData = m_ranges[i].fontFace()->getFontData(fontDescription, syntheticBold, syntheticItalic)) {
+ ASSERT(!rangeFontData->isSegmented());
+ fontData->appendRange(FontDataRange(m_ranges[i].from(), m_ranges[i].to(), static_cast<const SimpleFontData*>(rangeFontData)));
+ }
+ }
+ if (fontData->numRanges())
+ m_fontDataTable.set(hashKey, fontData);
+ else {
+ delete fontData;
+ fontData = 0;
+ }
+
+ return fontData;
+}
+
+}
diff --git a/WebCore/css/CSSSegmentedFontFace.h b/WebCore/css/CSSSegmentedFontFace.h
new file mode 100644
index 0000000..55a9da5
--- /dev/null
+++ b/WebCore/css/CSSSegmentedFontFace.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2008 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 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 CSSSegmentedFontFace_h
+#define CSSSegmentedFontFace_h
+
+#include <wtf/HashMap.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+#include <wtf/unicode/Unicode.h>
+
+namespace WebCore {
+
+class CSSFontFace;
+class CSSFontSelector;
+class FontData;
+class FontDescription;
+class SegmentedFontData;
+
+struct FontFaceRange {
+ FontFaceRange(UChar32 from, UChar32 to, PassRefPtr<CSSFontFace> fontFace)
+ : m_from(from)
+ , m_to(to)
+ , m_fontFace(fontFace)
+ {
+ }
+
+ UChar32 from() const { return m_from; }
+ UChar32 to() const { return m_to; }
+ CSSFontFace* fontFace() const { return m_fontFace.get(); }
+
+private:
+ UChar32 m_from;
+ UChar32 m_to;
+ RefPtr<CSSFontFace> m_fontFace;
+};
+
+class CSSSegmentedFontFace : public RefCounted<CSSSegmentedFontFace> {
+public:
+ CSSSegmentedFontFace(CSSFontSelector*);
+ ~CSSSegmentedFontFace();
+
+ bool isLoaded() const;
+ bool isValid() const;
+ CSSFontSelector* fontSelector() const { return m_fontSelector; }
+
+ void fontLoaded(CSSFontFace*);
+
+ unsigned numRanges() const { return m_ranges.size(); }
+ void overlayRange(UChar32 from, UChar32 to, PassRefPtr<CSSFontFace>);
+
+ FontData* getFontData(const FontDescription&, bool syntheticBold, bool syntheticItalic);
+
+private:
+ void pruneTable();
+
+ CSSFontSelector* m_fontSelector;
+ HashMap<unsigned, SegmentedFontData*> m_fontDataTable;
+ Vector<FontFaceRange, 1> m_ranges;
+};
+
+} // namespace WebCore
+
+#endif // CSSSegmentedFontFace_h
diff --git a/WebCore/css/CSSSelector.cpp b/WebCore/css/CSSSelector.cpp
new file mode 100644
index 0000000..2fd8d21
--- /dev/null
+++ b/WebCore/css/CSSSelector.cpp
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * 1999 Waldo Bastian (bastian@kde.org)
+ * 2001 Andreas Schlapbach (schlpbch@iam.unibe.ch)
+ * 2001-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2006, 2007, 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 "CSSSelector.h"
+
+namespace WebCore {
+
+void CSSSelector::print()
+{
+ if (m_tagHistory)
+ m_tagHistory->print();
+}
+
+unsigned int CSSSelector::specificity()
+{
+ // FIXME: Pseudo-elements and pseudo-classes do not have the same specificity. This function
+ // isn't quite correct.
+ int s = (m_tag.localName() == starAtom ? 0 : 1);
+ switch (m_match) {
+ case Id:
+ s += 0x10000;
+ break;
+ case Exact:
+ case Class:
+ case Set:
+ case List:
+ case Hyphen:
+ case PseudoClass:
+ case PseudoElement:
+ case Contain:
+ case Begin:
+ case End:
+ s += 0x100;
+ case None:
+ break;
+ }
+
+ if (m_tagHistory)
+ s += m_tagHistory->specificity();
+
+ // make sure it doesn't overflow
+ return s & 0xffffff;
+}
+
+void CSSSelector::extractPseudoType() const
+{
+ if (m_match != PseudoClass && m_match != PseudoElement)
+ return;
+
+ static AtomicString active("active");
+ static AtomicString after("after");
+ static AtomicString anyLink("-webkit-any-link");
+ static AtomicString autofill("-webkit-autofill");
+ static AtomicString before("before");
+ static AtomicString checked("checked");
+ static AtomicString fileUploadButton("-webkit-file-upload-button");
+ static AtomicString disabled("disabled");
+ static AtomicString drag("-webkit-drag");
+ static AtomicString dragAlias("-khtml-drag"); // was documented with this name in Apple documentation, so keep an alias
+ static AtomicString empty("empty");
+ static AtomicString enabled("enabled");
+ static AtomicString firstChild("first-child");
+ static AtomicString firstLetter("first-letter");
+ static AtomicString firstLine("first-line");
+ static AtomicString firstOfType("first-of-type");
+ static AtomicString nthChild("nth-child(");
+ static AtomicString nthOfType("nth-of-type(");
+ static AtomicString nthLastChild("nth-last-child(");
+ static AtomicString nthLastOfType("nth-last-of-type(");
+ static AtomicString focus("focus");
+ static AtomicString hover("hover");
+ static AtomicString indeterminate("indeterminate");
+ static AtomicString lastChild("last-child");
+ static AtomicString lastOfType("last-of-type");
+ static AtomicString link("link");
+ static AtomicString lang("lang(");
+ static AtomicString mediaControlsPanel("-webkit-media-controls-panel");
+ static AtomicString mediaControlsMuteButton("-webkit-media-controls-mute-button");
+ static AtomicString mediaControlsPlayButton("-webkit-media-controls-play-button");
+ static AtomicString mediaControlsTimeDisplay("-webkit-media-controls-time-display");
+ static AtomicString mediaControlsTimeline("-webkit-media-controls-timeline");
+ static AtomicString mediaControlsSeekBackButton("-webkit-media-controls-seek-back-button");
+ static AtomicString mediaControlsSeekForwardButton("-webkit-media-controls-seek-forward-button");
+ static AtomicString mediaControlsFullscreenButton("-webkit-media-controls-fullscreen-button");
+ static AtomicString notStr("not(");
+ static AtomicString onlyChild("only-child");
+ static AtomicString onlyOfType("only-of-type");
+ static AtomicString root("root");
+ static AtomicString searchCancelButton("-webkit-search-cancel-button");
+ static AtomicString searchDecoration("-webkit-search-decoration");
+ static AtomicString searchResultsDecoration("-webkit-search-results-decoration");
+ static AtomicString searchResultsButton("-webkit-search-results-button");
+ static AtomicString selection("selection");
+ static AtomicString sliderThumb("-webkit-slider-thumb");
+ static AtomicString target("target");
+ static AtomicString visited("visited");
+
+ bool element = false; // pseudo-element
+ bool compat = false; // single colon compatbility mode
+
+ m_pseudoType = PseudoUnknown;
+ if (m_value == active)
+ m_pseudoType = PseudoActive;
+ else if (m_value == after) {
+ m_pseudoType = PseudoAfter;
+ element = true;
+ compat = true;
+ } else if (m_value == anyLink)
+ m_pseudoType = PseudoAnyLink;
+ else if (m_value == autofill)
+ m_pseudoType = PseudoAutofill;
+ else if (m_value == before) {
+ m_pseudoType = PseudoBefore;
+ element = true;
+ compat = true;
+ } else if (m_value == checked)
+ m_pseudoType = PseudoChecked;
+ else if (m_value == fileUploadButton) {
+ m_pseudoType = PseudoFileUploadButton;
+ element = true;
+ } else if (m_value == disabled)
+ m_pseudoType = PseudoDisabled;
+ else if (m_value == drag || m_value == dragAlias)
+ m_pseudoType = PseudoDrag;
+ else if (m_value == enabled)
+ m_pseudoType = PseudoEnabled;
+ else if (m_value == empty)
+ m_pseudoType = PseudoEmpty;
+ else if (m_value == firstChild)
+ m_pseudoType = PseudoFirstChild;
+ else if (m_value == lastChild)
+ m_pseudoType = PseudoLastChild;
+ else if (m_value == lastOfType)
+ m_pseudoType = PseudoLastOfType;
+ else if (m_value == onlyChild)
+ m_pseudoType = PseudoOnlyChild;
+ else if (m_value == onlyOfType)
+ m_pseudoType = PseudoOnlyOfType;
+ else if (m_value == firstLetter) {
+ m_pseudoType = PseudoFirstLetter;
+ element = true;
+ compat = true;
+ } else if (m_value == firstLine) {
+ m_pseudoType = PseudoFirstLine;
+ element = true;
+ compat = true;
+ } else if (m_value == firstOfType)
+ m_pseudoType = PseudoFirstOfType;
+ else if (m_value == focus)
+ m_pseudoType = PseudoFocus;
+ else if (m_value == hover)
+ m_pseudoType = PseudoHover;
+ else if (m_value == indeterminate)
+ m_pseudoType = PseudoIndeterminate;
+ else if (m_value == link)
+ m_pseudoType = PseudoLink;
+ else if (m_value == lang)
+ m_pseudoType = PseudoLang;
+ else if (m_value == mediaControlsPanel) {
+ m_pseudoType = PseudoMediaControlsPanel;
+ element = true;
+ } else if (m_value == mediaControlsMuteButton) {
+ m_pseudoType = PseudoMediaControlsMuteButton;
+ element = true;
+ } else if (m_value == mediaControlsPlayButton) {
+ m_pseudoType = PseudoMediaControlsPlayButton;
+ element = true;
+ } else if (m_value == mediaControlsTimeDisplay) {
+ m_pseudoType = PseudoMediaControlsTimeDisplay;
+ element = true;
+ } else if (m_value == mediaControlsTimeline) {
+ m_pseudoType = PseudoMediaControlsTimeline;
+ element = true;
+ } else if (m_value == mediaControlsSeekBackButton) {
+ m_pseudoType = PseudoMediaControlsSeekBackButton;
+ element = true;
+ } else if (m_value == mediaControlsSeekForwardButton) {
+ m_pseudoType = PseudoMediaControlsSeekForwardButton;
+ element = true;
+ } else if (m_value == mediaControlsFullscreenButton) {
+ m_pseudoType = PseudoMediaControlsFullscreenButton;
+ element = true;
+ } else if (m_value == notStr)
+ m_pseudoType = PseudoNot;
+ else if (m_value == nthChild)
+ m_pseudoType = PseudoNthChild;
+ else if (m_value == nthOfType)
+ m_pseudoType = PseudoNthOfType;
+ else if (m_value == nthLastChild)
+ m_pseudoType = PseudoNthLastChild;
+ else if (m_value == nthLastOfType)
+ m_pseudoType = PseudoNthLastOfType;
+ else if (m_value == root)
+ m_pseudoType = PseudoRoot;
+ else if (m_value == searchCancelButton) {
+ m_pseudoType = PseudoSearchCancelButton;
+ element = true;
+ } else if (m_value == searchDecoration) {
+ m_pseudoType = PseudoSearchDecoration;
+ element = true;
+ } else if (m_value == searchResultsDecoration) {
+ m_pseudoType = PseudoSearchResultsDecoration;
+ element = true;
+ } else if (m_value == searchResultsButton) {
+ m_pseudoType = PseudoSearchResultsButton;
+ element = true;
+ } else if (m_value == selection) {
+ m_pseudoType = PseudoSelection;
+ element = true;
+ } else if (m_value == sliderThumb) {
+ m_pseudoType = PseudoSliderThumb;
+ element = true;
+ } else if (m_value == target)
+ m_pseudoType = PseudoTarget;
+ else if (m_value == visited)
+ m_pseudoType = PseudoVisited;
+
+ if (m_match == PseudoClass && element) {
+ if (!compat)
+ m_pseudoType = PseudoUnknown;
+ else
+ m_match = PseudoElement;
+ } else if (m_match == PseudoElement && !element)
+ m_pseudoType = PseudoUnknown;
+}
+
+bool CSSSelector::operator==(const CSSSelector& other)
+{
+ const CSSSelector* sel1 = this;
+ const CSSSelector* sel2 = &other;
+
+ while (sel1 && sel2) {
+ if (sel1->m_tag != sel2->m_tag || sel1->m_attr != sel2->m_attr ||
+ sel1->relation() != sel2->relation() || sel1->m_match != sel2->m_match ||
+ sel1->m_value != sel2->m_value ||
+ sel1->pseudoType() != sel2->pseudoType() ||
+ sel1->m_argument != sel2->m_argument)
+ return false;
+ sel1 = sel1->m_tagHistory;
+ sel2 = sel2->m_tagHistory;
+ }
+
+ if (sel1 || sel2)
+ return false;
+
+ return true;
+}
+
+String CSSSelector::selectorText() const
+{
+ String str = "";
+
+ const AtomicString& prefix = m_tag.prefix();
+ const AtomicString& localName = m_tag.localName();
+ if (m_match == CSSSelector::None || !prefix.isNull() || localName != starAtom) {
+ if (prefix.isNull())
+ str = localName;
+ else
+ str = prefix + "|" + localName;
+ }
+
+ const CSSSelector* cs = this;
+ while (true) {
+ if (cs->m_match == CSSSelector::Id) {
+ str += "#";
+ str += cs->m_value;
+ } else if (cs->m_match == CSSSelector::Class) {
+ str += ".";
+ str += cs->m_value;
+ } else if (cs->m_match == CSSSelector::PseudoClass) {
+ str += ":";
+ str += cs->m_value;
+ if (cs->pseudoType() == PseudoNot) {
+ if (CSSSelector* subSel = cs->m_simpleSelector)
+ str += subSel->selectorText();
+ str += ")";
+ } else if (cs->pseudoType() == PseudoLang) {
+ str += cs->m_argument;
+ str += ")";
+ }
+ } else if (cs->m_match == CSSSelector::PseudoElement) {
+ str += "::";
+ str += cs->m_value;
+ } else if (cs->hasAttribute()) {
+ str += "[";
+ const AtomicString& prefix = cs->m_attr.prefix();
+ if (!prefix.isNull())
+ str += prefix + "|";
+ str += cs->m_attr.localName();
+ switch (cs->m_match) {
+ case CSSSelector::Exact:
+ str += "=";
+ break;
+ case CSSSelector::Set:
+ // set has no operator or value, just the attrName
+ str += "]";
+ break;
+ case CSSSelector::List:
+ str += "~=";
+ break;
+ case CSSSelector::Hyphen:
+ str += "|=";
+ break;
+ case CSSSelector::Begin:
+ str += "^=";
+ break;
+ case CSSSelector::End:
+ str += "$=";
+ break;
+ case CSSSelector::Contain:
+ str += "*=";
+ break;
+ default:
+ break;
+ }
+ if (cs->m_match != CSSSelector::Set) {
+ str += "\"";
+ str += cs->m_value;
+ str += "\"]";
+ }
+ }
+ if (cs->relation() != CSSSelector::SubSelector || !cs->m_tagHistory)
+ break;
+ cs = cs->m_tagHistory;
+ }
+
+ if (cs->m_tagHistory) {
+ String tagHistoryText = cs->m_tagHistory->selectorText();
+ if (cs->relation() == CSSSelector::DirectAdjacent)
+ str = tagHistoryText + " + " + str;
+ else if (cs->relation() == CSSSelector::IndirectAdjacent)
+ str = tagHistoryText + " ~ " + str;
+ else if (cs->relation() == CSSSelector::Child)
+ str = tagHistoryText + " > " + str;
+ else
+ // Descendant
+ str = tagHistoryText + " " + str;
+ }
+
+ return str;
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSSelector.h b/WebCore/css/CSSSelector.h
new file mode 100644
index 0000000..32d7978
--- /dev/null
+++ b/WebCore/css/CSSSelector.h
@@ -0,0 +1,200 @@
+/*
+ * This file is part of the CSS implementation for KDE.
+ *
+ * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * 1999 Waldo Bastian (bastian@kde.org)
+ * Copyright (C) 2004, 2006, 2007, 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 CSSSelector_h
+#define CSSSelector_h
+
+#include "QualifiedName.h"
+
+namespace WebCore {
+
+ // this class represents a selector for a StyleRule
+ class CSSSelector {
+ public:
+ CSSSelector()
+ : m_tagHistory(0)
+ , m_simpleSelector(0)
+ , m_nextSelector(0)
+ , m_argument(nullAtom)
+ , m_attr(anyQName())
+ , m_tag(anyQName())
+ , m_relation(Descendant)
+ , m_match(None)
+ , m_pseudoType(PseudoNotParsed)
+ {
+ }
+
+ CSSSelector(const QualifiedName& qName)
+ : m_tagHistory(0)
+ , m_simpleSelector(0)
+ , m_nextSelector(0)
+ , m_argument(nullAtom)
+ , m_attr(anyQName())
+ , m_tag(qName)
+ , m_relation(Descendant)
+ , m_match(None)
+ , m_pseudoType(PseudoNotParsed)
+ {
+ }
+
+ ~CSSSelector()
+ {
+ delete m_tagHistory;
+ delete m_simpleSelector;
+ delete m_nextSelector;
+ }
+
+ void append(CSSSelector* n)
+ {
+ CSSSelector* end = this;
+ while (end->m_nextSelector)
+ end = end->m_nextSelector;
+ end->m_nextSelector = n;
+ }
+
+ CSSSelector* next() { return m_nextSelector; }
+
+ /**
+ * Print debug output for this selector
+ */
+ void print();
+
+ /**
+ * Re-create selector text from selector's data
+ */
+ String selectorText() const;
+
+ // checks if the 2 selectors (including sub selectors) agree.
+ bool operator==(const CSSSelector&);
+
+ // tag == -1 means apply to all elements (Selector = *)
+
+ unsigned specificity();
+
+ /* how the attribute value has to match.... Default is Exact */
+ enum Match {
+ None = 0,
+ Id,
+ Class,
+ Exact,
+ Set,
+ List,
+ Hyphen,
+ PseudoClass,
+ PseudoElement,
+ Contain, // css3: E[foo*="bar"]
+ Begin, // css3: E[foo^="bar"]
+ End // css3: E[foo$="bar"]
+ };
+
+ enum Relation {
+ Descendant = 0,
+ Child,
+ DirectAdjacent,
+ IndirectAdjacent,
+ SubSelector
+ };
+
+ enum PseudoType {
+ PseudoNotParsed = 0,
+ PseudoUnknown,
+ PseudoEmpty,
+ PseudoFirstChild,
+ PseudoFirstOfType,
+ PseudoLastChild,
+ PseudoLastOfType,
+ PseudoOnlyChild,
+ PseudoOnlyOfType,
+ PseudoFirstLine,
+ PseudoFirstLetter,
+ PseudoNthChild,
+ PseudoNthOfType,
+ PseudoNthLastChild,
+ PseudoNthLastOfType,
+ PseudoLink,
+ PseudoVisited,
+ PseudoAnyLink,
+ PseudoAutofill,
+ PseudoHover,
+ PseudoDrag,
+ PseudoFocus,
+ PseudoActive,
+ PseudoChecked,
+ PseudoEnabled,
+ PseudoDisabled,
+ PseudoIndeterminate,
+ PseudoTarget,
+ PseudoBefore,
+ PseudoAfter,
+ PseudoLang,
+ PseudoNot,
+ PseudoRoot,
+ PseudoSelection,
+ PseudoFileUploadButton,
+ PseudoSliderThumb,
+ PseudoSearchCancelButton,
+ PseudoSearchDecoration,
+ PseudoSearchResultsDecoration,
+ PseudoSearchResultsButton,
+ PseudoMediaControlsPanel,
+ PseudoMediaControlsMuteButton,
+ PseudoMediaControlsPlayButton,
+ PseudoMediaControlsTimeDisplay,
+ PseudoMediaControlsTimeline,
+ PseudoMediaControlsSeekBackButton,
+ PseudoMediaControlsSeekForwardButton,
+ PseudoMediaControlsFullscreenButton
+ };
+
+ PseudoType pseudoType() const
+ {
+ if (m_pseudoType == PseudoNotParsed)
+ extractPseudoType();
+ return static_cast<PseudoType>(m_pseudoType);
+ }
+
+ bool hasTag() const { return m_tag != anyQName(); }
+ bool hasAttribute() const { return m_attr != anyQName(); }
+
+ Relation relation() const { return static_cast<Relation>(m_relation); }
+
+ mutable AtomicString m_value;
+ CSSSelector* m_tagHistory;
+ CSSSelector* m_simpleSelector; // Used for :not.
+ CSSSelector* m_nextSelector; // used for ,-chained selectors
+ AtomicString m_argument; // Used for :contains, :lang and :nth-*
+
+ QualifiedName m_attr;
+ QualifiedName m_tag;
+
+ unsigned m_relation : 3; // enum Relation
+ mutable unsigned m_match : 4; // enum Match
+ mutable unsigned m_pseudoType : 8; // PseudoType
+
+ private:
+ void extractPseudoType() const;
+ };
+
+} // namespace WebCore
+
+#endif // CSSSelector_h
diff --git a/WebCore/css/CSSStyleDeclaration.cpp b/WebCore/css/CSSStyleDeclaration.cpp
new file mode 100644
index 0000000..4e1fb68
--- /dev/null
+++ b/WebCore/css/CSSStyleDeclaration.cpp
@@ -0,0 +1,156 @@
+/*
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 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 "CSSStyleDeclaration.h"
+
+#include "CSSMutableStyleDeclaration.h"
+#include "CSSParser.h"
+#include "CSSProperty.h"
+#include "CSSPropertyNames.h"
+#include "CSSRule.h"
+#include "DeprecatedValueList.h"
+#include <wtf/ASCIICType.h>
+
+using namespace WTF;
+
+namespace WebCore {
+
+CSSStyleDeclaration::CSSStyleDeclaration(CSSRule* parent)
+ : StyleBase(parent)
+{
+}
+
+bool CSSStyleDeclaration::isStyleDeclaration()
+{
+ return true;
+}
+
+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)
+{
+ 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)
+{
+ int propID = cssPropertyID(propertyName);
+ if (!propID)
+ return false;
+ return isPropertyImplicit(propID);
+}
+
+void CSSStyleDeclaration::setProperty(const String& propertyName, const String& value, ExceptionCode& ec)
+{
+ int important = value.find("!important", 0, false);
+ if (important == -1)
+ setProperty(propertyName, value, "", ec);
+ else
+ setProperty(propertyName, value.left(important - 1), "important", ec);
+}
+
+void CSSStyleDeclaration::setProperty(const String& propertyName, const String& value, const String& priority, ExceptionCode& ec)
+{
+ int propID = cssPropertyID(propertyName);
+ if (!propID) {
+ // FIXME: Should we raise an exception here?
+ return;
+ }
+ bool important = priority.find("important", 0, false) != -1;
+ setProperty(propID, value, important, ec);
+}
+
+String CSSStyleDeclaration::removeProperty(const String& propertyName, ExceptionCode& ec)
+{
+ int propID = cssPropertyID(propertyName);
+ if (!propID)
+ return String();
+ return removeProperty(propID, ec);
+}
+
+bool CSSStyleDeclaration::isPropertyName(const String& propertyName)
+{
+ return cssPropertyID(propertyName);
+}
+
+CSSRule* CSSStyleDeclaration::parentRule() const
+{
+ return (parent() && parent()->isRule()) ? static_cast<CSSRule*>(parent()) : 0;
+}
+
+void CSSStyleDeclaration::diff(CSSMutableStyleDeclaration* style) const
+{
+ if (!style)
+ return;
+
+ Vector<int> properties;
+ DeprecatedValueListConstIterator<CSSProperty> end;
+ for (DeprecatedValueListConstIterator<CSSProperty> it(style->valuesIterator()); it != end; ++it) {
+ const CSSProperty& property = *it;
+ RefPtr<CSSValue> value = getPropertyCSSValue(property.id());
+ if (value && (value->cssText() == property.value()->cssText()))
+ properties.append(property.id());
+ }
+
+ for (unsigned i = 0; i < properties.size(); i++)
+ style->removeProperty(properties[i]);
+}
+
+PassRefPtr<CSSMutableStyleDeclaration> CSSStyleDeclaration::copyPropertiesInSet(const int* set, unsigned length) const
+{
+ DeprecatedValueList<CSSProperty> list;
+ for (unsigned i = 0; i < length; i++) {
+ RefPtr<CSSValue> value = getPropertyCSSValue(set[i]);
+ if (value)
+ list.append(CSSProperty(set[i], value.release(), false));
+ }
+ return new CSSMutableStyleDeclaration(0, list);
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSStyleDeclaration.h b/WebCore/css/CSSStyleDeclaration.h
new file mode 100644
index 0000000..2153c67
--- /dev/null
+++ b/WebCore/css/CSSStyleDeclaration.h
@@ -0,0 +1,80 @@
+/*
+ * (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 CSSStyleDeclaration_h
+#define CSSStyleDeclaration_h
+
+#include "StyleBase.h"
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class CSSMutableStyleDeclaration;
+class CSSRule;
+class CSSValue;
+
+typedef int ExceptionCode;
+
+class CSSStyleDeclaration : public StyleBase {
+public:
+ virtual bool isStyleDeclaration();
+
+ static bool isPropertyName(const String&);
+
+ CSSRule* parentRule() const;
+
+ virtual String cssText() const = 0;
+ virtual void setCssText(const String&, ExceptionCode&) = 0;
+
+ 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, ExceptionCode&);
+ 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<CSSMutableStyleDeclaration> copy() const = 0;
+ virtual PassRefPtr<CSSMutableStyleDeclaration> makeMutable() = 0;
+
+ void diff(CSSMutableStyleDeclaration*) const;
+
+ PassRefPtr<CSSMutableStyleDeclaration> copyPropertiesInSet(const int* set, unsigned length) const;
+
+protected:
+ CSSStyleDeclaration(CSSRule* parentRule = 0);
+};
+
+} // namespace WebCore
+
+#endif // CSSStyleDeclaration_h
diff --git a/WebCore/css/CSSStyleDeclaration.idl b/WebCore/css/CSSStyleDeclaration.idl
new file mode 100644
index 0000000..60020d9
--- /dev/null
+++ b/WebCore/css/CSSStyleDeclaration.idl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [
+ GenerateConstructor,
+ CustomPutFunction,
+ HasNameGetter,
+ HasIndexGetter,
+ InterfaceUUID=9989b2c3-a2b6-449b-abf9-c60d2260b1d7,
+ ImplementationUUID=985c50c7-9f19-436a-9e45-c0aa02996d0e
+ ] CSSStyleDeclaration {
+ attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString cssText
+ setter raises(DOMException);
+
+ [ConvertNullStringTo=Null] DOMString getPropertyValue(in DOMString propertyName);
+ CSSValue getPropertyCSSValue(in DOMString propertyName);
+ [ConvertNullStringTo=Null] DOMString removeProperty(in DOMString propertyName)
+ raises(DOMException);
+ [ConvertNullStringTo=Null] DOMString getPropertyPriority(in DOMString propertyName);
+ [OldStyleObjC] void setProperty(in DOMString propertyName,
+ in [ConvertNullToNullString] DOMString value,
+ in DOMString priority)
+ raises(DOMException);
+
+ readonly attribute unsigned long length;
+ [ConvertNullStringTo=Null] DOMString item(in unsigned long index);
+ readonly attribute CSSRule parentRule;
+
+ // Extensions
+ [ConvertNullStringTo=Null] DOMString getPropertyShorthand(in DOMString propertyName);
+ boolean isPropertyImplicit(in DOMString propertyName);
+ };
+
+}
diff --git a/WebCore/css/CSSStyleRule.cpp b/WebCore/css/CSSStyleRule.cpp
new file mode 100644
index 0000000..913c18f
--- /dev/null
+++ b/WebCore/css/CSSStyleRule.cpp
@@ -0,0 +1,86 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 "CSSStyleRule.h"
+
+#include "CSSMutableStyleDeclaration.h"
+#include "CSSSelector.h"
+
+namespace WebCore {
+
+CSSStyleRule::CSSStyleRule(StyleBase* parent)
+ : CSSRule(parent)
+ , m_selector(0)
+{
+}
+
+CSSStyleRule::~CSSStyleRule()
+{
+ if (m_style)
+ m_style->setParent(0);
+ delete m_selector;
+}
+
+String CSSStyleRule::selectorText() const
+{
+ if (m_selector) {
+ String str;
+ for (CSSSelector* s = m_selector; s; s = s->next()) {
+ if (s != m_selector)
+ str += ", ";
+ str += s->selectorText();
+ }
+ return str;
+ }
+ return String();
+}
+
+void CSSStyleRule::setSelectorText(const String& /*selectorText*/, ExceptionCode& /*ec*/)
+{
+ // FIXME: Implement!
+}
+
+String CSSStyleRule::cssText() const
+{
+ String result = selectorText();
+
+ result += " { ";
+ result += m_style->cssText();
+ result += "}";
+
+ return result;
+}
+
+bool CSSStyleRule::parseString(const String& /*string*/, bool /*strict*/)
+{
+ // FIXME
+ return false;
+}
+
+void CSSStyleRule::setDeclaration(PassRefPtr<CSSMutableStyleDeclaration> style)
+{
+ m_style = style;
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSStyleRule.h b/WebCore/css/CSSStyleRule.h
new file mode 100644
index 0000000..f5dd928
--- /dev/null
+++ b/WebCore/css/CSSStyleRule.h
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2006 Apple Computer, Inc.
+ *
+ * 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 CSSStyleRule_h
+#define CSSStyleRule_h
+
+#include "CSSRule.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSMutableStyleDeclaration;
+class CSSSelector;
+
+typedef int ExceptionCode;
+
+class CSSStyleRule : public CSSRule {
+public:
+ CSSStyleRule(StyleBase* parent);
+ virtual ~CSSStyleRule();
+
+ virtual bool isStyleRule() { return true; }
+
+ String selectorText() const;
+ void setSelectorText(const String&, ExceptionCode&);
+
+ CSSMutableStyleDeclaration* style() const { return m_style.get(); }
+
+ // Inherited from CSSRule
+ virtual unsigned short type() const { return STYLE_RULE; }
+
+ virtual String cssText() const;
+
+ // Not part of the CSSOM
+ virtual bool parseString(const String&, bool = false);
+
+ void setSelector(CSSSelector* selector) { m_selector = selector; }
+ void setDeclaration(PassRefPtr<CSSMutableStyleDeclaration>);
+
+ CSSSelector* selector() { return m_selector; }
+ CSSMutableStyleDeclaration* declaration() { return m_style.get(); }
+
+protected:
+ RefPtr<CSSMutableStyleDeclaration> m_style;
+ CSSSelector* m_selector;
+};
+
+} // namespace WebCore
+
+#endif // CSSStyleRule_h
diff --git a/WebCore/css/CSSStyleRule.idl b/WebCore/css/CSSStyleRule.idl
new file mode 100644
index 0000000..0240dd0
--- /dev/null
+++ b/WebCore/css/CSSStyleRule.idl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [
+ GenerateConstructor,
+ InterfaceUUID=ce4e3330-c40b-4430-8ed4-030ab4ddbc93,
+ ImplementationUUID=c3d2f1b8-3970-4b36-882e-ce7f5668d8e2
+ ] CSSStyleRule : CSSRule {
+
+ attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString selectorText
+ setter raises(DOMException);
+
+ readonly attribute CSSStyleDeclaration style;
+
+ };
+
+}
diff --git a/WebCore/css/CSSStyleSelector.cpp b/WebCore/css/CSSStyleSelector.cpp
new file mode 100644
index 0000000..3deb314
--- /dev/null
+++ b/WebCore/css/CSSStyleSelector.cpp
@@ -0,0 +1,5177 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
+ * (C) 2006 Nicholas Shanks (webkit@nickshanks.com)
+ * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
+ * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
+ *
+ * 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 "CSSStyleSelector.h"
+
+#include "CSSBorderImageValue.h"
+#include "CSSCursorImageValue.h"
+#include "CSSFontFace.h"
+#include "CSSFontFaceRule.h"
+#include "CSSFontFaceSource.h"
+#include "CSSImageValue.h"
+#include "CSSImportRule.h"
+#include "CSSMediaRule.h"
+#include "CSSPrimitiveValueMappings.h"
+#include "CSSProperty.h"
+#include "CSSPropertyNames.h"
+#include "CSSRuleList.h"
+#include "CSSSelector.h"
+#include "CSSStyleRule.h"
+#include "CSSStyleSheet.h"
+#include "CSSTimingFunctionValue.h"
+#include "CSSValueList.h"
+#include "CachedImage.h"
+#include "Counter.h"
+#include "DashboardRegion.h"
+#include "FontFamilyValue.h"
+#include "FontValue.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "GlobalHistory.h"
+#include "HTMLDocument.h"
+#include "HTMLElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "MediaList.h"
+#include "MediaQueryEvaluator.h"
+#include "Pair.h"
+#include "Rect.h"
+#include "RenderTheme.h"
+#include "SelectionController.h"
+#include "Settings.h"
+#include "ShadowValue.h"
+#include "StyleSheetList.h"
+#include "Text.h"
+#include "UserAgentStyleSheets.h"
+#include "XMLNames.h"
+#include "loader.h"
+#include <wtf/Vector.h>
+
+#if ENABLE(SVG)
+#include "XLinkNames.h"
+#include "SVGNames.h"
+#endif
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+// #define STYLE_SHARING_STATS 1
+
+#define HANDLE_INHERIT(prop, Prop) \
+if (isInherit) { \
+ m_style->set##Prop(m_parentStyle->prop()); \
+ return; \
+}
+
+#define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
+HANDLE_INHERIT(prop, Prop) \
+if (isInitial) { \
+ m_style->set##Prop(RenderStyle::initial##Prop()); \
+ return; \
+}
+
+#define HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(prop, Prop, Value) \
+HANDLE_INHERIT(prop, Prop) \
+if (isInitial) { \
+ m_style->set##Prop(RenderStyle::initial##Value());\
+ return;\
+}
+
+#define HANDLE_MULTILAYER_INHERIT_AND_INITIAL(layerType, LayerType, prop, Prop) \
+if (isInherit) { \
+ LayerType* currChild = m_style->access##LayerType##s(); \
+ LayerType* prevChild = 0; \
+ const LayerType* currParent = m_parentStyle->layerType##s(); \
+ while (currParent && currParent->is##Prop##Set()) { \
+ if (!currChild) { \
+ /* Need to make a new layer.*/ \
+ currChild = new LayerType(); \
+ prevChild->setNext(currChild); \
+ } \
+ currChild->set##Prop(currParent->prop()); \
+ prevChild = currChild; \
+ currChild = prevChild->next(); \
+ currParent = currParent->next(); \
+ } \
+ \
+ while (currChild) { \
+ /* Reset any remaining layers to not have the property set. */ \
+ currChild->clear##Prop(); \
+ currChild = currChild->next(); \
+ } \
+ return; \
+} \
+if (isInitial) { \
+ LayerType* currChild = m_style->access##LayerType##s(); \
+ currChild->set##Prop(RenderStyle::initial##Prop()); \
+ for (currChild = currChild->next(); currChild; currChild = currChild->next()) \
+ currChild->clear##Prop(); \
+ return; \
+}
+
+#define HANDLE_MULTILAYER_VALUE(layerType, LayerType, prop, Prop, value) { \
+HANDLE_MULTILAYER_INHERIT_AND_INITIAL(layerType, LayerType, prop, Prop) \
+LayerType* currChild = m_style->access##LayerType##s(); \
+LayerType* prevChild = 0; \
+if (value->isValueList()) { \
+ /* Walk each value and put it into a layer, creating new layers as needed. */ \
+ CSSValueList* valueList = static_cast<CSSValueList*>(value); \
+ for (unsigned int i = 0; i < valueList->length(); i++) { \
+ if (!currChild) { \
+ /* Need to make a new layer to hold this value */ \
+ currChild = new LayerType(); \
+ prevChild->setNext(currChild); \
+ } \
+ map##Prop(currChild, valueList->item(i)); \
+ prevChild = currChild; \
+ currChild = currChild->next(); \
+ } \
+} else { \
+ map##Prop(currChild, value); \
+ currChild = currChild->next(); \
+} \
+while (currChild) { \
+ /* Reset all remaining layers to not have the property set. */ \
+ currChild->clear##Prop(); \
+ currChild = currChild->next(); \
+} }
+
+#define HANDLE_BACKGROUND_INHERIT_AND_INITIAL(prop, Prop) \
+HANDLE_MULTILAYER_INHERIT_AND_INITIAL(backgroundLayer, BackgroundLayer, prop, Prop)
+
+#define HANDLE_BACKGROUND_VALUE(prop, Prop, value) \
+HANDLE_MULTILAYER_VALUE(backgroundLayer, BackgroundLayer, prop, Prop, value)
+
+#define HANDLE_TRANSITION_INHERIT_AND_INITIAL(prop, Prop) \
+HANDLE_MULTILAYER_INHERIT_AND_INITIAL(transition, Transition, prop, Prop)
+
+#define HANDLE_TRANSITION_VALUE(prop, Prop, value) \
+HANDLE_MULTILAYER_VALUE(transition, Transition, prop, Prop, value)
+
+#define HANDLE_INHERIT_COND(propID, prop, Prop) \
+if (id == propID) { \
+ m_style->set##Prop(m_parentStyle->prop()); \
+ return; \
+}
+
+#define HANDLE_INITIAL_COND(propID, Prop) \
+if (id == propID) { \
+ m_style->set##Prop(RenderStyle::initial##Prop()); \
+ return; \
+}
+
+#define HANDLE_INITIAL_COND_WITH_VALUE(propID, Prop, Value) \
+if (id == propID) { \
+ m_style->set##Prop(RenderStyle::initial##Value()); \
+ return; \
+}
+
+class CSSRuleSet
+{
+public:
+ CSSRuleSet();
+ ~CSSRuleSet();
+
+ typedef HashMap<AtomicStringImpl*, CSSRuleDataList*> AtomRuleMap;
+
+ void addRulesFromSheet(CSSStyleSheet*, const MediaQueryEvaluator&, CSSStyleSelector* = 0);
+
+ void addRule(CSSStyleRule* rule, CSSSelector* sel);
+ void addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map,
+ CSSStyleRule* rule, CSSSelector* sel);
+
+ CSSRuleDataList* getIDRules(AtomicStringImpl* key) { return m_idRules.get(key); }
+ CSSRuleDataList* getClassRules(AtomicStringImpl* key) { return m_classRules.get(key); }
+ CSSRuleDataList* getTagRules(AtomicStringImpl* key) { return m_tagRules.get(key); }
+ CSSRuleDataList* getUniversalRules() { return m_universalRules; }
+
+public:
+ AtomRuleMap m_idRules;
+ AtomRuleMap m_classRules;
+ AtomRuleMap m_tagRules;
+ CSSRuleDataList* m_universalRules;
+ unsigned m_ruleCount;
+};
+
+CSSRuleSet* CSSStyleSelector::m_defaultStyle = 0;
+CSSRuleSet* CSSStyleSelector::m_defaultQuirksStyle = 0;
+CSSRuleSet* CSSStyleSelector::m_defaultPrintStyle = 0;
+CSSRuleSet* CSSStyleSelector::m_defaultViewSourceStyle = 0;
+
+CSSStyleSheet* CSSStyleSelector::m_defaultSheet = 0;
+RenderStyle* CSSStyleSelector::m_styleNotYetAvailable = 0;
+CSSStyleSheet* CSSStyleSelector::m_quirksSheet = 0;
+CSSStyleSheet* CSSStyleSelector::m_viewSourceSheet = 0;
+
+#if ENABLE(SVG)
+CSSStyleSheet *CSSStyleSelector::m_svgSheet = 0;
+#endif
+
+static CSSStyleSelector::EncodedURL* currentEncodedURL = 0;
+static PseudoState pseudoState;
+
+static const MediaQueryEvaluator& screenEval()
+{
+ static const MediaQueryEvaluator staticScreenEval("screen");
+ return staticScreenEval;
+}
+
+static const MediaQueryEvaluator& printEval()
+{
+ static const MediaQueryEvaluator staticPrintEval("print");
+ return staticPrintEval;
+}
+
+CSSStyleSelector::CSSStyleSelector(Document* doc, const String& userStyleSheet, StyleSheetList *styleSheets, CSSStyleSheet* mappedElementSheet, bool _strictParsing, bool matchAuthorAndUserStyles)
+{
+ init();
+
+ m_document = doc;
+ m_fontSelector = new CSSFontSelector(doc);
+
+ m_matchAuthorAndUserStyles = matchAuthorAndUserStyles;
+
+ strictParsing = _strictParsing;
+ if (!m_defaultStyle)
+ loadDefaultStyle();
+
+ m_userStyle = 0;
+
+ // construct document root element default style. this is needed
+ // to evaluate media queries that contain relative constraints, like "screen and (max-width: 10em)"
+ // This is here instead of constructor, because when constructor is run,
+ // document doesn't have documentElement
+ // NOTE: this assumes that element that gets passed to styleForElement -call
+ // is always from the document that owns the style selector
+ FrameView* view = m_document->view();
+ if (view)
+ m_medium = new MediaQueryEvaluator(view->mediaType());
+ else
+ m_medium = new MediaQueryEvaluator("all");
+
+ Element* root = doc->documentElement();
+
+ if (root)
+ m_rootDefaultStyle = styleForElement(root, 0, false, true); // dont ref, because the RenderStyle is allocated from global heap
+
+ if (m_rootDefaultStyle && view) {
+ delete m_medium;
+ m_medium = new MediaQueryEvaluator(view->mediaType(), view->frame(), m_rootDefaultStyle);
+ }
+
+ // FIXME: This sucks! The user sheet is reparsed every time!
+ if (!userStyleSheet.isEmpty()) {
+ m_userSheet = new CSSStyleSheet(doc);
+ m_userSheet->parseString(userStyleSheet, strictParsing);
+
+ m_userStyle = new CSSRuleSet();
+ m_userStyle->addRulesFromSheet(m_userSheet.get(), *m_medium, this);
+ }
+
+ // add stylesheets from document
+ m_authorStyle = new CSSRuleSet();
+
+ // Add rules from elments like SVG's <font-face>
+ if (mappedElementSheet)
+ m_authorStyle->addRulesFromSheet(mappedElementSheet, *m_medium, this);
+
+ DeprecatedPtrListIterator<StyleSheet> it(styleSheets->styleSheets);
+ for (; it.current(); ++it)
+ if (it.current()->isCSSStyleSheet() && !it.current()->disabled())
+ m_authorStyle->addRulesFromSheet(static_cast<CSSStyleSheet*>(it.current()), *m_medium, this);
+}
+
+void CSSStyleSelector::init()
+{
+ m_element = 0;
+ m_matchedDecls.clear();
+ m_ruleList = 0;
+ m_collectRulesOnly = false;
+ m_rootDefaultStyle = 0;
+ m_medium = 0;
+}
+
+void CSSStyleSelector::setEncodedURL(const KURL& url)
+{
+ KURL u = url;
+
+ u.setQuery(String());
+ u.setRef(String());
+ m_encodedURL.file = u.string();
+ int pos = m_encodedURL.file.reverseFind('/');
+ m_encodedURL.path = m_encodedURL.file;
+ if (pos > 0) {
+ m_encodedURL.path.truncate(pos);
+ m_encodedURL.path.append('/');
+ }
+ u.setPath(String());
+ m_encodedURL.prefix = u.string();
+}
+
+CSSStyleSelector::~CSSStyleSelector()
+{
+ delete m_medium;
+ ::delete m_rootDefaultStyle;
+
+ delete m_authorStyle;
+ delete m_userStyle;
+}
+
+static CSSStyleSheet* parseUASheet(const char* characters, unsigned size)
+{
+ CSSStyleSheet* const parent = 0;
+ CSSStyleSheet* sheet = new CSSStyleSheet(parent);
+ sheet->ref(); // leak the sheet on purpose since it will be stored in a global variable
+ sheet->parseString(String(characters, size));
+ return sheet;
+}
+
+template<typename T> CSSStyleSheet* parseUASheet(const T& array)
+{
+ return parseUASheet(array, sizeof(array));
+}
+
+void CSSStyleSelector::loadDefaultStyle()
+{
+ if (m_defaultStyle)
+ return;
+
+ m_defaultStyle = new CSSRuleSet;
+ m_defaultPrintStyle = new CSSRuleSet;
+ m_defaultQuirksStyle = new CSSRuleSet;
+ m_defaultViewSourceStyle = new CSSRuleSet;
+
+ // Strict-mode rules.
+ m_defaultSheet = parseUASheet(html4UserAgentStyleSheet);
+ m_defaultStyle->addRulesFromSheet(m_defaultSheet, screenEval());
+ m_defaultPrintStyle->addRulesFromSheet(m_defaultSheet, printEval());
+
+ // Quirks-mode rules.
+ m_quirksSheet = parseUASheet(quirksUserAgentStyleSheet);
+ m_defaultQuirksStyle->addRulesFromSheet(m_quirksSheet, screenEval());
+
+ // View source rules.
+ m_viewSourceSheet = parseUASheet(sourceUserAgentStyleSheet);
+ m_defaultViewSourceStyle->addRulesFromSheet(m_viewSourceSheet, screenEval());
+}
+
+void CSSStyleSelector::matchRules(CSSRuleSet* rules, int& firstRuleIndex, int& lastRuleIndex)
+{
+ m_matchedRules.clear();
+
+ if (!rules || !m_element)
+ return;
+
+ // 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->getIDRules(m_element->getIDAttribute().impl()), firstRuleIndex, lastRuleIndex);
+ if (m_element->hasClass()) {
+ const ClassNames& classNames = *m_element->getClassNames();
+ size_t classNamesSize = classNames.size();
+ for (size_t i = 0; i < classNamesSize; ++i)
+ matchRulesForList(rules->getClassRules(classNames[i].impl()), firstRuleIndex, lastRuleIndex);
+ }
+ matchRulesForList(rules->getTagRules(m_element->localName().impl()), firstRuleIndex, lastRuleIndex);
+ matchRulesForList(rules->getUniversalRules(), firstRuleIndex, lastRuleIndex);
+
+ // If we didn't match any rules, we're done.
+ if (m_matchedRules.isEmpty())
+ return;
+
+ // Sort the set of matched rules.
+ sortMatchedRules(0, m_matchedRules.size());
+
+ // Now transfer the set of matched rules over to our list of decls.
+ if (!m_collectRulesOnly) {
+ for (unsigned i = 0; i < m_matchedRules.size(); i++)
+ addMatchedDeclaration(m_matchedRules[i]->rule()->declaration());
+ } else {
+ for (unsigned i = 0; i < m_matchedRules.size(); i++) {
+ if (!m_ruleList)
+ m_ruleList = new CSSRuleList();
+ m_ruleList->append(m_matchedRules[i]->rule());
+ }
+ }
+}
+
+void CSSStyleSelector::matchRulesForList(CSSRuleDataList* rules, int& firstRuleIndex, int& lastRuleIndex)
+{
+ if (!rules)
+ return;
+
+ for (CSSRuleData* d = rules->first(); d; d = d->next()) {
+ CSSStyleRule* rule = d->rule();
+ const AtomicString& localName = m_element->localName();
+ const AtomicString& selectorLocalName = d->selector()->m_tag.localName();
+ if ((localName == selectorLocalName || selectorLocalName == starAtom) && checkSelector(d->selector())) {
+ // If the rule has no properties to apply, then ignore it.
+ CSSMutableStyleDeclaration* decl = rule->declaration();
+ if (!decl || !decl->length())
+ continue;
+
+ // If we're matching normal rules, set a pseudo bit if
+ // we really just matched a pseudo-element.
+ if (dynamicPseudo != RenderStyle::NOPSEUDO && m_pseudoStyle == RenderStyle::NOPSEUDO) {
+ if (m_collectRulesOnly)
+ return;
+ if (dynamicPseudo < RenderStyle::FIRST_INTERNAL_PSEUDOID)
+ m_style->setHasPseudoStyle(dynamicPseudo);
+ } else {
+ // Update our first/last rule indices in the matched rules array.
+ lastRuleIndex = m_matchedDecls.size() + m_matchedRules.size();
+ if (firstRuleIndex == -1)
+ firstRuleIndex = lastRuleIndex;
+
+ // Add this rule to our list of matched rules.
+ addMatchedRule(d);
+ }
+ }
+ }
+}
+
+bool operator >(CSSRuleData& r1, CSSRuleData& r2)
+{
+ int spec1 = r1.selector()->specificity();
+ int spec2 = r2.selector()->specificity();
+ return (spec1 == spec2) ? r1.position() > r2.position() : spec1 > spec2;
+}
+bool operator <=(CSSRuleData& r1, CSSRuleData& r2)
+{
+ return !(r1 > r2);
+}
+
+void CSSStyleSelector::sortMatchedRules(unsigned start, unsigned end)
+{
+ if (start >= end || (end - start == 1))
+ return; // Sanity check.
+
+ if (end - start <= 6) {
+ // Apply a bubble sort for smaller lists.
+ for (unsigned i = end - 1; i > start; i--) {
+ bool sorted = true;
+ for (unsigned j = start; j < i; j++) {
+ CSSRuleData* elt = m_matchedRules[j];
+ CSSRuleData* elt2 = m_matchedRules[j + 1];
+ if (*elt > *elt2) {
+ sorted = false;
+ m_matchedRules[j] = elt2;
+ m_matchedRules[j + 1] = elt;
+ }
+ }
+ if (sorted)
+ return;
+ }
+ return;
+ }
+
+ // Peform a merge sort for larger lists.
+ unsigned mid = (start + end) / 2;
+ sortMatchedRules(start, mid);
+ sortMatchedRules(mid, end);
+
+ CSSRuleData* elt = m_matchedRules[mid - 1];
+ CSSRuleData* elt2 = m_matchedRules[mid];
+
+ // Handle the fast common case (of equal specificity). The list may already
+ // be completely sorted.
+ if (*elt <= *elt2)
+ return;
+
+ // We have to merge sort. Ensure our merge buffer is big enough to hold
+ // all the items.
+ Vector<CSSRuleData*> rulesMergeBuffer;
+ rulesMergeBuffer.reserveCapacity(end - start);
+
+ unsigned i1 = start;
+ unsigned i2 = mid;
+
+ elt = m_matchedRules[i1];
+ elt2 = m_matchedRules[i2];
+
+ while (i1 < mid || i2 < end) {
+ if (i1 < mid && (i2 == end || *elt <= *elt2)) {
+ rulesMergeBuffer.append(elt);
+ if (++i1 < mid)
+ elt = m_matchedRules[i1];
+ } else {
+ rulesMergeBuffer.append(elt2);
+ if (++i2 < end)
+ elt2 = m_matchedRules[i2];
+ }
+ }
+
+ for (unsigned i = start; i < end; i++)
+ m_matchedRules[i] = rulesMergeBuffer[i - start];
+}
+
+void CSSStyleSelector::initElementAndPseudoState(Element* e)
+{
+ m_element = e;
+ if (m_element && m_element->isStyledElement())
+ m_styledElement = static_cast<StyledElement*>(m_element);
+ else
+ m_styledElement = 0;
+ currentEncodedURL = &m_encodedURL;
+ pseudoState = PseudoUnknown;
+}
+
+void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* defaultParent)
+{
+ // set some variables we will need
+ m_pseudoStyle = RenderStyle::NOPSEUDO;
+
+ m_parentNode = e->parentNode();
+
+#if ENABLE(SVG)
+ if (!m_parentNode && e->isSVGElement() && e->isShadowNode())
+ m_parentNode = e->shadowParentNode();
+#endif
+
+ if (defaultParent)
+ m_parentStyle = defaultParent;
+ else
+ m_parentStyle = m_parentNode ? m_parentNode->renderStyle() : 0;
+ m_isXMLDoc = !m_element->document()->isHTMLDocument();
+
+ m_style = 0;
+
+ m_matchedDecls.clear();
+
+ m_ruleList = 0;
+
+ m_fontDirty = false;
+}
+
+static inline int findSlashDotDotSlash(const UChar* characters, size_t length)
+{
+ unsigned loopLimit = length < 4 ? 0 : length - 3;
+ for (unsigned i = 0; i < loopLimit; ++i) {
+ if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '.' && characters[i + 3] == '/')
+ return i;
+ }
+ return -1;
+}
+
+static inline int findSlashSlash(const UChar* characters, size_t length, int position)
+{
+ unsigned loopLimit = length < 2 ? 0 : length - 1;
+ for (unsigned i = position; i < loopLimit; ++i) {
+ if (characters[i] == '/' && characters[i + 1] == '/')
+ return i;
+ }
+ return -1;
+}
+
+static inline int findSlashDotSlash(const UChar* characters, size_t length)
+{
+ unsigned loopLimit = length < 3 ? 0 : length - 2;
+ for (unsigned i = 0; i < loopLimit; ++i) {
+ if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '/')
+ return i;
+ }
+ return -1;
+}
+
+static inline bool containsColonSlashSlash(const UChar* characters, unsigned length)
+{
+ unsigned loopLimit = length < 3 ? 0 : length - 2;
+ for (unsigned i = 0; i < loopLimit; ++i)
+ if (characters[i] == ':' && characters[i + 1] == '/' && characters[i + 2] == '/')
+ return true;
+ return false;
+}
+
+static void cleanPath(Vector<UChar, 512>& path)
+{
+ int pos;
+ while ((pos = findSlashDotDotSlash(path.data(), path.size())) != -1) {
+ int prev = reverseFind(path.data(), path.size(), '/', pos - 1);
+ // don't remove the host, i.e. http://foo.org/../foo.html
+ if (prev < 0 || (prev > 3 && path[prev - 2] == ':' && path[prev - 1] == '/'))
+ path.remove(pos, 3);
+ else
+ path.remove(prev, pos - prev + 3);
+ }
+
+ // Don't remove "//" from an anchor identifier. -rjw
+ // Set refPos to -2 to mean "I haven't looked for the anchor yet".
+ // We don't want to waste a function call on the search for the the anchor
+ // in the vast majority of cases where there is no "//" in the path.
+ pos = 0;
+ int refPos = -2;
+ while ((pos = findSlashSlash(path.data(), path.size(), pos)) != -1) {
+ if (refPos == -2)
+ refPos = find(path.data(), path.size(), '#');
+ if (refPos > 0 && pos >= refPos)
+ break;
+
+ if (pos == 0 || path[pos - 1] != ':')
+ path.remove(pos);
+ else
+ pos += 2;
+ }
+
+ // FIXME: We don't want to remove "/./" from an anchor identifier either.
+ while ((pos = findSlashDotSlash(path.data(), path.size())) != -1)
+ path.remove(pos, 2);
+}
+
+static void checkPseudoState(Element *e, bool checkVisited = true)
+{
+ if (!e->isLink()) {
+ pseudoState = PseudoNone;
+ return;
+ }
+
+ const AtomicString* attr;
+ if (e->isHTMLElement())
+ attr = &e->getAttribute(hrefAttr);
+#if ENABLE(SVG)
+ else if (e->isSVGElement())
+ attr = &e->getAttribute(XLinkNames::hrefAttr);
+#endif
+ else {
+ pseudoState = PseudoNone;
+ return;
+ }
+
+ if (attr->isNull()) {
+ pseudoState = PseudoNone;
+ return;
+ }
+
+ if (!checkVisited) {
+ pseudoState = PseudoAnyLink;
+ return;
+ }
+
+ const UChar* characters = attr->characters();
+ unsigned length = attr->length();
+
+ if (containsColonSlashSlash(characters, length)) {
+ // FIXME: Strange to not clean the path just beacause it has "://" in it.
+ pseudoState = historyContains(characters, length) ? PseudoVisited : PseudoLink;
+ return;
+ }
+
+ Vector<UChar, 512> buffer;
+ if (length && characters[0] == '/') {
+ buffer.append(currentEncodedURL->prefix.characters(), currentEncodedURL->prefix.length());
+ } else if (length && characters[0] == '#') {
+ buffer.append(currentEncodedURL->file.characters(), currentEncodedURL->file.length());
+ } else {
+ buffer.append(currentEncodedURL->path.characters(), currentEncodedURL->path.length());
+ }
+ buffer.append(characters, length);
+ cleanPath(buffer);
+ pseudoState = historyContains(buffer.data(), buffer.size()) ? PseudoVisited : PseudoLink;
+}
+
+// a helper function for parsing nth-arguments
+static bool parseNth(const String& nth, int &a, int &b)
+{
+ if (nth.isEmpty())
+ return false;
+ a = 0;
+ b = 0;
+ if (nth == "odd") {
+ a = 2;
+ b = 1;
+ } else if (nth == "even") {
+ a = 2;
+ b = 0;
+ } else {
+ int n = nth.find('n');
+ if (n != -1) {
+ if (nth[0] == '-') {
+ if (n == 1)
+ a = -1; // -n == -1n
+ else
+ a = nth.substring(0, n).toInt();
+ } else if (!n)
+ a = 1; // n == 1n
+ else
+ a = nth.substring(0, n).toInt();
+
+ int p = nth.find('+', n);
+ if (p != -1)
+ b = nth.substring(p + 1, nth.length() - p - 1).toInt();
+ else {
+ p = nth.find('-', n);
+ b = -nth.substring(p + 1, nth.length() - p - 1).toInt();
+ }
+ } else
+ b = nth.toInt();
+ }
+ return true;
+}
+
+// a helper function for checking nth-arguments
+static bool matchNth(int count, int a, int b)
+{
+ if (!a)
+ return count == b;
+ else if (a > 0) {
+ if (count < b)
+ return false;
+ return (count - b) % a == 0;
+ } else {
+ if (count > b)
+ return false;
+ return (b - count) % (-a) == 0;
+ }
+}
+
+
+#ifdef STYLE_SHARING_STATS
+static int fraction = 0;
+static int total = 0;
+#endif
+
+static const unsigned cStyleSearchThreshold = 10;
+
+Node* CSSStyleSelector::locateCousinList(Element* parent, unsigned depth)
+{
+ if (parent && parent->isStyledElement()) {
+ StyledElement* p = static_cast<StyledElement*>(parent);
+ if (!p->inlineStyleDecl() && !p->hasID()) {
+ Node* r = p->previousSibling();
+ unsigned subcount = 0;
+ RenderStyle* st = p->renderStyle();
+ while (r) {
+ if (r->renderStyle() == st)
+ return r->lastChild();
+ if (subcount++ == cStyleSearchThreshold)
+ return 0;
+ r = r->previousSibling();
+ }
+ if (!r && depth < cStyleSearchThreshold)
+ r = locateCousinList(static_cast<Element*>(parent->parentNode()), depth + 1);
+ while (r) {
+ if (r->renderStyle() == st)
+ return r->lastChild();
+ if (subcount++ == cStyleSearchThreshold)
+ return 0;
+ r = r->previousSibling();
+ }
+ }
+ }
+ return 0;
+}
+
+bool CSSStyleSelector::canShareStyleWithElement(Node* n)
+{
+ if (n->isStyledElement()) {
+ StyledElement* s = static_cast<StyledElement*>(n);
+ RenderStyle* style = s->renderStyle();
+ if (style && !style->unique() &&
+ (s->tagQName() == m_element->tagQName()) && !s->hasID() &&
+ (s->hasClass() == m_element->hasClass()) && !s->inlineStyleDecl() &&
+ (s->hasMappedAttributes() == m_styledElement->hasMappedAttributes()) &&
+ (s->isLink() == m_element->isLink()) &&
+ !style->affectedByAttributeSelectors() &&
+ (s->hovered() == m_element->hovered()) &&
+ (s->active() == m_element->active()) &&
+ (s->focused() == m_element->focused()) &&
+ (s != s->document()->getCSSTarget() && m_element != m_element->document()->getCSSTarget()) &&
+ (s->getAttribute(typeAttr) == m_element->getAttribute(typeAttr)) &&
+ (s->getAttribute(XMLNames::langAttr) == m_element->getAttribute(XMLNames::langAttr)) &&
+ (s->getAttribute(langAttr) == m_element->getAttribute(langAttr)) &&
+ (s->getAttribute(readonlyAttr) == m_element->getAttribute(readonlyAttr)) &&
+ (s->getAttribute(cellpaddingAttr) == m_element->getAttribute(cellpaddingAttr))) {
+ bool isControl = s->isControl();
+ if (isControl != m_element->isControl())
+ return false;
+ if (isControl && (s->isEnabled() != m_element->isEnabled()) ||
+ (s->isIndeterminate() != m_element->isIndeterminate()) ||
+ (s->isChecked() != m_element->isChecked()))
+ return false;
+
+ if (style->transitions())
+ return false;
+
+ bool classesMatch = true;
+ if (s->hasClass()) {
+ const AtomicString& class1 = m_element->getAttribute(classAttr);
+ const AtomicString& class2 = s->getAttribute(classAttr);
+ classesMatch = (class1 == class2);
+ }
+
+ if (classesMatch) {
+ bool mappedAttrsMatch = true;
+ if (s->hasMappedAttributes())
+ mappedAttrsMatch = s->mappedAttributes()->mapsEquivalent(m_styledElement->mappedAttributes());
+ if (mappedAttrsMatch) {
+ bool linksMatch = true;
+ if (s->isLink()) {
+ // We need to check to see if the visited state matches.
+ Color linkColor = m_element->document()->linkColor();
+ Color visitedColor = m_element->document()->visitedLinkColor();
+ if (pseudoState == PseudoUnknown)
+ checkPseudoState(m_element, style->pseudoState() != PseudoAnyLink || linkColor != visitedColor);
+ linksMatch = (pseudoState == style->pseudoState());
+ }
+
+ if (linksMatch)
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+RenderStyle* CSSStyleSelector::locateSharedStyle()
+{
+ if (m_styledElement && !m_styledElement->inlineStyleDecl() && !m_styledElement->hasID() && !m_styledElement->document()->usesSiblingRules()) {
+ // Check previous siblings.
+ unsigned count = 0;
+ Node* n;
+ for (n = m_element->previousSibling(); n && !n->isElementNode(); n = n->previousSibling()) { }
+ while (n) {
+ if (canShareStyleWithElement(n))
+ return n->renderStyle();
+ if (count++ == cStyleSearchThreshold)
+ return 0;
+ for (n = n->previousSibling(); n && !n->isElementNode(); n = n->previousSibling()) { }
+ }
+ if (!n)
+ n = locateCousinList(static_cast<Element*>(m_element->parentNode()));
+ while (n) {
+ if (canShareStyleWithElement(n))
+ return n->renderStyle();
+ if (count++ == cStyleSearchThreshold)
+ return 0;
+ for (n = n->previousSibling(); n && !n->isElementNode(); n = n->previousSibling()) { }
+ }
+ }
+ return 0;
+}
+
+void CSSStyleSelector::matchUARules(int& firstUARule, int& lastUARule)
+{
+ // First we match rules from the user agent sheet.
+ CSSRuleSet* userAgentStyleSheet = m_medium->mediaTypeMatchSpecific("print")
+ ? m_defaultPrintStyle : m_defaultStyle;
+ matchRules(userAgentStyleSheet, firstUARule, lastUARule);
+
+ // In quirks mode, we match rules from the quirks user agent sheet.
+ if (!strictParsing)
+ matchRules(m_defaultQuirksStyle, firstUARule, lastUARule);
+
+ // If we're in view source mode, then we match rules from the view source style sheet.
+ if (m_document->frame() && m_document->frame()->inViewSourceMode())
+ matchRules(m_defaultViewSourceStyle, firstUARule, lastUARule);
+}
+
+// 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
+
+RenderStyle* CSSStyleSelector::styleForElement(Element* e, RenderStyle* defaultParent, bool allowSharing, bool resolveForRootDefault)
+{
+ // 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.
+ if (allowSharing && !e->document()->haveStylesheetsLoaded() && !e->renderer()) {
+ if (!m_styleNotYetAvailable) {
+ m_styleNotYetAvailable = ::new RenderStyle;
+ m_styleNotYetAvailable->ref();
+ m_styleNotYetAvailable->setDisplay(NONE);
+ m_styleNotYetAvailable->font().update(m_fontSelector);
+ }
+ m_styleNotYetAvailable->ref();
+ e->document()->setHasNodesWithPlaceholderStyle();
+ return m_styleNotYetAvailable;
+ }
+
+ initElementAndPseudoState(e);
+ if (allowSharing) {
+ m_style = locateSharedStyle();
+#ifdef STYLE_SHARING_STATS
+ fraction += m_style != 0;
+ total++;
+ printf("Sharing %d out of %d\n", fraction, total);
+#endif
+ if (m_style) {
+ m_style->ref();
+ return m_style;
+ }
+ }
+ initForStyleResolve(e, defaultParent);
+
+ if (resolveForRootDefault) {
+ m_style = ::new RenderStyle();
+ // don't ref, because we want to delete this, but we cannot unref it
+ } else {
+ m_style = new (e->document()->renderArena()) RenderStyle();
+ m_style->ref();
+ }
+ if (m_parentStyle)
+ m_style->inheritFrom(m_parentStyle);
+ else
+ m_parentStyle = m_style;
+
+#if ENABLE(SVG)
+ if (e->isSVGElement() && !m_svgSheet) {
+ // SVG rules.
+ m_svgSheet = parseUASheet(svgUserAgentStyleSheet);
+ m_defaultStyle->addRulesFromSheet(m_svgSheet, screenEval());
+ m_defaultPrintStyle->addRulesFromSheet(m_svgSheet, printEval());
+ }
+#endif
+
+ int firstUARule = -1, lastUARule = -1;
+ int firstUserRule = -1, lastUserRule = -1;
+ int firstAuthorRule = -1, lastAuthorRule = -1;
+ matchUARules(firstUARule, lastUARule);
+
+ if (!resolveForRootDefault) {
+ // 4. Now we check user sheet rules.
+ if (m_matchAuthorAndUserStyles)
+ matchRules(m_userStyle, firstUserRule, lastUserRule);
+
+ // 5. 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 NamedMappedAttrMap* map = m_styledElement->mappedAttributes();
+ for (unsigned i = 0; i < map->length(); i++) {
+ MappedAttribute* attr = map->attributeItem(i);
+ if (attr->decl()) {
+ lastAuthorRule = m_matchedDecls.size();
+ if (firstAuthorRule == -1)
+ firstAuthorRule = lastAuthorRule;
+ addMatchedDeclaration(attr->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()) {
+ m_additionalAttributeStyleDecls.clear();
+ m_styledElement->additionalAttributeStyleDecls(m_additionalAttributeStyleDecls);
+ if (!m_additionalAttributeStyleDecls.isEmpty()) {
+ unsigned additionalDeclsSize = m_additionalAttributeStyleDecls.size();
+ if (firstAuthorRule == -1)
+ firstAuthorRule = m_matchedDecls.size();
+ lastAuthorRule = m_matchedDecls.size() + additionalDeclsSize - 1;
+ for (unsigned i = 0; i < additionalDeclsSize; i++)
+ addMatchedDeclaration(m_additionalAttributeStyleDecls[i]);
+ }
+ }
+ }
+
+ // 6. Check the rules in author sheets next.
+ if (m_matchAuthorAndUserStyles)
+ matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
+
+ // 7. Now check our inline style attribute.
+ if (m_matchAuthorAndUserStyles && m_styledElement) {
+ CSSMutableStyleDeclaration* inlineDecl = m_styledElement->inlineStyleDecl();
+ if (inlineDecl) {
+ lastAuthorRule = m_matchedDecls.size();
+ if (firstAuthorRule == -1)
+ firstAuthorRule = lastAuthorRule;
+ addMatchedDeclaration(inlineDecl);
+ }
+ }
+ }
+
+ // Now we have all of the matched rules in the appropriate order. Walk the rules and apply
+ // high-priority properties first, i.e., those properties that other properties depend on.
+ // The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
+ // and (4) normal important.
+ m_lineHeightValue = 0;
+ applyDeclarations(true, false, 0, m_matchedDecls.size() - 1);
+ if (!resolveForRootDefault) {
+ applyDeclarations(true, true, firstAuthorRule, lastAuthorRule);
+ applyDeclarations(true, true, firstUserRule, lastUserRule);
+ }
+ applyDeclarations(true, true, firstUARule, lastUARule);
+
+ // If our font got dirtied, go ahead and update it now.
+ if (m_fontDirty)
+ updateFont();
+
+ // Line-height is set when we are sure we decided on the font-size
+ if (m_lineHeightValue)
+ applyProperty(CSS_PROP_LINE_HEIGHT, m_lineHeightValue);
+
+ // Now do the normal priority UA properties.
+ applyDeclarations(false, false, firstUARule, lastUARule);
+
+ // 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.
+ if (!resolveForRootDefault) {
+ applyDeclarations(false, false, lastUARule + 1, m_matchedDecls.size() - 1);
+ applyDeclarations(false, true, firstAuthorRule, lastAuthorRule);
+ applyDeclarations(false, true, firstUserRule, lastUserRule);
+ }
+ applyDeclarations(false, true, firstUARule, lastUARule);
+
+ // If our font got dirtied by one of the non-essential font props,
+ // go ahead and update it a second time.
+ if (m_fontDirty)
+ updateFont();
+
+ // Clean up our style object's display and text decorations (among other fixups).
+ adjustRenderStyle(m_style, e);
+
+ // If we are a link, cache the determined pseudo-state.
+ if (e->isLink())
+ m_style->setPseudoState(pseudoState);
+
+ // If we have first-letter pseudo style, do not share this style
+ if (m_style->hasPseudoStyle(RenderStyle::FIRST_LETTER))
+ m_style->setUnique();
+
+ // Now return the style.
+ return m_style;
+}
+
+RenderStyle* CSSStyleSelector::pseudoStyleForElement(RenderStyle::PseudoId pseudo, Element* e, RenderStyle* parentStyle)
+{
+ if (!e)
+ return 0;
+
+ initElementAndPseudoState(e);
+ initForStyleResolve(e, parentStyle);
+ m_pseudoStyle = pseudo;
+
+ // Since we don't use pseudo-elements in any of our quirk/print user agent rules, don't waste time walking
+ // those rules.
+
+ // Check UA, user and author rules.
+ int firstUARule = -1, lastUARule = -1, firstUserRule = -1, lastUserRule = -1, firstAuthorRule = -1, lastAuthorRule = -1;
+ matchUARules(firstUARule, lastUARule);
+
+ if (m_matchAuthorAndUserStyles) {
+ matchRules(m_userStyle, firstUserRule, lastUserRule);
+ matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
+ }
+
+ if (m_matchedDecls.isEmpty())
+ return 0;
+
+ m_style = new (e->document()->renderArena()) RenderStyle();
+ m_style->ref();
+ if (parentStyle)
+ m_style->inheritFrom(parentStyle);
+ else
+ parentStyle = m_style;
+ m_style->noninherited_flags._styleType = m_pseudoStyle;
+
+ m_lineHeightValue = 0;
+ // High-priority properties.
+ applyDeclarations(true, false, 0, m_matchedDecls.size() - 1);
+ applyDeclarations(true, true, firstAuthorRule, lastAuthorRule);
+ applyDeclarations(true, true, firstUserRule, lastUserRule);
+ applyDeclarations(true, true, firstUARule, lastUARule);
+
+ // If our font got dirtied, go ahead and update it now.
+ if (m_fontDirty)
+ updateFont();
+
+ // Line-height is set when we are sure we decided on the font-size
+ if (m_lineHeightValue)
+ applyProperty(CSS_PROP_LINE_HEIGHT, m_lineHeightValue);
+
+ // Now do the normal priority properties.
+ applyDeclarations(false, false, firstUARule, lastUARule);
+
+ // Cache our border and background so that we can examine them later.
+ cacheBorderAndBackground();
+
+ applyDeclarations(false, false, lastUARule + 1, m_matchedDecls.size() - 1);
+ applyDeclarations(false, true, firstAuthorRule, lastAuthorRule);
+ applyDeclarations(false, true, firstUserRule, lastUserRule);
+ applyDeclarations(false, true, firstUARule, lastUARule);
+
+ // If our font got dirtied by one of the non-essential font props,
+ // go ahead and update it a second time.
+ if (m_fontDirty)
+ updateFont();
+ // Clean up our style object's display and text decorations (among other fixups).
+ adjustRenderStyle(m_style, 0);
+
+ // Now return the style.
+ return m_style;
+}
+
+static void addIntrinsicMargins(RenderStyle* style)
+{
+ // Intrinsic margin value.
+ const int intrinsicMargin = 2;
+
+ // FIXME: Using width/height alone and not also dealing with min-width/max-width is flawed.
+ // FIXME: Using "quirk" to decide the margin wasn't set is kind of lame.
+ if (style->width().isIntrinsicOrAuto()) {
+ if (style->marginLeft().quirk())
+ style->setMarginLeft(Length(intrinsicMargin, Fixed));
+ if (style->marginRight().quirk())
+ style->setMarginRight(Length(intrinsicMargin, Fixed));
+ }
+
+ if (style->height().isAuto()) {
+ if (style->marginTop().quirk())
+ style->setMarginTop(Length(intrinsicMargin, Fixed));
+ if (style->marginBottom().quirk())
+ style->setMarginBottom(Length(intrinsicMargin, Fixed));
+ }
+}
+
+void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, Element *e)
+{
+ // Cache our original display.
+ style->setOriginalDisplay(style->display());
+
+ if (style->display() != NONE) {
+ // If we have a <td> that specifies a float property, in quirks mode we just drop the float
+ // property.
+ // Sites also commonly use display:inline/block on <td>s and <table>s. In quirks mode we force
+ // these tags to retain their display types.
+ if (!strictParsing && e) {
+ if (e->hasTagName(tdTag)) {
+ style->setDisplay(TABLE_CELL);
+ style->setFloating(FNONE);
+ }
+ else if (e->hasTagName(tableTag))
+ style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE);
+ }
+
+ // Tables never support the -webkit-* values for text-align and will reset back to the default.
+ if (e && e->hasTagName(tableTag) && (style->textAlign() == WEBKIT_LEFT || style->textAlign() == WEBKIT_CENTER || style->textAlign() == WEBKIT_RIGHT))
+ style->setTextAlign(TAAUTO);
+
+ // Frames and framesets never honor position:relative or position:absolute. This is necessary to
+ // fix a crash where a site tries to position these objects. They also never honor display.
+ if (e && (e->hasTagName(frameTag) || e->hasTagName(framesetTag))) {
+ style->setPosition(StaticPosition);
+ style->setDisplay(BLOCK);
+ }
+
+ // Table headers with a text-align of auto will change the text-align to center.
+ if (e && e->hasTagName(thTag) && style->textAlign() == TAAUTO)
+ style->setTextAlign(CENTER);
+
+ // Mutate the display to BLOCK or TABLE for certain cases, e.g., if someone attempts to
+ // position or float an inline, compact, or run-in. Cache the original display, since it
+ // may be needed for positioned elements that have to compute their static normal flow
+ // positions. We also force inline-level roots to be block-level.
+ if (style->display() != BLOCK && style->display() != TABLE && style->display() != BOX &&
+ (style->position() == AbsolutePosition || style->position() == FixedPosition || style->floating() != FNONE ||
+ (e && e->document()->documentElement() == e))) {
+ if (style->display() == INLINE_TABLE)
+ style->setDisplay(TABLE);
+ else if (style->display() == INLINE_BOX)
+ style->setDisplay(BOX);
+ else if (style->display() == LIST_ITEM) {
+ // It is a WinIE bug that floated list items lose their bullets, so we'll emulate the quirk,
+ // but only in quirks mode.
+ if (!strictParsing && style->floating() != FNONE)
+ style->setDisplay(BLOCK);
+ }
+ else
+ style->setDisplay(BLOCK);
+ }
+
+ // After performing the display mutation, check table rows. We do not honor position:relative on
+ // table rows or cells. This has been established in CSS2.1 (and caused a crash in containingBlock()
+ // on some sites).
+ if ((style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW_GROUP ||
+ style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW || style->display() == TABLE_CELL) &&
+ style->position() == RelativePosition)
+ style->setPosition(StaticPosition);
+ }
+
+ // Make sure our z-index value is only applied if the object is positioned,
+ // relatively positioned, transparent, or has a transform.
+ if (style->position() == StaticPosition && style->opacity() == 1.0f && !style->hasTransform())
+ style->setHasAutoZIndex();
+
+ // Auto z-index becomes 0 for the root element and transparent objects. This prevents
+ // cases where objects that should be blended as a single unit end up with a non-transparent
+ // object wedged in between them. Auto z-index also becomes 0 for objects that specify transforms.
+ if (style->hasAutoZIndex() && ((e && e->document()->documentElement() == e) || style->opacity() < 1.0f || style->hasTransform()))
+ style->setZIndex(0);
+
+ // Button, legend, input, select and textarea all consider width values of 'auto' to be 'intrinsic'.
+ // This will be important when we use block flows for all form controls.
+ if (e && (e->hasTagName(legendTag) || e->hasTagName(buttonTag) || e->hasTagName(inputTag) ||
+ e->hasTagName(selectTag) || e->hasTagName(textareaTag))) {
+ if (style->width().isAuto())
+ style->setWidth(Length(Intrinsic));
+ }
+
+ // Finally update our text decorations in effect, but don't allow text-decoration to percolate through
+ // tables, inline blocks, inline tables, or run-ins.
+ if (style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN
+ || style->display() == INLINE_BLOCK || style->display() == INLINE_BOX)
+ style->setTextDecorationsInEffect(style->textDecoration());
+ else
+ style->addToTextDecorationsInEffect(style->textDecoration());
+
+ // If either overflow value is not visible, change to auto.
+ if (style->overflowX() == OMARQUEE && style->overflowY() != OMARQUEE)
+ style->setOverflowY(OMARQUEE);
+ else if (style->overflowY() == OMARQUEE && style->overflowX() != OMARQUEE)
+ style->setOverflowX(OMARQUEE);
+ else if (style->overflowX() == OVISIBLE && style->overflowY() != OVISIBLE)
+ style->setOverflowX(OAUTO);
+ else if (style->overflowY() == OVISIBLE && style->overflowX() != OVISIBLE)
+ style->setOverflowY(OAUTO);
+
+ // Table rows, sections and the table itself will support overflow:hidden and will ignore scroll/auto.
+ // FIXME: Eventually table sections will support auto and scroll.
+ if (style->display() == TABLE || style->display() == INLINE_TABLE ||
+ style->display() == TABLE_ROW_GROUP || style->display() == TABLE_ROW) {
+ if (style->overflowX() != OVISIBLE && style->overflowX() != OHIDDEN)
+ style->setOverflowX(OVISIBLE);
+ if (style->overflowY() != OVISIBLE && style->overflowY() != OHIDDEN)
+ style->setOverflowY(OVISIBLE);
+ }
+
+ // Cull out any useless layers and also repeat patterns into additional layers.
+ style->adjustBackgroundLayers();
+
+ // Do the same for transitions.
+ style->adjustTransitions();
+
+ // Important: Intrinsic margins get added to controls before the theme has adjusted the style, since the theme will
+ // alter fonts and heights/widths.
+ if (e && e->isControl() && style->fontSize() >= 11) {
+ // Don't apply intrinsic margins to image buttons. The designer knows how big the images are,
+ // so we have to treat all image buttons as though they were explicitly sized.
+ if (!e->hasTagName(inputTag) || static_cast<HTMLInputElement*>(e)->inputType() != HTMLInputElement::IMAGE)
+ addIntrinsicMargins(style);
+ }
+
+ // Let the theme also have a crack at adjusting the style.
+ if (style->hasAppearance())
+ theme()->adjustStyle(this, style, e, m_hasUAAppearance, m_borderData, m_backgroundData, m_backgroundColor);
+
+#if ENABLE(SVG)
+ if (e && e->isSVGElement()) {
+ // Spec: http://www.w3.org/TR/SVG/masking.html#OverflowProperty
+ if (style->overflowY() == OSCROLL)
+ style->setOverflowY(OHIDDEN);
+ else if (style->overflowY() == OAUTO)
+ style->setOverflowY(OVISIBLE);
+
+ if (style->overflowX() == OSCROLL)
+ style->setOverflowX(OHIDDEN);
+ else if (style->overflowX() == OAUTO)
+ style->setOverflowX(OVISIBLE);
+
+ // Only the root <svg> element in an SVG document fragment tree honors css position
+ if (!(e->hasTagName(SVGNames::svgTag) && e->parentNode() && !e->parentNode()->isSVGElement()))
+ style->setPosition(RenderStyle::initialPosition());
+ }
+#endif
+}
+
+void CSSStyleSelector::updateFont()
+{
+ checkForTextSizeAdjust();
+ checkForGenericFamilyChange(m_style, m_parentStyle);
+ m_style->font().update(m_fontSelector);
+ m_fontDirty = false;
+}
+
+void CSSStyleSelector::cacheBorderAndBackground()
+{
+ m_hasUAAppearance = m_style->hasAppearance();
+ if (m_hasUAAppearance) {
+ m_borderData = m_style->border();
+ m_backgroundData = *m_style->backgroundLayers();
+ m_backgroundColor = m_style->backgroundColor();
+ }
+}
+
+RefPtr<CSSRuleList> CSSStyleSelector::styleRulesForElement(Element* e, bool authorOnly)
+{
+ if (!e || !e->document()->haveStylesheetsLoaded())
+ return 0;
+
+ m_collectRulesOnly = true;
+
+ initElementAndPseudoState(e);
+ initForStyleResolve(e, 0);
+
+ if (!authorOnly) {
+ int firstUARule = -1, lastUARule = -1;
+ // First we match rules from the user agent sheet.
+ matchUARules(firstUARule, lastUARule);
+
+ // Now we check user sheet rules.
+ if (m_matchAuthorAndUserStyles) {
+ int firstUserRule = -1, lastUserRule = -1;
+ matchRules(m_userStyle, firstUserRule, lastUserRule);
+ }
+ }
+
+ if (m_matchAuthorAndUserStyles) {
+ // Check the rules in author sheets.
+ int firstAuthorRule = -1, lastAuthorRule = -1;
+ matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
+ }
+
+ m_collectRulesOnly = false;
+
+ return m_ruleList;
+}
+
+RefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element* e, StringImpl* pseudoStyle, bool authorOnly)
+{
+ // FIXME: Implement this.
+ return 0;
+}
+
+bool CSSStyleSelector::checkSelector(CSSSelector* sel)
+{
+ dynamicPseudo = RenderStyle::NOPSEUDO;
+
+ // Check the selector
+ SelectorMatch match = checkSelector(sel, m_element, true, false);
+ if (match != SelectorMatches)
+ return false;
+
+ if (m_pseudoStyle != RenderStyle::NOPSEUDO && m_pseudoStyle != dynamicPseudo)
+ return false;
+
+ return true;
+}
+
+// Recursive check of selectors and combinators
+// It can return 3 different values:
+// * SelectorMatches - the selector matches the element e
+// * SelectorFailsLocally - the selector fails for the element e
+// * SelectorFailsCompletely - the selector fails for e and any sibling or ancestor of e
+CSSStyleSelector::SelectorMatch CSSStyleSelector::checkSelector(CSSSelector* sel, Element* e, bool isAncestor, bool isSubSelector)
+{
+#if ENABLE(SVG)
+ // Spec: CSS2 selectors cannot be applied to the (conceptually) cloned DOM tree
+ // because its contents are not part of the formal document structure.
+ if (e->isSVGElement() && e->isShadowNode())
+ return SelectorFailsCompletely;
+#endif
+
+ // first selector has to match
+ if (!checkOneSelector(sel, e, isAncestor, isSubSelector))
+ return SelectorFailsLocally;
+
+ // The rest of the selectors has to match
+ CSSSelector::Relation relation = sel->relation();
+
+ // Prepare next sel
+ sel = sel->m_tagHistory;
+ if (!sel)
+ return SelectorMatches;
+
+ if (relation != CSSSelector::SubSelector)
+ // Bail-out if this selector is irrelevant for the pseudoStyle
+ if (m_pseudoStyle != RenderStyle::NOPSEUDO && m_pseudoStyle != dynamicPseudo)
+ return SelectorFailsCompletely;
+
+ switch (relation) {
+ case CSSSelector::Descendant:
+ while (true) {
+ Node* n = e->parentNode();
+ if (!n || !n->isElementNode())
+ return SelectorFailsCompletely;
+ e = static_cast<Element*>(n);
+ SelectorMatch match = checkSelector(sel, e, true, false);
+ if (match != SelectorFailsLocally)
+ return match;
+ }
+ break;
+ case CSSSelector::Child:
+ {
+ Node* n = e->parentNode();
+ if (!n || !n->isElementNode())
+ return SelectorFailsCompletely;
+ e = static_cast<Element*>(n);
+ return checkSelector(sel, e, true, false);
+ }
+ case CSSSelector::DirectAdjacent:
+ {
+ if (!m_collectRulesOnly && e->parentNode() && e->parentNode()->isElementNode()) {
+ RenderStyle* parentStyle = (m_element == e) ? m_parentStyle : e->parentNode()->renderStyle();
+ if (parentStyle)
+ parentStyle->setChildrenAffectedByDirectAdjacentRules();
+ }
+ Node* n = e->previousSibling();
+ while (n && !n->isElementNode())
+ n = n->previousSibling();
+ if (!n)
+ return SelectorFailsLocally;
+ e = static_cast<Element*>(n);
+ return checkSelector(sel, e, false, false);
+ }
+ case CSSSelector::IndirectAdjacent:
+ if (!m_collectRulesOnly && e->parentNode() && e->parentNode()->isElementNode()) {
+ RenderStyle* parentStyle = (m_element == e) ? m_parentStyle : e->parentNode()->renderStyle();
+ if (parentStyle)
+ parentStyle->setChildrenAffectedByForwardPositionalRules();
+ }
+ while (true) {
+ Node* n = e->previousSibling();
+ while (n && !n->isElementNode())
+ n = n->previousSibling();
+ if (!n)
+ return SelectorFailsLocally;
+ e = static_cast<Element*>(n);
+ SelectorMatch match = checkSelector(sel, e, false, false);
+ if (match != SelectorFailsLocally)
+ return match;
+ };
+ break;
+ case CSSSelector::SubSelector:
+ // a selector is invalid if something follows a pseudo-element
+ if (e == m_element && dynamicPseudo != RenderStyle::NOPSEUDO)
+ return SelectorFailsCompletely;
+ return checkSelector(sel, e, isAncestor, true);
+ }
+
+ return SelectorFailsCompletely;
+}
+
+static void addLocalNameToSet(HashSet<AtomicStringImpl*>* set, const QualifiedName& qName)
+{
+ set->add(qName.localName().impl());
+}
+
+static HashSet<AtomicStringImpl*>* createHtmlCaseInsensitiveAttributesSet()
+{
+ // This is the list of attributes in HTML 4.01 with values marked as "[CI]" or case-insensitive
+ // Mozilla treats all other values as case-sensitive, thus so do we.
+ HashSet<AtomicStringImpl*>* attrSet = new HashSet<AtomicStringImpl*>;
+
+ addLocalNameToSet(attrSet, accept_charsetAttr);
+ addLocalNameToSet(attrSet, acceptAttr);
+ addLocalNameToSet(attrSet, alignAttr);
+ addLocalNameToSet(attrSet, alinkAttr);
+ addLocalNameToSet(attrSet, axisAttr);
+ addLocalNameToSet(attrSet, bgcolorAttr);
+ addLocalNameToSet(attrSet, charsetAttr);
+ addLocalNameToSet(attrSet, checkedAttr);
+ addLocalNameToSet(attrSet, clearAttr);
+ addLocalNameToSet(attrSet, codetypeAttr);
+ addLocalNameToSet(attrSet, colorAttr);
+ addLocalNameToSet(attrSet, compactAttr);
+ addLocalNameToSet(attrSet, declareAttr);
+ addLocalNameToSet(attrSet, deferAttr);
+ addLocalNameToSet(attrSet, dirAttr);
+ addLocalNameToSet(attrSet, disabledAttr);
+ addLocalNameToSet(attrSet, enctypeAttr);
+ addLocalNameToSet(attrSet, faceAttr);
+ addLocalNameToSet(attrSet, frameAttr);
+ addLocalNameToSet(attrSet, hreflangAttr);
+ addLocalNameToSet(attrSet, http_equivAttr);
+ addLocalNameToSet(attrSet, langAttr);
+ addLocalNameToSet(attrSet, languageAttr);
+ addLocalNameToSet(attrSet, linkAttr);
+ addLocalNameToSet(attrSet, mediaAttr);
+ addLocalNameToSet(attrSet, methodAttr);
+ addLocalNameToSet(attrSet, multipleAttr);
+ addLocalNameToSet(attrSet, nohrefAttr);
+ addLocalNameToSet(attrSet, noresizeAttr);
+ addLocalNameToSet(attrSet, noshadeAttr);
+ addLocalNameToSet(attrSet, nowrapAttr);
+ addLocalNameToSet(attrSet, readonlyAttr);
+ addLocalNameToSet(attrSet, relAttr);
+ addLocalNameToSet(attrSet, revAttr);
+ addLocalNameToSet(attrSet, rulesAttr);
+ addLocalNameToSet(attrSet, scopeAttr);
+ addLocalNameToSet(attrSet, scrollingAttr);
+ addLocalNameToSet(attrSet, selectedAttr);
+ addLocalNameToSet(attrSet, shapeAttr);
+ addLocalNameToSet(attrSet, targetAttr);
+ addLocalNameToSet(attrSet, textAttr);
+ addLocalNameToSet(attrSet, typeAttr);
+ addLocalNameToSet(attrSet, valignAttr);
+ addLocalNameToSet(attrSet, valuetypeAttr);
+ addLocalNameToSet(attrSet, vlinkAttr);
+
+ return attrSet;
+}
+
+static bool htmlAttributeHasCaseInsensitiveValue(const QualifiedName& attr)
+{
+ static HashSet<AtomicStringImpl*>* htmlCaseInsensitiveAttributesSet = createHtmlCaseInsensitiveAttributesSet();
+ bool isPossibleHTMLAttr = !attr.hasPrefix() && (attr.namespaceURI() == nullAtom);
+ return isPossibleHTMLAttr && htmlCaseInsensitiveAttributesSet->contains(attr.localName().impl());
+}
+
+bool CSSStyleSelector::checkOneSelector(CSSSelector* sel, Element* e, bool isAncestor, bool isSubSelector)
+{
+ if (!e)
+ return false;
+
+ if (sel->hasTag()) {
+ const AtomicString& localName = e->localName();
+ const AtomicString& ns = e->namespaceURI();
+ const AtomicString& selLocalName = sel->m_tag.localName();
+ const AtomicString& selNS = sel->m_tag.namespaceURI();
+
+ if ((selLocalName != starAtom && localName != selLocalName) ||
+ (selNS != starAtom && ns != selNS))
+ return false;
+ }
+
+ if (sel->hasAttribute()) {
+ if (sel->m_match == CSSSelector::Class) {
+ if (!e->hasClass())
+ return false;
+ return e->getClassNames()->contains(sel->m_value);
+ } else if (sel->m_match == CSSSelector::Id)
+ return e->hasID() && e->getIDAttribute() == sel->m_value;
+ else if (m_style && (e != m_element || !m_styledElement || (!m_styledElement->isMappedAttribute(sel->m_attr) && sel->m_attr != typeAttr && sel->m_attr != readonlyAttr))) {
+ m_style->setAffectedByAttributeSelectors(); // Special-case the "type" and "readonly" attributes so input form controls can share style.
+ m_selectorAttrs.add(sel->m_attr.localName().impl());
+ }
+
+ const AtomicString& value = e->getAttribute(sel->m_attr);
+ if (value.isNull())
+ return false; // attribute is not set
+
+ bool caseSensitive = m_isXMLDoc || !htmlAttributeHasCaseInsensitiveValue(sel->m_attr);
+
+ switch (sel->m_match) {
+ case CSSSelector::Exact:
+ if (caseSensitive ? sel->m_value != value : !equalIgnoringCase(sel->m_value, value))
+ return false;
+ break;
+ case CSSSelector::List:
+ {
+ // The selector's value can't contain a space, or it's totally bogus.
+ if (sel->m_value.contains(' '))
+ return false;
+
+ int startSearchAt = 0;
+ while (true) {
+ int foundPos = value.find(sel->m_value, startSearchAt, caseSensitive);
+ if (foundPos == -1)
+ return false;
+ if (foundPos == 0 || value[foundPos-1] == ' ') {
+ unsigned endStr = foundPos + sel->m_value.length();
+ if (endStr == value.length() || value[endStr] == ' ')
+ break; // We found a match.
+ }
+
+ // No match. Keep looking.
+ startSearchAt = foundPos + 1;
+ }
+ break;
+ }
+ case CSSSelector::Contain:
+ if (!value.contains(sel->m_value, caseSensitive))
+ return false;
+ break;
+ case CSSSelector::Begin:
+ if (!value.startsWith(sel->m_value, caseSensitive))
+ return false;
+ break;
+ case CSSSelector::End:
+ if (!value.endsWith(sel->m_value, caseSensitive))
+ return false;
+ break;
+ case CSSSelector::Hyphen:
+ if (value.length() < sel->m_value.length())
+ return false;
+ if (!value.startsWith(sel->m_value, caseSensitive))
+ return false;
+ // It they start the same, check for exact match or following '-':
+ if (value.length() != sel->m_value.length() && value[sel->m_value.length()] != '-')
+ return false;
+ break;
+ case CSSSelector::PseudoClass:
+ case CSSSelector::PseudoElement:
+ default:
+ break;
+ }
+ }
+ if (sel->m_match == CSSSelector::PseudoClass) {
+ switch (sel->pseudoType()) {
+ // Pseudo classes:
+ case CSSSelector::PseudoEmpty: {
+ bool result = true;
+ for (Node* n = e->firstChild(); n; n = n->nextSibling()) {
+ if (n->isElementNode()) {
+ result = false;
+ break;
+ } else if (n->isTextNode()) {
+ Text* textNode = static_cast<Text*>(n);
+ if (!textNode->data().isEmpty()) {
+ result = false;
+ break;
+ }
+ }
+ }
+ if (!m_collectRulesOnly) {
+ if (m_element == e && m_style)
+ m_style->setEmptyState(result);
+ else if (e->renderStyle() && (e->document()->usesSiblingRules() || e->renderStyle()->unique()))
+ e->renderStyle()->setEmptyState(result);
+ }
+ return result;
+ }
+ case CSSSelector::PseudoFirstChild: {
+ // first-child matches the first child that is an element
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ bool result = false;
+ Node* n = e->previousSibling();
+ while (n && !n->isElementNode())
+ n = n->previousSibling();
+ if (!n)
+ result = true;
+ if (!m_collectRulesOnly) {
+ RenderStyle* childStyle = (m_element == e) ? m_style : e->renderStyle();
+ RenderStyle* parentStyle = (m_element == e) ? m_parentStyle : e->parentNode()->renderStyle();
+ if (parentStyle)
+ parentStyle->setChildrenAffectedByFirstChildRules();
+ if (result && childStyle)
+ childStyle->setFirstChildState();
+ }
+ return result;
+ }
+ break;
+ }
+ case CSSSelector::PseudoFirstOfType: {
+ // first-of-type matches the first element of its type
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ bool result = false;
+ const QualifiedName& type = e->tagQName();
+ Node* n = e->previousSibling();
+ while (n) {
+ if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
+ break;
+ n = n->previousSibling();
+ }
+ if (!n)
+ result = true;
+ if (!m_collectRulesOnly) {
+ RenderStyle* parentStyle = (m_element == e) ? m_parentStyle : e->parentNode()->renderStyle();
+ if (parentStyle)
+ parentStyle->setChildrenAffectedByForwardPositionalRules();
+ }
+ return result;
+ }
+ break;
+ }
+ case CSSSelector::PseudoLastChild: {
+ // last-child matches the last child that is an element
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ Element* parentNode = static_cast<Element*>(e->parentNode());
+ bool result = false;
+ if (parentNode->isFinishedParsingChildren()) {
+ Node* n = e->nextSibling();
+ while (n && !n->isElementNode())
+ n = n->nextSibling();
+ if (!n)
+ result = true;
+ }
+ if (!m_collectRulesOnly) {
+ RenderStyle* childStyle = (m_element == e) ? m_style : e->renderStyle();
+ RenderStyle* parentStyle = (m_element == e) ? m_parentStyle : parentNode->renderStyle();
+ if (parentStyle)
+ parentStyle->setChildrenAffectedByLastChildRules();
+ if (result && childStyle)
+ childStyle->setLastChildState();
+ }
+ return result;
+ }
+ break;
+ }
+ case CSSSelector::PseudoLastOfType: {
+ // last-of-type matches the last element of its type
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ Element* parentNode = static_cast<Element*>(e->parentNode());
+ if (!m_collectRulesOnly) {
+ RenderStyle* parentStyle = (m_element == e) ? m_parentStyle : parentNode->renderStyle();
+ if (parentStyle)
+ parentStyle->setChildrenAffectedByBackwardPositionalRules();
+ }
+ if (!parentNode->isFinishedParsingChildren())
+ return false;
+ bool result = false;
+ const QualifiedName& type = e->tagQName();
+ Node* n = e->nextSibling();
+ while (n) {
+ if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
+ break;
+ n = n->nextSibling();
+ }
+ if (!n)
+ result = true;
+ return result;
+ }
+ break;
+ }
+ case CSSSelector::PseudoOnlyChild: {
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ Element* parentNode = static_cast<Element*>(e->parentNode());
+ bool firstChild = false;
+ bool lastChild = false;
+
+ Node* n = e->previousSibling();
+ while (n && !n->isElementNode())
+ n = n->previousSibling();
+ if (!n)
+ firstChild = true;
+ if (firstChild && parentNode->isFinishedParsingChildren()) {
+ n = e->nextSibling();
+ while (n && !n->isElementNode())
+ n = n->nextSibling();
+ if (!n)
+ lastChild = true;
+ }
+ if (!m_collectRulesOnly) {
+ RenderStyle* childStyle = (m_element == e) ? m_style : e->renderStyle();
+ RenderStyle* parentStyle = (m_element == e) ? m_parentStyle : parentNode->renderStyle();
+ if (parentStyle) {
+ parentStyle->setChildrenAffectedByFirstChildRules();
+ parentStyle->setChildrenAffectedByLastChildRules();
+ }
+ if (firstChild && childStyle)
+ childStyle->setFirstChildState();
+ if (lastChild && childStyle)
+ childStyle->setLastChildState();
+ }
+ return firstChild && lastChild;
+ }
+ break;
+ }
+ case CSSSelector::PseudoOnlyOfType: {
+ // FIXME: This selector is very slow.
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ Element* parentNode = static_cast<Element*>(e->parentNode());
+ if (!m_collectRulesOnly) {
+ RenderStyle* parentStyle = (m_element == e) ? m_parentStyle : parentNode->renderStyle();
+ if (parentStyle) {
+ parentStyle->setChildrenAffectedByForwardPositionalRules();
+ parentStyle->setChildrenAffectedByBackwardPositionalRules();
+ }
+ }
+ if (!parentNode->isFinishedParsingChildren())
+ return false;
+ bool firstChild = false;
+ bool lastChild = false;
+ const QualifiedName& type = e->tagQName();
+ Node* n = e->previousSibling();
+ while (n) {
+ if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
+ break;
+ n = n->previousSibling();
+ }
+ if (!n)
+ firstChild = true;
+ if (firstChild) {
+ n = e->nextSibling();
+ while (n) {
+ if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
+ break;
+ n = n->nextSibling();
+ }
+ if (!n)
+ lastChild = true;
+ }
+ return firstChild && lastChild;
+ }
+ break;
+ }
+ case CSSSelector::PseudoNthChild: {
+ int a, b;
+ // calculate a and b every time we run through checkOneSelector
+ // this should probably be saved after we calculate it once, but currently
+ // would require increasing the size of CSSSelector
+ if (!parseNth(sel->m_argument, a, b))
+ break;
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ int count = 1;
+ Node* n = e->previousSibling();
+ while (n) {
+ if (n->isElementNode()) {
+ RenderStyle* s = n->renderStyle();
+ unsigned index = s ? s->childIndex() : 0;
+ if (index) {
+ count += index;
+ break;
+ }
+ count++;
+ }
+ n = n->previousSibling();
+ }
+
+ if (!m_collectRulesOnly) {
+ RenderStyle* childStyle = (m_element == e) ? m_style : e->renderStyle();
+ RenderStyle* parentStyle = (m_element == e) ? m_parentStyle : e->parentNode()->renderStyle();
+ if (childStyle)
+ childStyle->setChildIndex(count);
+ if (parentStyle)
+ parentStyle->setChildrenAffectedByForwardPositionalRules();
+ }
+
+ if (matchNth(count, a, b))
+ return true;
+ }
+ break;
+ }
+ case CSSSelector::PseudoNthOfType: {
+ // FIXME: This selector is very slow.
+ int a, b;
+ // calculate a and b every time we run through checkOneSelector (see above)
+ if (!parseNth(sel->m_argument, a, b))
+ break;
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ int count = 1;
+ const QualifiedName& type = e->tagQName();
+ Node* n = e->previousSibling();
+ while (n) {
+ if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
+ count++;
+ n = n->previousSibling();
+ }
+
+ if (!m_collectRulesOnly) {
+ RenderStyle* parentStyle = (m_element == e) ? m_parentStyle : e->parentNode()->renderStyle();
+ if (parentStyle)
+ parentStyle->setChildrenAffectedByForwardPositionalRules();
+ }
+
+ if (matchNth(count, a, b))
+ return true;
+ }
+ break;
+ }
+ case CSSSelector::PseudoNthLastChild: {
+ int a, b;
+ // calculate a and b every time we run through checkOneSelector
+ // this should probably be saved after we calculate it once, but currently
+ // would require increasing the size of CSSSelector
+ if (!parseNth(sel->m_argument, a, b))
+ break;
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ Element* parentNode = static_cast<Element*>(e->parentNode());
+ if (!m_collectRulesOnly) {
+ RenderStyle* parentStyle = (m_element == e) ? m_parentStyle : parentNode->renderStyle();
+ if (parentStyle)
+ parentStyle->setChildrenAffectedByBackwardPositionalRules();
+ }
+ if (!parentNode->isFinishedParsingChildren())
+ return false;
+ int count = 1;
+ Node* n = e->nextSibling();
+ while (n) {
+ if (n->isElementNode())
+ count++;
+ n = n->nextSibling();
+ }
+ if (matchNth(count, a, b))
+ return true;
+ }
+ break;
+ }
+ case CSSSelector::PseudoNthLastOfType: {
+ // FIXME: This selector is very slow.
+ int a, b;
+ // calculate a and b every time we run through checkOneSelector (see above)
+ if (!parseNth(sel->m_argument, a, b))
+ break;
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ Element* parentNode = static_cast<Element*>(e->parentNode());
+ if (!m_collectRulesOnly) {
+ RenderStyle* parentStyle = (m_element == e) ? m_parentStyle : parentNode->renderStyle();
+ if (parentStyle)
+ parentStyle->setChildrenAffectedByBackwardPositionalRules();
+ }
+ if (!parentNode->isFinishedParsingChildren())
+ return false;
+ int count = 1;
+ const QualifiedName& type = e->tagQName();
+ Node* n = e->nextSibling();
+ while (n) {
+ if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
+ count++;
+ n = n->nextSibling();
+ }
+ if (matchNth(count, a, b))
+ return true;
+ }
+ break;
+ }
+ case CSSSelector::PseudoTarget:
+ if (e == e->document()->getCSSTarget())
+ return true;
+ break;
+ case CSSSelector::PseudoAnyLink:
+ if (pseudoState == PseudoUnknown)
+ checkPseudoState(e, false);
+ if (pseudoState == PseudoAnyLink || pseudoState == PseudoLink || pseudoState == PseudoVisited)
+ return true;
+ break;
+ case CSSSelector::PseudoAutofill:
+ if (e && e->hasTagName(inputTag))
+ return static_cast<HTMLInputElement*>(e)->autofilled();
+ break;
+ case CSSSelector::PseudoLink:
+ if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink)
+ checkPseudoState(e);
+ if (pseudoState == PseudoLink)
+ return true;
+ break;
+ case CSSSelector::PseudoVisited:
+ if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink)
+ checkPseudoState(e);
+ if (pseudoState == PseudoVisited)
+ return true;
+ break;
+ case CSSSelector::PseudoDrag: {
+ if (m_element == e && m_style)
+ m_style->setAffectedByDragRules(true);
+ if (m_element != e && e->renderStyle())
+ e->renderStyle()->setAffectedByDragRules(true);
+ if (e->renderer() && e->renderer()->isDragging())
+ return true;
+ break;
+ }
+ case CSSSelector::PseudoFocus:
+ if (e && e->focused() && e->document()->frame()->selectionController()->isFocusedAndActive())
+ return true;
+ break;
+ case CSSSelector::PseudoHover: {
+ // If we're in quirks mode, then hover should never match anchors with no
+ // href and *:hover should not match anything. This is important for sites like wsj.com.
+ if (strictParsing || isSubSelector || (sel->hasTag() && !e->hasTagName(aTag)) || e->isLink()) {
+ if (m_element == e && m_style)
+ m_style->setAffectedByHoverRules(true);
+ if (m_element != e && e->renderStyle())
+ e->renderStyle()->setAffectedByHoverRules(true);
+ if (e->hovered())
+ return true;
+ }
+ break;
+ }
+ case CSSSelector::PseudoActive:
+ // If we're in quirks mode, then :active should never match anchors with no
+ // href and *:active should not match anything.
+ if (strictParsing || isSubSelector || (sel->hasTag() && !e->hasTagName(aTag)) || e->isLink()) {
+ if (m_element == e && m_style)
+ m_style->setAffectedByActiveRules(true);
+ else if (e->renderStyle())
+ e->renderStyle()->setAffectedByActiveRules(true);
+ if (e->active())
+ return true;
+ }
+ break;
+ case CSSSelector::PseudoEnabled:
+ if (e && e->isControl() && !e->isInputTypeHidden())
+ // The UI spec states that you can't match :enabled unless you are an object that can
+ // "receive focus and be activated." We will limit matching of this pseudo-class to elements
+ // that are non-"hidden" controls.
+ return e->isEnabled();
+ break;
+ case CSSSelector::PseudoDisabled:
+ if (e && e->isControl() && !e->isInputTypeHidden())
+ // The UI spec states that you can't match :enabled unless you are an object that can
+ // "receive focus and be activated." We will limit matching of this pseudo-class to elements
+ // that are non-"hidden" controls.
+ return !e->isEnabled();
+ break;
+ case CSSSelector::PseudoChecked:
+ // Even though WinIE allows checked and indeterminate to co-exist, the CSS selector spec says that
+ // you can't be both checked and indeterminate. We will behave like WinIE behind the scenes and just
+ // obey the CSS spec here in the test for matching the pseudo.
+ if (e && e->isChecked() && !e->isIndeterminate())
+ return true;
+ break;
+ case CSSSelector::PseudoIndeterminate:
+ if (e && e->isIndeterminate())
+ return true;
+ break;
+ case CSSSelector::PseudoRoot:
+ if (e == e->document()->documentElement())
+ return true;
+ break;
+ case CSSSelector::PseudoLang: {
+ Node* n = e;
+ AtomicString value;
+ // The language property is inherited, so we iterate over the parents
+ // to find the first language.
+ while (n && value.isEmpty()) {
+ if (n->isElementNode()) {
+ // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
+ value = static_cast<Element*>(n)->getAttribute(XMLNames::langAttr);
+ if (value.isEmpty())
+ value = static_cast<Element*>(n)->getAttribute(langAttr);
+ } else if (n->isDocumentNode())
+ // checking the MIME content-language
+ value = static_cast<Document*>(n)->contentLanguage();
+
+ n = n->parent();
+ }
+ if (value.isEmpty() || !value.startsWith(sel->m_argument, false))
+ break;
+ if (value.length() != sel->m_argument.length() && value[sel->m_argument.length()] != '-')
+ break;
+ return true;
+ }
+ case CSSSelector::PseudoNot: {
+ // check the simple selector
+ for (CSSSelector* subSel = sel->m_simpleSelector; subSel; subSel = subSel->m_tagHistory) {
+ // :not cannot nest. I don't really know why this is a
+ // restriction in CSS3, but it is, so let's honour it.
+ if (subSel->m_simpleSelector)
+ break;
+ if (!checkOneSelector(subSel, e, isAncestor, true))
+ return true;
+ }
+ break;
+ }
+ case CSSSelector::PseudoUnknown:
+ case CSSSelector::PseudoNotParsed:
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ return false;
+ }
+ if (sel->m_match == CSSSelector::PseudoElement) {
+ if (e != m_element) return false;
+
+ switch (sel->pseudoType()) {
+ // Pseudo-elements:
+ case CSSSelector::PseudoFirstLine:
+ dynamicPseudo = RenderStyle::FIRST_LINE;
+ return true;
+ case CSSSelector::PseudoFirstLetter:
+ dynamicPseudo = RenderStyle::FIRST_LETTER;
+ if (Document* doc = e->document())
+ doc->setUsesFirstLetterRules(true);
+ return true;
+ case CSSSelector::PseudoSelection:
+ dynamicPseudo = RenderStyle::SELECTION;
+ return true;
+ case CSSSelector::PseudoBefore:
+ dynamicPseudo = RenderStyle::BEFORE;
+ return true;
+ case CSSSelector::PseudoAfter:
+ dynamicPseudo = RenderStyle::AFTER;
+ return true;
+ case CSSSelector::PseudoFileUploadButton:
+ dynamicPseudo = RenderStyle::FILE_UPLOAD_BUTTON;
+ return true;
+ case CSSSelector::PseudoSliderThumb:
+ dynamicPseudo = RenderStyle::SLIDER_THUMB;
+ return true;
+ case CSSSelector::PseudoSearchCancelButton:
+ dynamicPseudo = RenderStyle::SEARCH_CANCEL_BUTTON;
+ return true;
+ case CSSSelector::PseudoSearchDecoration:
+ dynamicPseudo = RenderStyle::SEARCH_DECORATION;
+ return true;
+ case CSSSelector::PseudoSearchResultsDecoration:
+ dynamicPseudo = RenderStyle::SEARCH_RESULTS_DECORATION;
+ return true;
+ case CSSSelector::PseudoSearchResultsButton:
+ dynamicPseudo = RenderStyle::SEARCH_RESULTS_BUTTON;
+ return true;
+ case CSSSelector::PseudoMediaControlsPanel:
+ dynamicPseudo = RenderStyle::MEDIA_CONTROLS_PANEL;
+ return true;
+ case CSSSelector::PseudoMediaControlsMuteButton:
+ dynamicPseudo = RenderStyle::MEDIA_CONTROLS_MUTE_BUTTON;
+ return true;
+ case CSSSelector::PseudoMediaControlsPlayButton:
+ dynamicPseudo = RenderStyle::MEDIA_CONTROLS_PLAY_BUTTON;
+ return true;
+ case CSSSelector::PseudoMediaControlsTimeDisplay:
+ dynamicPseudo = RenderStyle::MEDIA_CONTROLS_TIME_DISPLAY;
+ return true;
+ case CSSSelector::PseudoMediaControlsTimeline:
+ dynamicPseudo = RenderStyle::MEDIA_CONTROLS_TIMELINE;
+ return true;
+ case CSSSelector::PseudoMediaControlsSeekBackButton:
+ dynamicPseudo = RenderStyle::MEDIA_CONTROLS_SEEK_BACK_BUTTON;
+ return true;
+ case CSSSelector::PseudoMediaControlsSeekForwardButton:
+ dynamicPseudo = RenderStyle::MEDIA_CONTROLS_SEEK_FORWARD_BUTTON;
+ return true;
+ case CSSSelector::PseudoMediaControlsFullscreenButton:
+ dynamicPseudo = RenderStyle::MEDIA_CONTROLS_FULLSCREEN_BUTTON;
+ return true;
+ case CSSSelector::PseudoUnknown:
+ case CSSSelector::PseudoNotParsed:
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ return false;
+ }
+ // ### add the rest of the checks...
+ return true;
+}
+
+// -----------------------------------------------------------------
+
+CSSRuleSet::CSSRuleSet()
+{
+ m_universalRules = 0;
+ m_ruleCount = 0;
+}
+
+CSSRuleSet::~CSSRuleSet()
+{
+ deleteAllValues(m_idRules);
+ deleteAllValues(m_classRules);
+ deleteAllValues(m_tagRules);
+
+ delete m_universalRules;
+}
+
+
+void CSSRuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map,
+ CSSStyleRule* rule, CSSSelector* sel)
+{
+ if (!key) return;
+ CSSRuleDataList* rules = map.get(key);
+ if (!rules) {
+ rules = new CSSRuleDataList(m_ruleCount++, rule, sel);
+ map.set(key, rules);
+ } else
+ rules->append(m_ruleCount++, rule, sel);
+}
+
+void CSSRuleSet::addRule(CSSStyleRule* rule, CSSSelector* sel)
+{
+ if (sel->m_match == CSSSelector::Id) {
+ addToRuleSet(sel->m_value.impl(), m_idRules, rule, sel);
+ return;
+ }
+ if (sel->m_match == CSSSelector::Class) {
+ addToRuleSet(sel->m_value.impl(), m_classRules, rule, sel);
+ return;
+ }
+
+ const AtomicString& localName = sel->m_tag.localName();
+ if (localName != starAtom) {
+ addToRuleSet(localName.impl(), m_tagRules, rule, sel);
+ return;
+ }
+
+ // Just put it in the universal rule set.
+ if (!m_universalRules)
+ m_universalRules = new CSSRuleDataList(m_ruleCount++, rule, sel);
+ else
+ m_universalRules->append(m_ruleCount++, rule, sel);
+}
+
+void CSSRuleSet::addRulesFromSheet(CSSStyleSheet* sheet, const MediaQueryEvaluator& medium, CSSStyleSelector* styleSelector)
+{
+ if (!sheet || !sheet->isCSSStyleSheet())
+ return;
+
+ // No media implies "all", but if a media list exists it must
+ // contain our current medium
+ if (sheet->media() && !medium.eval(sheet->media(), styleSelector))
+ return; // the style sheet doesn't apply
+
+ int len = sheet->length();
+
+ for (int i = 0; i < len; i++) {
+ StyleBase* item = sheet->item(i);
+ if (item->isStyleRule()) {
+ CSSStyleRule* rule = static_cast<CSSStyleRule*>(item);
+ for (CSSSelector* s = rule->selector(); s; s = s->next())
+ addRule(rule, s);
+ }
+ else if (item->isImportRule()) {
+ CSSImportRule* import = static_cast<CSSImportRule*>(item);
+ if (!import->media() || medium.eval(import->media(), styleSelector))
+ addRulesFromSheet(import->styleSheet(), medium, styleSelector);
+ }
+ else if (item->isMediaRule()) {
+ CSSMediaRule* r = static_cast<CSSMediaRule*>(item);
+ CSSRuleList* rules = r->cssRules();
+
+ if ((!r->media() || medium.eval(r->media(), styleSelector)) && rules) {
+ // Traverse child elements of the @media rule.
+ for (unsigned j = 0; j < rules->length(); j++) {
+ CSSRule *childItem = rules->item(j);
+ if (childItem->isStyleRule()) {
+ // It is a StyleRule, so append it to our list
+ CSSStyleRule* rule = static_cast<CSSStyleRule*>(childItem);
+ for (CSSSelector* s = rule->selector(); s; s = s->next())
+ addRule(rule, s);
+ } else if (item->isFontFaceRule() && styleSelector) {
+ // Add this font face to our set.
+ const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(item);
+ styleSelector->fontSelector()->addFontFaceRule(fontFaceRule);
+ }
+ } // for rules
+ } // if rules
+ } else if (item->isFontFaceRule() && styleSelector) {
+ // Add this font face to our set.
+ const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(item);
+ styleSelector->fontSelector()->addFontFaceRule(fontFaceRule);
+ }
+ }
+}
+
+// -------------------------------------------------------------------------------------
+// this is mostly boring stuff on how to apply a certain rule to the renderstyle...
+
+static Length convertToLength(CSSPrimitiveValue *primitiveValue, RenderStyle *style, bool *ok = 0)
+{
+ Length l;
+ if (!primitiveValue) {
+ if (ok)
+ *ok = false;
+ } else {
+ int type = primitiveValue->primitiveType();
+ if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ l = Length(primitiveValue->computeLengthIntForLength(style), Fixed);
+ else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ l = Length(primitiveValue->getDoubleValue(), Percent);
+ else if (type == CSSPrimitiveValue::CSS_NUMBER)
+ l = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
+ else if (ok)
+ *ok = false;
+ }
+ return l;
+}
+
+void CSSStyleSelector::applyDeclarations(bool applyFirst, bool isImportant,
+ int startIndex, int endIndex)
+{
+ if (startIndex == -1) return;
+ for (int i = startIndex; i <= endIndex; i++) {
+ CSSMutableStyleDeclaration* decl = m_matchedDecls[i];
+ DeprecatedValueListConstIterator<CSSProperty> end;
+ for (DeprecatedValueListConstIterator<CSSProperty> it = decl->valuesIterator(); it != end; ++it) {
+ const CSSProperty& current = *it;
+ // give special priority to font-xxx, color properties
+ if (isImportant == current.isImportant()) {
+ bool first;
+ switch (current.id()) {
+ case CSS_PROP_LINE_HEIGHT:
+ m_lineHeightValue = current.value();
+ first = !applyFirst; // we apply line-height later
+ break;
+ case CSS_PROP_COLOR:
+ case CSS_PROP_DIRECTION:
+ case CSS_PROP_DISPLAY:
+ case CSS_PROP_FONT:
+ case CSS_PROP_FONT_SIZE:
+ case CSS_PROP_FONT_STYLE:
+ case CSS_PROP_FONT_FAMILY:
+ case CSS_PROP_FONT_WEIGHT:
+ case CSS_PROP__WEBKIT_TEXT_SIZE_ADJUST:
+ case CSS_PROP_FONT_VARIANT:
+ // these have to be applied first, because other properties use the computed
+ // values of these porperties.
+ first = true;
+ break;
+ default:
+ first = false;
+ break;
+ }
+ if (first == applyFirst)
+ applyProperty(current.id(), current.value());
+ }
+ }
+ }
+}
+
+static void applyCounterList(RenderStyle* style, CSSValueList* list, bool isReset)
+{
+ CounterDirectiveMap& map = style->accessCounterDirectives();
+ typedef CounterDirectiveMap::iterator Iterator;
+
+ Iterator end = map.end();
+ for (Iterator it = map.begin(); it != end; ++it)
+ if (isReset)
+ it->second.m_reset = false;
+ else
+ it->second.m_increment = false;
+
+ int length = list ? list->length() : 0;
+ for (int i = 0; i < length; ++i) {
+ Pair* pair = static_cast<CSSPrimitiveValue*>(list->item(i))->getPairValue();
+ AtomicString identifier = static_cast<CSSPrimitiveValue*>(pair->first())->getStringValue();
+ // FIXME: What about overflow?
+ int value = static_cast<CSSPrimitiveValue*>(pair->second())->getIntValue();
+ CounterDirectives& directives = map.add(identifier.impl(), CounterDirectives()).first->second;
+ if (isReset) {
+ directives.m_reset = true;
+ directives.m_resetValue = value;
+ } else {
+ if (directives.m_increment)
+ directives.m_incrementValue += value;
+ else {
+ directives.m_increment = true;
+ directives.m_incrementValue = value;
+ }
+ }
+ }
+}
+
+void CSSStyleSelector::applyProperty(int id, CSSValue *value)
+{
+ CSSPrimitiveValue* primitiveValue = 0;
+ if (value->isPrimitiveValue())
+ primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+
+ Length l;
+ bool apply = false;
+
+ unsigned short valueType = value->cssValueType();
+
+ bool isInherit = m_parentNode && valueType == CSSValue::CSS_INHERIT;
+ bool isInitial = valueType == CSSValue::CSS_INITIAL || (!m_parentNode && valueType == CSSValue::CSS_INHERIT);
+
+ // These properties are used to set the correct margins/padding on RTL lists.
+ if (id == CSS_PROP__WEBKIT_MARGIN_START)
+ id = m_style->direction() == LTR ? CSS_PROP_MARGIN_LEFT : CSS_PROP_MARGIN_RIGHT;
+ else if (id == CSS_PROP__WEBKIT_PADDING_START)
+ id = m_style->direction() == LTR ? CSS_PROP_PADDING_LEFT : CSS_PROP_PADDING_RIGHT;
+
+ // What follows is a list that maps the CSS properties into their corresponding front-end
+ // RenderStyle values. Shorthands (e.g. border, background) occur in this list as well and
+ // are only hit when mapping "inherit" or "initial" into front-end values.
+ switch (static_cast<CSSPropertyID>(id)) {
+// ident only properties
+ case CSS_PROP_BACKGROUND_ATTACHMENT:
+ HANDLE_BACKGROUND_VALUE(backgroundAttachment, BackgroundAttachment, value)
+ return;
+ case CSS_PROP__WEBKIT_BACKGROUND_CLIP:
+ HANDLE_BACKGROUND_VALUE(backgroundClip, BackgroundClip, value)
+ return;
+ case CSS_PROP__WEBKIT_BACKGROUND_COMPOSITE:
+ HANDLE_BACKGROUND_VALUE(backgroundComposite, BackgroundComposite, value)
+ return;
+ case CSS_PROP__WEBKIT_BACKGROUND_ORIGIN:
+ HANDLE_BACKGROUND_VALUE(backgroundOrigin, BackgroundOrigin, value)
+ return;
+ case CSS_PROP_BACKGROUND_REPEAT:
+ HANDLE_BACKGROUND_VALUE(backgroundRepeat, BackgroundRepeat, value)
+ return;
+ case CSS_PROP__WEBKIT_BACKGROUND_SIZE:
+ HANDLE_BACKGROUND_VALUE(backgroundSize, BackgroundSize, value)
+ return;
+ case CSS_PROP_BORDER_COLLAPSE:
+ HANDLE_INHERIT_AND_INITIAL(borderCollapse, BorderCollapse)
+ if (!primitiveValue)
+ return;
+ switch (primitiveValue->getIdent()) {
+ case CSS_VAL_COLLAPSE:
+ m_style->setBorderCollapse(true);
+ break;
+ case CSS_VAL_SEPARATE:
+ m_style->setBorderCollapse(false);
+ break;
+ default:
+ return;
+ }
+ return;
+
+ case CSS_PROP_BORDER_TOP_STYLE:
+ HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderTopStyle, BorderTopStyle, BorderStyle)
+ if (primitiveValue)
+ m_style->setBorderTopStyle(*primitiveValue);
+ return;
+ case CSS_PROP_BORDER_RIGHT_STYLE:
+ HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderRightStyle, BorderRightStyle, BorderStyle)
+ if (primitiveValue)
+ m_style->setBorderRightStyle(*primitiveValue);
+ return;
+ case CSS_PROP_BORDER_BOTTOM_STYLE:
+ HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderBottomStyle, BorderBottomStyle, BorderStyle)
+ if (primitiveValue)
+ m_style->setBorderBottomStyle(*primitiveValue);
+ return;
+ case CSS_PROP_BORDER_LEFT_STYLE:
+ HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderLeftStyle, BorderLeftStyle, BorderStyle)
+ if (primitiveValue)
+ m_style->setBorderLeftStyle(*primitiveValue);
+ return;
+ case CSS_PROP_OUTLINE_STYLE:
+ HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(outlineStyle, OutlineStyle, BorderStyle)
+ if (primitiveValue) {
+ if (primitiveValue->getIdent() == CSS_VAL_AUTO)
+ m_style->setOutlineStyle(DOTTED, true);
+ else
+ m_style->setOutlineStyle(*primitiveValue);
+ }
+ return;
+ case CSS_PROP_CAPTION_SIDE:
+ {
+ HANDLE_INHERIT_AND_INITIAL(captionSide, CaptionSide)
+ if (primitiveValue)
+ m_style->setCaptionSide(*primitiveValue);
+ return;
+ }
+ case CSS_PROP_CLEAR:
+ {
+ HANDLE_INHERIT_AND_INITIAL(clear, Clear)
+ if (primitiveValue)
+ m_style->setClear(*primitiveValue);
+ return;
+ }
+ case CSS_PROP_DIRECTION:
+ {
+ HANDLE_INHERIT_AND_INITIAL(direction, Direction)
+ if (primitiveValue)
+ m_style->setDirection(*primitiveValue);
+ return;
+ }
+ case CSS_PROP_DISPLAY:
+ {
+ HANDLE_INHERIT_AND_INITIAL(display, Display)
+ if (primitiveValue)
+ m_style->setDisplay(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP_EMPTY_CELLS:
+ {
+ HANDLE_INHERIT_AND_INITIAL(emptyCells, EmptyCells)
+ if (primitiveValue)
+ m_style->setEmptyCells(*primitiveValue);
+ return;
+ }
+ case CSS_PROP_FLOAT:
+ {
+ HANDLE_INHERIT_AND_INITIAL(floating, Floating)
+ if (primitiveValue)
+ m_style->setFloating(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP_FONT_STYLE:
+ {
+ FontDescription fontDescription = m_style->fontDescription();
+ if (isInherit)
+ fontDescription.setItalic(m_parentStyle->fontDescription().italic());
+ else if (isInitial)
+ fontDescription.setItalic(false);
+ else {
+ if (!primitiveValue)
+ return;
+ switch (primitiveValue->getIdent()) {
+ case CSS_VAL_OBLIQUE:
+ // FIXME: oblique is the same as italic for the moment...
+ case CSS_VAL_ITALIC:
+ fontDescription.setItalic(true);
+ break;
+ case CSS_VAL_NORMAL:
+ fontDescription.setItalic(false);
+ break;
+ default:
+ return;
+ }
+ }
+ if (m_style->setFontDescription(fontDescription))
+ m_fontDirty = true;
+ return;
+ }
+
+ case CSS_PROP_FONT_VARIANT:
+ {
+ FontDescription fontDescription = m_style->fontDescription();
+ if (isInherit)
+ fontDescription.setSmallCaps(m_parentStyle->fontDescription().smallCaps());
+ else if (isInitial)
+ fontDescription.setSmallCaps(false);
+ else {
+ if (!primitiveValue)
+ return;
+ int id = primitiveValue->getIdent();
+ if (id == CSS_VAL_NORMAL)
+ fontDescription.setSmallCaps(false);
+ else if (id == CSS_VAL_SMALL_CAPS)
+ fontDescription.setSmallCaps(true);
+ else
+ return;
+ }
+ if (m_style->setFontDescription(fontDescription))
+ m_fontDirty = true;
+ return;
+ }
+
+ case CSS_PROP_FONT_WEIGHT:
+ {
+ FontDescription fontDescription = m_style->fontDescription();
+ if (isInherit)
+ fontDescription.setWeight(m_parentStyle->fontDescription().weight());
+ else if (isInitial)
+ fontDescription.setWeight(cNormalWeight);
+ else {
+ if (!primitiveValue)
+ return;
+ if (primitiveValue->getIdent()) {
+ switch (primitiveValue->getIdent()) {
+ // FIXME: We aren't genuinely supporting specific weight values.
+ case CSS_VAL_BOLD:
+ case CSS_VAL_BOLDER:
+ case CSS_VAL_600:
+ case CSS_VAL_700:
+ case CSS_VAL_800:
+ case CSS_VAL_900:
+ fontDescription.setWeight(cBoldWeight);
+ break;
+ case CSS_VAL_NORMAL:
+ case CSS_VAL_LIGHTER:
+ case CSS_VAL_100:
+ case CSS_VAL_200:
+ case CSS_VAL_300:
+ case CSS_VAL_400:
+ case CSS_VAL_500:
+ fontDescription.setWeight(cNormalWeight);
+ break;
+ default:
+ return;
+ }
+ }
+ else
+ {
+ // ### fix parsing of 100-900 values in parser, apply them here
+ }
+ }
+ if (m_style->setFontDescription(fontDescription))
+ m_fontDirty = true;
+ return;
+ }
+
+ case CSS_PROP_LIST_STYLE_POSITION:
+ {
+ HANDLE_INHERIT_AND_INITIAL(listStylePosition, ListStylePosition)
+ if (primitiveValue)
+ m_style->setListStylePosition(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP_LIST_STYLE_TYPE:
+ {
+ HANDLE_INHERIT_AND_INITIAL(listStyleType, ListStyleType)
+ if (primitiveValue)
+ m_style->setListStyleType(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP_OVERFLOW:
+ {
+ if (isInherit) {
+ m_style->setOverflowX(m_parentStyle->overflowX());
+ m_style->setOverflowY(m_parentStyle->overflowY());
+ return;
+ }
+
+ if (isInitial) {
+ m_style->setOverflowX(RenderStyle::initialOverflowX());
+ m_style->setOverflowY(RenderStyle::initialOverflowY());
+ return;
+ }
+
+ EOverflow o = *primitiveValue;
+
+ m_style->setOverflowX(o);
+ m_style->setOverflowY(o);
+ return;
+ }
+
+ case CSS_PROP_OVERFLOW_X:
+ {
+ HANDLE_INHERIT_AND_INITIAL(overflowX, OverflowX)
+ m_style->setOverflowX(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP_OVERFLOW_Y:
+ {
+ HANDLE_INHERIT_AND_INITIAL(overflowY, OverflowY)
+ m_style->setOverflowY(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP_PAGE_BREAK_BEFORE:
+ {
+ HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakBefore, PageBreakBefore, PageBreak)
+ if (primitiveValue)
+ m_style->setPageBreakBefore(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP_PAGE_BREAK_AFTER:
+ {
+ HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakAfter, PageBreakAfter, PageBreak)
+ if (primitiveValue)
+ m_style->setPageBreakAfter(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP_PAGE_BREAK_INSIDE: {
+ HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakInside, PageBreakInside, PageBreak)
+ if (!primitiveValue)
+ return;
+ EPageBreak pageBreak = *primitiveValue;
+ if (pageBreak != PBALWAYS)
+ m_style->setPageBreakInside(pageBreak);
+ return;
+ }
+
+ case CSS_PROP_POSITION:
+ {
+ HANDLE_INHERIT_AND_INITIAL(position, Position)
+ if (primitiveValue)
+ m_style->setPosition(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP_TABLE_LAYOUT: {
+ HANDLE_INHERIT_AND_INITIAL(tableLayout, TableLayout)
+
+ ETableLayout l = *primitiveValue;
+ if (l == TAUTO)
+ l = RenderStyle::initialTableLayout();
+
+ m_style->setTableLayout(l);
+ return;
+ }
+
+ case CSS_PROP_UNICODE_BIDI: {
+ HANDLE_INHERIT_AND_INITIAL(unicodeBidi, UnicodeBidi)
+ m_style->setUnicodeBidi(*primitiveValue);
+ return;
+ }
+ case CSS_PROP_TEXT_TRANSFORM: {
+ HANDLE_INHERIT_AND_INITIAL(textTransform, TextTransform)
+ m_style->setTextTransform(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP_VISIBILITY:
+ {
+ HANDLE_INHERIT_AND_INITIAL(visibility, Visibility)
+ m_style->setVisibility(*primitiveValue);
+ return;
+ }
+ case CSS_PROP_WHITE_SPACE:
+ HANDLE_INHERIT_AND_INITIAL(whiteSpace, WhiteSpace)
+ m_style->setWhiteSpace(*primitiveValue);
+ return;
+
+ case CSS_PROP_BACKGROUND_POSITION:
+ HANDLE_BACKGROUND_INHERIT_AND_INITIAL(backgroundXPosition, BackgroundXPosition);
+ HANDLE_BACKGROUND_INHERIT_AND_INITIAL(backgroundYPosition, BackgroundYPosition);
+ return;
+ case CSS_PROP_BACKGROUND_POSITION_X: {
+ HANDLE_BACKGROUND_VALUE(backgroundXPosition, BackgroundXPosition, value)
+ return;
+ }
+ case CSS_PROP_BACKGROUND_POSITION_Y: {
+ HANDLE_BACKGROUND_VALUE(backgroundYPosition, BackgroundYPosition, value)
+ return;
+ }
+ case CSS_PROP_BORDER_SPACING: {
+ if (isInherit) {
+ m_style->setHorizontalBorderSpacing(m_parentStyle->horizontalBorderSpacing());
+ m_style->setVerticalBorderSpacing(m_parentStyle->verticalBorderSpacing());
+ }
+ else if (isInitial) {
+ m_style->setHorizontalBorderSpacing(0);
+ m_style->setVerticalBorderSpacing(0);
+ }
+ return;
+ }
+ case CSS_PROP__WEBKIT_BORDER_HORIZONTAL_SPACING: {
+ HANDLE_INHERIT_AND_INITIAL(horizontalBorderSpacing, HorizontalBorderSpacing)
+ if (!primitiveValue)
+ return;
+ short spacing = primitiveValue->computeLengthShort(m_style);
+ m_style->setHorizontalBorderSpacing(spacing);
+ return;
+ }
+ case CSS_PROP__WEBKIT_BORDER_VERTICAL_SPACING: {
+ HANDLE_INHERIT_AND_INITIAL(verticalBorderSpacing, VerticalBorderSpacing)
+ if (!primitiveValue)
+ return;
+ short spacing = primitiveValue->computeLengthShort(m_style);
+ m_style->setVerticalBorderSpacing(spacing);
+ return;
+ }
+ case CSS_PROP_CURSOR:
+ if (isInherit) {
+ m_style->setCursor(m_parentStyle->cursor());
+ m_style->setCursorList(m_parentStyle->cursors());
+ return;
+ }
+ m_style->clearCursorList();
+ if (isInitial) {
+ m_style->setCursor(RenderStyle::initialCursor());
+ return;
+ }
+ if (value->isValueList()) {
+ CSSValueList* list = static_cast<CSSValueList*>(value);
+ int len = list->length();
+ m_style->setCursor(CURSOR_AUTO);
+ for (int i = 0; i < len; i++) {
+ CSSValue* item = list->item(i);
+ if (!item->isPrimitiveValue())
+ continue;
+ primitiveValue = static_cast<CSSPrimitiveValue*>(item);
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_URI) {
+ CSSCursorImageValue* image = static_cast<CSSCursorImageValue*>(primitiveValue);
+ if (image->updateIfSVGCursorIsUsed(m_element)) // Elements with SVG cursors are not allowed to share style.
+ m_style->setUnique();
+ m_style->addCursor(image->image(m_element->document()->docLoader()), image->hotspot());
+ } else if (type == CSSPrimitiveValue::CSS_IDENT)
+ m_style->setCursor(*primitiveValue);
+ }
+ } else if (primitiveValue) {
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_IDENT)
+ m_style->setCursor(*primitiveValue);
+ }
+ return;
+// colors || inherit
+ case CSS_PROP_BACKGROUND_COLOR:
+ case CSS_PROP_BORDER_TOP_COLOR:
+ case CSS_PROP_BORDER_RIGHT_COLOR:
+ case CSS_PROP_BORDER_BOTTOM_COLOR:
+ case CSS_PROP_BORDER_LEFT_COLOR:
+ case CSS_PROP_COLOR:
+ case CSS_PROP_OUTLINE_COLOR:
+ case CSS_PROP__WEBKIT_COLUMN_RULE_COLOR:
+ case CSS_PROP__WEBKIT_TEXT_STROKE_COLOR:
+ case CSS_PROP__WEBKIT_TEXT_FILL_COLOR: {
+ Color col;
+ if (isInherit) {
+ HANDLE_INHERIT_COND(CSS_PROP_BACKGROUND_COLOR, backgroundColor, BackgroundColor)
+ HANDLE_INHERIT_COND(CSS_PROP_BORDER_TOP_COLOR, borderTopColor, BorderTopColor)
+ HANDLE_INHERIT_COND(CSS_PROP_BORDER_BOTTOM_COLOR, borderBottomColor, BorderBottomColor)
+ HANDLE_INHERIT_COND(CSS_PROP_BORDER_RIGHT_COLOR, borderRightColor, BorderRightColor)
+ HANDLE_INHERIT_COND(CSS_PROP_BORDER_LEFT_COLOR, borderLeftColor, BorderLeftColor)
+ HANDLE_INHERIT_COND(CSS_PROP_COLOR, color, Color)
+ HANDLE_INHERIT_COND(CSS_PROP_OUTLINE_COLOR, outlineColor, OutlineColor)
+ HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_COLUMN_RULE_COLOR, columnRuleColor, ColumnRuleColor)
+ HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_TEXT_STROKE_COLOR, textStrokeColor, TextStrokeColor)
+ HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_TEXT_FILL_COLOR, textFillColor, TextFillColor)
+ return;
+ }
+ if (isInitial) {
+ // The border/outline colors will just map to the invalid color |col| above. This will have the
+ // effect of forcing the use of the currentColor when it comes time to draw the borders (and of
+ // not painting the background since the color won't be valid).
+ if (id == CSS_PROP_COLOR)
+ col = RenderStyle::initialColor();
+ } else {
+ if (!primitiveValue)
+ return;
+ col = getColorFromPrimitiveValue(primitiveValue);
+ }
+
+ switch (id) {
+ case CSS_PROP_BACKGROUND_COLOR:
+ m_style->setBackgroundColor(col);
+ break;
+ case CSS_PROP_BORDER_TOP_COLOR:
+ m_style->setBorderTopColor(col);
+ break;
+ case CSS_PROP_BORDER_RIGHT_COLOR:
+ m_style->setBorderRightColor(col);
+ break;
+ case CSS_PROP_BORDER_BOTTOM_COLOR:
+ m_style->setBorderBottomColor(col);
+ break;
+ case CSS_PROP_BORDER_LEFT_COLOR:
+ m_style->setBorderLeftColor(col);
+ break;
+ case CSS_PROP_COLOR:
+ m_style->setColor(col);
+ break;
+ case CSS_PROP_OUTLINE_COLOR:
+ m_style->setOutlineColor(col);
+ break;
+ case CSS_PROP__WEBKIT_COLUMN_RULE_COLOR:
+ m_style->setColumnRuleColor(col);
+ break;
+ case CSS_PROP__WEBKIT_TEXT_STROKE_COLOR:
+ m_style->setTextStrokeColor(col);
+ break;
+ case CSS_PROP__WEBKIT_TEXT_FILL_COLOR:
+ m_style->setTextFillColor(col);
+ break;
+ }
+
+ return;
+ }
+
+// uri || inherit
+ case CSS_PROP_BACKGROUND_IMAGE:
+ HANDLE_BACKGROUND_VALUE(backgroundImage, BackgroundImage, value)
+ return;
+ case CSS_PROP_LIST_STYLE_IMAGE:
+ {
+ HANDLE_INHERIT_AND_INITIAL(listStyleImage, ListStyleImage)
+ if (!primitiveValue)
+ return;
+ m_style->setListStyleImage(static_cast<CSSImageValue*>(primitiveValue)->image(m_element->document()->docLoader()));
+ return;
+ }
+
+// length
+ case CSS_PROP_BORDER_TOP_WIDTH:
+ case CSS_PROP_BORDER_RIGHT_WIDTH:
+ case CSS_PROP_BORDER_BOTTOM_WIDTH:
+ case CSS_PROP_BORDER_LEFT_WIDTH:
+ case CSS_PROP_OUTLINE_WIDTH:
+ case CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH:
+ {
+ if (isInherit) {
+ HANDLE_INHERIT_COND(CSS_PROP_BORDER_TOP_WIDTH, borderTopWidth, BorderTopWidth)
+ HANDLE_INHERIT_COND(CSS_PROP_BORDER_RIGHT_WIDTH, borderRightWidth, BorderRightWidth)
+ HANDLE_INHERIT_COND(CSS_PROP_BORDER_BOTTOM_WIDTH, borderBottomWidth, BorderBottomWidth)
+ HANDLE_INHERIT_COND(CSS_PROP_BORDER_LEFT_WIDTH, borderLeftWidth, BorderLeftWidth)
+ HANDLE_INHERIT_COND(CSS_PROP_OUTLINE_WIDTH, outlineWidth, OutlineWidth)
+ HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH, columnRuleWidth, ColumnRuleWidth)
+ return;
+ }
+ else if (isInitial) {
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_TOP_WIDTH, BorderTopWidth, BorderWidth)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_RIGHT_WIDTH, BorderRightWidth, BorderWidth)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_BOTTOM_WIDTH, BorderBottomWidth, BorderWidth)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_LEFT_WIDTH, BorderLeftWidth, BorderWidth)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_OUTLINE_WIDTH, OutlineWidth, BorderWidth)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH, ColumnRuleWidth, BorderWidth)
+ return;
+ }
+
+ if (!primitiveValue)
+ return;
+ short width = 3;
+ switch (primitiveValue->getIdent()) {
+ case CSS_VAL_THIN:
+ width = 1;
+ break;
+ case CSS_VAL_MEDIUM:
+ width = 3;
+ break;
+ case CSS_VAL_THICK:
+ width = 5;
+ break;
+ case CSS_VAL_INVALID:
+ width = primitiveValue->computeLengthShort(m_style);
+ break;
+ default:
+ return;
+ }
+
+ if (width < 0) return;
+ switch (id) {
+ case CSS_PROP_BORDER_TOP_WIDTH:
+ m_style->setBorderTopWidth(width);
+ break;
+ case CSS_PROP_BORDER_RIGHT_WIDTH:
+ m_style->setBorderRightWidth(width);
+ break;
+ case CSS_PROP_BORDER_BOTTOM_WIDTH:
+ m_style->setBorderBottomWidth(width);
+ break;
+ case CSS_PROP_BORDER_LEFT_WIDTH:
+ m_style->setBorderLeftWidth(width);
+ break;
+ case CSS_PROP_OUTLINE_WIDTH:
+ m_style->setOutlineWidth(width);
+ break;
+ case CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH:
+ m_style->setColumnRuleWidth(width);
+ break;
+ default:
+ return;
+ }
+ return;
+ }
+
+ case CSS_PROP_LETTER_SPACING:
+ case CSS_PROP_WORD_SPACING:
+ {
+
+ if (isInherit) {
+ HANDLE_INHERIT_COND(CSS_PROP_LETTER_SPACING, letterSpacing, LetterSpacing)
+ HANDLE_INHERIT_COND(CSS_PROP_WORD_SPACING, wordSpacing, WordSpacing)
+ return;
+ }
+ else if (isInitial) {
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_LETTER_SPACING, LetterSpacing, LetterWordSpacing)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_WORD_SPACING, WordSpacing, LetterWordSpacing)
+ return;
+ }
+
+ int width = 0;
+ if (primitiveValue && primitiveValue->getIdent() == CSS_VAL_NORMAL){
+ width = 0;
+ } else {
+ if (!primitiveValue)
+ return;
+ width = primitiveValue->computeLengthInt(m_style);
+ }
+ switch (id) {
+ case CSS_PROP_LETTER_SPACING:
+ m_style->setLetterSpacing(width);
+ break;
+ case CSS_PROP_WORD_SPACING:
+ m_style->setWordSpacing(width);
+ break;
+ // ### needs the definitions in renderstyle
+ default: break;
+ }
+ return;
+ }
+
+ case CSS_PROP_WORD_BREAK: {
+ HANDLE_INHERIT_AND_INITIAL(wordBreak, WordBreak)
+ m_style->setWordBreak(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP_WORD_WRAP: {
+ HANDLE_INHERIT_AND_INITIAL(wordWrap, WordWrap)
+ m_style->setWordWrap(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP__WEBKIT_NBSP_MODE:
+ {
+ HANDLE_INHERIT_AND_INITIAL(nbspMode, NBSPMode)
+ m_style->setNBSPMode(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP__WEBKIT_LINE_BREAK:
+ {
+ HANDLE_INHERIT_AND_INITIAL(khtmlLineBreak, KHTMLLineBreak)
+ m_style->setKHTMLLineBreak(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP__WEBKIT_MATCH_NEAREST_MAIL_BLOCKQUOTE_COLOR:
+ {
+ HANDLE_INHERIT_AND_INITIAL(matchNearestMailBlockquoteColor, MatchNearestMailBlockquoteColor)
+ m_style->setMatchNearestMailBlockquoteColor(*primitiveValue);
+ return;
+ }
+
+ case CSS_PROP_RESIZE:
+ {
+ HANDLE_INHERIT_AND_INITIAL(resize, Resize)
+
+ if (!primitiveValue->getIdent())
+ return;
+
+ EResize r = RESIZE_NONE;
+ if (primitiveValue->getIdent() == CSS_VAL_AUTO) {
+ if (Settings* settings = m_document->settings())
+ r = settings->textAreasAreResizable() ? RESIZE_BOTH : RESIZE_NONE;
+ } else
+ r = *primitiveValue;
+
+ m_style->setResize(r);
+ return;
+ }
+
+ // length, percent
+ case CSS_PROP_MAX_WIDTH:
+ // +none +inherit
+ if (primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)
+ apply = true;
+ case CSS_PROP_TOP:
+ case CSS_PROP_LEFT:
+ case CSS_PROP_RIGHT:
+ case CSS_PROP_BOTTOM:
+ case CSS_PROP_WIDTH:
+ case CSS_PROP_MIN_WIDTH:
+ case CSS_PROP_MARGIN_TOP:
+ case CSS_PROP_MARGIN_RIGHT:
+ case CSS_PROP_MARGIN_BOTTOM:
+ case CSS_PROP_MARGIN_LEFT:
+ // +inherit +auto
+ if (id == CSS_PROP_WIDTH || id == CSS_PROP_MIN_WIDTH || id == CSS_PROP_MAX_WIDTH) {
+ if (primitiveValue && primitiveValue->getIdent() == CSS_VAL_INTRINSIC) {
+ l = Length(Intrinsic);
+ apply = true;
+ }
+ else if (primitiveValue && primitiveValue->getIdent() == CSS_VAL_MIN_INTRINSIC) {
+ l = Length(MinIntrinsic);
+ apply = true;
+ }
+ }
+ if (id != CSS_PROP_MAX_WIDTH && primitiveValue && primitiveValue->getIdent() == CSS_VAL_AUTO)
+ apply = true;
+ case CSS_PROP_PADDING_TOP:
+ case CSS_PROP_PADDING_RIGHT:
+ case CSS_PROP_PADDING_BOTTOM:
+ case CSS_PROP_PADDING_LEFT:
+ case CSS_PROP_TEXT_INDENT:
+ // +inherit
+ {
+ if (isInherit) {
+ HANDLE_INHERIT_COND(CSS_PROP_MAX_WIDTH, maxWidth, MaxWidth)
+ HANDLE_INHERIT_COND(CSS_PROP_BOTTOM, bottom, Bottom)
+ HANDLE_INHERIT_COND(CSS_PROP_TOP, top, Top)
+ HANDLE_INHERIT_COND(CSS_PROP_LEFT, left, Left)
+ HANDLE_INHERIT_COND(CSS_PROP_RIGHT, right, Right)
+ HANDLE_INHERIT_COND(CSS_PROP_WIDTH, width, Width)
+ HANDLE_INHERIT_COND(CSS_PROP_MIN_WIDTH, minWidth, MinWidth)
+ HANDLE_INHERIT_COND(CSS_PROP_PADDING_TOP, paddingTop, PaddingTop)
+ HANDLE_INHERIT_COND(CSS_PROP_PADDING_RIGHT, paddingRight, PaddingRight)
+ HANDLE_INHERIT_COND(CSS_PROP_PADDING_BOTTOM, paddingBottom, PaddingBottom)
+ HANDLE_INHERIT_COND(CSS_PROP_PADDING_LEFT, paddingLeft, PaddingLeft)
+ HANDLE_INHERIT_COND(CSS_PROP_MARGIN_TOP, marginTop, MarginTop)
+ HANDLE_INHERIT_COND(CSS_PROP_MARGIN_RIGHT, marginRight, MarginRight)
+ HANDLE_INHERIT_COND(CSS_PROP_MARGIN_BOTTOM, marginBottom, MarginBottom)
+ HANDLE_INHERIT_COND(CSS_PROP_MARGIN_LEFT, marginLeft, MarginLeft)
+ HANDLE_INHERIT_COND(CSS_PROP_TEXT_INDENT, textIndent, TextIndent)
+ return;
+ }
+ else if (isInitial) {
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MAX_WIDTH, MaxWidth, MaxSize)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BOTTOM, Bottom, Offset)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_TOP, Top, Offset)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_LEFT, Left, Offset)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_RIGHT, Right, Offset)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_WIDTH, Width, Size)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MIN_WIDTH, MinWidth, MinSize)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_TOP, PaddingTop, Padding)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_RIGHT, PaddingRight, Padding)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_BOTTOM, PaddingBottom, Padding)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_LEFT, PaddingLeft, Padding)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_TOP, MarginTop, Margin)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_RIGHT, MarginRight, Margin)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_BOTTOM, MarginBottom, Margin)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_LEFT, MarginLeft, Margin)
+ HANDLE_INITIAL_COND(CSS_PROP_TEXT_INDENT, TextIndent)
+ return;
+ }
+
+ if (primitiveValue && !apply) {
+ int type = primitiveValue->primitiveType();
+ if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ // Handle our quirky margin units if we have them.
+ l = Length(primitiveValue->computeLengthIntForLength(m_style), Fixed,
+ primitiveValue->isQuirkValue());
+ else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ l = Length(primitiveValue->getDoubleValue(), Percent);
+ else
+ return;
+ if (id == CSS_PROP_PADDING_LEFT || id == CSS_PROP_PADDING_RIGHT ||
+ id == CSS_PROP_PADDING_TOP || id == CSS_PROP_PADDING_BOTTOM)
+ // Padding can't be negative
+ apply = !((l.isFixed() || l.isPercent()) && l.calcValue(100) < 0);
+ else
+ apply = true;
+ }
+ if (!apply) return;
+ switch (id) {
+ case CSS_PROP_MAX_WIDTH:
+ m_style->setMaxWidth(l);
+ break;
+ case CSS_PROP_BOTTOM:
+ m_style->setBottom(l);
+ break;
+ case CSS_PROP_TOP:
+ m_style->setTop(l);
+ break;
+ case CSS_PROP_LEFT:
+ m_style->setLeft(l);
+ break;
+ case CSS_PROP_RIGHT:
+ m_style->setRight(l);
+ break;
+ case CSS_PROP_WIDTH:
+ m_style->setWidth(l);
+ break;
+ case CSS_PROP_MIN_WIDTH:
+ m_style->setMinWidth(l);
+ break;
+ case CSS_PROP_PADDING_TOP:
+ m_style->setPaddingTop(l);
+ break;
+ case CSS_PROP_PADDING_RIGHT:
+ m_style->setPaddingRight(l);
+ break;
+ case CSS_PROP_PADDING_BOTTOM:
+ m_style->setPaddingBottom(l);
+ break;
+ case CSS_PROP_PADDING_LEFT:
+ m_style->setPaddingLeft(l);
+ break;
+ case CSS_PROP_MARGIN_TOP:
+ m_style->setMarginTop(l);
+ break;
+ case CSS_PROP_MARGIN_RIGHT:
+ m_style->setMarginRight(l);
+ break;
+ case CSS_PROP_MARGIN_BOTTOM:
+ m_style->setMarginBottom(l);
+ break;
+ case CSS_PROP_MARGIN_LEFT:
+ m_style->setMarginLeft(l);
+ break;
+ case CSS_PROP_TEXT_INDENT:
+ m_style->setTextIndent(l);
+ break;
+ default:
+ break;
+ }
+ return;
+ }
+
+ case CSS_PROP_MAX_HEIGHT:
+ if (primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) {
+ l = Length(undefinedLength, Fixed);
+ apply = true;
+ }
+ case CSS_PROP_HEIGHT:
+ case CSS_PROP_MIN_HEIGHT:
+ if (primitiveValue && primitiveValue->getIdent() == CSS_VAL_INTRINSIC) {
+ l = Length(Intrinsic);
+ apply = true;
+ } else if (primitiveValue && primitiveValue->getIdent() == CSS_VAL_MIN_INTRINSIC) {
+ l = Length(MinIntrinsic);
+ apply = true;
+ } else if (id != CSS_PROP_MAX_HEIGHT && primitiveValue && primitiveValue->getIdent() == CSS_VAL_AUTO)
+ apply = true;
+ if (isInherit) {
+ HANDLE_INHERIT_COND(CSS_PROP_MAX_HEIGHT, maxHeight, MaxHeight)
+ HANDLE_INHERIT_COND(CSS_PROP_HEIGHT, height, Height)
+ HANDLE_INHERIT_COND(CSS_PROP_MIN_HEIGHT, minHeight, MinHeight)
+ return;
+ }
+ if (isInitial) {
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MAX_HEIGHT, MaxHeight, MaxSize)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_HEIGHT, Height, Size)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MIN_HEIGHT, MinHeight, MinSize)
+ return;
+ }
+
+ if (primitiveValue && !apply) {
+ unsigned short type = primitiveValue->primitiveType();
+ if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ l = Length(primitiveValue->computeLengthIntForLength(m_style), Fixed);
+ else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ l = Length(primitiveValue->getDoubleValue(), Percent);
+ else
+ return;
+ apply = true;
+ }
+ if (apply)
+ switch (id) {
+ case CSS_PROP_MAX_HEIGHT:
+ m_style->setMaxHeight(l);
+ break;
+ case CSS_PROP_HEIGHT:
+ m_style->setHeight(l);
+ break;
+ case CSS_PROP_MIN_HEIGHT:
+ m_style->setMinHeight(l);
+ break;
+ }
+ return;
+
+ case CSS_PROP_VERTICAL_ALIGN:
+ HANDLE_INHERIT_AND_INITIAL(verticalAlign, VerticalAlign)
+ if (!primitiveValue)
+ return;
+ if (primitiveValue->getIdent()) {
+ EVerticalAlign align;
+
+ switch (primitiveValue->getIdent()) {
+ case CSS_VAL_TOP:
+ align = TOP; break;
+ case CSS_VAL_BOTTOM:
+ align = BOTTOM; break;
+ case CSS_VAL_MIDDLE:
+ align = MIDDLE; break;
+ case CSS_VAL_BASELINE:
+ align = BASELINE; break;
+ case CSS_VAL_TEXT_BOTTOM:
+ align = TEXT_BOTTOM; break;
+ case CSS_VAL_TEXT_TOP:
+ align = TEXT_TOP; break;
+ case CSS_VAL_SUB:
+ align = SUB; break;
+ case CSS_VAL_SUPER:
+ align = SUPER; break;
+ case CSS_VAL__WEBKIT_BASELINE_MIDDLE:
+ align = BASELINE_MIDDLE; break;
+ default:
+ return;
+ }
+ m_style->setVerticalAlign(align);
+ return;
+ } else {
+ int type = primitiveValue->primitiveType();
+ Length l;
+ if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ l = Length(primitiveValue->computeLengthIntForLength(m_style), Fixed);
+ else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ l = Length(primitiveValue->getDoubleValue(), Percent);
+
+ m_style->setVerticalAlign(LENGTH);
+ m_style->setVerticalAlignLength(l);
+ }
+ return;
+
+ case CSS_PROP_FONT_SIZE:
+ {
+ FontDescription fontDescription = m_style->fontDescription();
+ fontDescription.setKeywordSize(0);
+ bool familyIsFixed = fontDescription.genericFamily() == FontDescription::MonospaceFamily;
+ float oldSize = 0;
+ float size = 0;
+
+ bool parentIsAbsoluteSize = false;
+ if (m_parentNode) {
+ oldSize = m_parentStyle->fontDescription().specifiedSize();
+ parentIsAbsoluteSize = m_parentStyle->fontDescription().isAbsoluteSize();
+ }
+
+ if (isInherit) {
+ size = oldSize;
+ if (m_parentNode)
+ fontDescription.setKeywordSize(m_parentStyle->fontDescription().keywordSize());
+ } else if (isInitial) {
+ size = fontSizeForKeyword(CSS_VAL_MEDIUM, m_style->htmlHacks(), familyIsFixed);
+ fontDescription.setKeywordSize(CSS_VAL_MEDIUM - CSS_VAL_XX_SMALL + 1);
+ } else if (primitiveValue->getIdent()) {
+ // Keywords are being used.
+ switch (primitiveValue->getIdent()) {
+ case CSS_VAL_XX_SMALL:
+ case CSS_VAL_X_SMALL:
+ case CSS_VAL_SMALL:
+ case CSS_VAL_MEDIUM:
+ case CSS_VAL_LARGE:
+ case CSS_VAL_X_LARGE:
+ case CSS_VAL_XX_LARGE:
+ case CSS_VAL__WEBKIT_XXX_LARGE:
+ size = fontSizeForKeyword(primitiveValue->getIdent(), m_style->htmlHacks(), familyIsFixed);
+ fontDescription.setKeywordSize(primitiveValue->getIdent() - CSS_VAL_XX_SMALL + 1);
+ break;
+ case CSS_VAL_LARGER:
+ size = largerFontSize(oldSize, m_style->htmlHacks());
+ break;
+ case CSS_VAL_SMALLER:
+ size = smallerFontSize(oldSize, m_style->htmlHacks());
+ break;
+ default:
+ return;
+ }
+
+ fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize &&
+ (primitiveValue->getIdent() == CSS_VAL_LARGER ||
+ primitiveValue->getIdent() == CSS_VAL_SMALLER));
+ } else {
+ int type = primitiveValue->primitiveType();
+ fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize ||
+ (type != CSSPrimitiveValue::CSS_PERCENTAGE &&
+ type != CSSPrimitiveValue::CSS_EMS &&
+ type != CSSPrimitiveValue::CSS_EXS));
+ if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ size = primitiveValue->computeLengthFloat(m_parentStyle, false);
+ else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ size = (primitiveValue->getFloatValue() * oldSize) / 100.0f;
+ else
+ return;
+ }
+
+ if (size < 0)
+ return;
+
+ setFontSize(fontDescription, size);
+ if (m_style->setFontDescription(fontDescription))
+ m_fontDirty = true;
+ return;
+ }
+
+ case CSS_PROP_Z_INDEX: {
+ if (isInherit) {
+ if (m_parentStyle->hasAutoZIndex())
+ m_style->setHasAutoZIndex();
+ else
+ m_style->setZIndex(m_parentStyle->zIndex());
+ return;
+ } else if (isInitial || primitiveValue->getIdent() == CSS_VAL_AUTO) {
+ m_style->setHasAutoZIndex();
+ return;
+ }
+
+ // FIXME: Should clamp all sorts of other integer properties too.
+ const double minIntAsDouble = INT_MIN;
+ const double maxIntAsDouble = INT_MAX;
+ m_style->setZIndex(static_cast<int>(max(minIntAsDouble, min(primitiveValue->getDoubleValue(), maxIntAsDouble))));
+ return;
+ }
+ case CSS_PROP_WIDOWS:
+ {
+ HANDLE_INHERIT_AND_INITIAL(widows, Widows)
+ if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
+ return;
+ m_style->setWidows(primitiveValue->getIntValue());
+ return;
+ }
+
+ case CSS_PROP_ORPHANS:
+ {
+ HANDLE_INHERIT_AND_INITIAL(orphans, Orphans)
+ if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
+ return;
+ m_style->setOrphans(primitiveValue->getIntValue());
+ return;
+ }
+
+// length, percent, number
+ case CSS_PROP_LINE_HEIGHT:
+ {
+ HANDLE_INHERIT_AND_INITIAL(lineHeight, LineHeight)
+ if (!primitiveValue)
+ return;
+ Length lineHeight;
+ int type = primitiveValue->primitiveType();
+ if (primitiveValue->getIdent() == CSS_VAL_NORMAL)
+ lineHeight = Length(-100.0, Percent);
+ else if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) {
+ double multiplier = 1.0;
+ // Scale for the font zoom factor only for types other than "em" and "ex", since those are
+ // already based on the font size.
+ if (type != CSSPrimitiveValue::CSS_EMS && type != CSSPrimitiveValue::CSS_EXS && m_style->textSizeAdjust() && m_document->frame()) {
+ multiplier = m_document->frame()->zoomFactor() / 100.0;
+ }
+ lineHeight = Length(primitiveValue->computeLengthIntForLength(m_style, multiplier), Fixed);
+ } else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ lineHeight = Length((m_style->fontSize() * primitiveValue->getIntValue()) / 100, Fixed);
+ else if (type == CSSPrimitiveValue::CSS_NUMBER)
+ lineHeight = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
+ else
+ return;
+ m_style->setLineHeight(lineHeight);
+ return;
+ }
+
+// string
+ case CSS_PROP_TEXT_ALIGN:
+ {
+ HANDLE_INHERIT_AND_INITIAL(textAlign, TextAlign)
+ if (!primitiveValue)
+ return;
+ int id = primitiveValue->getIdent();
+ if (id == CSS_VAL_START)
+ m_style->setTextAlign(m_style->direction() == LTR ? LEFT : RIGHT);
+ else if (id == CSS_VAL_END)
+ m_style->setTextAlign(m_style->direction() == LTR ? RIGHT : LEFT);
+ else
+ m_style->setTextAlign(*primitiveValue);
+ return;
+ }
+
+// rect
+ case CSS_PROP_CLIP:
+ {
+ 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 = convertToLength(rect->top(), m_style);
+ right = convertToLength(rect->right(), m_style);
+ bottom = convertToLength(rect->bottom(), m_style);
+ left = convertToLength(rect->left(), m_style);
+
+ } else if (primitiveValue->getIdent() != CSS_VAL_AUTO) {
+ return;
+ }
+ m_style->setClip(top, right, bottom, left);
+ m_style->setHasClip(hasClip);
+
+ // rect, ident
+ return;
+ }
+
+// lists
+ case CSS_PROP_CONTENT:
+ // list of string, uri, counter, attr, i
+ {
+ // FIXME: In CSS3, it will be possible to inherit content. In CSS2 it is not. This
+ // note is a reminder that eventually "inherit" needs to be supported.
+
+ if (isInitial) {
+ m_style->clearContent();
+ return;
+ }
+
+ if (!value->isValueList())
+ return;
+
+ CSSValueList* list = static_cast<CSSValueList*>(value);
+ int len = list->length();
+
+ bool didSet = false;
+ for (int i = 0; i < len; i++) {
+ CSSValue* item = list->item(i);
+ if (!item->isPrimitiveValue())
+ continue;
+
+ CSSPrimitiveValue* val = static_cast<CSSPrimitiveValue*>(item);
+ switch (val->primitiveType()) {
+ case CSSPrimitiveValue::CSS_STRING:
+ m_style->setContent(val->getStringValue().impl(), didSet);
+ didSet = true;
+ break;
+ case CSSPrimitiveValue::CSS_ATTR: {
+ // FIXME: Can a namespace be specified for an attr(foo)?
+ if (m_style->styleType() == RenderStyle::NOPSEUDO)
+ m_style->setUnique();
+ else
+ m_parentStyle->setUnique();
+ QualifiedName attr(nullAtom, val->getStringValue().impl(), nullAtom);
+ m_style->setContent(m_element->getAttribute(attr).impl(), didSet);
+ didSet = true;
+ // register the fact that the attribute value affects the style
+ m_selectorAttrs.add(attr.localName().impl());
+ break;
+ }
+ case CSSPrimitiveValue::CSS_URI: {
+ CSSImageValue *image = static_cast<CSSImageValue*>(val);
+ m_style->setContent(image->image(m_element->document()->docLoader()), didSet);
+ didSet = true;
+ break;
+ }
+ case CSSPrimitiveValue::CSS_COUNTER: {
+ Counter* counterValue = val->getCounterValue();
+ CounterContent* counter = new CounterContent(counterValue->identifier(),
+ (EListStyleType)counterValue->listStyleNumber(), counterValue->separator());
+ m_style->setContent(counter, didSet);
+ didSet = true;
+ }
+ }
+ }
+ if (!didSet)
+ m_style->clearContent();
+ return;
+ }
+
+ case CSS_PROP_COUNTER_INCREMENT:
+ applyCounterList(m_style, value->isValueList() ? static_cast<CSSValueList*>(value) : 0, false);
+ return;
+ case CSS_PROP_COUNTER_RESET:
+ applyCounterList(m_style, value->isValueList() ? static_cast<CSSValueList*>(value) : 0, true);
+ return;
+
+ case CSS_PROP_FONT_FAMILY: {
+ // list of strings and ids
+ if (isInherit) {
+ FontDescription parentFontDescription = m_parentStyle->fontDescription();
+ FontDescription fontDescription = m_style->fontDescription();
+ fontDescription.setGenericFamily(parentFontDescription.genericFamily());
+ fontDescription.setFamily(parentFontDescription.firstFamily());
+ if (m_style->setFontDescription(fontDescription))
+ m_fontDirty = true;
+ return;
+ }
+ else if (isInitial) {
+ FontDescription initialDesc = FontDescription();
+ FontDescription fontDescription = m_style->fontDescription();
+ // We need to adjust the size to account for the generic family change from monospace
+ // to non-monospace.
+ if (fontDescription.keywordSize() && fontDescription.genericFamily() == FontDescription::MonospaceFamily)
+ setFontSize(fontDescription, fontSizeForKeyword(CSS_VAL_XX_SMALL + fontDescription.keywordSize() - 1, m_style->htmlHacks(), false));
+ fontDescription.setGenericFamily(initialDesc.genericFamily());
+ fontDescription.setFamily(initialDesc.firstFamily());
+ if (m_style->setFontDescription(fontDescription))
+ m_fontDirty = true;
+ return;
+ }
+
+ if (!value->isValueList()) return;
+ FontDescription fontDescription = m_style->fontDescription();
+ CSSValueList *list = static_cast<CSSValueList*>(value);
+ int len = list->length();
+ FontFamily& firstFamily = fontDescription.firstFamily();
+ FontFamily *currFamily = 0;
+
+ // Before mapping in a new font-family property, we should reset the generic family.
+ bool oldFamilyIsMonospace = fontDescription.genericFamily() == FontDescription::MonospaceFamily;
+ fontDescription.setGenericFamily(FontDescription::NoFamily);
+
+ for (int i = 0; i < len; i++) {
+ CSSValue *item = list->item(i);
+ if (!item->isPrimitiveValue()) continue;
+ CSSPrimitiveValue *val = static_cast<CSSPrimitiveValue*>(item);
+ AtomicString face;
+ Settings* settings = m_document->settings();
+ if (val->primitiveType() == CSSPrimitiveValue::CSS_STRING)
+ face = static_cast<FontFamilyValue*>(val)->familyName();
+ else if (val->primitiveType() == CSSPrimitiveValue::CSS_IDENT && settings) {
+ switch (val->getIdent()) {
+ case CSS_VAL__WEBKIT_BODY:
+ face = settings->standardFontFamily();
+ break;
+ case CSS_VAL_SERIF:
+ face = "-webkit-serif";
+ fontDescription.setGenericFamily(FontDescription::SerifFamily);
+ break;
+ case CSS_VAL_SANS_SERIF:
+ face = "-webkit-sans-serif";
+ fontDescription.setGenericFamily(FontDescription::SansSerifFamily);
+ break;
+ case CSS_VAL_CURSIVE:
+ face = "-webkit-cursive";
+ fontDescription.setGenericFamily(FontDescription::CursiveFamily);
+ break;
+ case CSS_VAL_FANTASY:
+ face = "-webkit-fantasy";
+ fontDescription.setGenericFamily(FontDescription::FantasyFamily);
+ break;
+ case CSS_VAL_MONOSPACE:
+ face = "-webkit-monospace";
+ fontDescription.setGenericFamily(FontDescription::MonospaceFamily);
+ break;
+ }
+ }
+
+ if (!face.isEmpty()) {
+ if (!currFamily) {
+ // Filling in the first family.
+ firstFamily.setFamily(face);
+ currFamily = &firstFamily;
+ }
+ else {
+ FontFamily *newFamily = new FontFamily;
+ newFamily->setFamily(face);
+ currFamily->appendFamily(newFamily);
+ currFamily = newFamily;
+ }
+
+ if (fontDescription.keywordSize() && (fontDescription.genericFamily() == FontDescription::MonospaceFamily) != oldFamilyIsMonospace)
+ setFontSize(fontDescription, fontSizeForKeyword(CSS_VAL_XX_SMALL + fontDescription.keywordSize() - 1, m_style->htmlHacks(), !oldFamilyIsMonospace));
+
+ if (m_style->setFontDescription(fontDescription))
+ m_fontDirty = true;
+ }
+ }
+ return;
+ }
+ case CSS_PROP_TEXT_DECORATION: {
+ // list of ident
+ HANDLE_INHERIT_AND_INITIAL(textDecoration, TextDecoration)
+ int t = RenderStyle::initialTextDecoration();
+ if (primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) {
+ // do nothing
+ } else {
+ if (!value->isValueList()) return;
+ CSSValueList *list = static_cast<CSSValueList*>(value);
+ int len = list->length();
+ for (int i = 0; i < len; i++)
+ {
+ CSSValue *item = list->item(i);
+ if (!item->isPrimitiveValue()) continue;
+ primitiveValue = static_cast<CSSPrimitiveValue*>(item);
+ switch (primitiveValue->getIdent()) {
+ case CSS_VAL_NONE:
+ t = TDNONE; break;
+ case CSS_VAL_UNDERLINE:
+ t |= UNDERLINE; break;
+ case CSS_VAL_OVERLINE:
+ t |= OVERLINE; break;
+ case CSS_VAL_LINE_THROUGH:
+ t |= LINE_THROUGH; break;
+ case CSS_VAL_BLINK:
+ t |= BLINK; break;
+ default:
+ return;
+ }
+ }
+ }
+
+ m_style->setTextDecoration(t);
+ return;
+ }
+
+// shorthand properties
+ case CSS_PROP_BACKGROUND:
+ if (isInitial) {
+ m_style->clearBackgroundLayers();
+ m_style->setBackgroundColor(Color());
+ return;
+ }
+ else if (isInherit) {
+ m_style->inheritBackgroundLayers(*m_parentStyle->backgroundLayers());
+ m_style->setBackgroundColor(m_parentStyle->backgroundColor());
+ }
+ return;
+ case CSS_PROP_BORDER:
+ case CSS_PROP_BORDER_STYLE:
+ case CSS_PROP_BORDER_WIDTH:
+ case CSS_PROP_BORDER_COLOR:
+ if (id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_COLOR)
+ {
+ if (isInherit) {
+ m_style->setBorderTopColor(m_parentStyle->borderTopColor());
+ m_style->setBorderBottomColor(m_parentStyle->borderBottomColor());
+ m_style->setBorderLeftColor(m_parentStyle->borderLeftColor());
+ m_style->setBorderRightColor(m_parentStyle->borderRightColor());
+ }
+ else if (isInitial) {
+ m_style->setBorderTopColor(Color()); // Reset to invalid color so currentColor is used instead.
+ m_style->setBorderBottomColor(Color());
+ m_style->setBorderLeftColor(Color());
+ m_style->setBorderRightColor(Color());
+ }
+ }
+ if (id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_STYLE)
+ {
+ if (isInherit) {
+ m_style->setBorderTopStyle(m_parentStyle->borderTopStyle());
+ m_style->setBorderBottomStyle(m_parentStyle->borderBottomStyle());
+ m_style->setBorderLeftStyle(m_parentStyle->borderLeftStyle());
+ m_style->setBorderRightStyle(m_parentStyle->borderRightStyle());
+ }
+ else if (isInitial) {
+ m_style->setBorderTopStyle(RenderStyle::initialBorderStyle());
+ m_style->setBorderBottomStyle(RenderStyle::initialBorderStyle());
+ m_style->setBorderLeftStyle(RenderStyle::initialBorderStyle());
+ m_style->setBorderRightStyle(RenderStyle::initialBorderStyle());
+ }
+ }
+ if (id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_WIDTH)
+ {
+ if (isInherit) {
+ m_style->setBorderTopWidth(m_parentStyle->borderTopWidth());
+ m_style->setBorderBottomWidth(m_parentStyle->borderBottomWidth());
+ m_style->setBorderLeftWidth(m_parentStyle->borderLeftWidth());
+ m_style->setBorderRightWidth(m_parentStyle->borderRightWidth());
+ }
+ else if (isInitial) {
+ m_style->setBorderTopWidth(RenderStyle::initialBorderWidth());
+ m_style->setBorderBottomWidth(RenderStyle::initialBorderWidth());
+ m_style->setBorderLeftWidth(RenderStyle::initialBorderWidth());
+ m_style->setBorderRightWidth(RenderStyle::initialBorderWidth());
+ }
+ }
+ return;
+ case CSS_PROP_BORDER_TOP:
+ if (isInherit) {
+ m_style->setBorderTopColor(m_parentStyle->borderTopColor());
+ m_style->setBorderTopStyle(m_parentStyle->borderTopStyle());
+ m_style->setBorderTopWidth(m_parentStyle->borderTopWidth());
+ }
+ else if (isInitial)
+ m_style->resetBorderTop();
+ return;
+ case CSS_PROP_BORDER_RIGHT:
+ if (isInherit) {
+ m_style->setBorderRightColor(m_parentStyle->borderRightColor());
+ m_style->setBorderRightStyle(m_parentStyle->borderRightStyle());
+ m_style->setBorderRightWidth(m_parentStyle->borderRightWidth());
+ }
+ else if (isInitial)
+ m_style->resetBorderRight();
+ return;
+ case CSS_PROP_BORDER_BOTTOM:
+ if (isInherit) {
+ m_style->setBorderBottomColor(m_parentStyle->borderBottomColor());
+ m_style->setBorderBottomStyle(m_parentStyle->borderBottomStyle());
+ m_style->setBorderBottomWidth(m_parentStyle->borderBottomWidth());
+ }
+ else if (isInitial)
+ m_style->resetBorderBottom();
+ return;
+ case CSS_PROP_BORDER_LEFT:
+ if (isInherit) {
+ m_style->setBorderLeftColor(m_parentStyle->borderLeftColor());
+ m_style->setBorderLeftStyle(m_parentStyle->borderLeftStyle());
+ m_style->setBorderLeftWidth(m_parentStyle->borderLeftWidth());
+ }
+ else if (isInitial)
+ m_style->resetBorderLeft();
+ return;
+ case CSS_PROP_MARGIN:
+ if (isInherit) {
+ m_style->setMarginTop(m_parentStyle->marginTop());
+ m_style->setMarginBottom(m_parentStyle->marginBottom());
+ m_style->setMarginLeft(m_parentStyle->marginLeft());
+ m_style->setMarginRight(m_parentStyle->marginRight());
+ }
+ else if (isInitial)
+ m_style->resetMargin();
+ return;
+ case CSS_PROP_PADDING:
+ if (isInherit) {
+ m_style->setPaddingTop(m_parentStyle->paddingTop());
+ m_style->setPaddingBottom(m_parentStyle->paddingBottom());
+ m_style->setPaddingLeft(m_parentStyle->paddingLeft());
+ m_style->setPaddingRight(m_parentStyle->paddingRight());
+ }
+ else if (isInitial)
+ m_style->resetPadding();
+ return;
+ case CSS_PROP_FONT:
+ if (isInherit) {
+ FontDescription fontDescription = m_parentStyle->fontDescription();
+ m_style->setLineHeight(m_parentStyle->lineHeight());
+ m_lineHeightValue = 0;
+ if (m_style->setFontDescription(fontDescription))
+ m_fontDirty = true;
+ } else if (isInitial) {
+ Settings* settings = m_document->settings();
+ FontDescription fontDescription;
+ fontDescription.setGenericFamily(FontDescription::StandardFamily);
+ fontDescription.setRenderingMode(settings->fontRenderingMode());
+ fontDescription.setUsePrinterFont(m_document->printing());
+ const AtomicString& standardFontFamily = m_document->settings()->standardFontFamily();
+ if (!standardFontFamily.isEmpty()) {
+ fontDescription.firstFamily().setFamily(standardFontFamily);
+ fontDescription.firstFamily().appendFamily(0);
+ }
+ fontDescription.setKeywordSize(CSS_VAL_MEDIUM - CSS_VAL_XX_SMALL + 1);
+ setFontSize(fontDescription, fontSizeForKeyword(CSS_VAL_MEDIUM, m_style->htmlHacks(), false));
+ m_style->setLineHeight(RenderStyle::initialLineHeight());
+ m_lineHeightValue = 0;
+ if (m_style->setFontDescription(fontDescription))
+ m_fontDirty = true;
+ } else if (primitiveValue) {
+ m_style->setLineHeight(RenderStyle::initialLineHeight());
+ m_lineHeightValue = 0;
+ FontDescription fontDescription;
+ theme()->systemFont(primitiveValue->getIdent(), fontDescription);
+ // Double-check and see if the theme did anything. If not, don't bother updating the font.
+ if (fontDescription.isAbsoluteSize()) {
+ // Handle the zoom factor.
+ fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(fontDescription.isAbsoluteSize(), fontDescription.specifiedSize()));
+ if (m_style->setFontDescription(fontDescription))
+ m_fontDirty = true;
+ }
+ } else if (value->isFontValue()) {
+ FontValue *font = static_cast<FontValue*>(value);
+ if (!font->style || !font->variant || !font->weight ||
+ !font->size || !font->lineHeight || !font->family)
+ return;
+ applyProperty(CSS_PROP_FONT_STYLE, font->style.get());
+ applyProperty(CSS_PROP_FONT_VARIANT, font->variant.get());
+ applyProperty(CSS_PROP_FONT_WEIGHT, font->weight.get());
+ applyProperty(CSS_PROP_FONT_SIZE, font->size.get());
+
+ m_lineHeightValue = font->lineHeight.get();
+
+ applyProperty(CSS_PROP_FONT_FAMILY, font->family.get());
+ }
+ return;
+
+ case CSS_PROP_LIST_STYLE:
+ if (isInherit) {
+ m_style->setListStyleType(m_parentStyle->listStyleType());
+ m_style->setListStyleImage(m_parentStyle->listStyleImage());
+ m_style->setListStylePosition(m_parentStyle->listStylePosition());
+ }
+ else if (isInitial) {
+ m_style->setListStyleType(RenderStyle::initialListStyleType());
+ m_style->setListStyleImage(RenderStyle::initialListStyleImage());
+ m_style->setListStylePosition(RenderStyle::initialListStylePosition());
+ }
+ return;
+ case CSS_PROP_OUTLINE:
+ if (isInherit) {
+ m_style->setOutlineWidth(m_parentStyle->outlineWidth());
+ m_style->setOutlineColor(m_parentStyle->outlineColor());
+ m_style->setOutlineStyle(m_parentStyle->outlineStyle());
+ }
+ else if (isInitial)
+ m_style->resetOutline();
+ return;
+
+ // CSS3 Properties
+ case CSS_PROP__WEBKIT_APPEARANCE: {
+ HANDLE_INHERIT_AND_INITIAL(appearance, Appearance)
+ if (!primitiveValue)
+ return;
+ m_style->setAppearance(*primitiveValue);
+ return;
+ }
+ case CSS_PROP__WEBKIT_BINDING: {
+#if ENABLE(XBL)
+ if (isInitial || (primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)) {
+ m_style->deleteBindingURIs();
+ return;
+ }
+ else if (isInherit) {
+ if (m_parentStyle->bindingURIs())
+ m_style->inheritBindingURIs(m_parentStyle->bindingURIs());
+ else
+ m_style->deleteBindingURIs();
+ return;
+ }
+
+ if (!value->isValueList()) return;
+ CSSValueList* list = static_cast<CSSValueList*>(value);
+ bool firstBinding = true;
+ for (unsigned int i = 0; i < list->length(); i++) {
+ CSSValue *item = list->item(i);
+ CSSPrimitiveValue *val = static_cast<CSSPrimitiveValue*>(item);
+ if (val->primitiveType() == CSSPrimitiveValue::CSS_URI) {
+ if (firstBinding) {
+ firstBinding = false;
+ m_style->deleteBindingURIs();
+ }
+ m_style->addBindingURI(val->getStringValue());
+ }
+ }
+#endif
+ return;
+ }
+
+ case CSS_PROP__WEBKIT_BORDER_IMAGE: {
+ HANDLE_INHERIT_AND_INITIAL(borderImage, BorderImage)
+ BorderImage image;
+ if (primitiveValue) {
+ if (primitiveValue->getIdent() == CSS_VAL_NONE)
+ m_style->setBorderImage(image);
+ } else {
+ // Retrieve the border image value.
+ CSSBorderImageValue* borderImage = static_cast<CSSBorderImageValue*>(value);
+
+ // Set the image (this kicks off the load).
+ image.m_image = borderImage->m_image->image(m_element->document()->docLoader());
+
+ // Set up a length box to represent our image slices.
+ LengthBox& l = image.m_slices;
+ Rect* r = borderImage->m_imageSliceRect.get();
+ if (r->top()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ l.top = Length(r->top()->getDoubleValue(), Percent);
+ else
+ l.top = Length(r->top()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
+ if (r->bottom()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ l.bottom = Length(r->bottom()->getDoubleValue(), Percent);
+ else
+ l.bottom = Length((int)r->bottom()->getFloatValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
+ if (r->left()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ l.left = Length(r->left()->getDoubleValue(), Percent);
+ else
+ l.left = Length(r->left()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
+ if (r->right()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ l.right = Length(r->right()->getDoubleValue(), Percent);
+ else
+ l.right = Length(r->right()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
+
+ // Set the appropriate rules for stretch/round/repeat of the slices
+ switch (borderImage->m_horizontalSizeRule) {
+ case CSS_VAL_STRETCH:
+ image.m_horizontalRule = BI_STRETCH;
+ break;
+ case CSS_VAL_ROUND:
+ image.m_horizontalRule = BI_ROUND;
+ break;
+ default: // CSS_VAL_REPEAT
+ image.m_horizontalRule = BI_REPEAT;
+ break;
+ }
+
+ switch (borderImage->m_verticalSizeRule) {
+ case CSS_VAL_STRETCH:
+ image.m_verticalRule = BI_STRETCH;
+ break;
+ case CSS_VAL_ROUND:
+ image.m_verticalRule = BI_ROUND;
+ break;
+ default: // CSS_VAL_REPEAT
+ image.m_verticalRule = BI_REPEAT;
+ break;
+ }
+
+ m_style->setBorderImage(image);
+ }
+ return;
+ }
+
+ case CSS_PROP__WEBKIT_BORDER_RADIUS:
+ if (isInherit) {
+ m_style->setBorderTopLeftRadius(m_parentStyle->borderTopLeftRadius());
+ m_style->setBorderTopRightRadius(m_parentStyle->borderTopRightRadius());
+ m_style->setBorderBottomLeftRadius(m_parentStyle->borderBottomLeftRadius());
+ m_style->setBorderBottomRightRadius(m_parentStyle->borderBottomRightRadius());
+ return;
+ }
+ if (isInitial) {
+ m_style->resetBorderRadius();
+ return;
+ }
+ // Fall through
+ case CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS:
+ case CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS:
+ case CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS:
+ case CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS: {
+ if (isInherit) {
+ HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS, borderTopLeftRadius, BorderTopLeftRadius)
+ HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS, borderTopRightRadius, BorderTopRightRadius)
+ HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS, borderBottomLeftRadius, BorderBottomLeftRadius)
+ HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS, borderBottomRightRadius, BorderBottomRightRadius)
+ return;
+ }
+
+ if (isInitial) {
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS, BorderTopLeftRadius, BorderRadius)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS, BorderTopRightRadius, BorderRadius)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS, BorderBottomLeftRadius, BorderRadius)
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS, BorderBottomRightRadius, BorderRadius)
+ return;
+ }
+
+ if (!primitiveValue)
+ return;
+
+ Pair* pair = primitiveValue->getPairValue();
+ if (!pair)
+ return;
+
+ int width = pair->first()->computeLengthInt(m_style);
+ int height = pair->second()->computeLengthInt(m_style);
+ if (width < 0 || height < 0)
+ return;
+
+ if (width == 0)
+ height = 0; // Null out the other value.
+ else if (height == 0)
+ width = 0; // Null out the other value.
+
+ IntSize size(width, height);
+ switch (id) {
+ case CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS:
+ m_style->setBorderTopLeftRadius(size);
+ break;
+ case CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS:
+ m_style->setBorderTopRightRadius(size);
+ break;
+ case CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS:
+ m_style->setBorderBottomLeftRadius(size);
+ break;
+ case CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS:
+ m_style->setBorderBottomRightRadius(size);
+ break;
+ default:
+ m_style->setBorderRadius(size);
+ break;
+ }
+ return;
+ }
+
+ case CSS_PROP_OUTLINE_OFFSET:
+ HANDLE_INHERIT_AND_INITIAL(outlineOffset, OutlineOffset)
+ m_style->setOutlineOffset(primitiveValue->computeLengthInt(m_style));
+ return;
+
+ case CSS_PROP_TEXT_SHADOW:
+ case CSS_PROP__WEBKIT_BOX_SHADOW: {
+ if (isInherit) {
+ if (id == CSS_PROP_TEXT_SHADOW)
+ return m_style->setTextShadow(m_parentStyle->textShadow() ? new ShadowData(*m_parentStyle->textShadow()) : 0);
+ return m_style->setBoxShadow(m_parentStyle->boxShadow() ? new ShadowData(*m_parentStyle->boxShadow()) : 0);
+ }
+ if (isInitial || primitiveValue) // initial | none
+ return id == CSS_PROP_TEXT_SHADOW ? m_style->setTextShadow(0) : m_style->setBoxShadow(0);
+
+ if (!value->isValueList())
+ return;
+
+ CSSValueList *list = static_cast<CSSValueList*>(value);
+ int len = list->length();
+ for (int i = 0; i < len; i++) {
+ ShadowValue* item = static_cast<ShadowValue*>(list->item(i));
+ int x = item->x->computeLengthInt(m_style);
+ int y = item->y->computeLengthInt(m_style);
+ int blur = item->blur ? item->blur->computeLengthInt(m_style) : 0;
+ Color color;
+ if (item->color)
+ color = getColorFromPrimitiveValue(item->color.get());
+ ShadowData* shadowData = new ShadowData(x, y, blur, color.isValid() ? color : Color::transparent);
+ if (id == CSS_PROP_TEXT_SHADOW)
+ m_style->setTextShadow(shadowData, i != 0);
+ else
+ m_style->setBoxShadow(shadowData, i != 0);
+ }
+ return;
+ }
+ case CSS_PROP_OPACITY:
+ HANDLE_INHERIT_AND_INITIAL(opacity, Opacity)
+ if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
+ return; // Error case.
+ // Clamp opacity to the range 0-1
+ m_style->setOpacity(min(1.0f, max(0.0f, primitiveValue->getFloatValue())));
+ return;
+ case CSS_PROP__WEBKIT_BOX_ALIGN:
+ {
+ HANDLE_INHERIT_AND_INITIAL(boxAlign, BoxAlign)
+ if (!primitiveValue)
+ return;
+ EBoxAlignment boxAlignment = *primitiveValue;
+ if (boxAlignment != BJUSTIFY)
+ m_style->setBoxAlign(boxAlignment);
+ return;
+ }
+ case CSS_PROP_SRC: // Only used in @font-face rules.
+ return;
+ case CSS_PROP_UNICODE_RANGE: // Only used in @font-face rules.
+ return;
+ case CSS_PROP__WEBKIT_BOX_DIRECTION:
+ HANDLE_INHERIT_AND_INITIAL(boxDirection, BoxDirection)
+ if (primitiveValue)
+ m_style->setBoxDirection(*primitiveValue);
+ return;
+ case CSS_PROP__WEBKIT_BOX_LINES:
+ HANDLE_INHERIT_AND_INITIAL(boxLines, BoxLines)
+ if (primitiveValue)
+ m_style->setBoxLines(*primitiveValue);
+ return;
+ case CSS_PROP__WEBKIT_BOX_ORIENT:
+ HANDLE_INHERIT_AND_INITIAL(boxOrient, BoxOrient)
+ if (primitiveValue)
+ m_style->setBoxOrient(*primitiveValue);
+ return;
+ case CSS_PROP__WEBKIT_BOX_PACK:
+ {
+ HANDLE_INHERIT_AND_INITIAL(boxPack, BoxPack)
+ if (!primitiveValue)
+ return;
+ EBoxAlignment boxPack = *primitiveValue;
+ if (boxPack != BSTRETCH && boxPack != BBASELINE)
+ m_style->setBoxPack(boxPack);
+ return;
+ }
+ case CSS_PROP__WEBKIT_BOX_FLEX:
+ HANDLE_INHERIT_AND_INITIAL(boxFlex, BoxFlex)
+ if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
+ return; // Error case.
+ m_style->setBoxFlex(primitiveValue->getFloatValue());
+ return;
+ case CSS_PROP__WEBKIT_BOX_FLEX_GROUP:
+ HANDLE_INHERIT_AND_INITIAL(boxFlexGroup, BoxFlexGroup)
+ if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
+ return; // Error case.
+ m_style->setBoxFlexGroup((unsigned int)(primitiveValue->getDoubleValue()));
+ return;
+ case CSS_PROP__WEBKIT_BOX_ORDINAL_GROUP:
+ HANDLE_INHERIT_AND_INITIAL(boxOrdinalGroup, BoxOrdinalGroup)
+ if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
+ return; // Error case.
+ m_style->setBoxOrdinalGroup((unsigned int)(primitiveValue->getDoubleValue()));
+ return;
+ case CSS_PROP__WEBKIT_BOX_SIZING:
+ HANDLE_INHERIT_AND_INITIAL(boxSizing, BoxSizing)
+ if (!primitiveValue)
+ return;
+ if (primitiveValue->getIdent() == CSS_VAL_CONTENT_BOX)
+ m_style->setBoxSizing(CONTENT_BOX);
+ else
+ m_style->setBoxSizing(BORDER_BOX);
+ return;
+ case CSS_PROP__WEBKIT_COLUMN_COUNT: {
+ if (isInherit) {
+ if (m_parentStyle->hasAutoColumnCount())
+ m_style->setHasAutoColumnCount();
+ else
+ m_style->setColumnCount(m_parentStyle->columnCount());
+ return;
+ } else if (isInitial || primitiveValue->getIdent() == CSS_VAL_AUTO) {
+ m_style->setHasAutoColumnCount();
+ return;
+ }
+ m_style->setColumnCount(static_cast<unsigned short>(primitiveValue->getDoubleValue()));
+ return;
+ }
+ case CSS_PROP__WEBKIT_COLUMN_GAP: {
+ if (isInherit) {
+ if (m_parentStyle->hasNormalColumnGap())
+ m_style->setHasNormalColumnGap();
+ else
+ m_style->setColumnGap(m_parentStyle->columnGap());
+ return;
+ } else if (isInitial || primitiveValue->getIdent() == CSS_VAL_NORMAL) {
+ m_style->setHasNormalColumnGap();
+ return;
+ }
+ m_style->setColumnGap(primitiveValue->computeLengthFloat(m_style));
+ return;
+ }
+ case CSS_PROP__WEBKIT_COLUMN_WIDTH: {
+ if (isInherit) {
+ if (m_parentStyle->hasAutoColumnWidth())
+ m_style->setHasAutoColumnWidth();
+ else
+ m_style->setColumnWidth(m_parentStyle->columnWidth());
+ return;
+ } else if (isInitial || primitiveValue->getIdent() == CSS_VAL_AUTO) {
+ m_style->setHasAutoColumnWidth();
+ return;
+ }
+ m_style->setColumnWidth(primitiveValue->computeLengthFloat(m_style));
+ return;
+ }
+ case CSS_PROP__WEBKIT_COLUMN_RULE_STYLE:
+ HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(columnRuleStyle, ColumnRuleStyle, BorderStyle)
+ m_style->setColumnRuleStyle(*primitiveValue);
+ return;
+ case CSS_PROP__WEBKIT_COLUMN_BREAK_BEFORE: {
+ HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(columnBreakBefore, ColumnBreakBefore, PageBreak)
+ m_style->setColumnBreakBefore(*primitiveValue);
+ return;
+ }
+ case CSS_PROP__WEBKIT_COLUMN_BREAK_AFTER: {
+ HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(columnBreakAfter, ColumnBreakAfter, PageBreak)
+ m_style->setColumnBreakAfter(*primitiveValue);
+ return;
+ }
+ case CSS_PROP__WEBKIT_COLUMN_BREAK_INSIDE: {
+ HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(columnBreakInside, ColumnBreakInside, PageBreak)
+ EPageBreak pb = *primitiveValue;
+ if (pb != PBALWAYS)
+ m_style->setColumnBreakInside(pb);
+ return;
+ }
+ case CSS_PROP__WEBKIT_COLUMN_RULE:
+ if (isInherit) {
+ m_style->setColumnRuleColor(m_parentStyle->columnRuleColor());
+ m_style->setColumnRuleStyle(m_parentStyle->columnRuleStyle());
+ m_style->setColumnRuleWidth(m_parentStyle->columnRuleWidth());
+ }
+ else if (isInitial)
+ m_style->resetColumnRule();
+ return;
+ case CSS_PROP__WEBKIT_COLUMNS:
+ if (isInherit) {
+ if (m_parentStyle->hasAutoColumnWidth())
+ m_style->setHasAutoColumnWidth();
+ else
+ m_style->setColumnWidth(m_parentStyle->columnWidth());
+ m_style->setColumnCount(m_parentStyle->columnCount());
+ } else if (isInitial) {
+ m_style->setHasAutoColumnWidth();
+ m_style->setColumnCount(RenderStyle::initialColumnCount());
+ }
+ return;
+ case CSS_PROP__WEBKIT_MARQUEE:
+ if (valueType != CSSValue::CSS_INHERIT || !m_parentNode) return;
+ m_style->setMarqueeDirection(m_parentStyle->marqueeDirection());
+ m_style->setMarqueeIncrement(m_parentStyle->marqueeIncrement());
+ m_style->setMarqueeSpeed(m_parentStyle->marqueeSpeed());
+ m_style->setMarqueeLoopCount(m_parentStyle->marqueeLoopCount());
+ m_style->setMarqueeBehavior(m_parentStyle->marqueeBehavior());
+ return;
+ case CSS_PROP__WEBKIT_MARQUEE_REPETITION: {
+ HANDLE_INHERIT_AND_INITIAL(marqueeLoopCount, MarqueeLoopCount)
+ if (!primitiveValue)
+ return;
+ if (primitiveValue->getIdent() == CSS_VAL_INFINITE)
+ m_style->setMarqueeLoopCount(-1); // -1 means repeat forever.
+ else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
+ m_style->setMarqueeLoopCount(primitiveValue->getIntValue());
+ return;
+ }
+ case CSS_PROP__WEBKIT_MARQUEE_SPEED: {
+ HANDLE_INHERIT_AND_INITIAL(marqueeSpeed, MarqueeSpeed)
+ if (!primitiveValue)
+ return;
+ if (primitiveValue->getIdent()) {
+ switch (primitiveValue->getIdent()) {
+ case CSS_VAL_SLOW:
+ m_style->setMarqueeSpeed(500); // 500 msec.
+ break;
+ case CSS_VAL_NORMAL:
+ m_style->setMarqueeSpeed(85); // 85msec. The WinIE default.
+ break;
+ case CSS_VAL_FAST:
+ 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.
+ m_style->setMarqueeSpeed(primitiveValue->getIntValue());
+ return;
+ }
+ case CSS_PROP__WEBKIT_MARQUEE_INCREMENT: {
+ HANDLE_INHERIT_AND_INITIAL(marqueeIncrement, MarqueeIncrement)
+ if (!primitiveValue)
+ return;
+ if (primitiveValue->getIdent()) {
+ switch (primitiveValue->getIdent()) {
+ case CSS_VAL_SMALL:
+ m_style->setMarqueeIncrement(Length(1, Fixed)); // 1px.
+ break;
+ case CSS_VAL_NORMAL:
+ m_style->setMarqueeIncrement(Length(6, Fixed)); // 6px. The WinIE default.
+ break;
+ case CSS_VAL_LARGE:
+ m_style->setMarqueeIncrement(Length(36, Fixed)); // 36px.
+ break;
+ }
+ }
+ else {
+ bool ok = true;
+ Length l = convertToLength(primitiveValue, m_style, &ok);
+ if (ok)
+ m_style->setMarqueeIncrement(l);
+ }
+ return;
+ }
+ case CSS_PROP__WEBKIT_MARQUEE_STYLE: {
+ HANDLE_INHERIT_AND_INITIAL(marqueeBehavior, MarqueeBehavior)
+ if (primitiveValue)
+ m_style->setMarqueeBehavior(*primitiveValue);
+ return;
+ }
+ case CSS_PROP__WEBKIT_MARQUEE_DIRECTION: {
+ HANDLE_INHERIT_AND_INITIAL(marqueeDirection, MarqueeDirection)
+ if (primitiveValue)
+ m_style->setMarqueeDirection(*primitiveValue);
+ return;
+ }
+ case CSS_PROP__WEBKIT_USER_DRAG: {
+ HANDLE_INHERIT_AND_INITIAL(userDrag, UserDrag)
+ if (primitiveValue)
+ m_style->setUserDrag(*primitiveValue);
+ return;
+ }
+ case CSS_PROP__WEBKIT_USER_MODIFY: {
+ HANDLE_INHERIT_AND_INITIAL(userModify, UserModify)
+ if (primitiveValue)
+ m_style->setUserModify(*primitiveValue);
+ return;
+ }
+ case CSS_PROP__WEBKIT_USER_SELECT: {
+ HANDLE_INHERIT_AND_INITIAL(userSelect, UserSelect)
+ if (primitiveValue)
+ m_style->setUserSelect(*primitiveValue);
+ return;
+ }
+ case CSS_PROP_TEXT_OVERFLOW: {
+ // This property is supported by WinIE, and so we leave off the "-webkit-" in order to
+ // work with WinIE-specific pages that use the property.
+ HANDLE_INHERIT_AND_INITIAL(textOverflow, TextOverflow)
+ if (!primitiveValue || !primitiveValue->getIdent())
+ return;
+ m_style->setTextOverflow(primitiveValue->getIdent() == CSS_VAL_ELLIPSIS);
+ return;
+ }
+ case CSS_PROP__WEBKIT_MARGIN_COLLAPSE: {
+ if (isInherit) {
+ m_style->setMarginTopCollapse(m_parentStyle->marginTopCollapse());
+ m_style->setMarginBottomCollapse(m_parentStyle->marginBottomCollapse());
+ }
+ else if (isInitial) {
+ m_style->setMarginTopCollapse(MCOLLAPSE);
+ m_style->setMarginBottomCollapse(MCOLLAPSE);
+ }
+ return;
+ }
+ case CSS_PROP__WEBKIT_MARGIN_TOP_COLLAPSE: {
+ HANDLE_INHERIT_AND_INITIAL(marginTopCollapse, MarginTopCollapse)
+ if (primitiveValue)
+ m_style->setMarginTopCollapse(*primitiveValue);
+ return;
+ }
+ case CSS_PROP__WEBKIT_MARGIN_BOTTOM_COLLAPSE: {
+ HANDLE_INHERIT_AND_INITIAL(marginBottomCollapse, MarginBottomCollapse)
+ if (primitiveValue)
+ m_style->setMarginBottomCollapse(*primitiveValue);
+ return;
+ }
+
+ // Apple-specific changes. Do not merge these properties into KHTML.
+ case CSS_PROP__WEBKIT_LINE_CLAMP: {
+ HANDLE_INHERIT_AND_INITIAL(lineClamp, LineClamp)
+ if (!primitiveValue)
+ return;
+ m_style->setLineClamp(primitiveValue->getIntValue(CSSPrimitiveValue::CSS_PERCENTAGE));
+ return;
+ }
+ case CSS_PROP__WEBKIT_HIGHLIGHT: {
+ HANDLE_INHERIT_AND_INITIAL(highlight, Highlight);
+ if (primitiveValue->getIdent() == CSS_VAL_NONE)
+ m_style->setHighlight(nullAtom);
+ else
+ m_style->setHighlight(primitiveValue->getStringValue());
+ return;
+ }
+ case CSS_PROP__WEBKIT_BORDER_FIT: {
+ HANDLE_INHERIT_AND_INITIAL(borderFit, BorderFit);
+ if (primitiveValue->getIdent() == CSS_VAL_BORDER)
+ m_style->setBorderFit(BorderFitBorder);
+ else
+ m_style->setBorderFit(BorderFitLines);
+ return;
+ }
+ case CSS_PROP__WEBKIT_TEXT_SIZE_ADJUST: {
+ HANDLE_INHERIT_AND_INITIAL(textSizeAdjust, TextSizeAdjust)
+ if (!primitiveValue || !primitiveValue->getIdent()) return;
+ m_style->setTextSizeAdjust(primitiveValue->getIdent() == CSS_VAL_AUTO);
+ m_fontDirty = true;
+ return;
+ }
+ case CSS_PROP__WEBKIT_TEXT_SECURITY: {
+ HANDLE_INHERIT_AND_INITIAL(textSecurity, TextSecurity)
+ if (primitiveValue)
+ m_style->setTextSecurity(*primitiveValue);
+ return;
+ }
+ case CSS_PROP__WEBKIT_DASHBOARD_REGION: {
+ HANDLE_INHERIT_AND_INITIAL(dashboardRegions, DashboardRegions)
+ if (!primitiveValue)
+ return;
+
+ if (primitiveValue->getIdent() == CSS_VAL_NONE) {
+ m_style->setDashboardRegions(RenderStyle::noneDashboardRegions());
+ return;
+ }
+
+ DashboardRegion *region = primitiveValue->getDashboardRegionValue();
+ if (!region)
+ return;
+
+ DashboardRegion *first = region;
+ while (region) {
+ Length top = convertToLength (region->top(), m_style);
+ Length right = convertToLength (region->right(), m_style);
+ Length bottom = convertToLength (region->bottom(), m_style);
+ Length left = convertToLength (region->left(), m_style);
+ if (region->m_isCircle)
+ m_style->setDashboardRegion(StyleDashboardRegion::Circle, region->m_label, top, right, bottom, left, region == first ? false : true);
+ else if (region->m_isRectangle)
+ m_style->setDashboardRegion(StyleDashboardRegion::Rectangle, region->m_label, top, right, bottom, left, region == first ? false : true);
+ region = region->m_next.get();
+ }
+
+ m_element->document()->setHasDashboardRegions(true);
+
+ return;
+ }
+ case CSS_PROP__WEBKIT_RTL_ORDERING:
+ HANDLE_INHERIT_AND_INITIAL(visuallyOrdered, VisuallyOrdered)
+ if (!primitiveValue || !primitiveValue->getIdent())
+ return;
+ m_style->setVisuallyOrdered(primitiveValue->getIdent() == CSS_VAL_VISUAL);
+ return;
+ case CSS_PROP__WEBKIT_TEXT_STROKE_WIDTH: {
+ HANDLE_INHERIT_AND_INITIAL(textStrokeWidth, TextStrokeWidth)
+ float width = 0;
+ switch (primitiveValue->getIdent()) {
+ case CSS_VAL_THIN:
+ case CSS_VAL_MEDIUM:
+ case CSS_VAL_THICK: {
+ double result = 1.0 / 48;
+ if (primitiveValue->getIdent() == CSS_VAL_MEDIUM)
+ result *= 3;
+ else if (primitiveValue->getIdent() == CSS_VAL_THICK)
+ result *= 5;
+ CSSPrimitiveValue val(result, CSSPrimitiveValue::CSS_EMS);
+ width = val.computeLengthFloat(m_style);
+ break;
+ }
+ default:
+ width = primitiveValue->computeLengthFloat(m_style);
+ break;
+ }
+ m_style->setTextStrokeWidth(width);
+ return;
+ }
+ case CSS_PROP__WEBKIT_TRANSFORM: {
+ HANDLE_INHERIT_AND_INITIAL(transform, Transform);
+ TransformOperations operations;
+ if (!value->isPrimitiveValue()) {
+ CSSValueList* list = static_cast<CSSValueList*>(value);
+ unsigned size = list->length();
+ for (unsigned i = 0; i < size; i++) {
+ CSSTransformValue* val = static_cast<CSSTransformValue*>(list->item(i));
+ CSSValueList* values = val->values();
+
+ CSSPrimitiveValue* firstValue = static_cast<CSSPrimitiveValue*>(values->item(0));
+
+ switch (val->type()) {
+ case CSSTransformValue::ScaleTransformOperation:
+ case CSSTransformValue::ScaleXTransformOperation:
+ case CSSTransformValue::ScaleYTransformOperation: {
+ double sx = 1.0;
+ double sy = 1.0;
+ if (val->type() == CSSTransformValue::ScaleYTransformOperation)
+ sy = firstValue->getDoubleValue();
+ else {
+ sx = firstValue->getDoubleValue();
+ if (val->type() == CSSTransformValue::ScaleTransformOperation) {
+ if (values->length() > 1) {
+ CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(values->item(1));
+ sy = secondValue->getDoubleValue();
+ } else
+ sy = sx;
+ }
+ }
+
+ ScaleTransformOperation* scale = new ScaleTransformOperation(sx, sy);
+ operations.append(scale);
+ break;
+ }
+ case CSSTransformValue::TranslateTransformOperation:
+ case CSSTransformValue::TranslateXTransformOperation:
+ case CSSTransformValue::TranslateYTransformOperation: {
+ bool ok;
+ Length tx = Length(0, Fixed);
+ Length ty = Length(0, Fixed);
+ if (val->type() == CSSTransformValue::TranslateYTransformOperation)
+ ty = convertToLength(firstValue, m_style, &ok);
+ else {
+ tx = convertToLength(firstValue, m_style, &ok);
+ if (val->type() == CSSTransformValue::TranslateTransformOperation) {
+ if (values->length() > 1) {
+ CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(values->item(1));
+ ty = convertToLength(secondValue, m_style, &ok);
+ } else
+ ty = tx;
+ }
+ }
+
+ TranslateTransformOperation* translate = new TranslateTransformOperation(tx, ty);
+ operations.append(translate);
+ break;
+ }
+ case CSSTransformValue::RotateTransformOperation: {
+ double angle = firstValue->getDoubleValue();
+ if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
+ angle = rad2deg(angle);
+ else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
+ angle = grad2deg(angle);
+ RotateTransformOperation* rotate = new RotateTransformOperation(angle);
+ operations.append(rotate);
+ break;
+ }
+ case CSSTransformValue::SkewTransformOperation:
+ case CSSTransformValue::SkewXTransformOperation:
+ case CSSTransformValue::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);
+ if (val->type() == CSSTransformValue::SkewYTransformOperation)
+ angleY = angle;
+ else {
+ angleX = angle;
+ if (val->type() == CSSTransformValue::SkewTransformOperation) {
+ if (values->length() > 1) {
+ CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(values->item(1));
+ angleY = secondValue->getDoubleValue();
+ if (secondValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
+ angleY = rad2deg(angle);
+ else if (secondValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
+ angleY = grad2deg(angle);
+ } else
+ angleY = angleX;
+ }
+ }
+
+ SkewTransformOperation* skew = new SkewTransformOperation(angleX, angleY);
+ operations.append(skew);
+ break;
+ }
+ case CSSTransformValue::MatrixTransformOperation: {
+ CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(values->item(1));
+ CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitiveValue*>(values->item(2));
+ CSSPrimitiveValue* fourthValue = static_cast<CSSPrimitiveValue*>(values->item(3));
+ CSSPrimitiveValue* fifthValue = static_cast<CSSPrimitiveValue*>(values->item(4));
+ CSSPrimitiveValue* sixthValue = static_cast<CSSPrimitiveValue*>(values->item(5));
+ MatrixTransformOperation* matrix = new MatrixTransformOperation(firstValue->getDoubleValue(),
+ secondValue->getDoubleValue(),
+ thirdValue->getDoubleValue(),
+ fourthValue->getDoubleValue(),
+ fifthValue->getDoubleValue(),
+ sixthValue->getDoubleValue());
+ operations.append(matrix);
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ }
+ m_style->setTransform(operations);
+ return;
+ }
+ case CSS_PROP__WEBKIT_TRANSFORM_ORIGIN:
+ HANDLE_INHERIT_AND_INITIAL(transformOriginX, TransformOriginX)
+ HANDLE_INHERIT_AND_INITIAL(transformOriginY, TransformOriginY)
+ return;
+ case CSS_PROP__WEBKIT_TRANSFORM_ORIGIN_X: {
+ HANDLE_INHERIT_AND_INITIAL(transformOriginX, TransformOriginX)
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ Length l;
+ int type = primitiveValue->primitiveType();
+ if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ l = Length(primitiveValue->computeLengthIntForLength(m_style), Fixed);
+ else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ l = Length(primitiveValue->getDoubleValue(), Percent);
+ else
+ return;
+ m_style->setTransformOriginX(l);
+ break;
+ }
+ case CSS_PROP__WEBKIT_TRANSFORM_ORIGIN_Y: {
+ HANDLE_INHERIT_AND_INITIAL(transformOriginY, TransformOriginY)
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ Length l;
+ int type = primitiveValue->primitiveType();
+ if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ l = Length(primitiveValue->computeLengthIntForLength(m_style), Fixed);
+ else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ l = Length(primitiveValue->getDoubleValue(), Percent);
+ else
+ return;
+ m_style->setTransformOriginY(l);
+ break;
+ }
+ case CSS_PROP__WEBKIT_TRANSITION:
+ if (isInitial)
+ m_style->clearTransitions();
+ else if (isInherit)
+ m_style->inheritTransitions(m_parentStyle->transitions());
+ return;
+ case CSS_PROP__WEBKIT_TRANSITION_DURATION:
+ HANDLE_TRANSITION_VALUE(transitionDuration, TransitionDuration, value)
+ return;
+ case CSS_PROP__WEBKIT_TRANSITION_REPEAT_COUNT:
+ HANDLE_TRANSITION_VALUE(transitionRepeatCount, TransitionRepeatCount, value)
+ return;
+ case CSS_PROP__WEBKIT_TRANSITION_TIMING_FUNCTION:
+ HANDLE_TRANSITION_VALUE(transitionTimingFunction, TransitionTimingFunction, value)
+ return;
+ case CSS_PROP__WEBKIT_TRANSITION_PROPERTY:
+ HANDLE_TRANSITION_VALUE(transitionProperty, TransitionProperty, value)
+ return;
+ case CSS_PROP_INVALID:
+ return;
+ case CSS_PROP_FONT_STRETCH:
+ case CSS_PROP_PAGE:
+ case CSS_PROP_QUOTES:
+ case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
+ case CSS_PROP_SCROLLBAR_ARROW_COLOR:
+ case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
+ case CSS_PROP_SCROLLBAR_FACE_COLOR:
+ case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
+ case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
+ case CSS_PROP_SCROLLBAR_TRACK_COLOR:
+ case CSS_PROP_SIZE:
+ case CSS_PROP_TEXT_LINE_THROUGH:
+ case CSS_PROP_TEXT_LINE_THROUGH_COLOR:
+ case CSS_PROP_TEXT_LINE_THROUGH_MODE:
+ case CSS_PROP_TEXT_LINE_THROUGH_STYLE:
+ case CSS_PROP_TEXT_LINE_THROUGH_WIDTH:
+ case CSS_PROP_TEXT_OVERLINE:
+ case CSS_PROP_TEXT_OVERLINE_COLOR:
+ case CSS_PROP_TEXT_OVERLINE_MODE:
+ case CSS_PROP_TEXT_OVERLINE_STYLE:
+ case CSS_PROP_TEXT_OVERLINE_WIDTH:
+ case CSS_PROP_TEXT_UNDERLINE:
+ case CSS_PROP_TEXT_UNDERLINE_COLOR:
+ case CSS_PROP_TEXT_UNDERLINE_MODE:
+ case CSS_PROP_TEXT_UNDERLINE_STYLE:
+ case CSS_PROP_TEXT_UNDERLINE_WIDTH:
+ case CSS_PROP__WEBKIT_FONT_SIZE_DELTA:
+ case CSS_PROP__WEBKIT_MARGIN_START:
+ case CSS_PROP__WEBKIT_PADDING_START:
+ case CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT:
+ case CSS_PROP__WEBKIT_TEXT_STROKE:
+ return;
+#if ENABLE(SVG)
+ default:
+ // Try the SVG properties
+ applySVGProperty(id, value);
+#endif
+ }
+}
+
+void CSSStyleSelector::mapBackgroundAttachment(BackgroundLayer* layer, CSSValue* value)
+{
+ if (value->cssValueType() == CSSValue::CSS_INITIAL) {
+ layer->setBackgroundAttachment(RenderStyle::initialBackgroundAttachment());
+ return;
+ }
+
+ if (!value->isPrimitiveValue())
+ return;
+
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ switch (primitiveValue->getIdent()) {
+ case CSS_VAL_FIXED:
+ layer->setBackgroundAttachment(false);
+ break;
+ case CSS_VAL_SCROLL:
+ layer->setBackgroundAttachment(true);
+ break;
+ default:
+ return;
+ }
+}
+
+void CSSStyleSelector::mapBackgroundClip(BackgroundLayer* layer, CSSValue* value)
+{
+ if (value->cssValueType() == CSSValue::CSS_INITIAL) {
+ layer->setBackgroundClip(RenderStyle::initialBackgroundClip());
+ return;
+ }
+
+ if (!value->isPrimitiveValue())
+ return;
+
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ layer->setBackgroundClip(*primitiveValue);
+}
+
+void CSSStyleSelector::mapBackgroundComposite(BackgroundLayer* layer, CSSValue* value)
+{
+ if (value->cssValueType() == CSSValue::CSS_INITIAL) {
+ layer->setBackgroundComposite(RenderStyle::initialBackgroundComposite());
+ return;
+ }
+
+ if (!value->isPrimitiveValue())
+ return;
+
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ layer->setBackgroundComposite(*primitiveValue);
+}
+
+void CSSStyleSelector::mapBackgroundOrigin(BackgroundLayer* layer, CSSValue* value)
+{
+ if (value->cssValueType() == CSSValue::CSS_INITIAL) {
+ layer->setBackgroundOrigin(RenderStyle::initialBackgroundOrigin());
+ return;
+ }
+
+ if (!value->isPrimitiveValue())
+ return;
+
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ layer->setBackgroundOrigin(*primitiveValue);
+}
+
+void CSSStyleSelector::mapBackgroundImage(BackgroundLayer* layer, CSSValue* value)
+{
+ if (value->cssValueType() == CSSValue::CSS_INITIAL) {
+ layer->setBackgroundImage(RenderStyle::initialBackgroundImage());
+ return;
+ }
+
+ if (!value->isPrimitiveValue())
+ return;
+
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ layer->setBackgroundImage(static_cast<CSSImageValue*>(primitiveValue)->image(m_element->document()->docLoader()));
+}
+
+void CSSStyleSelector::mapBackgroundRepeat(BackgroundLayer* layer, CSSValue* value)
+{
+ if (value->cssValueType() == CSSValue::CSS_INITIAL) {
+ layer->setBackgroundRepeat(RenderStyle::initialBackgroundRepeat());
+ return;
+ }
+
+ if (!value->isPrimitiveValue())
+ return;
+
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ layer->setBackgroundRepeat(*primitiveValue);
+}
+
+void CSSStyleSelector::mapBackgroundSize(BackgroundLayer* layer, CSSValue* value)
+{
+ LengthSize b = RenderStyle::initialBackgroundSize();
+
+ if (value->cssValueType() == CSSValue::CSS_INITIAL) {
+ layer->setBackgroundSize(b);
+ return;
+ }
+
+ if (!value->isPrimitiveValue())
+ return;
+
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ Pair* pair = primitiveValue->getPairValue();
+ if (!pair)
+ return;
+
+ CSSPrimitiveValue* first = static_cast<CSSPrimitiveValue*>(pair->first());
+ CSSPrimitiveValue* second = static_cast<CSSPrimitiveValue*>(pair->second());
+
+ if (!first || !second)
+ return;
+
+ Length firstLength, secondLength;
+ int firstType = first->primitiveType();
+ int secondType = second->primitiveType();
+
+ if (firstType == CSSPrimitiveValue::CSS_UNKNOWN)
+ firstLength = Length(Auto);
+ else if (firstType > CSSPrimitiveValue::CSS_PERCENTAGE && firstType < CSSPrimitiveValue::CSS_DEG)
+ firstLength = Length(first->computeLengthIntForLength(m_style), Fixed);
+ else if (firstType == CSSPrimitiveValue::CSS_PERCENTAGE)
+ firstLength = Length(first->getDoubleValue(), Percent);
+ else
+ return;
+
+ if (secondType == CSSPrimitiveValue::CSS_UNKNOWN)
+ secondLength = Length(Auto);
+ else if (secondType > CSSPrimitiveValue::CSS_PERCENTAGE && secondType < CSSPrimitiveValue::CSS_DEG)
+ secondLength = Length(second->computeLengthIntForLength(m_style), Fixed);
+ else if (secondType == CSSPrimitiveValue::CSS_PERCENTAGE)
+ secondLength = Length(second->getDoubleValue(), Percent);
+ else
+ return;
+
+ b.width = firstLength;
+ b.height = secondLength;
+ layer->setBackgroundSize(b);
+}
+
+void CSSStyleSelector::mapBackgroundXPosition(BackgroundLayer* layer, CSSValue* value)
+{
+ if (value->cssValueType() == CSSValue::CSS_INITIAL) {
+ layer->setBackgroundXPosition(RenderStyle::initialBackgroundXPosition());
+ return;
+ }
+
+ if (!value->isPrimitiveValue())
+ return;
+
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ Length l;
+ int type = primitiveValue->primitiveType();
+ if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ l = Length(primitiveValue->computeLengthIntForLength(m_style), Fixed);
+ else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ l = Length(primitiveValue->getDoubleValue(), Percent);
+ else
+ return;
+ layer->setBackgroundXPosition(l);
+}
+
+void CSSStyleSelector::mapBackgroundYPosition(BackgroundLayer* layer, CSSValue* value)
+{
+ if (value->cssValueType() == CSSValue::CSS_INITIAL) {
+ layer->setBackgroundYPosition(RenderStyle::initialBackgroundYPosition());
+ return;
+ }
+
+ if (!value->isPrimitiveValue())
+ return;
+
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ Length l;
+ int type = primitiveValue->primitiveType();
+ if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ l = Length(primitiveValue->computeLengthIntForLength(m_style), Fixed);
+ else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ l = Length(primitiveValue->getDoubleValue(), Percent);
+ else
+ return;
+ layer->setBackgroundYPosition(l);
+}
+
+void CSSStyleSelector::mapTransitionDuration(Transition* transition, CSSValue* value)
+{
+ if (value->cssValueType() == CSSValue::CSS_INITIAL) {
+ transition->setTransitionDuration(RenderStyle::initialTransitionDuration());
+ return;
+ }
+
+ if (!value->isPrimitiveValue())
+ return;
+
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S)
+ transition->setTransitionDuration(int(1000*primitiveValue->getFloatValue()));
+ else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_MS)
+ transition->setTransitionDuration(int(primitiveValue->getFloatValue()));
+}
+
+void CSSStyleSelector::mapTransitionRepeatCount(Transition* transition, CSSValue* value)
+{
+ if (value->cssValueType() == CSSValue::CSS_INITIAL) {
+ transition->setTransitionRepeatCount(RenderStyle::initialTransitionRepeatCount());
+ return;
+ }
+
+ if (!value->isPrimitiveValue())
+ return;
+
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ if (primitiveValue->getIdent() == CSS_VAL_INFINITE)
+ transition->setTransitionRepeatCount(-1);
+ else
+ transition->setTransitionRepeatCount(int(primitiveValue->getFloatValue()));
+}
+
+void CSSStyleSelector::mapTransitionTimingFunction(Transition* transition, CSSValue* value)
+{
+ if (value->cssValueType() == CSSValue::CSS_INITIAL) {
+ transition->setTransitionTimingFunction(RenderStyle::initialTransitionTimingFunction());
+ return;
+ }
+
+ if (value->isPrimitiveValue()) {
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ switch (primitiveValue->getIdent()) {
+ case CSS_VAL_LINEAR:
+ transition->setTransitionTimingFunction(TimingFunction(LinearTimingFunction));
+ break;
+ case CSS_VAL_AUTO:
+ transition->setTransitionTimingFunction(TimingFunction());
+ break;
+ case CSS_VAL_EASE_IN:
+ transition->setTransitionTimingFunction(TimingFunction(CubicBezierTimingFunction, .42, .0, 1.0, 1.0));
+ break;
+ case CSS_VAL_EASE_OUT:
+ transition->setTransitionTimingFunction(TimingFunction(CubicBezierTimingFunction, .0, .0, .58, 1.0));
+ break;
+ case CSS_VAL_EASE_IN_OUT:
+ transition->setTransitionTimingFunction(TimingFunction(CubicBezierTimingFunction, .42, .0, .58, 1.0));
+ break;
+ }
+ return;
+ }
+
+ if (value->isTransitionTimingFunctionValue()) {
+ CSSTimingFunctionValue* timingFunction = static_cast<CSSTimingFunctionValue*>(value);
+ transition->setTransitionTimingFunction(TimingFunction(CubicBezierTimingFunction, timingFunction->x1(), timingFunction->y1(), timingFunction->x2(), timingFunction->y2()));
+ }
+}
+
+void CSSStyleSelector::mapTransitionProperty(Transition* transition, CSSValue* value)
+{
+ if (value->cssValueType() == CSSValue::CSS_INITIAL) {
+ transition->setTransitionProperty(RenderStyle::initialTransitionProperty());
+ return;
+ }
+
+ if (!value->isPrimitiveValue())
+ return;
+
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ transition->setTransitionProperty(primitiveValue->getIdent());
+}
+
+void CSSStyleSelector::checkForTextSizeAdjust()
+{
+ if (m_style->textSizeAdjust())
+ return;
+
+ FontDescription newFontDescription(m_style->fontDescription());
+ newFontDescription.setComputedSize(newFontDescription.specifiedSize());
+ m_style->setFontDescription(newFontDescription);
+}
+
+void CSSStyleSelector::checkForGenericFamilyChange(RenderStyle* style, RenderStyle* parentStyle)
+{
+ const FontDescription& childFont = style->fontDescription();
+
+ if (childFont.isAbsoluteSize() || !parentStyle)
+ return;
+
+ const FontDescription& parentFont = parentStyle->fontDescription();
+
+ if (childFont.genericFamily() == parentFont.genericFamily())
+ return;
+
+ // For now, lump all families but monospace together.
+ if (childFont.genericFamily() != FontDescription::MonospaceFamily &&
+ parentFont.genericFamily() != FontDescription::MonospaceFamily)
+ return;
+
+ // We know the parent is monospace or the child is monospace, and that font
+ // size was unspecified. We want to scale our font size as appropriate.
+ // If the font uses a keyword size, then we refetch from the table rather than
+ // multiplying by our scale factor.
+ float size;
+ if (childFont.keywordSize()) {
+ size = fontSizeForKeyword(CSS_VAL_XX_SMALL + childFont.keywordSize() - 1, style->htmlHacks(),
+ childFont.genericFamily() == FontDescription::MonospaceFamily);
+ } else {
+ Settings* settings = m_document->settings();
+ float fixedScaleFactor = settings
+ ? static_cast<float>(settings->defaultFixedFontSize()) / settings->defaultFontSize()
+ : 1;
+ size = (parentFont.genericFamily() == FontDescription::MonospaceFamily) ?
+ childFont.specifiedSize()/fixedScaleFactor :
+ childFont.specifiedSize()*fixedScaleFactor;
+ }
+
+ FontDescription newFontDescription(childFont);
+ setFontSize(newFontDescription, size);
+ style->setFontDescription(newFontDescription);
+}
+
+void CSSStyleSelector::setFontSize(FontDescription& fontDescription, float size)
+{
+ fontDescription.setSpecifiedSize(size);
+ fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(fontDescription.isAbsoluteSize(), size));
+}
+
+float CSSStyleSelector::getComputedSizeFromSpecifiedSize(bool isAbsoluteSize, float specifiedSize)
+{
+ // We support two types of minimum font size. The first is a hard override that applies to
+ // all fonts. This is "minSize." The second type of minimum font size is a "smart minimum"
+ // that is applied only when the Web page can't know what size it really asked for, e.g.,
+ // when it uses logical sizes like "small" or expresses the font-size as a percentage of
+ // the user's default font setting.
+
+ // With the smart minimum, we never want to get smaller than the minimum font size to keep fonts readable.
+ // However we always allow the page to set an explicit pixel size that is smaller,
+ // since sites will mis-render otherwise (e.g., http://www.gamespot.com with a 9px minimum).
+
+ Settings* settings = m_document->settings();
+ if (!settings)
+ return 1.0f;
+
+ int minSize = settings->minimumFontSize();
+ int minLogicalSize = settings->minimumLogicalFontSize();
+
+ float zoomPercent = m_document->frame() ? m_document->frame()->zoomFactor() / 100.0f : 1.0f;
+ float zoomedSize = specifiedSize * zoomPercent;
+
+ // Apply the hard minimum first. We only apply the hard minimum if after zooming we're still too small.
+ if (zoomedSize < minSize)
+ zoomedSize = minSize;
+
+ // Now apply the "smart minimum." This minimum is also only applied if we're still too small
+ // after zooming. The font size must either be relative to the user default or the original size
+ // must have been acceptable. In other words, we only apply the smart minimum whenever we're positive
+ // doing so won't disrupt the layout.
+ if (zoomedSize < minLogicalSize && (specifiedSize >= minLogicalSize || !isAbsoluteSize))
+ zoomedSize = minLogicalSize;
+
+ // Also clamp to a reasonable maximum to prevent insane font sizes from causing crashes on various
+ // platforms (I'm looking at you, Windows.)
+ return min(1000000.0f, max(zoomedSize, 1.0f));
+}
+
+const int fontSizeTableMax = 16;
+const int fontSizeTableMin = 9;
+const int totalKeywords = 8;
+
+// WinIE/Nav4 table for font sizes. Designed to match the legacy font mapping system of HTML.
+static const int quirksFontSizeTable[fontSizeTableMax - fontSizeTableMin + 1][totalKeywords] =
+{
+ { 9, 9, 9, 9, 11, 14, 18, 28 },
+ { 9, 9, 9, 10, 12, 15, 20, 31 },
+ { 9, 9, 9, 11, 13, 17, 22, 34 },
+ { 9, 9, 10, 12, 14, 18, 24, 37 },
+ { 9, 9, 10, 13, 16, 20, 26, 40 }, // fixed font default (13)
+ { 9, 9, 11, 14, 17, 21, 28, 42 },
+ { 9, 10, 12, 15, 17, 23, 30, 45 },
+ { 9, 10, 13, 16, 18, 24, 32, 48 } // proportional font default (16)
+};
+// HTML 1 2 3 4 5 6 7
+// CSS xxs xs s m l xl xxl
+// |
+// user pref
+
+// Strict mode table matches MacIE and Mozilla's settings exactly.
+static const int strictFontSizeTable[fontSizeTableMax - fontSizeTableMin + 1][totalKeywords] =
+{
+ { 9, 9, 9, 9, 11, 14, 18, 27 },
+ { 9, 9, 9, 10, 12, 15, 20, 30 },
+ { 9, 9, 10, 11, 13, 17, 22, 33 },
+ { 9, 9, 10, 12, 14, 18, 24, 36 },
+ { 9, 10, 12, 13, 16, 20, 26, 39 }, // fixed font default (13)
+ { 9, 10, 12, 14, 17, 21, 28, 42 },
+ { 9, 10, 13, 15, 18, 23, 30, 45 },
+ { 9, 10, 13, 16, 18, 24, 32, 48 } // proportional font default (16)
+};
+// HTML 1 2 3 4 5 6 7
+// CSS xxs xs s m l xl xxl
+// |
+// user pref
+
+// For values outside the range of the table, we use Todd Fahrner's suggested scale
+// factors for each keyword value.
+static const float fontSizeFactors[totalKeywords] = { 0.60f, 0.75f, 0.89f, 1.0f, 1.2f, 1.5f, 2.0f, 3.0f };
+
+float CSSStyleSelector::fontSizeForKeyword(int keyword, bool quirksMode, bool fixed) const
+{
+ Settings* settings = m_document->settings();
+ if (!settings)
+ return 1.0f;
+
+ int mediumSize = fixed ? settings->defaultFixedFontSize() : settings->defaultFontSize();
+ if (mediumSize >= fontSizeTableMin && mediumSize <= fontSizeTableMax) {
+ // Look up the entry in the table.
+ int row = mediumSize - fontSizeTableMin;
+ int col = (keyword - CSS_VAL_XX_SMALL);
+ return quirksMode ? quirksFontSizeTable[row][col] : strictFontSizeTable[row][col];
+ }
+
+ // Value is outside the range of the table. Apply the scale factor instead.
+ float minLogicalSize = max(settings->minimumLogicalFontSize(), 1);
+ return max(fontSizeFactors[keyword - CSS_VAL_XX_SMALL]*mediumSize, minLogicalSize);
+}
+
+float CSSStyleSelector::largerFontSize(float size, bool quirksMode) const
+{
+ // FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large) and scale up to
+ // the next size level.
+ return size * 1.2f;
+}
+
+float CSSStyleSelector::smallerFontSize(float size, bool quirksMode) const
+{
+ // FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large) and scale down to
+ // the next size level.
+ return size / 1.2f;
+}
+
+struct ColorValue {
+ int cssValueId;
+ RGBA32 color;
+};
+
+static const ColorValue colorValues[] = {
+ { CSS_VAL_AQUA, 0xFF00FFFF },
+ { CSS_VAL_BLACK, 0xFF000000 },
+ { CSS_VAL_BLUE, 0xFF0000FF },
+ { CSS_VAL_FUCHSIA, 0xFFFF00FF },
+ { CSS_VAL_GRAY, 0xFF808080 },
+ { CSS_VAL_GREEN, 0xFF008000 },
+ { CSS_VAL_LIME, 0xFF00FF00 },
+ { CSS_VAL_MAROON, 0xFF800000 },
+ { CSS_VAL_NAVY, 0xFF000080 },
+ { CSS_VAL_OLIVE, 0xFF808000 },
+ { CSS_VAL_ORANGE, 0xFFFFA500 },
+ { CSS_VAL_PURPLE, 0xFF800080 },
+ { CSS_VAL_RED, 0xFFFF0000 },
+ { CSS_VAL_SILVER, 0xFFC0C0C0 },
+ { CSS_VAL_TEAL, 0xFF008080 },
+ { CSS_VAL_WHITE, 0xFFFFFFFF },
+ { CSS_VAL_YELLOW, 0xFFFFFF00 },
+ { CSS_VAL_TRANSPARENT, 0x00000000 },
+ { CSS_VAL_GREY, 0xFF808080 },
+ { 0, 0 }
+};
+
+static Color colorForCSSValue(int cssValueId)
+{
+ for (const ColorValue* col = colorValues; col->cssValueId; ++col)
+ if (col->cssValueId == cssValueId)
+ return col->color;
+ return theme()->systemColor(cssValueId);
+}
+
+Color CSSStyleSelector::getColorFromPrimitiveValue(CSSPrimitiveValue* primitiveValue)
+{
+ Color col;
+ int ident = primitiveValue->getIdent();
+ if (ident) {
+ if (ident == CSS_VAL__WEBKIT_TEXT)
+ col = m_element->document()->textColor();
+ else if (ident == CSS_VAL__WEBKIT_LINK) {
+ Color linkColor = m_element->document()->linkColor();
+ Color visitedColor = m_element->document()->visitedLinkColor();
+ if (linkColor == visitedColor)
+ col = linkColor;
+ else {
+ if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink)
+ checkPseudoState(m_element);
+ col = (pseudoState == PseudoLink) ? linkColor : visitedColor;
+ }
+ } else if (ident == CSS_VAL__WEBKIT_ACTIVELINK)
+ col = m_element->document()->activeLinkColor();
+ else if (ident == CSS_VAL__WEBKIT_FOCUS_RING_COLOR)
+ col = focusRingColor();
+ else
+ col = colorForCSSValue(ident);
+ } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RGBCOLOR)
+ col.setRGB(primitiveValue->getRGBColorValue());
+ return col;
+}
+
+bool CSSStyleSelector::hasSelectorForAttribute(const AtomicString &attrname)
+{
+ return m_selectorAttrs.contains(attrname.impl());
+}
+
+void CSSStyleSelector::addViewportDependentMediaQueryResult(const MediaQueryExp* expr, bool result)
+{
+ m_viewportDependentMediaQueryResults.append(new MediaQueryResult(*expr, result));
+}
+
+bool CSSStyleSelector::affectedByViewportChange() const
+{
+ unsigned s = m_viewportDependentMediaQueryResults.size();
+ for (unsigned i = 0; i < s; i++) {
+ if (m_medium->eval(&m_viewportDependentMediaQueryResults[i]->m_expression) != m_viewportDependentMediaQueryResults[i]->m_result)
+ return true;
+ }
+ return false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSStyleSelector.h b/WebCore/css/CSSStyleSelector.h
new file mode 100644
index 0000000..b5ba49b
--- /dev/null
+++ b/WebCore/css/CSSStyleSelector.h
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 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 CSSStyleSelector_h
+#define CSSStyleSelector_h
+
+#include "CSSFontSelector.h"
+#include "MediaQueryExp.h"
+#include "RenderStyle.h"
+#include <wtf/HashSet.h>
+#include <wtf/Vector.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSMutableStyleDeclaration;
+class CSSPrimitiveValue;
+class CSSProperty;
+class CSSFontFace;
+class CSSFontFaceRule;
+class CSSRuleData;
+class CSSRuleDataList;
+class CSSRuleList;
+class CSSRuleSet;
+class CSSSelector;
+class CSSStyleRule;
+class CSSStyleSheet;
+class CSSValue;
+class Document;
+class Element;
+class Frame;
+class FrameView;
+class KURL;
+class MediaQueryEvaluator;
+class Node;
+class Settings;
+class StyleSheet;
+class StyleSheetList;
+class StyledElement;
+
+class MediaQueryResult
+{
+public:
+ MediaQueryResult(const MediaQueryExp& expr, bool result)
+ : m_expression(expr)
+ , m_result(result)
+ {}
+
+ MediaQueryExp m_expression;
+ bool m_result;
+};
+
+ /**
+ * this class selects a RenderStyle for a given Element based on the
+ * collection of styleshets it contains. This is just a vrtual base class
+ * for specific implementations of the Selector. At the moment only CSSStyleSelector
+ * exists, but someone may wish to implement XSL.
+ */
+ class StyleSelector {
+ public:
+ enum State {
+ None = 0x00,
+ Hover = 0x01,
+ Focus = 0x02,
+ Active = 0x04,
+ Drag = 0x08
+ };
+ };
+
+ /**
+ * the StyleSelector implementation for CSS.
+ */
+ class CSSStyleSelector : public StyleSelector {
+ public:
+ CSSStyleSelector(Document*, const String& userStyleSheet, StyleSheetList*, CSSStyleSheet*, bool strictParsing, bool matchAuthorAndUserStyles);
+ ~CSSStyleSelector();
+
+ static void loadDefaultStyle();
+
+ void initElementAndPseudoState(Element*);
+ void initForStyleResolve(Element*, RenderStyle* parentStyle);
+ RenderStyle* styleForElement(Element*, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false);
+ RenderStyle* pseudoStyleForElement(RenderStyle::PseudoId, Element*, RenderStyle* parentStyle = 0);
+
+ RenderStyle* locateSharedStyle();
+ Node* locateCousinList(Element* parent, unsigned depth = 1);
+ bool canShareStyleWithElement(Node* n);
+
+ // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
+ RefPtr<CSSRuleList> styleRulesForElement(Element*, bool authorOnly);
+ RefPtr<CSSRuleList> pseudoStyleRulesForElement(Element*, StringImpl* pseudoStyle, bool authorOnly);
+
+ bool strictParsing;
+
+ struct EncodedURL {
+ String prefix; // protocol, host, etc.
+ String path;
+ String file;
+ } m_encodedURL;
+
+ void setEncodedURL(const KURL& url);
+
+ // Given a CSS keyword in the range (xx-small to -webkit-xxx-large), this function will return
+ // the correct font size scaled relative to the user's default (medium).
+ float fontSizeForKeyword(int keyword, bool quirksMode, bool monospace) const;
+
+ // When the CSS keyword "larger" is used, this function will attempt to match within the keyword
+ // table, and failing that, will simply multiply by 1.2.
+ float largerFontSize(float size, bool quirksMode) const;
+
+ // Like the previous function, but for the keyword "smaller".
+ float smallerFontSize(float size, bool quirksMode) const;
+
+ void setFontSize(FontDescription&, float size);
+ float getComputedSizeFromSpecifiedSize(bool isAbsoluteSize, float specifiedSize);
+
+ Color getColorFromPrimitiveValue(CSSPrimitiveValue*);
+
+ bool hasSelectorForAttribute(const AtomicString&);
+
+ CSSFontSelector* fontSelector() { return m_fontSelector.get(); }
+
+ /* checks if a compound selector (which can consist of multiple simple selectors)
+ matches the given Element */
+ bool checkSelector(CSSSelector*);
+
+ void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result);
+ bool affectedByViewportChange() const;
+
+ protected:
+ enum SelectorMatch {
+ SelectorMatches = 0,
+ SelectorFailsLocally,
+ SelectorFailsCompletely
+ };
+
+ SelectorMatch checkSelector(CSSSelector*, Element *, bool isAncestor, bool isSubSelector);
+
+ /* checks if the selector matches the given Element */
+ bool checkOneSelector(CSSSelector*, Element*, bool isAncestor, bool isSubSelector = false);
+
+ /* This function fixes up the default font size if it detects that the
+ current generic font family has changed. -dwh */
+ void checkForGenericFamilyChange(RenderStyle* style, RenderStyle* parentStyle);
+ void checkForTextSizeAdjust();
+
+ void adjustRenderStyle(RenderStyle*, Element*);
+
+ void addMatchedRule(CSSRuleData* rule) { m_matchedRules.append(rule); }
+ void addMatchedDeclaration(CSSMutableStyleDeclaration* decl) { m_matchedDecls.append(decl); }
+
+ void matchRules(CSSRuleSet*, int& firstRuleIndex, int& lastRuleIndex);
+ void matchRulesForList(CSSRuleDataList* rules, int& firstRuleIndex, int& lastRuleIndex);
+ void sortMatchedRules(unsigned start, unsigned end);
+
+ void applyDeclarations(bool firstPass, bool important, int startIndex, int endIndex);
+
+ static CSSStyleSheet* m_defaultSheet;
+ static CSSStyleSheet* m_quirksSheet;
+ static CSSStyleSheet* m_viewSourceSheet;
+#if ENABLE(SVG)
+ static CSSStyleSheet* m_svgSheet;
+#endif
+
+ static CSSRuleSet* m_defaultStyle;
+ static CSSRuleSet* m_defaultQuirksStyle;
+ static CSSRuleSet* m_defaultPrintStyle;
+ static CSSRuleSet* m_defaultViewSourceStyle;
+
+ CSSRuleSet* m_authorStyle;
+ CSSRuleSet* m_userStyle;
+ RefPtr<CSSStyleSheet> m_userSheet;
+
+ bool m_hasUAAppearance;
+ BorderData m_borderData;
+ BackgroundLayer m_backgroundData;
+ Color m_backgroundColor;
+
+ public:
+ static RenderStyle* m_styleNotYetAvailable;
+
+ private:
+ void init();
+
+ void matchUARules(int& firstUARule, int& lastUARule);
+ void updateFont();
+ void cacheBorderAndBackground();
+
+ void mapBackgroundAttachment(BackgroundLayer*, CSSValue*);
+ void mapBackgroundClip(BackgroundLayer*, CSSValue*);
+ void mapBackgroundComposite(BackgroundLayer*, CSSValue*);
+ void mapBackgroundOrigin(BackgroundLayer*, CSSValue*);
+ void mapBackgroundImage(BackgroundLayer*, CSSValue*);
+ void mapBackgroundRepeat(BackgroundLayer*, CSSValue*);
+ void mapBackgroundSize(BackgroundLayer*, CSSValue*);
+ void mapBackgroundXPosition(BackgroundLayer*, CSSValue*);
+ void mapBackgroundYPosition(BackgroundLayer*, CSSValue*);
+
+ void mapTransitionDuration(Transition*, CSSValue*);
+ void mapTransitionRepeatCount(Transition*, CSSValue*);
+ void mapTransitionTimingFunction(Transition*, CSSValue*);
+ void mapTransitionProperty(Transition*, CSSValue*);
+
+ // We collect the set of decls that match in |m_matchedDecls|. We then walk the
+ // set of matched decls four times, once for those properties that others depend on (like font-size),
+ // and then a second time for all the remaining properties. We then do the same two passes
+ // for any !important rules.
+ Vector<CSSMutableStyleDeclaration*> m_matchedDecls;
+
+ // A buffer used to hold the set of matched rules for an element, and a temporary buffer used for
+ // merge sorting.
+ Vector<CSSRuleData*> m_matchedRules;
+
+ CSSRuleList* m_ruleList;
+ bool m_collectRulesOnly;
+
+ MediaQueryEvaluator* m_medium;
+ RenderStyle* m_rootDefaultStyle;
+
+ RenderStyle::PseudoId dynamicPseudo;
+
+ Document* m_document; // back pointer to owner document
+ RenderStyle* m_style;
+ RenderStyle* m_parentStyle;
+ Element* m_element;
+ StyledElement* m_styledElement;
+ Node* m_parentNode;
+ RenderStyle::PseudoId m_pseudoStyle;
+ CSSValue* m_lineHeightValue;
+ bool m_fontDirty;
+ bool m_isXMLDoc;
+ bool m_matchAuthorAndUserStyles;
+
+ RefPtr<CSSFontSelector> m_fontSelector;
+
+ HashSet<AtomicStringImpl*> m_selectorAttrs;
+
+ Vector<CSSMutableStyleDeclaration*> m_additionalAttributeStyleDecls;
+
+ Vector<MediaQueryResult*> m_viewportDependentMediaQueryResults;
+
+ void applyProperty(int id, CSSValue*);
+
+#if ENABLE(SVG)
+ void applySVGProperty(int id, CSSValue*);
+#endif
+
+ friend class CSSRuleSet;
+ friend class Node;
+ };
+
+ class CSSRuleData {
+ public:
+ CSSRuleData(unsigned pos, CSSStyleRule* r, CSSSelector* sel, CSSRuleData* prev = 0)
+ : m_position(pos)
+ , m_rule(r)
+ , m_selector(sel)
+ , m_next(0)
+ {
+ if (prev)
+ prev->m_next = this;
+ }
+
+ ~CSSRuleData() { delete m_next; }
+
+ unsigned position() { return m_position; }
+ CSSStyleRule* rule() { return m_rule; }
+ CSSSelector* selector() { return m_selector; }
+ CSSRuleData* next() { return m_next; }
+
+ private:
+ unsigned m_position;
+ CSSStyleRule* m_rule;
+ CSSSelector* m_selector;
+ CSSRuleData* m_next;
+ };
+
+ class CSSRuleDataList {
+ public:
+ CSSRuleDataList(unsigned pos, CSSStyleRule* rule, CSSSelector* sel)
+ : m_first(new CSSRuleData(pos, rule, sel))
+ , m_last(m_first)
+ {
+ }
+
+ ~CSSRuleDataList() { delete m_first; }
+
+ CSSRuleData* first() { return m_first; }
+ CSSRuleData* last() { return m_last; }
+
+ void append(unsigned pos, CSSStyleRule* rule, CSSSelector* sel) { m_last = new CSSRuleData(pos, rule, sel, m_last); }
+
+ private:
+ CSSRuleData* m_first;
+ CSSRuleData* m_last;
+ };
+
+} // namespace WebCore
+
+#endif // CSSStyleSelector_h
diff --git a/WebCore/css/CSSStyleSheet.cpp b/WebCore/css/CSSStyleSheet.cpp
new file mode 100644
index 0000000..acd0955
--- /dev/null
+++ b/WebCore/css/CSSStyleSheet.cpp
@@ -0,0 +1,206 @@
+/*
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2006, 2007 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 "CSSStyleSheet.h"
+
+#include "CSSImportRule.h"
+#include "CSSNamespace.h"
+#include "CSSParser.h"
+#include "CSSRuleList.h"
+#include "Document.h"
+#include "ExceptionCode.h"
+#include "Node.h"
+
+namespace WebCore {
+
+CSSStyleSheet::CSSStyleSheet(CSSStyleSheet* parentSheet, const String& href, const String& charset)
+ : StyleSheet(parentSheet, href)
+ , m_doc(parentSheet ? parentSheet->doc() : 0)
+ , m_namespaces(0)
+ , m_charset(charset)
+ , m_loadCompleted(false)
+{
+}
+
+CSSStyleSheet::CSSStyleSheet(Node *parentNode, const String& href, const String& charset)
+ : StyleSheet(parentNode, href)
+ , m_doc(parentNode->document())
+ , m_namespaces(0)
+ , m_charset(charset)
+ , m_loadCompleted(false)
+{
+}
+
+CSSStyleSheet::CSSStyleSheet(CSSRule *ownerRule, const String& href, const String& charset)
+ : StyleSheet(ownerRule, href)
+ , m_doc(0)
+ , m_namespaces(0)
+ , m_charset(charset)
+ , m_loadCompleted(false)
+{
+}
+
+CSSStyleSheet::~CSSStyleSheet()
+{
+ delete m_namespaces;
+}
+
+CSSRule *CSSStyleSheet::ownerRule() const
+{
+ return (parent() && parent()->isRule()) ? static_cast<CSSRule*>(parent()) : 0;
+}
+
+unsigned CSSStyleSheet::insertRule(const String& rule, unsigned index, ExceptionCode& ec)
+{
+ ec = 0;
+ if (index > length()) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+ CSSParser p(useStrictParsing());
+ RefPtr<CSSRule> r = p.parseRule(this, rule);
+
+ if (!r) {
+ ec = SYNTAX_ERR;
+ return 0;
+ }
+
+ // ###
+ // HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at the specified index e.g. if an
+ //@import rule is inserted after a standard rule set or other at-rule.
+ insert(index, r.release());
+
+ styleSheetChanged();
+
+ return index;
+}
+
+int CSSStyleSheet::addRule(const String& selector, const String& style, int index, ExceptionCode& ec)
+{
+ insertRule(selector + " { " + style + " }", index, ec);
+
+ // As per Microsoft documentation, always return -1.
+ return -1;
+}
+
+int CSSStyleSheet::addRule(const String& selector, const String& style, ExceptionCode& ec)
+{
+ return addRule(selector, style, length(), ec);
+}
+
+
+CSSRuleList* CSSStyleSheet::cssRules(bool omitCharsetRules)
+{
+ return new CSSRuleList(this, omitCharsetRules);
+}
+
+void CSSStyleSheet::deleteRule(unsigned index, ExceptionCode& ec)
+{
+ if (index >= length()) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ ec = 0;
+ remove(index);
+ styleSheetChanged();
+}
+
+void CSSStyleSheet::addNamespace(CSSParser* p, const AtomicString& prefix, const AtomicString& uri)
+{
+ if (uri.isEmpty())
+ return;
+
+ m_namespaces = new CSSNamespace(prefix, uri, m_namespaces);
+
+ if (prefix.isEmpty())
+ // Set the default namespace on the parser so that selectors that omit namespace info will
+ // be able to pick it up easily.
+ p->defaultNamespace = uri;
+}
+
+const AtomicString& CSSStyleSheet::determineNamespace(const AtomicString& prefix)
+{
+ if (prefix.isEmpty())
+ return nullAtom; // No namespace. If an element/attribute has a namespace, we won't match it.
+ else if (prefix == starAtom)
+ return starAtom; // We'll match any namespace.
+ else if (m_namespaces) {
+ CSSNamespace* ns = m_namespaces->namespaceForPrefix(prefix);
+ if (ns)
+ return ns->uri();
+ }
+ return nullAtom; // Assume we wont match any namespaces.
+}
+
+bool CSSStyleSheet::parseString(const String &string, bool strict)
+{
+ setStrictParsing(strict);
+ CSSParser p(strict);
+ p.parseSheet(this, string);
+ return true;
+}
+
+bool CSSStyleSheet::isLoading()
+{
+ unsigned len = length();
+ for (unsigned i = 0; i < len; ++i) {
+ StyleBase* rule = item(i);
+ if (rule->isImportRule() && static_cast<CSSImportRule*>(rule)->isLoading())
+ return true;
+ }
+ return false;
+}
+
+void CSSStyleSheet::checkLoaded()
+{
+ if (isLoading())
+ return;
+ if (parent())
+ parent()->checkLoaded();
+ m_loadCompleted = m_parentNode ? m_parentNode->sheetLoaded() : true;
+}
+
+DocLoader *CSSStyleSheet::docLoader()
+{
+ if (!m_doc) // doc is 0 for the user- and default-sheet!
+ return 0;
+
+ // ### remove? (clients just use sheet->doc()->docLoader())
+ return m_doc->docLoader();
+}
+
+void CSSStyleSheet::styleSheetChanged()
+{
+ StyleBase* root = this;
+ while (StyleBase* parent = root->parent())
+ root = parent;
+ Document* documentToUpdate = (root && root->isCSSStyleSheet()) ? static_cast<CSSStyleSheet*>(root)->doc() : 0;
+
+ /* FIXME: We don't need to do everything updateStyleSelector does,
+ * basically we just need to recreate the document's selector with the
+ * already existing style sheets.
+ */
+ if (documentToUpdate)
+ documentToUpdate->updateStyleSelector();
+}
+
+}
diff --git a/WebCore/css/CSSStyleSheet.h b/WebCore/css/CSSStyleSheet.h
new file mode 100644
index 0000000..30cbd2a
--- /dev/null
+++ b/WebCore/css/CSSStyleSheet.h
@@ -0,0 +1,85 @@
+/*
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2006, 2007, 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 CSSStyleSheet_h
+#define CSSStyleSheet_h
+
+#include "StyleSheet.h"
+
+namespace WebCore {
+
+class CSSNamespace;
+class CSSParser;
+class CSSRule;
+class CSSRuleList;
+class DocLoader;
+class Document;
+
+typedef int ExceptionCode;
+
+class CSSStyleSheet : public StyleSheet {
+public:
+ CSSStyleSheet(Node* parentNode, const String& href = String(), const String& charset = String());
+ CSSStyleSheet(CSSStyleSheet* parentSheet, const String& href = String(), const String& charset = String());
+ CSSStyleSheet(CSSRule* ownerRule, const String& href = String(), const String& charset = String());
+
+ ~CSSStyleSheet();
+
+ virtual bool isCSSStyleSheet() const { return true; }
+
+ virtual String type() const { return "text/css"; }
+
+ CSSRule* ownerRule() const;
+ CSSRuleList* cssRules(bool omitCharsetRules = false);
+ unsigned insertRule(const String& rule, unsigned index, ExceptionCode&);
+ void deleteRule(unsigned index, ExceptionCode&);
+
+ // IE Extensions
+ CSSRuleList* rules() { return cssRules(true); }
+ int addRule(const String& selector, const String& style, int index, ExceptionCode&);
+ int addRule(const String& selector, const String& style, ExceptionCode&);
+ void removeRule(unsigned index, ExceptionCode& ec) { deleteRule(index, ec); }
+
+ void addNamespace(CSSParser*, const AtomicString& prefix, const AtomicString& uri);
+ const AtomicString& determineNamespace(const AtomicString& prefix);
+
+ virtual void styleSheetChanged();
+
+ virtual bool parseString(const String&, bool strict = true);
+
+ virtual bool isLoading();
+
+ virtual void checkLoaded();
+ DocLoader* docLoader();
+ Document* doc() { return m_doc; }
+ const String& charset() const { return m_charset; }
+
+ bool loadCompleted() const { return m_loadCompleted; }
+
+protected:
+ Document* m_doc;
+ CSSNamespace* m_namespaces;
+ String m_charset;
+ bool m_loadCompleted;
+};
+
+} // namespace
+
+#endif
diff --git a/WebCore/css/CSSStyleSheet.idl b/WebCore/css/CSSStyleSheet.idl
new file mode 100644
index 0000000..dacaeb5
--- /dev/null
+++ b/WebCore/css/CSSStyleSheet.idl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [
+ InterfaceUUID=2f547f65-f8c4-4f13-8724-ed10ed79dcc4,
+ ImplementationUUID=1b5c24b3-8b6f-43a9-8891-654ba858f42f
+ ] CSSStyleSheet : stylesheets::StyleSheet {
+ readonly attribute CSSRule ownerRule;
+ readonly attribute CSSRuleList cssRules;
+
+ [OldStyleObjC] unsigned long insertRule(in DOMString rule,
+ in unsigned long index)
+ raises(DOMException);
+ void deleteRule(in unsigned long index)
+ raises(DOMException);
+
+ // IE Extensions
+ readonly attribute CSSRuleList rules;
+
+ long addRule(in DOMString selector,
+ in DOMString style,
+ in [Optional] unsigned long index)
+ raises(DOMException);
+ void removeRule(in unsigned long index)
+ raises(DOMException);
+ };
+
+}
diff --git a/WebCore/css/CSSTimingFunctionValue.cpp b/WebCore/css/CSSTimingFunctionValue.cpp
new file mode 100644
index 0000000..e576d36
--- /dev/null
+++ b/WebCore/css/CSSTimingFunctionValue.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 Apple Computer, 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 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.
+ */
+
+#include "config.h"
+#include "CSSTimingFunctionValue.h"
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+String CSSTimingFunctionValue::cssText() const
+{
+ String text("cubic-bezier(");
+ text += String::number(m_x1);
+ text += ", ";
+ text += String::number(m_y1);
+ text += ", ";
+ text += String::number(m_x2);
+ text += ", ";
+ text += String::number(m_y2);
+ text += ")";
+ return text;
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSTimingFunctionValue.h b/WebCore/css/CSSTimingFunctionValue.h
new file mode 100644
index 0000000..5d808be
--- /dev/null
+++ b/WebCore/css/CSSTimingFunctionValue.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007 Apple Computer, 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 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 CSSTimingFunctionValue_h
+#define CSSTimingFunctionValue_h
+
+#include "CSSValue.h"
+#include "FloatPoint.h"
+
+namespace WebCore {
+
+class CSSTimingFunctionValue : public CSSValue
+{
+public:
+ CSSTimingFunctionValue(double x1, double y1, double x2, double y2)
+ : m_x1(x1)
+ , m_y1(y1)
+ , m_x2(x2)
+ , m_y2(y2)
+ {
+ }
+
+ virtual String cssText() const;
+
+ virtual bool isTransitionTimingFunctionValue() { return true; }
+
+ double x1() const { return m_x1; }
+ double y1() const { return m_y1; }
+ double x2() const { return m_x2; }
+ double y2() const { return m_y2; }
+
+private:
+ double m_x1;
+ double m_y1;
+ double m_x2;
+ double m_y2;
+};
+
+} // namespace
+
+#endif
diff --git a/WebCore/css/CSSTransformValue.cpp b/WebCore/css/CSSTransformValue.cpp
new file mode 100644
index 0000000..34f4dae
--- /dev/null
+++ b/WebCore/css/CSSTransformValue.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2007 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 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.
+ */
+
+#include "config.h"
+#include "CSSTransformValue.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+CSSTransformValue::CSSTransformValue(TransformOperationType op)
+: m_type(op)
+{}
+
+CSSTransformValue::~CSSTransformValue()
+{}
+
+void CSSTransformValue::addValue(CSSValue* val)
+{
+ if (!m_values)
+ m_values = new CSSValueList;
+ m_values->append(val);
+}
+
+String CSSTransformValue::cssText() const
+{
+ String result;
+ switch(m_type) {
+ case ScaleTransformOperation:
+ result += "scale(";
+ break;
+ case ScaleXTransformOperation:
+ result += "scaleX(";
+ break;
+ case ScaleYTransformOperation:
+ result += "scaleY(";
+ break;
+ case RotateTransformOperation:
+ result += "rotate(";
+ break;
+ case SkewTransformOperation:
+ result += "skew(";
+ break;
+ case SkewXTransformOperation:
+ result += "skewX(";
+ break;
+ case SkewYTransformOperation:
+ result += "skewY(";
+ break;
+ case TranslateTransformOperation:
+ result += "translate(";
+ break;
+ case TranslateXTransformOperation:
+ result += "translateX(";
+ break;
+ case TranslateYTransformOperation:
+ result += "translateY(";
+ break;
+ case MatrixTransformOperation:
+ result += "matrix(";
+ break;
+ default:
+ break;
+ }
+
+ if (m_values)
+ result += m_values->cssText();
+
+ result += ")";
+ return result;
+}
+
+}
diff --git a/WebCore/css/CSSTransformValue.h b/WebCore/css/CSSTransformValue.h
new file mode 100644
index 0000000..6a35d39
--- /dev/null
+++ b/WebCore/css/CSSTransformValue.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007 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 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.
+ */
+
+#include "CSSValue.h"
+#include "CSSValueList.h"
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSTransformValue : public CSSValue
+{
+public:
+ enum TransformOperationType {
+ UnknownTransformOperation,
+ ScaleTransformOperation,
+ ScaleXTransformOperation,
+ ScaleYTransformOperation,
+ RotateTransformOperation,
+ SkewTransformOperation,
+ SkewXTransformOperation,
+ SkewYTransformOperation,
+ TranslateTransformOperation,
+ TranslateXTransformOperation,
+ TranslateYTransformOperation,
+ MatrixTransformOperation
+ };
+
+ CSSTransformValue(TransformOperationType);
+ virtual ~CSSTransformValue();
+
+ void addValue(CSSValue*);
+
+ virtual String cssText() const;
+
+ TransformOperationType type() const { return m_type; }
+ CSSValueList* values() const { return m_values.get(); }
+
+protected:
+ TransformOperationType m_type;
+ RefPtr<CSSValueList> m_values;
+};
+
+}
diff --git a/WebCore/css/CSSUnicodeRangeValue.cpp b/WebCore/css/CSSUnicodeRangeValue.cpp
new file mode 100644
index 0000000..599c078
--- /dev/null
+++ b/WebCore/css/CSSUnicodeRangeValue.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 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 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.
+ */
+
+#include "config.h"
+#include "CSSUnicodeRangeValue.h"
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+CSSUnicodeRangeValue::~CSSUnicodeRangeValue()
+{
+}
+
+String CSSUnicodeRangeValue::cssText() const
+{
+ String result;
+ // FIXME: Implement.
+ return result;
+}
+
+}
diff --git a/WebCore/css/CSSUnicodeRangeValue.h b/WebCore/css/CSSUnicodeRangeValue.h
new file mode 100644
index 0000000..8eca31e
--- /dev/null
+++ b/WebCore/css/CSSUnicodeRangeValue.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 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 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 CSSUnicodeRangeValue_h
+#define CSSUnicodeRangeValue_h
+
+#include "CSSValue.h"
+#include <wtf/unicode/Unicode.h>
+
+namespace WebCore {
+
+class CSSUnicodeRangeValue : public CSSValue {
+public:
+ CSSUnicodeRangeValue(UChar32 from, UChar32 to)
+ : m_from(from)
+ , m_to(to)
+ {
+ }
+
+ virtual ~CSSUnicodeRangeValue();
+
+ UChar32 from() const { return m_from; }
+ UChar32 to() const { return m_to; }
+
+ virtual String cssText() const;
+
+private:
+ UChar32 m_from;
+ UChar32 m_to;
+};
+
+} // namespace WebCore
+
+#endif // CSSUnicodeRangeValue_h
diff --git a/WebCore/css/CSSUnknownRule.h b/WebCore/css/CSSUnknownRule.h
new file mode 100644
index 0000000..4396eb7
--- /dev/null
+++ b/WebCore/css/CSSUnknownRule.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2006 Apple Computer, Inc.
+ *
+ * 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 CSSUnknownRule_h
+#define CSSUnknownRule_h
+
+#include "CSSRule.h"
+
+namespace WebCore {
+
+class CSSUnknownRule : public CSSRule {
+public:
+ CSSUnknownRule(StyleBase* parent)
+ : CSSRule(parent)
+ {
+ }
+
+ virtual bool isUnknownRule() { return true; }
+
+ virtual unsigned short type() const { return UNKNOWN_RULE; }
+};
+
+} // namespace WebCore
+
+#endif // CSSUnknownRule_h
diff --git a/WebCore/css/CSSUnknownRule.idl b/WebCore/css/CSSUnknownRule.idl
new file mode 100644
index 0000000..2365cd2
--- /dev/null
+++ b/WebCore/css/CSSUnknownRule.idl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [
+ InterfaceUUID=35670098-b732-419c-b7cd-dc0d5e26d5e3,
+ ImplementationUUID=4b755f87-2509-4b98-a953-8ecb88fe4b21
+ ] CSSUnknownRule : CSSRule {
+ };
+
+}
diff --git a/WebCore/css/CSSValue.h b/WebCore/css/CSSValue.h
new file mode 100644
index 0000000..b24f605
--- /dev/null
+++ b/WebCore/css/CSSValue.h
@@ -0,0 +1,55 @@
+/*
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007 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 CSSValue_h
+#define CSSValue_h
+
+#include "StyleBase.h"
+
+namespace WebCore {
+
+typedef int ExceptionCode;
+
+class CSSValue : public StyleBase {
+public:
+ enum UnitTypes {
+ CSS_INHERIT = 0,
+ CSS_PRIMITIVE_VALUE = 1,
+ CSS_VALUE_LIST = 2,
+ CSS_CUSTOM = 3,
+ CSS_INITIAL = 4
+ };
+
+ CSSValue() : StyleBase(0) { }
+
+ virtual unsigned short cssValueType() const { return CSS_CUSTOM; }
+
+ virtual String cssText() const = 0;
+ void setCssText(const String&, ExceptionCode&) { } // FIXME: Not implemented.
+
+ virtual bool isValue() { return true; }
+ virtual bool isFontValue() { return false; }
+ virtual bool isImplicitInitialValue() const { return false; }
+ virtual bool isTransitionTimingFunctionValue() { return false; }
+};
+
+} // namespace WebCore
+
+#endif // CSSValue_h
diff --git a/WebCore/css/CSSValue.idl b/WebCore/css/CSSValue.idl
new file mode 100644
index 0000000..8979b61
--- /dev/null
+++ b/WebCore/css/CSSValue.idl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ */
+
+module css {
+
+ interface [
+ GenerateConstructor,
+ ObjCCustomInternalImpl,
+ InterfaceUUID=9fd62a7b-539d-4500-bd6c-ec075abbc404,
+ ImplementationUUID=e10a2860-f98e-4bd3-96b4-1493ad941dfe
+ ] CSSValue {
+
+ // UnitTypes
+ const unsigned short CSS_INHERIT = 0;
+ const unsigned short CSS_PRIMITIVE_VALUE = 1;
+ const unsigned short CSS_VALUE_LIST = 2;
+ const unsigned short CSS_CUSTOM = 3;
+
+ attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString cssText
+ setter raises(DOMException);
+
+ readonly attribute unsigned short cssValueType;
+
+ };
+
+}
diff --git a/WebCore/css/CSSValueKeywords.in b/WebCore/css/CSSValueKeywords.in
new file mode 100644
index 0000000..a8c0062
--- /dev/null
+++ b/WebCore/css/CSSValueKeywords.in
@@ -0,0 +1,567 @@
+# These are all values accepted for CSS2.
+#
+# WARNING:
+# --------
+#
+# The Values are sorted according to the properties they belong to,
+# and have to be in the same order as the enums in RenderStyle.h.
+#
+# If not, the optimizations in the cssparser and style selector will fail,
+# and produce incorrect results.
+#
+inherit
+initial
+#
+# CSS_PROP_OUTLINE_STYLE
+# CSS_PROP_BORDER_TOP_STYLE
+# CSS_PROP_BORDER_BOTTOM_STYLE
+# CSS_PROP_BORDER_LEFT_STYLE
+none
+hidden
+inset
+groove
+ridge
+outset
+dotted
+dashed
+solid
+double
+#
+# CSS_PROP_FONT:
+#
+caption
+icon
+menu
+message-box
+small-caption
+-webkit-mini-control
+-webkit-small-control
+-webkit-control
+status-bar
+
+#
+# CSS_PROP_FONT_STYLE:
+#
+#normal
+italic
+oblique
+#
+# CSS_PROP_FONT_VARIANT:
+#
+#normal
+small-caps
+#
+# CSS_PROP_FONT_WEIGHT:
+#
+normal
+bold
+bolder
+lighter
+100
+200
+300
+400
+500
+600
+700
+800
+900
+#
+# CSS_PROP_FONT_SIZE:
+#
+xx-small
+x-small
+small
+medium
+large
+x-large
+xx-large
+-webkit-xxx-large
+smaller
+larger
+#
+# CSS_PROP_FONT_STRETCH:
+#
+#normal
+wider
+narrower
+ultra-condensed
+extra-condensed
+condensed
+semi-condensed
+semi-expanded
+expanded
+extra-expanded
+ultra-expanded
+#
+# CSS_PROP_GENERIC_FONT_FAMILY:
+#
+serif
+sans-serif
+cursive
+fantasy
+monospace
+-webkit-body
+#
+#
+# CSS_PROP_*_COLOR
+#
+aqua
+black
+blue
+fuchsia
+gray
+green
+lime
+maroon
+navy
+olive
+orange
+purple
+red
+silver
+teal
+white
+yellow
+transparent
+-webkit-link
+-webkit-activelink
+activeborder
+activecaption
+appworkspace
+background
+buttonface
+buttonhighlight
+buttonshadow
+buttontext
+captiontext
+graytext
+highlight
+highlighttext
+inactiveborder
+inactivecaption
+inactivecaptiontext
+infobackground
+infotext
+match
+menutext
+scrollbar
+threeddarkshadow
+threedface
+threedhighlight
+threedlightshadow
+threedshadow
+window
+windowframe
+windowtext
+-webkit-focus-ring-color
+#
+# colors in non strict mode
+grey
+-webkit-text
+#
+# CSS_PROP_BACKGROUND_REPEAT:
+#
+repeat
+repeat-x
+repeat-y
+no-repeat
+#
+# CSS_PROP__WEBKIT_BACKGROUND_COMPOSITE:
+#
+clear
+copy
+source-over
+source-in
+source-out
+source-atop
+destination-over
+destination-in
+destination-out
+destination-atop
+xor
+plus-darker
+# highlight
+plus-lighter
+#
+# CSS_PROP_VERTICAL_ALIGN:
+#
+baseline
+middle
+sub
+super
+text-top
+text-bottom
+top
+bottom
+# HTML alignment MIDDLE has no corresponding CSS alignment
+-webkit-baseline-middle
+#
+# CSS_PROP_TEXT_ALIGN:
+#
+-webkit-auto
+left
+right
+center
+justify
+-webkit-left
+-webkit-right
+-webkit-center
+#
+# CSS_PROP_LIST_STYLE_POSITION:
+#
+outside
+inside
+#
+# CSS_PROP_LIST_STYLE_TYPE:
+#
+disc
+circle
+square
+decimal
+decimal-leading-zero
+lower-roman
+upper-roman
+lower-greek
+lower-alpha
+lower-latin
+upper-alpha
+upper-latin
+hebrew
+armenian
+georgian
+cjk-ideographic
+hiragana
+katakana
+hiragana-iroha
+katakana-iroha
+#none
+#
+# CSS_PROP_DISPLAY:
+#
+inline
+block
+list-item
+run-in
+compact
+inline-block
+table
+inline-table
+table-row-group
+table-header-group
+table-footer-group
+table-row
+table-column-group
+table-column
+table-cell
+table-caption
+-webkit-box
+-webkit-inline-box
+#none
+#
+# CSS_PROP_CURSOR:
+#
+auto
+crosshair
+default
+pointer
+move
+vertical-text
+cell
+context-menu
+alias
+# copy
+progress
+no-drop
+not-allowed
+-webkit-zoom-in
+-webkit-zoom-out
+e-resize
+ne-resize
+nw-resize
+n-resize
+se-resize
+sw-resize
+s-resize
+w-resize
+ew-resize
+ns-resize
+nesw-resize
+nwse-resize
+col-resize
+row-resize
+text
+wait
+help
+all-scroll
+# none
+#
+# CSS_PROP_DIRECTION:
+#
+ltr
+rtl
+#
+# CSS_PROP_TEXT_TRANSFORM:
+#
+capitalize
+uppercase
+lowercase
+#none
+#
+# CSS_PROP_VISIBILITY:
+#
+visible
+#hidden
+collapse
+#
+# Unordered rest
+#
+above
+absolute
+always
+avoid
+below
+bidi-override
+blink
+both
+close-quote
+crop
+cross
+embed
+fixed
+hand
+hide
+higher
+invert
+landscape
+level
+line-through
+loud
+lower
+-webkit-marquee
+mix
+no-close-quote
+no-open-quote
+nowrap
+open-quote
+overlay
+overline
+portrait
+pre
+pre-line
+pre-wrap
+relative
+scroll
+separate
+show
+static
+thick
+thin
+underline
+-webkit-nowrap
+
+# CSS3 Values
+# CSS_PROP_BOX_ALIGN
+stretch
+start
+end
+#center
+#baseline
+
+# CSS_PROP_BOX_DIRECTION
+# normal
+reverse
+
+# CSS_PROP_BOX_ORIENT
+horizontal
+vertical
+inline-axis
+block-axis
+
+# CSS_PROP_BOX_PACK
+# start
+# end
+# center
+# justify
+
+# CSS_PROP_BOX_LINES
+single
+multiple
+
+# CSS_PROP_MARQUEE_DIRECTION
+forwards
+backwards
+ahead
+# reverse
+# left
+# right
+up
+down
+# auto
+
+# CSS_PROP_MARQUEE_SPEED
+slow
+# normal
+fast
+
+# CSS_PROP_MARQUEE_REPETITION
+infinite
+
+# CSS_PROP_MARQUEE_STYLE
+# none
+slide
+# scroll
+alternate
+
+#
+# CSS_PROP__KHTML_USER_MODIFY
+#
+read-only
+read-write
+read-write-plaintext-only
+
+#
+# CSS_PROP__KHTML_USER_DRAG
+#
+element
+
+#
+# CSS_PROP__KHTML_USER_SELECT
+#
+ignore
+
+#
+# CSS_PROP_WIDTH/MIN_WIDTH/MAX_WIDTH
+#
+intrinsic
+min-intrinsic
+
+#
+# CSS_PROP_TEXT_OVERFLOW
+#
+clip
+ellipsis
+
+#
+# CSS_PROP__KHTML_MARGIN_COLLAPSE
+#
+# collapse
+# separate
+discard
+
+#
+# CSS_PROP_TEXT_*_COLOR
+#
+dot-dash
+dot-dot-dash
+wave
+
+#
+# CSS_PROP_TEXT_*_MODE
+#
+continuous
+skip-white-space
+
+#
+# CSS_PROP_WORD_BREAK
+#
+break-all
+
+#
+# CSS_PROP_WORD_WRAP
+#
+break-word
+
+#
+# CSS_PROP__KHTML_NBSP_MODE
+#
+space
+
+#
+# CSS_PROP__KHTML_LINE_BREAK
+#
+after-white-space
+
+#
+# CSS_PROP__KHTML_APPEARANCE
+#
+checkbox
+radio
+push-button
+square-button
+button
+button-bevel
+listbox
+listitem
+media-fullscreen-button
+media-mute-button
+media-play-button
+media-seek-back-button
+media-seek-forward-button
+media-slider
+media-sliderthumb
+menulist
+menulist-button
+menulist-text
+menulist-textfield
+scrollbarbutton-up
+scrollbarbutton-down
+scrollbarbutton-left
+scrollbarbutton-right
+scrollbartrack-horizontal
+scrollbartrack-vertical
+scrollbarthumb-horizontal
+scrollbarthumb-vertical
+scrollbargripper-horizontal
+scrollbargripper-vertical
+slider-horizontal
+slider-vertical
+sliderthumb-horizontal
+sliderthumb-vertical
+caret
+searchfield
+searchfield-decoration
+searchfield-results-decoration
+searchfield-results-button
+searchfield-cancel-button
+textfield
+textarea
+
+#
+# CSS_PROP_BORDER_IMAGE
+#
+# stretch
+# repeat
+round
+
+#
+# CSS_PROP_BACKGROUND_CLIP/ORIGIN
+#
+border
+content
+padding
+
+#
+# CSS_PROP_BOX_SIZING
+#
+border-box
+content-box
+
+#
+# CSS_PROP__KHTML_RTL_ORDERING
+#
+logical
+visual
+
+#
+# CSS_PROP__WEBKIT_BORDER_FIT
+#
+lines
+
+#
+# CSS_PROP__WEBKIT_TRANSITION_TIMING_FUNCTION
+#
+linear
+ease-in
+ease-out
+ease-in-out
diff --git a/WebCore/css/CSSValueList.cpp b/WebCore/css/CSSValueList.cpp
new file mode 100644
index 0000000..c845ab9
--- /dev/null
+++ b/WebCore/css/CSSValueList.cpp
@@ -0,0 +1,66 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007 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 "CSSValueList.h"
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+CSSValueList::CSSValueList(bool isSpaceSeparated)
+ : m_isSpaceSeparated(isSpaceSeparated)
+{
+}
+
+CSSValueList::~CSSValueList()
+{
+}
+
+unsigned short CSSValueList::cssValueType() const
+{
+ return CSS_VALUE_LIST;
+}
+
+void CSSValueList::append(PassRefPtr<CSSValue> val)
+{
+ m_values.append(val);
+}
+
+String CSSValueList::cssText() const
+{
+ String result = "";
+
+ unsigned size = m_values.size();
+ for (unsigned i = 0; i < size; i++) {
+ if (!result.isEmpty()) {
+ if (m_isSpaceSeparated)
+ result += " ";
+ else
+ result += ", ";
+ }
+ result += m_values[i]->cssText();
+ }
+
+ return result;
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/CSSValueList.h b/WebCore/css/CSSValueList.h
new file mode 100644
index 0000000..405df52
--- /dev/null
+++ b/WebCore/css/CSSValueList.h
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007 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 CSSValueList_h
+#define CSSValueList_h
+
+#include "CSSValue.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class CSSValueList : public CSSValue {
+public:
+ CSSValueList(bool isSpaceSeparated = false);
+ virtual ~CSSValueList();
+
+ unsigned length() const { return m_values.size(); }
+ CSSValue* item (unsigned index) { return m_values[index].get(); }
+
+ virtual bool isValueList() { return true; }
+
+ virtual unsigned short cssValueType() const;
+
+ void append(PassRefPtr<CSSValue>);
+ virtual String cssText() const;
+
+protected:
+ Vector<RefPtr<CSSValue> > m_values;
+ bool m_isSpaceSeparated;
+};
+
+} // namespace WebCore
+
+#endif // CSSValueList_h
diff --git a/WebCore/css/CSSValueList.idl b/WebCore/css/CSSValueList.idl
new file mode 100644
index 0000000..8ddfaae
--- /dev/null
+++ b/WebCore/css/CSSValueList.idl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006, 2007 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 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.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [
+ GenerateConstructor,
+ HasIndexGetter,
+ InterfaceUUID=2fb74620-9029-400c-bc4b-4ce8e25b081f,
+ ImplementationUUID=1d8fc822-f89a-48d5-a2ac-827e5a24357e
+ ] CSSValueList : CSSValue {
+ readonly attribute unsigned long length;
+ CSSValue item(in unsigned long index);
+ };
+
+}
diff --git a/WebCore/css/Counter.h b/WebCore/css/Counter.h
new file mode 100644
index 0000000..9bca29b
--- /dev/null
+++ b/WebCore/css/Counter.h
@@ -0,0 +1,61 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 Counter_h
+#define Counter_h
+
+#include "CSSPrimitiveValue.h"
+#include "PlatformString.h"
+#include <wtf/RefCounted.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class Counter : public RefCounted<Counter> {
+public:
+ Counter(PassRefPtr<CSSPrimitiveValue> identifier, PassRefPtr<CSSPrimitiveValue> listStyle, PassRefPtr<CSSPrimitiveValue> separator)
+ : RefCounted<Counter>(0)
+ , m_identifier(identifier)
+ , m_listStyle(listStyle)
+ , m_separator(separator)
+ {
+ }
+
+ String identifier() const { return m_identifier ? m_identifier->getStringValue() : String(); }
+ String listStyle() const { return m_listStyle ? m_listStyle->getStringValue() : String(); }
+ String separator() const { return m_separator ? m_separator->getStringValue() : String(); }
+
+ int listStyleNumber() const { return m_listStyle ? m_listStyle->getIntValue() : 0; }
+
+ void setIdentifier(PassRefPtr<CSSPrimitiveValue> identifier) { m_identifier = identifier; }
+ void setListStyle(PassRefPtr<CSSPrimitiveValue> listStyle) { m_listStyle = listStyle; }
+ void setSeparator(PassRefPtr<CSSPrimitiveValue> separator) { m_separator = separator; }
+
+protected:
+ RefPtr<CSSPrimitiveValue> m_identifier; // String
+ RefPtr<CSSPrimitiveValue> m_listStyle; // int
+ RefPtr<CSSPrimitiveValue> m_separator; // String
+};
+
+} // namespace WebCore
+
+#endif // Counter_h
diff --git a/WebCore/css/Counter.idl b/WebCore/css/Counter.idl
new file mode 100644
index 0000000..5be8f0d
--- /dev/null
+++ b/WebCore/css/Counter.idl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006, 2007 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.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [
+ GenerateConstructor,
+ InterfaceUUID=365d0f26-3a6e-457c-a34c-174d98f79798,
+ ImplementationUUID=8bfdc968-9a1b-4e4f-8d36-732d49b48eaa
+ ] Counter {
+ readonly attribute DOMString identifier;
+ readonly attribute DOMString listStyle;
+ readonly attribute DOMString separator;
+ };
+
+}
diff --git a/WebCore/css/DashboardRegion.h b/WebCore/css/DashboardRegion.h
new file mode 100644
index 0000000..338b6aa
--- /dev/null
+++ b/WebCore/css/DashboardRegion.h
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 DashboardRegion_h
+#define DashboardRegion_h
+
+#include "Rect.h"
+
+namespace WebCore {
+
+class DashboardRegion : public Rect {
+public:
+ DashboardRegion() : m_isCircle(0), m_isRectangle(0) { }
+
+ RefPtr<DashboardRegion> m_next;
+ String m_label;
+ String m_geometryType;
+ bool m_isCircle : 1;
+ bool m_isRectangle : 1;
+};
+
+} // namespace
+
+#endif
diff --git a/WebCore/css/FontFamilyValue.cpp b/WebCore/css/FontFamilyValue.cpp
new file mode 100644
index 0000000..f9bd75c
--- /dev/null
+++ b/WebCore/css/FontFamilyValue.cpp
@@ -0,0 +1,106 @@
+/*
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 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 "FontFamilyValue.h"
+
+namespace WebCore {
+
+static bool isValidCSSIdentifier(const String& string)
+{
+ unsigned length = string.length();
+ if (!length)
+ return false;
+
+ const UChar* characters = string.characters();
+ UChar c = characters[0];
+ if (!(c == '_' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c >= 0x80))
+ return false;
+
+ for (unsigned i = 1; i < length; ++i) {
+ c = characters[i];
+ if (!(c == '_' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c >= 0x80))
+ return false;
+ }
+
+ return true;
+}
+
+// Quotes the string if it needs quoting.
+// We use single quotes because serialization code uses double quotes, and it's nice to
+// avoid having to turn all the quote marks into &quot; as we would have to.
+static String quoteStringIfNeeded(const String& string)
+{
+ if (isValidCSSIdentifier(string))
+ return string;
+
+ // FIXME: Also need to transform control characters (00-1F) into \ sequences.
+ // FIXME: This is inefficient -- should use a Vector<UChar> instead.
+ String quotedString = string;
+ quotedString.replace('\\', "\\\\");
+ quotedString.replace('\'', "\\'");
+ return "'" + quotedString + "'";
+}
+
+FontFamilyValue::FontFamilyValue(const String& familyName)
+ : CSSPrimitiveValue(String(), CSS_STRING)
+ , m_familyName(familyName)
+{
+ // If there is anything in parentheses or square brackets at the end, delete it.
+ // FIXME: Do we really need this? The original code mentioned "a language tag in
+ // braces at the end" and "[Xft] qualifiers", but it's not clear either of those
+ // is in active use on the web.
+ unsigned length = m_familyName.length();
+ while (length >= 3) {
+ UChar startCharacter = 0;
+ switch (m_familyName[length - 1]) {
+ case ']':
+ startCharacter = '[';
+ break;
+ case ')':
+ startCharacter = '(';
+ break;
+ }
+ if (!startCharacter)
+ break;
+ unsigned first = 0;
+ for (unsigned i = length - 2; i > 0; --i) {
+ if (m_familyName[i - 1] == ' ' && m_familyName[i] == startCharacter)
+ first = i - 1;
+ }
+ if (!first)
+ break;
+ length = first;
+ }
+ m_familyName.truncate(length);
+}
+
+void FontFamilyValue::appendSpaceSeparated(const UChar* characters, unsigned length)
+{
+ m_familyName.append(' ');
+ m_familyName.append(characters, length);
+}
+
+String FontFamilyValue::cssText() const
+{
+ return quoteStringIfNeeded(m_familyName);
+}
+
+}
diff --git a/WebCore/css/FontFamilyValue.h b/WebCore/css/FontFamilyValue.h
new file mode 100644
index 0000000..9e3cef4
--- /dev/null
+++ b/WebCore/css/FontFamilyValue.h
@@ -0,0 +1,44 @@
+/*
+ * (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 FontFamilyValue_h
+#define FontFamilyValue_h
+
+#include "CSSPrimitiveValue.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class FontFamilyValue : public CSSPrimitiveValue {
+public:
+ FontFamilyValue(const String& familyName);
+ void appendSpaceSeparated(const UChar* characters, unsigned length);
+
+ const String& familyName() const { return m_familyName; }
+
+ virtual String cssText() const;
+
+private:
+ String m_familyName;
+};
+
+} // namespace
+
+#endif
diff --git a/WebCore/css/FontValue.cpp b/WebCore/css/FontValue.cpp
new file mode 100644
index 0000000..231ac64
--- /dev/null
+++ b/WebCore/css/FontValue.cpp
@@ -0,0 +1,69 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 "FontValue.h"
+
+#include "CSSValueList.h"
+#include "CSSPrimitiveValue.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+String FontValue::cssText() const
+{
+ // font variant weight size / line-height family
+
+ String result("");
+
+ if (style)
+ result += style->cssText();
+ if (variant) {
+ if (!result.isEmpty())
+ result += " ";
+ result += variant->cssText();
+ }
+ if (weight) {
+ if (!result.isEmpty())
+ result += " ";
+ result += weight->cssText();
+ }
+ if (size) {
+ if (!result.isEmpty())
+ result += " ";
+ result += size->cssText();
+ }
+ if (lineHeight) {
+ if (!size)
+ result += " ";
+ result += "/";
+ result += lineHeight->cssText();
+ }
+ if (family) {
+ if (!result.isEmpty())
+ result += " ";
+ result += family->cssText();
+ }
+
+ return result;
+}
+
+}
diff --git a/WebCore/css/FontValue.h b/WebCore/css/FontValue.h
new file mode 100644
index 0000000..d52bfdd
--- /dev/null
+++ b/WebCore/css/FontValue.h
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 FontValue_h
+#define FontValue_h
+
+#include "CSSValue.h"
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSPrimitiveValue;
+class CSSValueList;
+
+class FontValue : public CSSValue
+{
+public:
+ virtual String cssText() const;
+
+ virtual bool isFontValue() { return true; }
+
+ RefPtr<CSSPrimitiveValue> style;
+ RefPtr<CSSPrimitiveValue> variant;
+ RefPtr<CSSPrimitiveValue> weight;
+ RefPtr<CSSPrimitiveValue> size;
+ RefPtr<CSSPrimitiveValue> lineHeight;
+ RefPtr<CSSValueList> family;
+};
+
+} // namespace
+
+#endif
diff --git a/WebCore/css/MediaFeatureNames.cpp b/WebCore/css/MediaFeatureNames.cpp
new file mode 100644
index 0000000..958436d
--- /dev/null
+++ b/WebCore/css/MediaFeatureNames.cpp
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * Copyright (C) 2005 Apple Computer, Inc.
+ *
+ * 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"
+
+#ifdef AVOID_STATIC_CONSTRUCTORS
+#define CSS_MEDIAQUERY_NAMES_HIDE_GLOBALS 1
+#endif
+
+#include "MediaFeatureNames.h"
+#include "StaticConstructors.h"
+
+namespace WebCore {
+namespace MediaFeatureNames {
+
+#define DEFINE_MEDIAFEATURE_GLOBAL(name, str) \
+ DEFINE_GLOBAL(AtomicString, name##MediaFeature, str)
+CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(DEFINE_MEDIAFEATURE_GLOBAL)
+#undef DEFINE_MEDIAFEATURE_GLOBAL
+
+void init()
+{
+ static bool initialized;
+ if (!initialized) {
+ // Use placement new to initialize the globals.
+
+ AtomicString::init();
+ #define INITIALIZE_GLOBAL(name, str) new ((void*)&name##MediaFeature) AtomicString(str);
+ CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(INITIALIZE_GLOBAL)
+ #undef INITIALIZE_GLOBAL
+ initialized = true;
+ }
+}
+
+} // namespace MediaFeatureNames
+} // namespace WebCore
diff --git a/WebCore/css/MediaFeatureNames.h b/WebCore/css/MediaFeatureNames.h
new file mode 100644
index 0000000..54b61b1
--- /dev/null
+++ b/WebCore/css/MediaFeatureNames.h
@@ -0,0 +1,69 @@
+/*
+ * This file is part of the CSS implementation for KDE.
+ *
+ * Copyright (C) 2005 Apple Computer, Inc.
+ *
+ * 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 MediaFeatureNames_h
+#define MediaFeatureNames_h
+
+#include "AtomicString.h"
+
+namespace WebCore {
+ namespace MediaFeatureNames {
+
+#define CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(macro) \
+ macro(color, "color") \
+ macro(grid, "grid") \
+ macro(monochrome, "monochrome") \
+ macro(height, "height") \
+ macro(width, "width") \
+ macro(device_aspect_ratio, "device-aspect-ratio") \
+ macro(device_pixel_ratio, "-webkit-device-pixel-ratio") \
+ macro(device_height, "device-height") \
+ macro(device_width, "device-width") \
+ macro(max_color, "max-color") \
+ macro(max_device_aspect_ratio, "max-device-aspect-ratio") \
+ macro(max_device_pixel_ratio, "-webkit-max-device-pixel-ratio") \
+ macro(max_device_height, "max-device-height") \
+ macro(max_device_width, "max-device-width") \
+ macro(max_height, "max-height") \
+ macro(max_monochrome, "max-monochrome") \
+ macro(max_width, "max-width") \
+ macro(min_color, "min-color") \
+ macro(min_device_aspect_ratio, "min-device-aspect-ratio") \
+ macro(min_device_pixel_ratio, "-webkit-min-device-pixel-ratio") \
+ macro(min_device_height, "min-device-height") \
+ macro(min_device_width, "min-device-width") \
+ macro(min_height, "min-height") \
+ macro(min_monochrome, "min-monochrome") \
+ macro(min_width, "min-width") \
+// end of macro
+
+#ifndef CSS_MEDIAQUERY_NAMES_HIDE_GLOBALS
+ #define CSS_MEDIAQUERY_NAMES_DECLARE(name, str) extern const AtomicString name##MediaFeature;
+ CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(CSS_MEDIAQUERY_NAMES_DECLARE)
+ #undef CSS_MEDIAQUERY_NAMES_DECLARE
+#endif
+
+ void init();
+
+ } // namespace MediaFeatureNames
+} // namespace WebCore
+
+#endif // MediaFeatureNames_h
diff --git a/WebCore/css/MediaList.cpp b/WebCore/css/MediaList.cpp
new file mode 100644
index 0000000..397eb1b
--- /dev/null
+++ b/WebCore/css/MediaList.cpp
@@ -0,0 +1,271 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ *
+ * 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 "MediaList.h"
+
+#include "CSSParser.h"
+#include "CSSRule.h"
+#include "CSSStyleSheet.h"
+#include "ExceptionCode.h"
+#include "MediaQuery.h"
+
+namespace WebCore {
+
+/* MediaList is used to store 3 types of media related entities which mean the same:
+ * Media Queries, Media Types and Media Descriptors.
+ * Currently MediaList always tries to parse media queries and if parsing fails,
+ * tries to fallback to Media Descriptors if m_fallback flag is set.
+ * Slight problem with syntax error handling:
+ * CSS 2.1 Spec (http://www.w3.org/TR/CSS21/media.html)
+ * specifies that failing media type parsing is a syntax error
+ * CSS 3 Media Queries Spec (http://www.w3.org/TR/css3-mediaqueries/)
+ * specifies that failing media query is a syntax error
+ * HTML 4.01 spec (http://www.w3.org/TR/REC-html40/present/styles.html#adef-media)
+ * specifies that Media Descriptors should be parsed with forward-compatible syntax
+ * DOM Level 2 Style Sheet spec (http://www.w3.org/TR/DOM-Level-2-Style/)
+ * talks about MediaList.mediaText and refers
+ * - to Media Descriptors of HTML 4.0 in context of StyleSheet
+ * - to Media Types of CSS 2.0 in context of CSSMediaRule and CSSImportRule
+ *
+ * These facts create situation where same (illegal) media specification may result in
+ * different parses depending on whether it is media attr of style element or part of
+ * css @media rule.
+ * <style media="screen and resolution > 40dpi"> ..</style> will be enabled on screen devices where as
+ * @media screen and resolution > 40dpi {..} will not.
+ * This gets more counter-intuitive in JavaScript:
+ * document.styleSheets[0].media.mediaText = "screen and resolution > 40dpi" will be ok and
+ * enabled, while
+ * document.styleSheets[0].cssRules[0].media.mediaText = "screen and resolution > 40dpi" will
+ * throw SYNTAX_ERR exception.
+ */
+
+MediaList::MediaList(CSSStyleSheet* parentSheet, bool fallbackToDescriptor)
+ : StyleBase(parentSheet)
+ , m_fallback(fallbackToDescriptor)
+{
+}
+
+MediaList::MediaList(CSSStyleSheet* parentSheet, const String& media, bool fallbackToDescriptor)
+ : StyleBase(parentSheet)
+ , m_fallback(fallbackToDescriptor)
+{
+ ExceptionCode ec = 0;
+ setMediaText(media, ec);
+ // FIXME: parsing can fail. The problem with failing constructor is that
+ // we would need additional flag saying MediaList is not valid
+ // Parse can fail only when fallbackToDescriptor == false, i.e when HTML4 media descriptor
+ // forward-compatible syntax is not in use.
+ // DOMImplementationCSS seems to mandate that media descriptors are used
+ // for both html and svg, even though svg:style doesn't use media descriptors
+ // Currently the only places where parsing can fail are
+ // creating <svg:style>, creating css media / import rules from js
+ if (ec)
+ setMediaText("invalid", ec);
+}
+
+MediaList::MediaList(CSSRule* parentRule, const String& media, bool fallbackToDescriptor)
+ : StyleBase(parentRule)
+ , m_fallback(fallbackToDescriptor)
+{
+ ExceptionCode ec = 0;
+ setMediaText(media, ec);
+ //FIXME: parsing can fail.
+ if (ec)
+ setMediaText("invalid", ec);
+}
+
+MediaList::~MediaList()
+{
+ deleteAllValues(m_queries);
+}
+
+CSSStyleSheet *MediaList::parentStyleSheet() const
+{
+ return parent()->isCSSStyleSheet() ? static_cast<CSSStyleSheet*>(parent()) : 0;
+}
+
+CSSRule *MediaList::parentRule() const
+{
+ return parent()->isRule() ? static_cast<CSSRule*>(parent()) : 0;
+}
+
+static String parseMediaDescriptor(const String& s)
+{
+ int len = s.length();
+
+ // http://www.w3.org/TR/REC-html40/types.html#type-media-descriptors
+ // "Each entry is truncated just before the first character that isn't a
+ // US ASCII letter [a-zA-Z] (ISO 10646 hex 41-5a, 61-7a), digit [0-9] (hex 30-39),
+ // or hyphen (hex 2d)."
+ int i;
+ unsigned short c;
+ for (i = 0; i < len; ++i) {
+ c = s[i];
+ if (! ((c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || (c >= '1' && c <= '9')
+ || (c == '-')))
+ break;
+ }
+ return s.left(i);
+}
+
+void MediaList::deleteMedium(const String& oldMedium, ExceptionCode& ec)
+{
+ MediaList tempMediaList;
+ CSSParser p(true);
+
+ MediaQuery* oldQuery = 0;
+ bool deleteOldQuery = false;
+
+ if (p.parseMediaQuery(&tempMediaList, oldMedium)) {
+ if (tempMediaList.m_queries.size() > 0)
+ oldQuery = tempMediaList.m_queries[0];
+ } else if (m_fallback) {
+ String medium = parseMediaDescriptor(oldMedium);
+ if (!medium.isNull()) {
+ oldQuery = new MediaQuery(MediaQuery::None, medium, 0);
+ deleteOldQuery = true;
+ }
+ }
+
+ // DOM Style Sheets spec doesn't allow SYNTAX_ERR to be thrown in deleteMedium
+ ec = NOT_FOUND_ERR;
+
+ if (oldQuery) {
+ for(size_t i = 0; i < m_queries.size(); ++i) {
+ MediaQuery* a = m_queries[i];
+ if (*a == *oldQuery) {
+ m_queries.remove(i);
+ delete a;
+ ec = 0;
+ break;
+ }
+ }
+ if (deleteOldQuery)
+ delete oldQuery;
+ }
+
+ if (!ec)
+ notifyChanged();
+}
+
+String MediaList::mediaText() const
+{
+ String text("");
+
+ bool first = true;
+ for (size_t i = 0; i < m_queries.size(); ++i) {
+ if (!first)
+ text += ", ";
+ else
+ first = false;
+ text += m_queries[i]->cssText();
+ }
+
+ return text;
+}
+
+void MediaList::setMediaText(const String& value, ExceptionCode& ec)
+{
+ MediaList tempMediaList;
+ CSSParser p(true);
+
+ Vector<String> list;
+ value.split(',', list);
+ Vector<String>::const_iterator end = list.end();
+ for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) {
+ String medium = (*it).stripWhiteSpace();
+ if (!medium.isEmpty()) {
+ if (!p.parseMediaQuery(&tempMediaList, medium)) {
+ if (m_fallback) {
+ String mediaDescriptor = parseMediaDescriptor(medium);
+ if (!mediaDescriptor.isNull())
+ tempMediaList.m_queries.append(new MediaQuery(MediaQuery::None, mediaDescriptor, 0));
+ } else {
+ ec = SYNTAX_ERR;
+ return;
+ }
+ }
+ } else if (!m_fallback) {
+ ec = SYNTAX_ERR;
+ return;
+ }
+ }
+ // ",,,," falls straight through, but is not valid unless fallback
+ if (!m_fallback && list.begin() == list.end()) {
+ String s = value.stripWhiteSpace();
+ if (!s.isEmpty()) {
+ ec = SYNTAX_ERR;
+ return;
+ }
+ }
+
+ ec = 0;
+ deleteAllValues(m_queries);
+ m_queries = tempMediaList.m_queries;
+ tempMediaList.m_queries.clear();
+ notifyChanged();
+}
+
+String MediaList::item(unsigned index) const
+{
+ if (index < m_queries.size()) {
+ MediaQuery* query = m_queries[index];
+ return query->cssText();
+ }
+
+ return String();
+}
+
+void MediaList::appendMedium(const String& newMedium, ExceptionCode& ec)
+{
+ ec = INVALID_CHARACTER_ERR;
+ CSSParser p(true);
+ if (p.parseMediaQuery(this, newMedium)) {
+ ec = 0;
+ } else if (m_fallback) {
+ String medium = parseMediaDescriptor(newMedium);
+ if (!medium.isNull()) {
+ m_queries.append(new MediaQuery(MediaQuery::None, medium, 0));
+ ec = 0;
+ }
+ }
+
+ if (!ec)
+ notifyChanged();
+}
+
+void MediaList::appendMediaQuery(MediaQuery* mediaQuery)
+{
+ m_queries.append(mediaQuery);
+}
+
+void MediaList::notifyChanged()
+{
+ for (StyleBase* p = parent(); p; p = p->parent()) {
+ if (p->isCSSStyleSheet())
+ return static_cast<CSSStyleSheet*>(p)->styleSheetChanged();
+ }
+}
+
+}
diff --git a/WebCore/css/MediaList.h b/WebCore/css/MediaList.h
new file mode 100644
index 0000000..3b27e1f
--- /dev/null
+++ b/WebCore/css/MediaList.h
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ *
+ * 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 MediaList_h
+#define MediaList_h
+
+#include "StyleBase.h"
+#include <wtf/Vector.h>
+#include "PlatformString.h"
+
+namespace WebCore {
+typedef int ExceptionCode;
+class CSSStyleSheet;
+class MediaQuery;
+class CSSRule;
+
+class MediaList : public StyleBase
+{
+public:
+ MediaList(bool fallbackToDescription = false) : StyleBase(0), m_fallback(fallbackToDescription) {}
+ MediaList(CSSStyleSheet* parentSheet, bool fallbackToDescription = false);
+ MediaList(CSSStyleSheet* parentSheet, const String& media, bool fallbackToDescription = false);
+ MediaList(CSSRule* parentRule, const String& media, bool fallbackToDescription = false);
+ ~MediaList();
+
+ virtual bool isMediaList() { return true; }
+
+ CSSStyleSheet* parentStyleSheet() const;
+ CSSRule* parentRule() const;
+ unsigned length() const { return (unsigned) m_queries.size(); }
+ String item(unsigned index) const;
+ void deleteMedium(const String& oldMedium, ExceptionCode&);
+ void appendMedium(const String& newMedium, ExceptionCode&);
+
+ String mediaText() const;
+ void setMediaText(const String&, ExceptionCode&xo);
+
+ void appendMediaQuery(MediaQuery* mediaQuery);
+ const Vector<MediaQuery*>* mediaQueries() const { return &m_queries; }
+
+private:
+ void notifyChanged();
+
+protected:
+ Vector<MediaQuery*> m_queries;
+ bool m_fallback; // true if failed media query parsing should fallback to media description parsing
+};
+
+} // namespace
+
+#endif
diff --git a/WebCore/css/MediaList.idl b/WebCore/css/MediaList.idl
new file mode 100644
index 0000000..dc10e63
--- /dev/null
+++ b/WebCore/css/MediaList.idl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2006, 2007 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 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.
+ */
+
+module stylesheets {
+
+ // Introduced in DOM Level 2:
+ interface [
+ GenerateConstructor,
+ HasIndexGetter,
+ InterfaceUUID=4ed02a0b-15b3-4a20-8f16-d91295aaf2cb,
+ ImplementationUUID=6c5095d8-fdcc-4f9a-b04a-23c2a6d2cf49
+ ] MediaList {
+
+ attribute [ConvertNullToNullString, ConvertNullStringTo=Null] DOMString mediaText
+ setter raises(DOMException);
+ readonly attribute unsigned long length;
+
+ [ConvertNullStringTo=Null] DOMString item(in unsigned long index);
+ void deleteMedium(in DOMString oldMedium)
+ raises(DOMException);
+ void appendMedium(in DOMString newMedium)
+ raises(DOMException);
+
+ };
+
+}
diff --git a/WebCore/css/MediaQuery.cpp b/WebCore/css/MediaQuery.cpp
new file mode 100644
index 0000000..ff57372
--- /dev/null
+++ b/WebCore/css/MediaQuery.cpp
@@ -0,0 +1,97 @@
+/*
+ * CSS Media Query
+ *
+ * Copyright (C) 2005, 2006 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>.
+ *
+ * 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 AUTHOR ``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.
+ */
+
+#include "config.h"
+#include "MediaQuery.h"
+
+#include "MediaQueryExp.h"
+
+namespace WebCore {
+
+MediaQuery::MediaQuery(Restrictor r, const String& mediaType, Vector<MediaQueryExp*>* exprs)
+ : m_restrictor(r)
+ , m_mediaType(mediaType)
+ , m_expressions(exprs)
+{
+ if (!m_expressions)
+ m_expressions = new Vector<MediaQueryExp*>;
+}
+
+MediaQuery::~MediaQuery()
+{
+ if (m_expressions) {
+ deleteAllValues(*m_expressions);
+ delete m_expressions;
+ }
+}
+
+bool MediaQuery::operator==(const MediaQuery& other) const
+{
+ if (m_restrictor != other.m_restrictor
+ || m_mediaType != other.m_mediaType
+ || m_expressions->size() != other.m_expressions->size())
+ return false;
+
+ for (size_t i = 0; i < m_expressions->size(); ++i) {
+ MediaQueryExp* exp = m_expressions->at(i);
+ MediaQueryExp* oexp = other.m_expressions->at(i);
+ if (!(*exp == *oexp))
+ return false;
+ }
+
+ return true;
+}
+
+String MediaQuery::cssText() const
+{
+ String text;
+ switch (m_restrictor) {
+ case MediaQuery::Only:
+ text += "only ";
+ break;
+ case MediaQuery::Not:
+ text += "not ";
+ break;
+ case MediaQuery::None:
+ default:
+ break;
+ }
+ text += m_mediaType;
+ for (size_t i = 0; i < m_expressions->size(); ++i) {
+ MediaQueryExp* exp = m_expressions->at(i);
+ text += " and (";
+ text += exp->mediaFeature();
+ if (exp->value()) {
+ text += ": ";
+ text += exp->value()->cssText();
+ }
+ text += ")";
+ }
+ return text;
+}
+
+} //namespace
diff --git a/WebCore/css/MediaQuery.h b/WebCore/css/MediaQuery.h
new file mode 100644
index 0000000..0aa0da1
--- /dev/null
+++ b/WebCore/css/MediaQuery.h
@@ -0,0 +1,62 @@
+/*
+ * CSS Media Query
+ *
+ * Copyright (C) 2006 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>.
+ *
+ * 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 AUTHOR ``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 MediaQuery_h
+#define MediaQuery_h
+
+#include "PlatformString.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+class MediaQueryExp;
+
+class MediaQuery
+{
+public:
+ enum Restrictor {
+ Only, Not, None
+ };
+
+ MediaQuery(Restrictor r, const String& mediaType, Vector<MediaQueryExp*>* exprs);
+ ~MediaQuery();
+
+ Restrictor restrictor() const { return m_restrictor; }
+ const Vector<MediaQueryExp*>* expressions() const { return m_expressions; }
+ String mediaType() const { return m_mediaType; }
+ bool operator==(const MediaQuery& other) const;
+ void append(MediaQueryExp* newExp) { m_expressions->append(newExp); }
+ String cssText() const;
+
+ private:
+ Restrictor m_restrictor;
+ String m_mediaType;
+ Vector<MediaQueryExp*>* m_expressions;
+};
+
+} // namespace
+
+#endif
diff --git a/WebCore/css/MediaQueryEvaluator.cpp b/WebCore/css/MediaQueryEvaluator.cpp
new file mode 100644
index 0000000..d5ea65e
--- /dev/null
+++ b/WebCore/css/MediaQueryEvaluator.cpp
@@ -0,0 +1,414 @@
+/*
+ * CSS Media Query Evaluator
+ *
+ * Copyright (C) 2006 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>.
+ *
+ * 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 AUTHOR ``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.
+ */
+
+#include "config.h"
+#include "MediaQueryEvaluator.h"
+
+#include "Chrome.h"
+#include "CSSPrimitiveValue.h"
+#include "CSSStyleSelector.h"
+#include "CSSValueList.h"
+#include "FloatRect.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "IntRect.h"
+#include "MediaFeatureNames.h"
+#include "MediaList.h"
+#include "MediaQuery.h"
+#include "MediaQueryExp.h"
+#include "Page.h"
+#include "RenderStyle.h"
+#include "PlatformScreen.h"
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+using namespace MediaFeatureNames;
+
+enum MediaFeaturePrefix { MinPrefix, MaxPrefix, NoPrefix };
+
+typedef bool (*EvalFunc)(CSSValue*, RenderStyle*, Frame*, MediaFeaturePrefix);
+typedef HashMap<AtomicStringImpl*, EvalFunc> FunctionMap;
+static FunctionMap* gFunctionMap;
+
+/*
+ * FIXME: following media features are not implemented: color_index, scan, resolution
+ *
+ * color_index, min-color-index, max_color_index: It's unknown how to retrieve
+ * the information if the display mode is indexed
+ * scan: The "scan" media feature describes the scanning process of
+ * tv output devices. It's unknown how to retrieve this information from
+ * the platform
+ * resolution, min-resolution, max-resolution: css parser doesn't seem to
+ * support CSS_DIMENSION
+ */
+
+MediaQueryEvaluator::MediaQueryEvaluator(bool mediaFeatureResult)
+ : m_frame(0)
+ , m_style(0)
+ , m_expResult(mediaFeatureResult)
+{
+}
+
+MediaQueryEvaluator:: MediaQueryEvaluator(const String& acceptedMediaType, bool mediaFeatureResult)
+ : m_mediaType(acceptedMediaType)
+ , m_frame(0)
+ , m_style(0)
+ , m_expResult(mediaFeatureResult)
+{
+}
+
+MediaQueryEvaluator:: MediaQueryEvaluator(const char* acceptedMediaType, bool mediaFeatureResult)
+ : m_mediaType(acceptedMediaType)
+ , m_frame(0)
+ , m_style(0)
+ , m_expResult(mediaFeatureResult)
+{
+}
+
+MediaQueryEvaluator:: MediaQueryEvaluator(const String& acceptedMediaType, Frame* frame, RenderStyle* style)
+ : m_mediaType(acceptedMediaType.lower())
+ , m_frame(frame)
+ , m_style(style)
+ , m_expResult(false) // doesn't matter when we have m_frame and m_style
+{
+}
+
+MediaQueryEvaluator::~MediaQueryEvaluator()
+{
+}
+
+bool MediaQueryEvaluator::mediaTypeMatch(const String& mediaTypeToMatch) const
+{
+ return mediaTypeToMatch.isEmpty()
+ || equalIgnoringCase(mediaTypeToMatch, "all")
+ || equalIgnoringCase(mediaTypeToMatch, m_mediaType);
+}
+
+bool MediaQueryEvaluator::mediaTypeMatchSpecific(const char* mediaTypeToMatch) const
+{
+ // Like mediaTypeMatch, but without the special cases for "" and "all".
+ ASSERT(mediaTypeToMatch);
+ ASSERT(mediaTypeToMatch[0] != '\0');
+ ASSERT(!equalIgnoringCase(mediaTypeToMatch, String("all")));
+ return equalIgnoringCase(mediaTypeToMatch, m_mediaType);
+}
+
+static bool applyRestrictor(MediaQuery::Restrictor r, bool value)
+{
+ return r == MediaQuery::Not ? !value : value;
+}
+
+bool MediaQueryEvaluator::eval(const MediaList* mediaList, CSSStyleSelector* styleSelector) const
+{
+ if (!mediaList)
+ return true;
+
+ const Vector<MediaQuery*>* queries = mediaList->mediaQueries();
+ if (!queries->size())
+ return true; // empty query list evaluates to true
+
+ // iterate over queries, stop if any of them eval to true (OR semantics)
+ bool result = false;
+ for (size_t i = 0; i < queries->size() && !result; ++i) {
+ MediaQuery* query = queries->at(i);
+
+ if (mediaTypeMatch(query->mediaType())) {
+ const Vector<MediaQueryExp*>* exps = query->expressions();
+ // iterate through expressions, stop if any of them eval to false
+ // (AND semantics)
+ size_t j = 0;
+ for (; j < exps->size(); ++j) {
+ bool exprResult = eval(exps->at(j));
+ if (styleSelector && exps->at(j)->isViewportDependent())
+ styleSelector->addViewportDependentMediaQueryResult(exps->at(j), exprResult);
+ if (!exprResult)
+ break;
+ }
+
+ // assume true if we are at the end of the list,
+ // otherwise assume false
+ result = applyRestrictor(query->restrictor(), exps->size() == j);
+ } else
+ result = applyRestrictor(query->restrictor(), false);
+ }
+
+ return result;
+}
+
+static bool parseAspectRatio(CSSValue* value, int& h, int& v)
+{
+ if (value->isValueList()){
+ CSSValueList* valueList = static_cast<CSSValueList*>(value);
+ if (valueList->length() == 3) {
+ CSSValue* i0 = valueList->item(0);
+ CSSValue* i1 = valueList->item(1);
+ CSSValue* i2 = valueList->item(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) {
+ String str = static_cast<CSSPrimitiveValue*>(i1)->getStringValue();
+ if (!str.isNull() && str.length() == 1 && str[0] == '/') {
+ h = static_cast<CSSPrimitiveValue*>(i0)->getIntValue(CSSPrimitiveValue::CSS_NUMBER);
+ v = static_cast<CSSPrimitiveValue*>(i2)->getIntValue(CSSPrimitiveValue::CSS_NUMBER);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+template<typename T>
+bool compareValue(T a, T b, MediaFeaturePrefix op)
+{
+ switch (op) {
+ case MinPrefix:
+ return a >= b;
+ case MaxPrefix:
+ return a <= b;
+ case NoPrefix:
+ return a == b;
+ }
+ return false;
+}
+
+static bool numberValue(CSSValue* value, float& result)
+{
+ if (value->isPrimitiveValue()
+ && static_cast<CSSPrimitiveValue*>(value)->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) {
+ result = static_cast<CSSPrimitiveValue*>(value)->getFloatValue(CSSPrimitiveValue::CSS_NUMBER);
+ return true;
+ }
+ return false;
+}
+
+static bool colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+{
+ int bitsPerComponent = screenDepthPerComponent(frame->page()->mainFrame()->view());
+ float number;
+ if (value)
+ return numberValue(value, number) && compareValue(bitsPerComponent, static_cast<int>(number), op);
+
+ return bitsPerComponent != 0;
+}
+
+static bool monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+{
+ if (!screenIsMonochrome(frame->page()->mainFrame()->view()))
+ return false;
+
+ return colorMediaFeatureEval(value, style, frame, op);
+}
+
+static bool device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+{
+ if (value) {
+ FloatRect sg = screenRect(frame->page()->mainFrame()->view());
+ int h = 0;
+ int v = 0;
+ if (parseAspectRatio(value, h, v))
+ return v != 0 && compareValue(static_cast<int>(sg.width()) * v, static_cast<int>(sg.height()) * h, op);
+ return false;
+ }
+
+ // ({,min-,max-}device-aspect-ratio)
+ // assume if we have a device, its aspect ratio is non-zero
+ return true;
+}
+
+static bool device_pixel_ratioMediaFeatureEval(CSSValue *value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+{
+ if (value)
+ return value->isPrimitiveValue() && compareValue(frame->page()->chrome()->scaleFactor(), static_cast<CSSPrimitiveValue*>(value)->getFloatValue(), op);
+
+ return frame->page()->chrome()->scaleFactor() != 0;
+}
+
+static bool gridMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+{
+ // if output device is bitmap, grid: 0 == true
+ // assume we have bitmap device
+ float number;
+ if (value && numberValue(value, number))
+ return compareValue(static_cast<int>(number), 0, op);
+ return false;
+}
+
+static bool device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+{
+ if (value) {
+ FloatRect sg = screenRect(frame->page()->mainFrame()->view());
+ return value->isPrimitiveValue() && compareValue(static_cast<int>(sg.height()), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style), op);
+ }
+ // ({,min-,max-}device-height)
+ // assume if we have a device, assume non-zero
+ return true;
+}
+
+static bool device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+{
+ if (value) {
+ FloatRect sg = screenRect(frame->page()->mainFrame()->view());
+ return value->isPrimitiveValue() && compareValue(static_cast<int>(sg.width()), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style), op);
+ }
+ // ({,min-,max-}device-width)
+ // assume if we have a device, assume non-zero
+ return true;
+}
+
+static bool heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+{
+ FrameView* view = frame->view();
+
+ if (value)
+ return value->isPrimitiveValue() && compareValue(view->visibleHeight(), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style), op);
+
+ return view->visibleHeight() != 0;
+}
+
+static bool widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+{
+ FrameView* view = frame->view();
+
+ if (value)
+ return value->isPrimitiveValue() && compareValue(view->visibleWidth(), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style), op);
+
+ return view->visibleWidth() != 0;
+}
+
+// rest of the functions are trampolines which set the prefix according to the media feature expression used
+
+static bool min_colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return colorMediaFeatureEval(value, style, frame, MinPrefix);
+}
+
+static bool max_colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return colorMediaFeatureEval(value, style, frame, MaxPrefix);
+}
+
+static bool min_monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return monochromeMediaFeatureEval(value, style, frame, MinPrefix);
+}
+
+static bool max_monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return monochromeMediaFeatureEval(value, style, frame, MaxPrefix);
+}
+
+static bool min_device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return device_aspect_ratioMediaFeatureEval(value, style, frame, MinPrefix);
+}
+
+static bool max_device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return device_aspect_ratioMediaFeatureEval(value, style, frame, MaxPrefix);
+}
+
+static bool min_device_pixel_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return device_pixel_ratioMediaFeatureEval(value, style, frame, MinPrefix);
+}
+
+static bool max_device_pixel_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return device_pixel_ratioMediaFeatureEval(value, style, frame, MaxPrefix);
+}
+
+static bool min_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return heightMediaFeatureEval(value, style, frame, MinPrefix);
+}
+
+static bool max_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return heightMediaFeatureEval(value, style, frame, MaxPrefix);
+}
+
+static bool min_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return widthMediaFeatureEval(value, style, frame, MinPrefix);
+}
+
+static bool max_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return widthMediaFeatureEval(value, style, frame, MaxPrefix);
+}
+
+static bool min_device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return device_heightMediaFeatureEval(value, style, frame, MinPrefix);
+}
+
+static bool max_device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return device_heightMediaFeatureEval(value, style, frame, MaxPrefix);
+}
+
+static bool min_device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return device_widthMediaFeatureEval(value, style, frame, MinPrefix);
+}
+
+static bool max_device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix /*op*/)
+{
+ return device_widthMediaFeatureEval(value, style, frame, MaxPrefix);
+}
+
+static void createFunctionMap()
+{
+ // Create the table.
+ gFunctionMap = new FunctionMap;
+#define ADD_TO_FUNCTIONMAP(name, str) \
+ gFunctionMap->set(name##MediaFeature.impl(), name##MediaFeatureEval);
+ CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(ADD_TO_FUNCTIONMAP);
+#undef ADD_TO_FUNCTIONMAP
+}
+
+bool MediaQueryEvaluator::eval(const MediaQueryExp* expr) const
+{
+ if (!m_frame || !m_style)
+ return m_expResult;
+
+ if (!gFunctionMap)
+ createFunctionMap();
+
+ // call the media feature evaluation function. Assume no prefix
+ // and let trampoline functions override the prefix if prefix is
+ // used
+ EvalFunc func = gFunctionMap->get(expr->mediaFeature().impl());
+ if (func)
+ return func(expr->value(), m_style, m_frame, NoPrefix);
+
+ return false;
+}
+
+} // namespace
diff --git a/WebCore/css/MediaQueryEvaluator.h b/WebCore/css/MediaQueryEvaluator.h
new file mode 100644
index 0000000..5ae8fec
--- /dev/null
+++ b/WebCore/css/MediaQueryEvaluator.h
@@ -0,0 +1,91 @@
+/*
+ * CSS Media Query Evaluator
+ *
+ * Copyright (C) 2006 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>.
+ *
+ * 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 AUTHOR ``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 MediaQueryEvaluator_h
+#define MediaQueryEvaluator_h
+
+#include "PlatformString.h"
+
+namespace WebCore {
+class CSSStyleSelector;
+class Frame;
+class RenderStyle;
+class MediaList;
+class MediaQueryExp;
+
+/**
+ * Class that evaluates css media queries as defined in
+ * CSS3 Module "Media Queries" (http://www.w3.org/TR/css3-mediaqueries/)
+ * Special constructors are needed, if simple media queries are to be
+ * evaluated without knowledge of the medium features. This can happen
+ * for example when parsing UA stylesheets, if evaluation is done
+ * right after parsing.
+ *
+ * the boolean parameter is used to approximate results of evaluation, if
+ * the device characteristics are not known. This can be used to prune the loading
+ * of stylesheets to only those which are probable to match.
+ */
+class MediaQueryEvaluator
+{
+public:
+ /** Creates evaluator which evaluates only simple media queries
+ * Evaluator returns true for "all", and returns value of \mediaFeatureResult
+ * for any media features
+ */
+ MediaQueryEvaluator(bool mediaFeatureResult = false);
+
+ /** Creates evaluator which evaluates only simple media queries
+ * Evaluator returns true for acceptedMediaType and returns value of \mediafeatureResult
+ * for any media features
+ */
+ MediaQueryEvaluator(const String& acceptedMediaType, bool mediaFeatureResult = false);
+ MediaQueryEvaluator(const char* acceptedMediaType, bool mediaFeatureResult = false);
+
+ /** Creates evaluator which evaluates full media queries
+ */
+ MediaQueryEvaluator(const String& acceptedMediaType, Frame*, RenderStyle*);
+
+ ~MediaQueryEvaluator();
+
+ bool mediaTypeMatch(const String& mediaTypeToMatch) const;
+ bool mediaTypeMatchSpecific(const char* mediaTypeToMatch) const;
+
+ /** Evaluates a list of media queries */
+ bool eval(const MediaList*, CSSStyleSelector* = 0) const;
+
+ /** Evaluates media query subexpression, ie "and (media-feature: value)" part */
+ bool eval(const MediaQueryExp*) const;
+
+private:
+ String m_mediaType;
+ Frame* m_frame; // not owned
+ RenderStyle* m_style; // not owned
+ bool m_expResult;
+};
+
+} // namespace
+#endif
diff --git a/WebCore/css/MediaQueryExp.cpp b/WebCore/css/MediaQueryExp.cpp
new file mode 100644
index 0000000..e6f9ff0
--- /dev/null
+++ b/WebCore/css/MediaQueryExp.cpp
@@ -0,0 +1,85 @@
+/*
+ * CSS Media Query
+ *
+ * Copyright (C) 2006 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>.
+ *
+ * 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 AUTHOR ``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.
+ */
+
+#include "config.h"
+#include "MediaQueryExp.h"
+
+#include "CSSParser.h"
+#include "CSSPrimitiveValue.h"
+#include "CSSValueList.h"
+
+namespace WebCore {
+
+MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, ValueList* valueList)
+ : m_mediaFeature(mediaFeature)
+ , m_value(0)
+{
+ if (valueList) {
+ if (valueList->size() == 1) {
+ Value* value = valueList->current();
+
+ if (value->id != 0)
+ m_value = new CSSPrimitiveValue(value->id);
+ else if (value->unit == CSSPrimitiveValue::CSS_STRING)
+ m_value = new CSSPrimitiveValue(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
+ else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER &&
+ value->unit <= CSSPrimitiveValue::CSS_KHZ)
+ m_value = new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+
+ valueList->next();
+ } else if (valueList->size() > 1) {
+ // create list of values
+ // currently accepts only <integer>/<integer>
+
+ CSSValueList* list = new CSSValueList();
+ Value* value = 0;
+ bool isValid = true;
+
+ while ((value = valueList->current()) && isValid) {
+ if (value->unit == Value::Operator && value->iValue == '/')
+ list->append(new CSSPrimitiveValue("/", CSSPrimitiveValue::CSS_STRING));
+ else if (value->unit == CSSPrimitiveValue::CSS_NUMBER)
+ list->append(new CSSPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_NUMBER));
+ else
+ isValid = false;
+
+ value = valueList->next();
+ }
+
+ if (isValid)
+ m_value = list;
+ else
+ delete list;
+ }
+ }
+}
+
+MediaQueryExp::~MediaQueryExp()
+{
+}
+
+} // namespace
diff --git a/WebCore/css/MediaQueryExp.h b/WebCore/css/MediaQueryExp.h
new file mode 100644
index 0000000..14cb123
--- /dev/null
+++ b/WebCore/css/MediaQueryExp.h
@@ -0,0 +1,68 @@
+/*
+ * CSS Media Query
+ *
+ * Copyright (C) 2006 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>.
+ *
+ * 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 AUTHOR ``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 MediaQueryExp_h
+#define MediaQueryExp_h
+
+#include "AtomicString.h"
+#include "CSSValue.h"
+#include "MediaFeatureNames.h"
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+class ValueList;
+
+class MediaQueryExp
+{
+public:
+ MediaQueryExp(const AtomicString& mediaFeature, ValueList* values);
+ ~MediaQueryExp();
+
+ AtomicString mediaFeature() const { return m_mediaFeature; }
+
+ CSSValue* value() const { return m_value.get(); }
+
+ bool operator==(const MediaQueryExp& other) const {
+ return (other.m_mediaFeature == m_mediaFeature)
+ && ((!other.m_value && !m_value)
+ || (other.m_value && m_value && other.m_value->cssText() == m_value->cssText()));
+ }
+
+ bool isViewportDependent() const { return m_mediaFeature == MediaFeatureNames::widthMediaFeature ||
+ m_mediaFeature == MediaFeatureNames::heightMediaFeature ||
+ m_mediaFeature == MediaFeatureNames::min_widthMediaFeature ||
+ m_mediaFeature == MediaFeatureNames::min_heightMediaFeature ||
+ m_mediaFeature == MediaFeatureNames::max_widthMediaFeature ||
+ m_mediaFeature == MediaFeatureNames::max_heightMediaFeature; }
+private:
+ AtomicString m_mediaFeature;
+ RefPtr<CSSValue> m_value;
+};
+
+} // namespace
+
+#endif
diff --git a/WebCore/css/Pair.h b/WebCore/css/Pair.h
new file mode 100644
index 0000000..df4f84b
--- /dev/null
+++ b/WebCore/css/Pair.h
@@ -0,0 +1,56 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 Pair_h
+#define Pair_h
+
+#include <wtf/RefCounted.h>
+#include "CSSPrimitiveValue.h"
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+// A primitive value representing a pair. This is useful for properties like border-radius, background-size/position,
+// and border-spacing (all of which are space-separated sets of two values). At the moment we are only using it for
+// border-radius and background-size, but (FIXME) border-spacing and background-position could be converted over to use
+// it (eliminating some extra -webkit- internal properties).
+class Pair : public RefCounted<Pair> {
+public:
+ Pair() : RefCounted<Pair>(0), m_first(0), m_second(0) { }
+ Pair(PassRefPtr<CSSPrimitiveValue> first, PassRefPtr<CSSPrimitiveValue> second)
+ : RefCounted<Pair>(0), m_first(first), m_second(second) { }
+ virtual ~Pair() { }
+
+ CSSPrimitiveValue* first() const { return m_first.get(); }
+ CSSPrimitiveValue* second() const { return m_second.get(); }
+
+ void setFirst(PassRefPtr<CSSPrimitiveValue> first) { m_first = first; }
+ void setSecond(PassRefPtr<CSSPrimitiveValue> second) { m_second = second; }
+
+protected:
+ RefPtr<CSSPrimitiveValue> m_first;
+ RefPtr<CSSPrimitiveValue> m_second;
+};
+
+} // namespace
+
+#endif
diff --git a/WebCore/css/RGBColor.idl b/WebCore/css/RGBColor.idl
new file mode 100644
index 0000000..d16c0c6
--- /dev/null
+++ b/WebCore/css/RGBColor.idl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [
+ ObjCCustomImplementation,
+ InterfaceUUID=2e3b1501-2cf7-4a4a-bbf7-d8843d1c3be7,
+ ImplementationUUID=cf779953-4898-4800-aa31-6c9e3f4711be
+ ] RGBColor {
+ readonly attribute CSSPrimitiveValue red;
+ readonly attribute CSSPrimitiveValue green;
+ readonly attribute CSSPrimitiveValue blue;
+
+ // WebKit extensions
+#if !defined(LANGUAGE_JAVASCRIPT)
+ readonly attribute CSSPrimitiveValue alpha;
+#endif
+#if defined(LANGUAGE_OBJECTIVE_C)
+ readonly attribute Color color;
+#endif
+ };
+
+}
diff --git a/WebCore/css/Rect.h b/WebCore/css/Rect.h
new file mode 100644
index 0000000..e0cc024
--- /dev/null
+++ b/WebCore/css/Rect.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007 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 Rect_h
+#define Rect_h
+
+#include "CSSPrimitiveValue.h"
+#include <wtf/RefCounted.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+ class Rect : public RefCounted<Rect> {
+ public:
+ Rect() : RefCounted<Rect>(0) { }
+ virtual ~Rect() { }
+
+ CSSPrimitiveValue* top() const { return m_top.get(); }
+ CSSPrimitiveValue* right() const { return m_right.get(); }
+ CSSPrimitiveValue* bottom() const { return m_bottom.get(); }
+ CSSPrimitiveValue* left() const { return m_left.get(); }
+
+ void setTop(PassRefPtr<CSSPrimitiveValue> top) { m_top = top; }
+ void setRight(PassRefPtr<CSSPrimitiveValue> right) { m_right = right; }
+ void setBottom(PassRefPtr<CSSPrimitiveValue> bottom) { m_bottom = bottom; }
+ void setLeft(PassRefPtr<CSSPrimitiveValue> left) { m_left = left; }
+
+ private:
+ RefPtr<CSSPrimitiveValue> m_top;
+ RefPtr<CSSPrimitiveValue> m_right;
+ RefPtr<CSSPrimitiveValue> m_bottom;
+ RefPtr<CSSPrimitiveValue> m_left;
+ };
+
+} // namespace WebCore
+
+#endif // Rect_h
diff --git a/WebCore/css/Rect.idl b/WebCore/css/Rect.idl
new file mode 100644
index 0000000..3c31dc6
--- /dev/null
+++ b/WebCore/css/Rect.idl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006, 2007 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.
+ */
+
+module css {
+
+ interface [
+ GenerateConstructor,
+ InterfaceUUID=696bc4d9-c1d3-4225-a5b3-2cef28967705,
+ ImplementationUUID=ae83743f-4dc4-4785-869b-8c3010c7d006
+ ] Rect {
+ readonly attribute CSSPrimitiveValue top;
+ readonly attribute CSSPrimitiveValue right;
+ readonly attribute CSSPrimitiveValue bottom;
+ readonly attribute CSSPrimitiveValue left;
+ };
+
+}
diff --git a/WebCore/css/SVGCSSComputedStyleDeclaration.cpp b/WebCore/css/SVGCSSComputedStyleDeclaration.cpp
new file mode 100644
index 0000000..7168e5d
--- /dev/null
+++ b/WebCore/css/SVGCSSComputedStyleDeclaration.cpp
@@ -0,0 +1,190 @@
+/*
+ Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
+
+ 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"
+
+#if ENABLE(SVG)
+#include "CSSComputedStyleDeclaration.h"
+
+#include "CSSPrimitiveValueMappings.h"
+#include "CSSPropertyNames.h"
+#include "Document.h"
+
+namespace WebCore {
+
+static CSSPrimitiveValue* glyphOrientationToCSSPrimitiveValue(EGlyphOrientation orientation)
+{
+ switch (orientation) {
+ case GO_0DEG:
+ return new CSSPrimitiveValue(0.0f, CSSPrimitiveValue::CSS_DEG);
+ case GO_90DEG:
+ return new CSSPrimitiveValue(90.0f, CSSPrimitiveValue::CSS_DEG);
+ case GO_180DEG:
+ return new CSSPrimitiveValue(180.0f, CSSPrimitiveValue::CSS_DEG);
+ case GO_270DEG:
+ return new CSSPrimitiveValue(270.0f, CSSPrimitiveValue::CSS_DEG);
+ default:
+ return 0;
+ }
+}
+
+PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(int propertyID, EUpdateLayout updateLayout) const
+{
+ Node* node = m_node.get();
+ if (!node)
+ return 0;
+
+ // Make sure our layout is up to date before we allow a query on these attributes.
+ if (updateLayout)
+ node->document()->updateLayout();
+
+ RenderStyle* style = node->computedStyle();
+ if (!style)
+ return 0;
+
+ const SVGRenderStyle* svgStyle = style->svgStyle();
+ if (!svgStyle)
+ return 0;
+
+ switch (static_cast<CSSPropertyID>(propertyID)) {
+ case CSS_PROP_CLIP_RULE:
+ return new CSSPrimitiveValue(svgStyle->clipRule());
+ case CSS_PROP_FLOOD_OPACITY:
+ return new CSSPrimitiveValue(svgStyle->floodOpacity(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP_STOP_OPACITY:
+ return new CSSPrimitiveValue(svgStyle->stopOpacity(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP_POINTER_EVENTS:
+ return new CSSPrimitiveValue(svgStyle->pointerEvents());
+ case CSS_PROP_COLOR_INTERPOLATION:
+ return new CSSPrimitiveValue(svgStyle->colorInterpolation());
+ case CSS_PROP_COLOR_INTERPOLATION_FILTERS:
+ return new CSSPrimitiveValue(svgStyle->colorInterpolationFilters());
+ case CSS_PROP_FILL_OPACITY:
+ return new CSSPrimitiveValue(svgStyle->fillOpacity(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP_FILL_RULE:
+ return new CSSPrimitiveValue(svgStyle->fillRule());
+ case CSS_PROP_COLOR_RENDERING:
+ return new CSSPrimitiveValue(svgStyle->colorRendering());
+ case CSS_PROP_IMAGE_RENDERING:
+ return new CSSPrimitiveValue(svgStyle->imageRendering());
+ case CSS_PROP_SHAPE_RENDERING:
+ return new CSSPrimitiveValue(svgStyle->shapeRendering());
+ case CSS_PROP_STROKE_LINECAP:
+ return new CSSPrimitiveValue(svgStyle->capStyle());
+ case CSS_PROP_STROKE_LINEJOIN:
+ return new CSSPrimitiveValue(svgStyle->joinStyle());
+ case CSS_PROP_STROKE_MITERLIMIT:
+ return new CSSPrimitiveValue(svgStyle->strokeMiterLimit(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP_STROKE_OPACITY:
+ return new CSSPrimitiveValue(svgStyle->strokeOpacity(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSS_PROP_TEXT_RENDERING:
+ return new CSSPrimitiveValue(svgStyle->textRendering());
+ case CSS_PROP_ALIGNMENT_BASELINE:
+ return new CSSPrimitiveValue(svgStyle->alignmentBaseline());
+ case CSS_PROP_DOMINANT_BASELINE:
+ return new CSSPrimitiveValue(svgStyle->dominantBaseline());
+ case CSS_PROP_TEXT_ANCHOR:
+ return new CSSPrimitiveValue(svgStyle->textAnchor());
+ case CSS_PROP_WRITING_MODE:
+ return new CSSPrimitiveValue(svgStyle->writingMode());
+ case CSS_PROP_CLIP_PATH:
+ if (!svgStyle->clipPath().isEmpty())
+ return new CSSPrimitiveValue(svgStyle->clipPath(), CSSPrimitiveValue::CSS_URI);
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ case CSS_PROP_MASK:
+ if (!svgStyle->maskElement().isEmpty())
+ return new CSSPrimitiveValue(svgStyle->maskElement(), CSSPrimitiveValue::CSS_URI);
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ case CSS_PROP_FILTER:
+ if (!svgStyle->filter().isEmpty())
+ return new CSSPrimitiveValue(svgStyle->filter(), CSSPrimitiveValue::CSS_URI);
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ case CSS_PROP_FLOOD_COLOR:
+ return new CSSPrimitiveValue(svgStyle->floodColor().rgb());
+ case CSS_PROP_LIGHTING_COLOR:
+ return new CSSPrimitiveValue(svgStyle->lightingColor().rgb());
+ case CSS_PROP_STOP_COLOR:
+ return new CSSPrimitiveValue(svgStyle->stopColor().rgb());
+ case CSS_PROP_FILL:
+ return svgStyle->fillPaint();
+ case CSS_PROP_KERNING:
+ return svgStyle->kerning();
+ case CSS_PROP_MARKER_END:
+ if (!svgStyle->endMarker().isEmpty())
+ return new CSSPrimitiveValue(svgStyle->endMarker(), CSSPrimitiveValue::CSS_URI);
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ case CSS_PROP_MARKER_MID:
+ if (!svgStyle->midMarker().isEmpty())
+ return new CSSPrimitiveValue(svgStyle->midMarker(), CSSPrimitiveValue::CSS_URI);
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ case CSS_PROP_MARKER_START:
+ if (!svgStyle->startMarker().isEmpty())
+ return new CSSPrimitiveValue(svgStyle->startMarker(), CSSPrimitiveValue::CSS_URI);
+ return new CSSPrimitiveValue(CSS_VAL_NONE);
+ case CSS_PROP_STROKE:
+ return svgStyle->strokePaint();
+ case CSS_PROP_STROKE_DASHARRAY:
+ return svgStyle->strokeDashArray();
+ case CSS_PROP_STROKE_DASHOFFSET:
+ return svgStyle->strokeDashOffset();
+ case CSS_PROP_STROKE_WIDTH:
+ return svgStyle->strokeWidth();
+ case CSS_PROP_BASELINE_SHIFT: {
+ switch (svgStyle->baselineShift()) {
+ case BS_BASELINE:
+ return new CSSPrimitiveValue(CSS_VAL_BASELINE);
+ case BS_SUPER:
+ return new CSSPrimitiveValue(CSS_VAL_SUPER);
+ case BS_SUB:
+ return new CSSPrimitiveValue(CSS_VAL_SUB);
+ case BS_LENGTH:
+ return svgStyle->baselineShiftValue();
+ }
+ }
+ case CSS_PROP_GLYPH_ORIENTATION_HORIZONTAL:
+ return glyphOrientationToCSSPrimitiveValue(svgStyle->glyphOrientationHorizontal());
+ case CSS_PROP_GLYPH_ORIENTATION_VERTICAL: {
+ if (CSSPrimitiveValue* value = glyphOrientationToCSSPrimitiveValue(svgStyle->glyphOrientationVertical()))
+ return value;
+
+ if (svgStyle->glyphOrientationVertical() == GO_AUTO)
+ return new CSSPrimitiveValue(CSS_VAL_AUTO);
+
+ return 0;
+ }
+ case CSS_PROP_MARKER:
+ case CSS_PROP_ENABLE_BACKGROUND:
+ case CSS_PROP_COLOR_PROFILE:
+ // the above properties are not yet implemented in the engine
+ break;
+ default:
+ // If you crash here, it's because you added a css property and are not handling it
+ // in either this switch statement or the one in CSSComputedStyleDelcaration::getPropertyCSSValue
+ ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propertyID);
+ }
+ LOG_ERROR("unimplemented propertyID: %d", propertyID);
+ return 0;
+}
+
+}
+
+#endif // ENABLE(SVG)
+
+// vim:ts=4:noet
diff --git a/WebCore/css/SVGCSSParser.cpp b/WebCore/css/SVGCSSParser.cpp
new file mode 100644
index 0000000..4aca97d
--- /dev/null
+++ b/WebCore/css/SVGCSSParser.cpp
@@ -0,0 +1,358 @@
+/*
+ Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ 2004, 2005, 2007 Rob Buis <buis@kde.org>
+ Copyright (C) 2005, 2006 Apple Computer, Inc.
+
+ This file is part of the KDE project
+
+ 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"
+
+#if ENABLE(SVG)
+#include "CSSInheritedValue.h"
+#include "CSSInitialValue.h"
+#include "CSSParser.h"
+#include "CSSProperty.h"
+#include "CSSPropertyNames.h"
+#include "CSSQuirkPrimitiveValue.h"
+#include "CSSValueKeywords.h"
+#include "CSSValueList.h"
+#include "SVGPaint.h"
+
+using namespace std;
+
+namespace WebCore {
+
+bool CSSParser::parseSVGValue(int propId, bool important)
+{
+ Value* value = valueList->current();
+ if (!value)
+ return false;
+
+ int id = value->id;
+
+ bool valid_primitive = false;
+ RefPtr<CSSValue> parsedValue;
+
+ switch (propId) {
+ /* The comment to the right defines all valid value of these
+ * properties as defined in SVG 1.1, Appendix N. Property index */
+ case CSS_PROP_ALIGNMENT_BASELINE:
+ // auto | baseline | before-edge | text-before-edge | middle |
+ // central | after-edge | text-after-edge | ideographic | alphabetic |
+ // hanging | mathematical | inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_BASELINE || id == CSS_VAL_MIDDLE ||
+ (id >= CSS_VAL_BEFORE_EDGE && id <= CSS_VAL_MATHEMATICAL))
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_BASELINE_SHIFT:
+ // baseline | super | sub | <percentage> | <length> | inherit
+ if (id == CSS_VAL_BASELINE || id == CSS_VAL_SUB ||
+ id >= CSS_VAL_SUPER)
+ valid_primitive = true;
+ else
+ valid_primitive = validUnit(value, FLength|FPercent, false);
+ break;
+
+ case CSS_PROP_DOMINANT_BASELINE:
+ // auto | use-script | no-change | reset-size | ideographic |
+ // alphabetic | hanging | mathematical | central | middle |
+ // text-after-edge | text-before-edge | inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_MIDDLE ||
+ (id >= CSS_VAL_USE_SCRIPT && id <= CSS_VAL_RESET_SIZE) ||
+ (id >= CSS_VAL_CENTRAL && id <= CSS_VAL_MATHEMATICAL))
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_ENABLE_BACKGROUND:
+ // accumulate | new [x] [y] [width] [height] | inherit
+ if (id == CSS_VAL_ACCUMULATE) // TODO : new
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_MARKER_START:
+ case CSS_PROP_MARKER_MID:
+ case CSS_PROP_MARKER_END:
+ case CSS_PROP_MASK:
+ if (id == CSS_VAL_NONE)
+ valid_primitive = true;
+ else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ parsedValue = new CSSPrimitiveValue(value->string, CSSPrimitiveValue::CSS_URI);
+ if (parsedValue)
+ valueList->next();
+ }
+ break;
+
+ case CSS_PROP_CLIP_RULE: // nonzero | evenodd | inherit
+ case CSS_PROP_FILL_RULE:
+ if (id == CSS_VAL_NONZERO || id == CSS_VAL_EVENODD)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_STROKE_MITERLIMIT: // <miterlimit> | inherit
+ valid_primitive = validUnit(value, FNumber|FNonNeg, false);
+ break;
+
+ case CSS_PROP_STROKE_LINEJOIN: // miter | round | bevel | inherit
+ if (id == CSS_VAL_MITER || id == CSS_VAL_ROUND || id == CSS_VAL_BEVEL)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_STROKE_LINECAP: // butt | round | square | inherit
+ if (id == CSS_VAL_BUTT || id == CSS_VAL_ROUND || id == CSS_VAL_SQUARE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_STROKE_OPACITY: // <opacity-value> | inherit
+ case CSS_PROP_FILL_OPACITY:
+ case CSS_PROP_STOP_OPACITY:
+ case CSS_PROP_FLOOD_OPACITY:
+ valid_primitive = (!id && validUnit(value, FNumber|FPercent, false));
+ break;
+
+ case CSS_PROP_SHAPE_RENDERING:
+ // auto | optimizeSpeed | crispEdges | geometricPrecision | inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_OPTIMIZESPEED ||
+ id == CSS_VAL_CRISPEDGES || id == CSS_VAL_GEOMETRICPRECISION)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_TEXT_RENDERING: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision | inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_OPTIMIZESPEED || id == CSS_VAL_OPTIMIZELEGIBILITY ||
+ id == CSS_VAL_GEOMETRICPRECISION)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_IMAGE_RENDERING: // auto | optimizeSpeed |
+ case CSS_PROP_COLOR_RENDERING: // optimizeQuality | inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_OPTIMIZESPEED ||
+ id == CSS_VAL_OPTIMIZEQUALITY)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_COLOR_PROFILE: // auto | sRGB | <name> | <uri> inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_SRGB)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_COLOR_INTERPOLATION: // auto | sRGB | linearRGB | inherit
+ case CSS_PROP_COLOR_INTERPOLATION_FILTERS:
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_SRGB || id == CSS_VAL_LINEARRGB)
+ valid_primitive = true;
+ break;
+
+ /* Start of supported CSS properties with validation. This is needed for parseShortHand to work
+ * correctly and allows optimization in applyRule(..)
+ */
+
+ case CSS_PROP_POINTER_EVENTS:
+ // none | visiblePainted | visibleFill | visibleStroke | visible |
+ // painted | fill | stroke | none | all | inherit
+ if (id == CSS_VAL_VISIBLE || id == CSS_VAL_NONE ||
+ (id >= CSS_VAL_VISIBLEPAINTED && id <= CSS_VAL_ALL))
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_TEXT_ANCHOR: // start | middle | end | inherit
+ if (id == CSS_VAL_START || id == CSS_VAL_MIDDLE || id == CSS_VAL_END)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_GLYPH_ORIENTATION_VERTICAL: // auto | <angle> | inherit
+ if (id == CSS_VAL_AUTO) {
+ valid_primitive = true;
+ break;
+ }
+ /* fallthrough intentional */
+ case CSS_PROP_GLYPH_ORIENTATION_HORIZONTAL: // <angle> (restricted to _deg_ per SVG 1.1 spec) | inherit
+ if (value->unit == CSSPrimitiveValue::CSS_DEG || value->unit == CSSPrimitiveValue::CSS_NUMBER) {
+ parsedValue = new CSSPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_DEG);
+
+ if (parsedValue)
+ valueList->next();
+ }
+ break;
+
+ case CSS_PROP_FILL: // <paint> | inherit
+ case CSS_PROP_STROKE: // <paint> | inherit
+ {
+ if (id == CSS_VAL_NONE)
+ parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_NONE);
+ else if (id == CSS_VAL_CURRENTCOLOR)
+ parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR);
+ else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ RGBA32 c = Color::transparent;
+ if (valueList->next() && parseColorFromValue(valueList->current(), c, true)) {
+ parsedValue = new SVGPaint(value->string, c);
+ } else
+ parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_URI, value->string);
+ } else
+ parsedValue = parseSVGPaint();
+
+ if (parsedValue)
+ valueList->next();
+ }
+ break;
+
+ case CSS_PROP_COLOR: // <color> | inherit
+ if ((id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT) ||
+ (id >= CSS_VAL_ALICEBLUE && id <= CSS_VAL_YELLOWGREEN))
+ parsedValue = new SVGColor(value->string);
+ else
+ parsedValue = parseSVGColor();
+
+ if (parsedValue)
+ valueList->next();
+ break;
+
+ case CSS_PROP_STOP_COLOR: // TODO : icccolor
+ case CSS_PROP_FLOOD_COLOR:
+ case CSS_PROP_LIGHTING_COLOR:
+ if ((id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT) ||
+ (id >= CSS_VAL_ALICEBLUE && id <= CSS_VAL_YELLOWGREEN))
+ parsedValue = new SVGColor(value->string);
+ else if (id == CSS_VAL_CURRENTCOLOR)
+ parsedValue = new SVGColor(SVGColor::SVG_COLORTYPE_CURRENTCOLOR);
+ else // TODO : svgcolor (iccColor)
+ parsedValue = parseSVGColor();
+
+ if (parsedValue)
+ valueList->next();
+
+ break;
+
+ case CSS_PROP_WRITING_MODE:
+ // lr-tb | rl_tb | tb-rl | lr | rl | tb | inherit
+ if (id >= CSS_VAL_LR_TB && id <= CSS_VAL_TB)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_STROKE_WIDTH: // <length> | inherit
+ case CSS_PROP_STROKE_DASHOFFSET:
+ valid_primitive = validUnit(value, FLength | FPercent, false);
+ break;
+ case CSS_PROP_STROKE_DASHARRAY: // none | <dasharray> | inherit
+ if (id == CSS_VAL_NONE)
+ valid_primitive = true;
+ else
+ parsedValue = parseSVGStrokeDasharray();
+
+ break;
+
+ case CSS_PROP_KERNING: // auto | normal | <length> | inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_NORMAL)
+ valid_primitive = true;
+ else
+ valid_primitive = validUnit(value, FLength, false);
+ break;
+
+ case CSS_PROP_CLIP_PATH: // <uri> | none | inherit
+ case CSS_PROP_FILTER:
+ if (id == CSS_VAL_NONE)
+ valid_primitive = true;
+ else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ parsedValue = new CSSPrimitiveValue(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
+ if (parsedValue)
+ valueList->next();
+ }
+ break;
+
+ /* shorthand properties */
+ case CSS_PROP_MARKER:
+ {
+ if (!parseValue(CSS_PROP_MARKER_START, important))
+ return false;
+ CSSValue *value = parsedProperties[numParsedProperties - 1]->value();
+ m_implicitShorthand = true;
+ addProperty(CSS_PROP_MARKER_MID, value, important);
+ addProperty(CSS_PROP_MARKER_END, value, important);
+ m_implicitShorthand = false;
+ return true;
+ }
+ default:
+ // If you crash here, it's because you added a css property and are not handling it
+ // in either this switch statement or the one in CSSParser::parseValue
+ ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propId);
+ return false;
+ }
+
+ if (valid_primitive) {
+ if (id != 0)
+ parsedValue = new CSSPrimitiveValue(id);
+ else if (value->unit == CSSPrimitiveValue::CSS_STRING)
+ parsedValue = new CSSPrimitiveValue(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
+ else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
+ parsedValue = new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+ else if (value->unit >= Value::Q_EMS)
+ parsedValue = new CSSQuirkPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_EMS);
+ valueList->next();
+ }
+ if (!parsedValue || (valueList->current() && !inShorthand()))
+ return false;
+
+ addProperty(propId, parsedValue.release(), important);
+ return true;
+}
+
+PassRefPtr<CSSValue> CSSParser::parseSVGStrokeDasharray()
+{
+ CSSValueList* ret = new CSSValueList;
+ Value* value = valueList->current();
+ bool valid_primitive = true;
+ while (value) {
+ valid_primitive = validUnit(value, FLength | FPercent |FNonNeg, false);
+ if (!valid_primitive)
+ break;
+ if (value->id != 0)
+ ret->append(new CSSPrimitiveValue(value->id));
+ else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
+ ret->append(new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit));
+ value = valueList->next();
+ if (value && value->unit == Value::Operator && value->iValue == ',')
+ value = valueList->next();
+ }
+ if (!valid_primitive) {
+ delete ret;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+PassRefPtr<CSSValue> CSSParser::parseSVGPaint()
+{
+ RGBA32 c = Color::transparent;
+ if (!parseColorFromValue(valueList->current(), c, true))
+ return new SVGPaint();
+ return new SVGPaint(Color(c));
+}
+
+PassRefPtr<CSSValue> CSSParser::parseSVGColor()
+{
+ RGBA32 c = Color::transparent;
+ if (!parseColorFromValue(valueList->current(), c, true))
+ return 0;
+ return new SVGColor(Color(c));
+}
+
+}
+
+#endif // ENABLE(SVG)
+
+// vim:ts=4:noet
diff --git a/WebCore/css/SVGCSSPropertyNames.in b/WebCore/css/SVGCSSPropertyNames.in
new file mode 100644
index 0000000..e1ca112
--- /dev/null
+++ b/WebCore/css/SVGCSSPropertyNames.in
@@ -0,0 +1,48 @@
+#
+# all valid SVG CSS2 properties.
+#
+
+# SVG style props
+clip-path
+clip-rule
+mask
+# opacity
+enable-background
+filter
+flood-color
+flood-opacity
+lighting-color
+stop-color
+stop-opacity
+pointer-events
+color-interpolation
+color-interpolation-filters
+color-profile
+color-rendering
+fill
+fill-opacity
+fill-rule
+#font-size-adjust
+image-rendering
+marker
+marker-end
+marker-mid
+marker-start
+shape-rendering
+stroke
+stroke-dasharray
+stroke-dashoffset
+stroke-linecap
+stroke-linejoin
+stroke-miterlimit
+stroke-opacity
+stroke-width
+text-rendering
+alignment-baseline
+baseline-shift
+dominant-baseline
+glyph-orientation-horizontal
+glyph-orientation-vertical
+kerning
+text-anchor
+writing-mode
diff --git a/WebCore/css/SVGCSSStyleSelector.cpp b/WebCore/css/SVGCSSStyleSelector.cpp
new file mode 100644
index 0000000..e3831df
--- /dev/null
+++ b/WebCore/css/SVGCSSStyleSelector.cpp
@@ -0,0 +1,615 @@
+/*
+ Copyright (C) 2005 Apple Computer, Inc.
+ Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ 2004, 2005 Rob Buis <buis@kde.org>
+ Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
+
+ Based on khtml css code by:
+ Copyright(C) 1999-2003 Lars Knoll(knoll@kde.org)
+ (C) 2003 Apple Computer, Inc.
+ (C) 2004 Allan Sandfeld Jensen(kde@carewolf.com)
+ (C) 2004 Germain Garand(germain@ebooksfrance.org)
+
+ This file is part of the KDE project
+
+ 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"
+
+#if ENABLE(SVG)
+#include "CSSStyleSelector.h"
+
+#include "CSSPrimitiveValueMappings.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueList.h"
+#include "SVGColor.h"
+#include "SVGNames.h"
+#include "SVGPaint.h"
+#include "SVGRenderStyle.h"
+#include "SVGRenderStyleDefs.h"
+#include "SVGStyledElement.h"
+#include <stdlib.h>
+#include <wtf/MathExtras.h>
+
+#define HANDLE_INHERIT(prop, Prop) \
+if (isInherit) \
+{\
+ svgstyle->set##Prop(m_parentStyle->svgStyle()->prop());\
+ return;\
+}
+
+#define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
+HANDLE_INHERIT(prop, Prop) \
+else if (isInitial) \
+ svgstyle->set##Prop(SVGRenderStyle::initial##Prop());
+
+#define HANDLE_INHERIT_COND(propID, prop, Prop) \
+if (id == propID) \
+{\
+ svgstyle->set##Prop(m_parentStyle->svgStyle()->prop());\
+ return;\
+}
+
+#define HANDLE_INITIAL_COND(propID, Prop) \
+if (id == propID) \
+{\
+ svgstyle->set##Prop(SVGRenderStyle::initial##Prop());\
+ return;\
+}
+
+#define HANDLE_INITIAL_COND_WITH_VALUE(propID, Prop, Value) \
+if (id == propID) { \
+ svgstyle->set##Prop(SVGRenderStyle::initial##Value()); \
+ return; \
+}
+
+namespace WebCore {
+
+static float roundToNearestGlyphOrientationAngle(float angle)
+{
+ angle = fabsf(fmodf(angle, 360.0f));
+
+ if (angle <= 45.0f || angle > 315.0f)
+ return 0.0f;
+ else if (angle > 45.0f && angle <= 135.0f)
+ return 90.0f;
+ else if (angle > 135.0f && angle <= 225.0f)
+ return 180.0f;
+
+ return 270.0f;
+}
+
+static int angleToGlyphOrientation(float angle)
+{
+ angle = roundToNearestGlyphOrientationAngle(angle);
+
+ if (angle == 0.0f)
+ return GO_0DEG;
+ else if (angle == 90.0f)
+ return GO_90DEG;
+ else if (angle == 180.0f)
+ return GO_180DEG;
+ else if (angle == 270.0f)
+ return GO_270DEG;
+
+ return -1;
+}
+
+void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
+{
+ CSSPrimitiveValue* primitiveValue = 0;
+ if (value->isPrimitiveValue())
+ primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+
+ SVGRenderStyle* svgstyle = m_style->accessSVGStyle();
+ unsigned short valueType = value->cssValueType();
+
+ bool isInherit = m_parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT;
+ bool isInitial = valueType == CSSPrimitiveValue::CSS_INITIAL || (!m_parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT);
+
+ // What follows is a list that maps the CSS properties into their
+ // corresponding front-end RenderStyle values. Shorthands(e.g. border,
+ // background) occur in this list as well and are only hit when mapping
+ // "inherit" or "initial" into front-end values.
+ switch (id)
+ {
+ // ident only properties
+ case CSS_PROP_ALIGNMENT_BASELINE:
+ {
+ HANDLE_INHERIT_AND_INITIAL(alignmentBaseline, AlignmentBaseline)
+ if (!primitiveValue)
+ break;
+
+ svgstyle->setAlignmentBaseline(*primitiveValue);
+ break;
+ }
+ case CSS_PROP_BASELINE_SHIFT:
+ {
+ HANDLE_INHERIT_AND_INITIAL(baselineShift, BaselineShift);
+ if (!primitiveValue)
+ break;
+
+ if (primitiveValue->getIdent()) {
+ switch (primitiveValue->getIdent()) {
+ case CSS_VAL_BASELINE:
+ svgstyle->setBaselineShift(BS_BASELINE);
+ break;
+ case CSS_VAL_SUB:
+ svgstyle->setBaselineShift(BS_SUB);
+ break;
+ case CSS_VAL_SUPER:
+ svgstyle->setBaselineShift(BS_SUPER);
+ break;
+ default:
+ break;
+ }
+ } else {
+ svgstyle->setBaselineShift(BS_LENGTH);
+ svgstyle->setBaselineShiftValue(primitiveValue);
+ }
+
+ break;
+ }
+ case CSS_PROP_KERNING:
+ {
+ if (isInherit) {
+ HANDLE_INHERIT_COND(CSS_PROP_KERNING, kerning, Kerning)
+ return;
+ }
+ else if (isInitial) {
+ HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_KERNING, Kerning, Kerning)
+ return;
+ }
+
+ svgstyle->setKerning(primitiveValue);
+ break;
+ }
+ case CSS_PROP_POINTER_EVENTS:
+ {
+ HANDLE_INHERIT_AND_INITIAL(pointerEvents, PointerEvents)
+ if (!primitiveValue)
+ break;
+
+ svgstyle->setPointerEvents(*primitiveValue);
+ break;
+ }
+ case CSS_PROP_DOMINANT_BASELINE:
+ {
+ HANDLE_INHERIT_AND_INITIAL(dominantBaseline, DominantBaseline)
+ if (primitiveValue)
+ svgstyle->setDominantBaseline(*primitiveValue);
+ break;
+ }
+ case CSS_PROP_COLOR_INTERPOLATION:
+ {
+ HANDLE_INHERIT_AND_INITIAL(colorInterpolation, ColorInterpolation)
+ if (primitiveValue)
+ svgstyle->setColorInterpolation(*primitiveValue);
+ break;
+ }
+ case CSS_PROP_COLOR_INTERPOLATION_FILTERS:
+ {
+ HANDLE_INHERIT_AND_INITIAL(colorInterpolationFilters, ColorInterpolationFilters)
+ if (primitiveValue)
+ svgstyle->setColorInterpolationFilters(*primitiveValue);
+ break;
+ }
+ case CSS_PROP_COLOR_RENDERING:
+ {
+ HANDLE_INHERIT_AND_INITIAL(colorRendering, ColorRendering)
+ if (primitiveValue)
+ svgstyle->setColorRendering(*primitiveValue);
+ break;
+ }
+ case CSS_PROP_CLIP_RULE:
+ {
+ HANDLE_INHERIT_AND_INITIAL(clipRule, ClipRule)
+ if (primitiveValue)
+ svgstyle->setClipRule(*primitiveValue);
+ break;
+ }
+ case CSS_PROP_FILL_RULE:
+ {
+ HANDLE_INHERIT_AND_INITIAL(fillRule, FillRule)
+ if (primitiveValue)
+ svgstyle->setFillRule(*primitiveValue);
+ break;
+ }
+ case CSS_PROP_STROKE_LINEJOIN:
+ {
+ HANDLE_INHERIT_AND_INITIAL(joinStyle, JoinStyle)
+ if (primitiveValue)
+ svgstyle->setJoinStyle(*primitiveValue);
+ break;
+ }
+ case CSS_PROP_IMAGE_RENDERING:
+ {
+ HANDLE_INHERIT_AND_INITIAL(imageRendering, ImageRendering)
+ if (primitiveValue)
+ svgstyle->setImageRendering(*primitiveValue);
+ break;
+ }
+ case CSS_PROP_SHAPE_RENDERING:
+ {
+ HANDLE_INHERIT_AND_INITIAL(shapeRendering, ShapeRendering)
+ if (primitiveValue)
+ svgstyle->setShapeRendering(*primitiveValue);
+ break;
+ }
+ case CSS_PROP_TEXT_RENDERING:
+ {
+ HANDLE_INHERIT_AND_INITIAL(textRendering, TextRendering)
+ if (primitiveValue)
+ svgstyle->setTextRendering(*primitiveValue);
+ break;
+ }
+ // end of ident only properties
+ case CSS_PROP_FILL:
+ {
+ HANDLE_INHERIT_AND_INITIAL(fillPaint, FillPaint)
+ if (!primitiveValue && value) {
+ SVGPaint *paint = static_cast<SVGPaint*>(value);
+ if (paint)
+ svgstyle->setFillPaint(paint);
+ }
+
+ break;
+ }
+ case CSS_PROP_STROKE:
+ {
+ HANDLE_INHERIT_AND_INITIAL(strokePaint, StrokePaint)
+ if (!primitiveValue && value) {
+ SVGPaint *paint = static_cast<SVGPaint*>(value);
+ if (paint)
+ svgstyle->setStrokePaint(paint);
+ }
+
+ break;
+ }
+ case CSS_PROP_STROKE_WIDTH:
+ {
+ HANDLE_INHERIT_AND_INITIAL(strokeWidth, StrokeWidth)
+ if (!primitiveValue)
+ return;
+
+ svgstyle->setStrokeWidth(primitiveValue);
+ break;
+ }
+ case CSS_PROP_STROKE_DASHARRAY:
+ {
+ HANDLE_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray)
+ if (!primitiveValue && value) {
+ CSSValueList* dashes = static_cast<CSSValueList*>(value);
+ if (dashes)
+ svgstyle->setStrokeDashArray(dashes);
+ }
+
+ break;
+ }
+ case CSS_PROP_STROKE_DASHOFFSET:
+ {
+ HANDLE_INHERIT_AND_INITIAL(strokeDashOffset, StrokeDashOffset)
+ if (!primitiveValue)
+ return;
+
+ svgstyle->setStrokeDashOffset(primitiveValue);
+ break;
+ }
+ case CSS_PROP_FILL_OPACITY:
+ {
+ HANDLE_INHERIT_AND_INITIAL(fillOpacity, FillOpacity)
+ if (!primitiveValue)
+ return;
+
+ float f = 0.0f;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ f = primitiveValue->getFloatValue() / 100.0f;
+ else if (type == CSSPrimitiveValue::CSS_NUMBER)
+ f = primitiveValue->getFloatValue();
+ else
+ return;
+
+ svgstyle->setFillOpacity(f);
+ break;
+ }
+ case CSS_PROP_STROKE_OPACITY:
+ {
+ HANDLE_INHERIT_AND_INITIAL(strokeOpacity, StrokeOpacity)
+ if (!primitiveValue)
+ return;
+
+ float f = 0.0f;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ f = primitiveValue->getFloatValue() / 100.0f;
+ else if (type == CSSPrimitiveValue::CSS_NUMBER)
+ f = primitiveValue->getFloatValue();
+ else
+ return;
+
+ svgstyle->setStrokeOpacity(f);
+ break;
+ }
+ case CSS_PROP_STOP_OPACITY:
+ {
+ HANDLE_INHERIT_AND_INITIAL(stopOpacity, StopOpacity)
+ if (!primitiveValue)
+ return;
+
+ float f = 0.0f;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ f = primitiveValue->getFloatValue() / 100.0f;
+ else if (type == CSSPrimitiveValue::CSS_NUMBER)
+ f = primitiveValue->getFloatValue();
+ else
+ return;
+
+ svgstyle->setStopOpacity(f);
+ break;
+ }
+ case CSS_PROP_MARKER_START:
+ {
+ HANDLE_INHERIT_AND_INITIAL(startMarker, StartMarker)
+ if (!primitiveValue)
+ return;
+
+ String s;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_URI)
+ s = primitiveValue->getStringValue();
+ else
+ return;
+
+ svgstyle->setStartMarker(s);
+ break;
+ }
+ case CSS_PROP_MARKER_MID:
+ {
+ HANDLE_INHERIT_AND_INITIAL(midMarker, MidMarker)
+ if (!primitiveValue)
+ return;
+
+ String s;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_URI)
+ s = primitiveValue->getStringValue();
+ else
+ return;
+
+ svgstyle->setMidMarker(s);
+ break;
+ }
+ case CSS_PROP_MARKER_END:
+ {
+ HANDLE_INHERIT_AND_INITIAL(endMarker, EndMarker)
+ if (!primitiveValue)
+ return;
+
+ String s;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_URI)
+ s = primitiveValue->getStringValue();
+ else
+ return;
+
+ svgstyle->setEndMarker(s);
+ break;
+ }
+ case CSS_PROP_STROKE_LINECAP:
+ {
+ HANDLE_INHERIT_AND_INITIAL(capStyle, CapStyle)
+ if (primitiveValue)
+ svgstyle->setCapStyle(*primitiveValue);
+ break;
+ }
+ case CSS_PROP_STROKE_MITERLIMIT:
+ {
+ HANDLE_INHERIT_AND_INITIAL(strokeMiterLimit, StrokeMiterLimit)
+ if (!primitiveValue)
+ return;
+
+ float f = 0.0f;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_NUMBER)
+ f = primitiveValue->getFloatValue();
+ else
+ return;
+
+ svgstyle->setStrokeMiterLimit(f);
+ break;
+ }
+ case CSS_PROP_FILTER:
+ {
+ HANDLE_INHERIT_AND_INITIAL(filter, Filter)
+ if (!primitiveValue)
+ return;
+
+ String s;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_URI)
+ s = primitiveValue->getStringValue();
+ else
+ return;
+ svgstyle->setFilter(s);
+ break;
+ }
+ case CSS_PROP_MASK:
+ {
+ HANDLE_INHERIT_AND_INITIAL(maskElement, MaskElement)
+ if (!primitiveValue)
+ return;
+
+ String s;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_URI)
+ s = primitiveValue->getStringValue();
+ else
+ return;
+
+ svgstyle->setMaskElement(s);
+ break;
+ }
+ case CSS_PROP_CLIP_PATH:
+ {
+ HANDLE_INHERIT_AND_INITIAL(clipPath, ClipPath)
+ if (!primitiveValue)
+ return;
+
+ String s;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_URI)
+ s = primitiveValue->getStringValue();
+ else
+ return;
+
+ svgstyle->setClipPath(s);
+ break;
+ }
+ case CSS_PROP_TEXT_ANCHOR:
+ {
+ HANDLE_INHERIT_AND_INITIAL(textAnchor, TextAnchor)
+ if (primitiveValue)
+ svgstyle->setTextAnchor(*primitiveValue);
+ break;
+ }
+ case CSS_PROP_WRITING_MODE:
+ {
+ HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode)
+ if (primitiveValue)
+ svgstyle->setWritingMode(*primitiveValue);
+ break;
+ }
+ case CSS_PROP_STOP_COLOR:
+ {
+ HANDLE_INHERIT_AND_INITIAL(stopColor, StopColor);
+
+ SVGColor* c = static_cast<SVGColor*>(value);
+ if (!c)
+ return CSSStyleSelector::applyProperty(id, value);
+
+ Color col;
+ if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
+ col = m_style->color();
+ else
+ col = c->color();
+
+ svgstyle->setStopColor(col);
+ break;
+ }
+ case CSS_PROP_LIGHTING_COLOR:
+ {
+ HANDLE_INHERIT_AND_INITIAL(lightingColor, LightingColor);
+
+ SVGColor* c = static_cast<SVGColor*>(value);
+ if (!c)
+ return CSSStyleSelector::applyProperty(id, value);
+
+ Color col;
+ if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
+ col = m_style->color();
+ else
+ col = c->color();
+
+ svgstyle->setLightingColor(col);
+ break;
+ }
+ case CSS_PROP_FLOOD_OPACITY:
+ {
+ HANDLE_INHERIT_AND_INITIAL(floodOpacity, FloodOpacity)
+ if (!primitiveValue)
+ return;
+
+ float f = 0.0f;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ f = primitiveValue->getFloatValue() / 100.0f;
+ else if (type == CSSPrimitiveValue::CSS_NUMBER)
+ f = primitiveValue->getFloatValue();
+ else
+ return;
+
+ svgstyle->setFloodOpacity(f);
+ break;
+ }
+ case CSS_PROP_FLOOD_COLOR:
+ {
+ Color col;
+ if (isInitial)
+ col = SVGRenderStyle::initialFloodColor();
+ else {
+ SVGColor *c = static_cast<SVGColor*>(value);
+ if (!c)
+ return CSSStyleSelector::applyProperty(id, value);
+
+ if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
+ col = m_style->color();
+ else
+ col = c->color();
+ }
+
+ svgstyle->setFloodColor(col);
+ break;
+ }
+ case CSS_PROP_GLYPH_ORIENTATION_HORIZONTAL:
+ {
+ HANDLE_INHERIT_AND_INITIAL(glyphOrientationHorizontal, GlyphOrientationHorizontal)
+ if (!primitiveValue)
+ return;
+
+ if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) {
+ int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue());
+ ASSERT(orientation != -1);
+
+ svgstyle->setGlyphOrientationHorizontal((EGlyphOrientation) orientation);
+ }
+
+ break;
+ }
+ case CSS_PROP_GLYPH_ORIENTATION_VERTICAL:
+ {
+ HANDLE_INHERIT_AND_INITIAL(glyphOrientationVertical, GlyphOrientationVertical)
+ if (!primitiveValue)
+ return;
+
+ if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) {
+ int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue());
+ ASSERT(orientation != -1);
+
+ svgstyle->setGlyphOrientationVertical((EGlyphOrientation) orientation);
+ } else if (primitiveValue->getIdent() == CSS_VAL_AUTO)
+ svgstyle->setGlyphOrientationVertical(GO_AUTO);
+
+ break;
+ }
+ case CSS_PROP_ENABLE_BACKGROUND:
+ // Silently ignoring this property for now
+ // http://bugs.webkit.org/show_bug.cgi?id=6022
+ break;
+ default:
+ // If you crash here, it's because you added a css property and are not handling it
+ // in either this switch statement or the one in CSSStyleSelector::applyProperty
+ ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", id);
+ return;
+ }
+}
+
+}
+
+// vim:ts=4:noet
+#endif // ENABLE(SVG)
diff --git a/WebCore/css/SVGCSSValueKeywords.in b/WebCore/css/SVGCSSValueKeywords.in
new file mode 100644
index 0000000..e655378
--- /dev/null
+++ b/WebCore/css/SVGCSSValueKeywords.in
@@ -0,0 +1,298 @@
+# These are all values accepted for CSS2.
+#
+# WARNING:
+# --------
+#
+# The Values are sorted according to the properties they belong to,
+# and have to be in the same order as the enums in RenderStyle.h.
+#
+# If not, the optimizations in the cssparser and style selector will fail,
+# and produce incorrect results.
+#
+#
+# CSS_PROP_*_COLOR
+#
+aliceblue
+antiquewhite
+# aqua
+aquamarine
+azure
+beige
+bisque
+# black
+blanchedalmond
+# blue
+blueviolet
+brown
+burlywood
+cadetblue
+chartreuse
+chocolate
+coral
+cornflowerblue
+cornsilk
+crimson
+cyan
+darkblue
+darkcyan
+darkgoldenrod
+darkgray
+darkgreen
+darkgrey
+darkkhaki
+darkmagenta
+darkolivegreen
+darkorange
+darkorchid
+darkred
+darksalmon
+darkseagreen
+darkslateblue
+darkslategray
+darkslategrey
+darkturquoise
+darkviolet
+deeppink
+deepskyblue
+dimgray
+dimgrey
+dodgerblue
+firebrick
+floralwhite
+forestgreen
+# fuchsia
+gainsboro
+ghostwhite
+gold
+goldenrod
+# gray
+# grey
+# green
+greenyellow
+honeydew
+hotpink
+indianred
+indigo
+ivory
+khaki
+lavender
+lavenderblush
+lawngreen
+lemonchiffon
+lightblue
+lightcoral
+lightcyan
+lightgoldenrodyellow
+lightgray
+lightgreen
+lightgrey
+lightpink
+lightsalmon
+lightseagreen
+lightskyblue
+lightslategray
+lightslategrey
+lightsteelblue
+lightyellow
+# lime
+limegreen
+linen
+magenta
+# maroon
+mediumaquamarine
+mediumblue
+mediumorchid
+mediumpurple
+mediumseagreen
+mediumslateblue
+mediumspringgreen
+mediumturquoise
+mediumvioletred
+midnightblue
+mintcream
+mistyrose
+moccasin
+navajowhite
+# navy
+oldlace
+# olive
+olivedrab
+# orange
+orangered
+orchid
+palegoldenrod
+palegreen
+paleturquoise
+palevioletred
+papayawhip
+peachpuff
+peru
+pink
+plum
+powderblue
+# purple
+# red
+rosybrown
+royalblue
+saddlebrown
+salmon
+sandybrown
+seagreen
+seashell
+sienna
+# silver
+skyblue
+slateblue
+slategray
+slategrey
+snow
+springgreen
+steelblue
+tan
+# teal
+thistle
+tomato
+turquoise
+violet
+wheat
+# white
+whitesmoke
+# yellow
+yellowgreen
+
+# CSS_PROP_CLIP_PATH
+# CSS_PROP_CLIP_RULE
+nonzero
+evenodd
+
+# CSS_PROP_MASK
+# CSS_PROP_OPACITY
+# CSS_PROP_ENABLE_BACKGROUND
+accumulate
+new
+
+# CSS_PROP_FILTER
+# CSS_PROP_FLOOD_COLOR
+currentColor
+
+# CSS_PROP_FLOOD_OPACITY
+# CSS_PROP_LIGHTING_COLOR
+#currentColor
+
+# CSS_PROP_STOP_COLOR
+# CSS_PROP_STOP_OPACITY
+# CSS_PROP_POINTER_EVENTS
+visiblePainted
+visibleFill
+visibleStroke
+#visible
+painted
+fill
+stroke
+all
+#none
+
+# CSS_PROP_COLOR_INTERPOLATION
+#auto
+sRGB
+linearRGB
+
+# CSS_PROP_COLOR_INTERPOLATION_FILTERS
+#auto
+#sRGB
+#linearRGB
+
+# CSS_PROP_COLOR_PROFILE
+#sRGB
+
+# CSS_PROP_COLOR_RENDERING
+#auto
+optimizeSpeed
+optimizeQuality
+
+## CSS_PROP_FILL
+#currentColor
+
+# CSS_PROP_FILL_OPACITY
+# CSS_PROP_FILL_RULE
+#nonzero
+#evenodd
+
+# CSS_PROP_IMAGE_RENDERING
+#auto
+#optimizeSpeed
+#optimizeQuality
+
+# CSS_PROP_MARKER
+# CSS_PROP_MARKER_END
+# CSS_PROP_MARKER_MID
+# CSS_PROP_MARKER_START
+# CSS_PROP_SHAPE_RENDERING
+#auto
+#optimizeSpeed
+crispEdges
+geometricPrecision
+
+# CSS_PROP_STROKE
+# CSS_PROP_STROKE_DASHARRAY
+# CSS_PROP_STROKE_DASHOFFSET
+# CSS_PROP_STROKE_LINECAP
+butt
+# round
+# square
+
+# CSS_PROP_STROKE_LINEJOIN
+miter
+# round
+bevel
+
+# CSS_PROP_STROKE_MITERLIMIT
+# CSS_PROP_STROKE_OPACITY
+# CSS_PROP_STROKE_WIDTH
+# CSS_PROP_TEXT_RENDERING
+#auto
+#optimizeSpeed
+optimizeLegibility
+#geometricPrecision
+
+# CSS_PROP_ALIGNMENT_BASELINE
+#auto
+# baseline
+before-edge
+after-edge
+#middle
+central
+text-before-edge
+text-after-edge
+ideographic
+alphabetic
+hanging
+mathematical
+
+# CSS_PROP_BASELINE_SHIFT
+#baseline
+# sub
+# super
+
+# CSS_PROP_DOMINANT_BASELINE
+#auto
+use-script
+no-change
+reset-size
+
+# CSS_PROP_GLYPH_ORIENTATION_HORIZONTAL
+
+# CSS_PROP_GLYPH_ORIENTATION_VERTICAL
+# CSS_PROP_KERNING
+# CSS_PROP_TEXT_ANCHOR
+# start
+# middle
+# end
+
+# CSS_PROP_WRITING_MODE
+lr-tb
+rl-tb
+tb-rl
+lr
+rl
+tb
diff --git a/WebCore/css/ShadowValue.cpp b/WebCore/css/ShadowValue.cpp
new file mode 100644
index 0000000..5794405
--- /dev/null
+++ b/WebCore/css/ShadowValue.cpp
@@ -0,0 +1,67 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 "ShadowValue.h"
+
+#include "CSSPrimitiveValue.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+// Used for text-shadow and box-shadow
+ShadowValue::ShadowValue(PassRefPtr<CSSPrimitiveValue> _x,
+ PassRefPtr<CSSPrimitiveValue> _y,
+ PassRefPtr<CSSPrimitiveValue> _blur,
+ PassRefPtr<CSSPrimitiveValue> _color)
+ : x(_x)
+ , y(_y)
+ , blur(_blur)
+ , color(_color)
+{
+}
+
+String ShadowValue::cssText() const
+{
+ String text("");
+
+ if (color)
+ text += color->cssText();
+ if (x) {
+ if (!text.isEmpty())
+ text += " ";
+ text += x->cssText();
+ }
+ if (y) {
+ if (!text.isEmpty())
+ text += " ";
+ text += y->cssText();
+ }
+ if (blur) {
+ if (!text.isEmpty())
+ text += " ";
+ text += blur->cssText();
+ }
+
+ return text;
+}
+
+}
diff --git a/WebCore/css/ShadowValue.h b/WebCore/css/ShadowValue.h
new file mode 100644
index 0000000..2f94b94
--- /dev/null
+++ b/WebCore/css/ShadowValue.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *
+ * 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 ShadowValue_h
+#define ShadowValue_h
+
+#include "CSSValue.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSPrimitiveValue;
+
+// Used for text-shadow and box-shadow
+class ShadowValue : public CSSValue
+{
+public:
+ ShadowValue(PassRefPtr<CSSPrimitiveValue> x,
+ PassRefPtr<CSSPrimitiveValue> y,
+ PassRefPtr<CSSPrimitiveValue> blur,
+ PassRefPtr<CSSPrimitiveValue> color);
+
+ virtual String cssText() const;
+
+ RefPtr<CSSPrimitiveValue> x;
+ RefPtr<CSSPrimitiveValue> y;
+ RefPtr<CSSPrimitiveValue> blur;
+ RefPtr<CSSPrimitiveValue> color;
+};
+
+} // namespace
+
+#endif
diff --git a/WebCore/css/StyleBase.cpp b/WebCore/css/StyleBase.cpp
new file mode 100644
index 0000000..f608c63
--- /dev/null
+++ b/WebCore/css/StyleBase.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * 1999 Waldo Bastian (bastian@kde.org)
+ * 2001 Andreas Schlapbach (schlpbch@iam.unibe.ch)
+ * 2001-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 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 "StyleBase.h"
+
+#include "Document.h"
+#include "Node.h"
+#include "StyleSheet.h"
+
+namespace WebCore {
+
+void StyleBase::checkLoaded()
+{
+ if (parent())
+ parent()->checkLoaded();
+}
+
+StyleSheet* StyleBase::stylesheet()
+{
+ StyleBase *b = this;
+ while (b && !b->isStyleSheet())
+ b = b->parent();
+ return static_cast<StyleSheet*>(b);
+}
+
+KURL StyleBase::baseURL() const
+{
+ // Try to find the style sheet. If found look for its URL.
+ // If it has none, get the URL from the parent sheet or the parent node.
+
+ StyleSheet* sheet = const_cast<StyleBase*>(this)->stylesheet();
+ if (!sheet)
+ return KURL();
+ if (!sheet->href().isNull())
+ return KURL(sheet->href());
+ if (sheet->parent())
+ return sheet->parent()->baseURL();
+ if (!sheet->ownerNode())
+ return KURL();
+ return sheet->ownerNode()->document()->baseURL();
+}
+
+}
diff --git a/WebCore/css/StyleBase.h b/WebCore/css/StyleBase.h
new file mode 100644
index 0000000..020dbd3
--- /dev/null
+++ b/WebCore/css/StyleBase.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 1999 Waldo Bastian (bastian@kde.org)
+ * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmial.com)
+ * Copyright (C) 2004, 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 StyleBase_h
+#define StyleBase_h
+
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class String;
+ class StyleSheet;
+ class KURL;
+
+ // a style class which has a parent (almost all have)
+ class StyleBase : public RefCounted<StyleBase> {
+ public:
+ StyleBase(StyleBase* parent)
+ : RefCounted<StyleBase>(0)
+ , m_parent(parent)
+ , m_strictParsing(!parent || parent->useStrictParsing())
+ {
+ }
+ virtual ~StyleBase() { }
+
+ StyleBase* parent() const { return m_parent; }
+ void setParent(StyleBase* parent) { m_parent = parent; }
+
+ // returns the url of the style sheet this object belongs to
+ KURL baseURL() const;
+
+ virtual bool isStyleSheet() const { return false; }
+ virtual bool isCSSStyleSheet() const { return false; }
+ virtual bool isXSLStyleSheet() const { return false; }
+ virtual bool isStyleSheetList() const { return false; }
+ virtual bool isMediaList() { return false; }
+ virtual bool isRuleList() { return false; }
+ virtual bool isRule() { return false; }
+ virtual bool isStyleRule() { return false; }
+ virtual bool isCharsetRule() { return false; }
+ virtual bool isImportRule() { return false; }
+ virtual bool isMediaRule() { return false; }
+ virtual bool isFontFaceRule() { return false; }
+ virtual bool isPageRule() { return false; }
+ virtual bool isUnknownRule() { return false; }
+ virtual bool isStyleDeclaration() { return false; }
+ virtual bool isValue() { return false; }
+ virtual bool isPrimitiveValue() const { return false; }
+ virtual bool isValueList() { return false; }
+ virtual bool isValueCustom() { return false; }
+#if ENABLE(SVG)
+ virtual bool isSVGColor() const { return false; }
+ virtual bool isSVGPaint() const { return false; }
+#endif
+
+ virtual bool parseString(const String&, bool /*strict*/ = false) { return false; }
+ virtual void checkLoaded();
+
+ void setStrictParsing(bool b) { m_strictParsing = b; }
+ bool useStrictParsing() const { return m_strictParsing; }
+
+ virtual void insertedIntoParent() { }
+
+ StyleSheet* stylesheet();
+
+ private:
+ StyleBase* m_parent;
+ bool m_strictParsing;
+ };
+}
+
+#endif
diff --git a/WebCore/css/StyleList.cpp b/WebCore/css/StyleList.cpp
new file mode 100644
index 0000000..412509e
--- /dev/null
+++ b/WebCore/css/StyleList.cpp
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * 1999 Waldo Bastian (bastian@kde.org)
+ * 2001 Andreas Schlapbach (schlpbch@iam.unibe.ch)
+ * 2001-2003 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2002, 2006 Apple Computer, Inc.
+ *
+ * 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 "StyleList.h"
+
+namespace WebCore {
+
+void StyleList::append(PassRefPtr<StyleBase> child)
+{
+ StyleBase* c = child.get();
+ m_children.append(child);
+ c->insertedIntoParent();
+}
+
+void StyleList::insert(unsigned position, PassRefPtr<StyleBase> child)
+{
+ StyleBase* c = child.get();
+ if (position >= length())
+ m_children.append(child);
+ else
+ m_children.insert(position, child);
+ c->insertedIntoParent();
+}
+
+void StyleList::remove(unsigned position)
+{
+ if (position >= length())
+ return;
+ m_children.remove(position);
+}
+
+}
diff --git a/WebCore/css/StyleList.h b/WebCore/css/StyleList.h
new file mode 100644
index 0000000..2a4e112
--- /dev/null
+++ b/WebCore/css/StyleList.h
@@ -0,0 +1,50 @@
+/*
+ * This file is part of the CSS implementation for KDE.
+ *
+ * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * 1999 Waldo Bastian (bastian@kde.org)
+ * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ *
+ * 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 StyleList_h
+#define StyleList_h
+
+#include "StyleBase.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ // a style class which has a list of children (StyleSheets for example)
+ class StyleList : public StyleBase {
+ public:
+ StyleList(StyleBase* parent) : StyleBase(parent) { }
+
+ unsigned length() { return m_children.size(); }
+ StyleBase* item(unsigned num) { return num < length() ? m_children[num].get() : 0; }
+
+ void append(PassRefPtr<StyleBase>);
+ void insert(unsigned position, PassRefPtr<StyleBase>);
+ void remove(unsigned position);
+
+ protected:
+ Vector<RefPtr<StyleBase> > m_children;
+ };
+}
+
+#endif
diff --git a/WebCore/css/StyleSheet.cpp b/WebCore/css/StyleSheet.cpp
new file mode 100644
index 0000000..7941d70
--- /dev/null
+++ b/WebCore/css/StyleSheet.cpp
@@ -0,0 +1,74 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ *
+ * 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 "StyleSheet.h"
+
+#include "MediaList.h"
+
+namespace WebCore {
+
+StyleSheet::StyleSheet(StyleSheet* parentSheet, const String& href)
+ : StyleList(parentSheet)
+ , m_parentNode(0)
+ , m_strHref(href)
+ , m_disabled(false)
+{
+}
+
+
+StyleSheet::StyleSheet(Node* parentNode, const String& href)
+ : StyleList(0)
+ , m_parentNode(parentNode)
+ , m_strHref(href)
+ , m_disabled(false)
+{
+}
+
+StyleSheet::StyleSheet(StyleBase* owner, const String& href)
+ : StyleList(owner)
+ , m_parentNode(0)
+ , m_strHref(href)
+ , m_disabled(false)
+{
+}
+
+StyleSheet::~StyleSheet()
+{
+ if (m_media)
+ m_media->setParent(0);
+}
+
+StyleSheet* StyleSheet::parentStyleSheet() const
+{
+ return (parent() && parent()->isStyleSheet()) ? static_cast<StyleSheet*>(parent()) : 0;
+}
+
+void StyleSheet::setMedia(MediaList* media)
+{
+ if (m_media)
+ m_media->setParent(0);
+
+ m_media = media;
+ m_media->setParent(this);
+}
+
+}
diff --git a/WebCore/css/StyleSheet.h b/WebCore/css/StyleSheet.h
new file mode 100644
index 0000000..c00faa2
--- /dev/null
+++ b/WebCore/css/StyleSheet.h
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ *
+ * 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 StyleSheet_h
+#define StyleSheet_h
+
+#include "StyleList.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class Node;
+class CachedCSSStyleSheet;
+class MediaList;
+
+class StyleSheet : public StyleList {
+public:
+ StyleSheet(Node* ownerNode, const String& href = String());
+ StyleSheet(StyleSheet* parentSheet, const String& href = String());
+ StyleSheet(StyleBase* owner, const String& href = String());
+ virtual ~StyleSheet();
+
+ virtual bool isStyleSheet() const { return true; }
+
+ virtual String type() const { return String(); }
+
+ bool disabled() const { return m_disabled; }
+ void setDisabled(bool disabled) { m_disabled = disabled; styleSheetChanged(); }
+
+ Node* ownerNode() const { return m_parentNode; }
+ StyleSheet *parentStyleSheet() const;
+ String href() const { return m_strHref; }
+ void setHref(const String& href) { m_strHref = href; }
+ String title() const { return m_strTitle; }
+ void setTitle(const String& s) { m_strTitle = s; }
+ MediaList* media() const { return m_media.get(); }
+ void setMedia(MediaList*);
+
+ virtual bool isLoading() { return false; }
+
+ virtual void styleSheetChanged() { }
+
+protected:
+ Node* m_parentNode;
+ String m_strHref;
+ String m_strTitle;
+ RefPtr<MediaList> m_media;
+ bool m_disabled;
+};
+
+} // namespace
+
+#endif
diff --git a/WebCore/css/StyleSheet.idl b/WebCore/css/StyleSheet.idl
new file mode 100644
index 0000000..2c17248
--- /dev/null
+++ b/WebCore/css/StyleSheet.idl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ */
+
+module stylesheets {
+
+ // Introduced in DOM Level 2:
+ interface [
+ GenerateConstructor,
+ ObjCCustomInternalImpl,
+ InterfaceUUID=2bd2db5f-aaab-4422-96a0-e05455313f35,
+ ImplementationUUID=a8ca694d-71f2-4479-8c76-ee9c1c729b49
+ ] StyleSheet {
+ readonly attribute [ConvertNullStringTo=Null] DOMString type;
+ attribute boolean disabled;
+ readonly attribute Node ownerNode;
+ readonly attribute StyleSheet parentStyleSheet;
+ readonly attribute [ConvertNullStringTo=Null] DOMString href;
+ readonly attribute [ConvertNullStringTo=Null] DOMString title;
+ readonly attribute MediaList media;
+ };
+
+}
diff --git a/WebCore/css/StyleSheetList.cpp b/WebCore/css/StyleSheetList.cpp
new file mode 100644
index 0000000..d9d678d
--- /dev/null
+++ b/WebCore/css/StyleSheetList.cpp
@@ -0,0 +1,94 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2006, 2007 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 "StyleSheetList.h"
+
+#include "CSSStyleSheet.h"
+#include "Document.h"
+#include "HTMLNames.h"
+#include "HTMLStyleElement.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+StyleSheetList::StyleSheetList(Document* doc)
+ : RefCounted<StyleSheetList>(0)
+ , m_doc(doc)
+{
+}
+
+StyleSheetList::~StyleSheetList()
+{
+ for (DeprecatedPtrListIterator<StyleSheet> it (styleSheets); it.current(); ++it)
+ it.current()->deref();
+}
+
+void StyleSheetList::documentDestroyed()
+{
+ m_doc = 0;
+}
+
+void StyleSheetList::add(StyleSheet* s)
+{
+ if (!styleSheets.containsRef(s)) {
+ s->ref();
+ styleSheets.append(s);
+ }
+}
+
+void StyleSheetList::remove(StyleSheet* s)
+{
+ if (styleSheets.removeRef(s))
+ s->deref();
+}
+
+unsigned StyleSheetList::length() const
+{
+ return styleSheets.count();
+}
+
+StyleSheet* StyleSheetList::item(unsigned index)
+{
+ return index < length() ? styleSheets.at(index) : 0;
+}
+
+HTMLStyleElement* StyleSheetList::getNamedItem(const String& name) const
+{
+ if (!m_doc)
+ return 0;
+
+ // IE also supports retrieving a stylesheet by name, using the name/id of the <style> tag
+ // (this is consistent with all the other collections)
+ // ### Bad implementation because returns a single element (are IDs always unique?)
+ // and doesn't look for name attribute.
+ // But unicity of stylesheet ids is good practice anyway ;)
+
+ Element* element = m_doc->getElementById(name);
+ if (element && element->hasTagName(styleTag))
+ return static_cast<HTMLStyleElement*>(element);
+ return 0;
+}
+
+} // namespace WebCore
diff --git a/WebCore/css/StyleSheetList.h b/WebCore/css/StyleSheetList.h
new file mode 100644
index 0000000..cfc1b81
--- /dev/null
+++ b/WebCore/css/StyleSheetList.h
@@ -0,0 +1,57 @@
+/*
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2006, 2007 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 StyleSheetList_h
+#define StyleSheetList_h
+
+#include <wtf/RefCounted.h>
+#include "DeprecatedPtrList.h"
+
+namespace WebCore {
+
+class Document;
+class HTMLStyleElement;
+class StyleSheet;
+class String;
+
+class StyleSheetList : public RefCounted<StyleSheetList> {
+public:
+ StyleSheetList(Document*);
+ ~StyleSheetList();
+
+ void documentDestroyed();
+
+ unsigned length() const;
+ StyleSheet* item(unsigned index);
+
+ void add(StyleSheet*);
+ void remove(StyleSheet*);
+
+ HTMLStyleElement* getNamedItem(const String&) const;
+
+ DeprecatedPtrList<StyleSheet> styleSheets;
+
+private:
+ Document* m_doc;
+};
+
+} // namespace WebCore
+
+#endif // StyleSheetList_h
diff --git a/WebCore/css/StyleSheetList.idl b/WebCore/css/StyleSheetList.idl
new file mode 100644
index 0000000..2abd22f
--- /dev/null
+++ b/WebCore/css/StyleSheetList.idl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ */
+
+module stylesheets {
+
+ // Introduced in DOM Level 2:
+ interface [
+ GenerateConstructor,
+ HasIndexGetter,
+ HasNameGetter,
+ InterfaceUUID=707da1d7-7c8f-42b1-bbbf-c009e429663f,
+ ImplementationUUID=5991ebaf-ce6c-42db-b1c8-fb34af8d5c76
+ ] StyleSheetList {
+ readonly attribute unsigned long length;
+ StyleSheet item(in unsigned long index);
+ };
+
+}
diff --git a/WebCore/css/html4.css b/WebCore/css/html4.css
new file mode 100644
index 0000000..65ec4e5
--- /dev/null
+++ b/WebCore/css/html4.css
@@ -0,0 +1,658 @@
+/*
+ * The default style sheet used to render HTML.
+ *
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 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.
+ *
+ */
+
+@namespace "http://www.w3.org/1999/xhtml";
+
+html {
+ display: block
+}
+
+/* children of the <head> element all have display:none */
+head {
+ display: none
+}
+
+meta {
+ display: none
+}
+
+title {
+ display: none
+}
+
+link {
+ display: none
+}
+
+style {
+ display: none
+}
+
+script {
+ display: none
+}
+
+/* generic block-level elements */
+
+body {
+ display: block;
+ margin: 8px
+}
+
+p {
+ display: block;
+ margin: 1.0__qem 0px
+}
+
+div {
+ display: block
+}
+
+layer {
+ display: block
+}
+
+marquee {
+ display: inline-block;
+ overflow: -webkit-marquee
+}
+
+address {
+ display: block
+}
+
+blockquote {
+ display: block;
+ margin: 1__qem 40px 1em 40px
+}
+
+q {
+ display: inline
+}
+
+q:before {
+ content: '"'
+ /* FIXME: content: open-quote; */
+}
+
+q:after {
+ content: '"'
+ /* FIXME: content: close-quote; */
+}
+
+center {
+ display: block;
+ /* special centering to be able to emulate the html4/netscape behaviour */
+ text-align: -webkit-center
+}
+
+hr {
+ display: block;
+ margin: 0.5em auto;
+ border-style: inset;
+ border-width: 1px
+}
+
+map {
+ display: inline
+}
+
+/* heading elements */
+
+h1 {
+ display: block;
+ font-size: 2em;
+ margin: .67__qem 0 .67em 0;
+ font-weight: bold
+}
+
+h2 {
+ display: block;
+ font-size: 1.5em;
+ margin: .83__qem 0 .83em 0;
+ font-weight: bold
+}
+
+h3 {
+ display: block;
+ font-size: 1.17em;
+ margin: 1__qem 0 1em 0;
+ font-weight: bold
+}
+
+h4 {
+ display: block;
+ margin: 1.33__qem 0 1.33em 0;
+ font-weight: bold
+}
+
+h5 {
+ display: block;
+ font-size: .83em;
+ margin: 1.67__qem 0 1.67em 0;
+ font-weight: bold
+}
+
+h6 {
+ display: block;
+ font-size: .67em;
+ margin: 2.33__qem 0 2.33em 0;
+ font-weight: bold
+}
+
+/* tables */
+
+table {
+ display: table;
+ border-collapse: separate;
+ border-spacing: 2px;
+ border-color: gray
+}
+
+thead {
+ display: table-header-group;
+ vertical-align: middle;
+ border-color: inherit
+}
+
+tbody {
+ display: table-row-group;
+ vertical-align: middle;
+ border-color: inherit
+}
+
+tfoot {
+ display: table-footer-group;
+ vertical-align: middle;
+ border-color: inherit
+}
+
+/* for tables without table section elements (can happen with XHTML or dynamically created tables) */
+table > tr {
+ vertical-align: middle;
+}
+
+col {
+ display: table-column
+}
+
+colgroup {
+ display: table-column-group
+}
+
+tr {
+ display: table-row;
+ vertical-align: inherit;
+ border-color: inherit
+}
+
+td, th {
+ display: table-cell;
+ vertical-align: inherit
+}
+
+th {
+ font-weight: bold
+}
+
+caption {
+ display: table-caption;
+ text-align: -webkit-center
+}
+
+/* lists */
+
+ul, menu, dir {
+ display: block;
+ list-style-type: disc;
+ margin: 1__qem 0 1em 0;
+ -webkit-padding-start: 40px
+}
+
+ol {
+ display: block;
+ list-style-type: decimal;
+ margin: 1__qem 0 1em 0;
+ -webkit-padding-start: 40px
+}
+
+li {
+ display: list-item
+}
+
+ul ul, ol ul {
+ list-style-type: circle
+}
+
+ol ol ul, ol ul ul, ul ol ul, ul ul ul {
+ list-style-type: square
+}
+
+dd {
+ display: block;
+ -webkit-margin-start: 40px
+}
+
+dl {
+ display: block;
+ margin: 1__qem 0 1em 0
+}
+
+dt {
+ display: block
+}
+
+ol ul, ul ol, ul ul, ol ol {
+ margin-top: 0;
+ margin-bottom: 0
+}
+
+/* form elements */
+
+form {
+ display: block;
+ margin: 0__qem 0 1em 0
+}
+
+label {
+ cursor: default;
+}
+
+legend {
+ display: block;
+ padding-left: 2px;
+ padding-right: 2px;
+ border: none
+}
+
+fieldset {
+ display: block;
+ margin-left: 2px;
+ margin-right: 2px;
+ padding: 0.35em 0.75em 0.625em;
+ border: 2px groove ThreeDFace
+}
+
+button {
+ -webkit-appearance: button;
+}
+
+input, textarea, keygen, select, button, isindex {
+ margin: 0__qem;
+ font: -webkit-small-control;
+ color: initial;
+ letter-spacing: normal;
+ word-spacing: normal;
+ line-height: normal;
+ text-transform: none;
+ text-indent: 0;
+ text-shadow: none;
+ display: inline-block;
+ text-align: -webkit-auto;
+}
+
+input[type="hidden"] {
+ display: none
+}
+
+input, input[type="password"], input[type="search"], isindex {
+ -webkit-appearance: textfield;
+ padding: 1px;
+ background-color: white;
+ border: 2px inset;
+ -webkit-rtl-ordering: logical;
+ -webkit-user-select: text;
+ cursor: auto;
+}
+
+input[type="search"] {
+ -webkit-appearance: searchfield;
+ -webkit-box-sizing: border-box;
+}
+
+input[type="search"]::-webkit-search-cancel-button {
+ -webkit-appearance: searchfield-cancel-button;
+}
+
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: searchfield-decoration;
+}
+
+input[type="search"]::-webkit-search-results-decoration {
+ -webkit-appearance: searchfield-results-decoration;
+}
+
+input[type="search"]::-webkit-search-results-button {
+ -webkit-appearance: searchfield-results-button;
+}
+
+textarea {
+ -webkit-appearance: textarea;
+ background-color: white;
+ border: 1px solid;
+ -webkit-rtl-ordering: logical;
+ -webkit-user-select: text;
+ -webkit-box-orient: vertical;
+ resize: auto;
+ cursor: auto;
+}
+
+input[type="password"] {
+ -webkit-text-security: disc !important;
+}
+
+input[type="hidden"], input[type="image"], input[type="file"] {
+ -webkit-appearance: initial;
+ padding: initial;
+ background-color: initial;
+ border: initial;
+}
+
+input[type="file"] {
+ -webkit-box-align: baseline;
+}
+
+input:-webkit-autofill {
+ background-color: #FAFFBD !important;
+ background-image:none !important;
+}
+
+input[type="radio"], input[type="checkbox"] {
+ margin: 3px 0.5ex;
+ padding: initial;
+ background-color: initial;
+ border: initial;
+}
+
+input[type="button"], input[type="submit"], input[type="reset"], input[type="file"]::-webkit-file-upload-button {
+ -webkit-appearance: push-button;
+ white-space: pre
+}
+
+input[type="button"], input[type="submit"], input[type="reset"], input[type="file"]::-webkit-file-upload-button, button {
+ -webkit-box-align: center;
+ text-align: center;
+ cursor: default;
+ color: ButtonText;
+ padding: 2px 6px 3px 6px;
+ border: 2px outset ButtonFace;
+ background-color: ButtonFace;
+ -webkit-box-sizing: border-box
+}
+
+input[type="range"] {
+ -webkit-appearance: slider-horizontal;
+ padding: initial;
+ border: initial;
+ margin: 2px;
+}
+
+input[type="range"]::-webkit-slider-thumb {
+ -webkit-appearance: sliderthumb-horizontal;
+}
+
+input[type="button"]:disabled, input[type="submit"]:disabled, input[type="reset"]:disabled, input[type="file"]:disabled::-webkit-file-upload-button, button:disabled, select:disabled, keygen:disabled, optgroup:disabled, option:disabled {
+ color: GrayText
+}
+
+input[type="button"]:active, input[type="submit"]:active, input[type="reset"]:active, input[type="file"]:active::-webkit-file-upload-button, button:active {
+ border-style: inset
+}
+
+input[type="button"]:active:disabled, input[type="submit"]:active:disabled, input[type="reset"]:active:disabled, input[type="file"]:active:disabled::-webkit-file-upload-button, button:active:disabled {
+ border-style: outset
+}
+
+area, param {
+ display: none
+}
+
+input[type="checkbox"] {
+ -webkit-appearance: checkbox;
+ -webkit-box-sizing: border-box;
+}
+
+input[type="radio"] {
+ -webkit-appearance: radio;
+ -webkit-box-sizing: border-box;
+}
+
+keygen, select {
+ -webkit-appearance: menulist;
+ -webkit-box-sizing: border-box;
+ -webkit-box-align: center;
+ border: 1px solid;
+ -webkit-border-radius: 5px;
+ white-space: pre;
+ -webkit-rtl-ordering: logical;
+ color: black;
+ background-color: white;
+ cursor: default;
+}
+
+select[size],
+select[multiple],
+select[size][multiple] {
+ -webkit-appearance: listbox;
+ -webkit-box-align: start;
+ border: 1px inset gray;
+ -webkit-border-radius: initial;
+ white-space: initial;
+}
+
+select[size="0"],
+select[size="1"] {
+ -webkit-appearance: menulist;
+ -webkit-box-align: center;
+ border: 1px solid;
+ -webkit-border-radius: 5px;
+ white-space: pre;
+}
+
+optgroup {
+ font-weight: bolder;
+}
+
+option {
+ font-weight: normal;
+}
+
+/* inline elements */
+
+u, ins {
+ text-decoration: underline
+}
+
+strong, b {
+ font-weight: bolder
+}
+
+i, cite, em, var, address {
+ font-style: italic
+}
+
+tt, code, kbd, samp {
+ font-family: monospace
+}
+
+pre, xmp, plaintext, listing {
+ display: block;
+ font-family: monospace;
+ white-space: pre;
+ margin: 1__qem 0
+}
+
+big {
+ font-size: larger
+}
+
+small {
+ font-size: smaller
+}
+
+s, strike, del {
+ text-decoration: line-through
+}
+
+sub {
+ vertical-align: sub;
+ font-size: smaller
+}
+
+sup {
+ vertical-align: super;
+ font-size: smaller
+}
+
+nobr {
+ white-space: nowrap
+}
+
+/* states */
+
+:focus {
+ outline: auto 5px -webkit-focus-ring-color
+}
+
+/* Read-only text fields do not show a focus ring but do still receive focus */
+html:focus, body:focus, input[readonly]:focus {
+ outline: none
+}
+
+input:focus, textarea:focus, isindex:focus, keygen:focus, select:focus {
+ outline-offset: -2px
+}
+
+input[type="button"]:focus,
+input[type="checkbox"]:focus,
+input[type="file"]:focus,
+input[type="hidden"]:focus,
+input[type="image"]:focus,
+input[type="radio"]:focus,
+input[type="reset"]:focus,
+input[type="search"]:focus,
+input[type="submit"]:focus,
+input[type="file"]:focus::-webkit-file-upload-button {
+ outline-offset: 0
+}
+
+a:-webkit-any-link {
+ color: -webkit-link;
+ text-decoration: underline;
+ cursor: auto;
+}
+
+a:-webkit-any-link:active {
+ color: -webkit-activelink
+}
+
+/* other elements */
+
+noframes {
+ display: none
+}
+
+frameset, frame {
+ display: block
+}
+
+frameset {
+ border-color: inherit
+}
+
+iframe {
+ border: 2px inset
+}
+
+/* media controls */
+/* FIXME this is not the final styling */
+
+audio {
+ width: 200px;
+ height: 16px;
+}
+
+audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel {
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ height: 16px;
+ -webkit-user-select: none;
+}
+
+audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-button {
+ -webkit-appearance: media-mute-button;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 17px;
+ height: 16px;
+}
+
+audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button {
+ -webkit-appearance: media-play-button;
+ position: absolute;
+ top: 0;
+ left: 16px;
+ width: 17px;
+ height: 16px;
+}
+
+audio::-webkit-media-controls-time-display, video::-webkit-media-controls-time-display {
+ display: none;
+}
+
+audio::-webkit-media-controls-timeline, video::-webkit-media-controls-timeline {
+ -webkit-appearance: media-slider;
+ position: absolute;
+ top: 0;
+ left: 32px;
+ right: 32px;
+ height: 16px;
+ padding: 0px 2px;
+}
+
+audio::-webkit-media-controls-seek-back-button, video::-webkit-media-controls-seek-back-button {
+ -webkit-appearance: media-seek-back-button;
+ position: absolute;
+ top: 0;
+ right: 16px;
+ width: 17px;
+ height: 16px;
+}
+
+
+audio::-webkit-media-controls-seek-forward-button, video::-webkit-media-controls-seek-forward-button {
+ -webkit-appearance: media-seek-forward-button;
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 17px;
+ height: 16px;
+}
+
+audio::-webkit-media-controls-fullscreen-button, video::-webkit-media-controls-fullscreen-button {
+ display: none;
+}
+
+/* noscript is handled internally, as it depends on settings */
diff --git a/WebCore/css/make-css-file-arrays.pl b/WebCore/css/make-css-file-arrays.pl
new file mode 100755
index 0000000..05c8fd1
--- /dev/null
+++ b/WebCore/css/make-css-file-arrays.pl
@@ -0,0 +1,88 @@
+#!/usr/bin/perl -w
+#
+# Copyright (C) 2006 Apple Computer, Inc.
+#
+# 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.
+#
+
+# Usage: make-css-file-arrays.pl <header> <output> <input> ...
+
+use strict;
+use Getopt::Long;
+
+my $preprocessor;
+
+GetOptions('preprocessor=s' => \$preprocessor);
+
+if (!$preprocessor) {
+ $preprocessor = "/usr/bin/gcc -E -P -x c++";
+}
+
+my $header = $ARGV[0];
+shift;
+
+my $out = $ARGV[0];
+shift;
+
+open HEADER, ">", $header or die;
+open OUT, ">", $out or die;
+
+print HEADER "namespace WebCore {\n";
+print OUT "namespace WebCore {\n";
+
+for my $in (@ARGV) {
+ $in =~ /(\w+)\.css$/ or die;
+ my $name = $1;
+
+ # Slurp in the CSS file.
+ open IN, $preprocessor . " " . $in . "|" or die;
+ my $text; { local $/; $text = <IN>; }
+ close IN;
+
+ # Remove comments in a simple-minded way that will work fine for our files.
+ # Could do this a fancier way if we were worried about arbitrary CSS source.
+ $text =~ s|/\*.*?\*/||gs;
+
+ # Crunch whitespace just to make it a little smaller.
+ # Could do work to avoid doing this inside quote marks but our files don't have runs of spaces in quotes.
+ # Could crunch further based on places where whitespace is optional.
+ $text =~ s|\s+| |gs;
+ $text =~ s|^ ||;
+ $text =~ s| $||;
+
+ # Write out a C array of the characters.
+ my $length = length $text;
+ print HEADER "extern const char ${name}UserAgentStyleSheet[${length}];\n";
+ print OUT "extern const char ${name}UserAgentStyleSheet[${length}] = {\n";
+ my $i = 0;
+ while ($i < $length) {
+ print OUT " ";
+ my $j = 0;
+ while ($j < 16 && $i < $length) {
+ print OUT ", " unless $j == 0;
+ print OUT ord substr $text, $i, 1;
+ ++$i;
+ ++$j;
+ }
+ print OUT "," unless $i == $length;
+ print OUT "\n";
+ }
+ print OUT "};\n";
+
+}
+
+print HEADER "}\n";
+print OUT "}\n";
diff --git a/WebCore/css/makegrammar.pl b/WebCore/css/makegrammar.pl
new file mode 100644
index 0000000..fc19e10
--- /dev/null
+++ b/WebCore/css/makegrammar.pl
@@ -0,0 +1,55 @@
+#! /usr/bin/perl
+#
+# This file is part of the WebKit project
+#
+# Copyright (C) 2007 Trolltech ASA
+#
+# 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.
+use strict;
+use warnings;
+
+my $grammar = $ARGV[0];
+my $fileBase = $ARGV[1];
+
+system("bison -d -p cssyy " . $grammar . " -o " . $fileBase . ".tab.c");
+
+open HEADER, ">" . $fileBase . ".h" or die;
+print HEADER << "EOF";
+#ifndef CSSGRAMMAR_H
+#define CSSGRAMMAR_H
+EOF
+
+open HPP, "<" . $fileBase . ".tab.h" or die;
+while (<HPP>) {
+ print HEADER;
+}
+close HPP;
+
+print HEADER "#endif\n";
+
+close HEADER;
+
+unlink($fileBase . ".tab.h");
+
+open CPP, ">" . $fileBase . ".cpp" or die;
+open GENSRC, "<" . $fileBase . ".tab.c" or die;
+while (<GENSRC>) {
+ print CPP;
+}
+close GENSRC;
+close CPP;
+
+unlink($fileBase . ".tab.c");
diff --git a/WebCore/css/makeprop.pl b/WebCore/css/makeprop.pl
new file mode 100644
index 0000000..1600c1b
--- /dev/null
+++ b/WebCore/css/makeprop.pl
@@ -0,0 +1,114 @@
+#! /usr/bin/perl
+#
+# This file is part of the WebKit project
+#
+# Copyright (C) 1999 Waldo Bastian (bastian@kde.org)
+# Copyright (C) 2007 Apple Inc. All rights reserved.
+# Copyright (C) 2007 Trolltech ASA
+#
+# 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.
+use strict;
+use warnings;
+
+open NAMES, "<CSSPropertyNames.in" || die "Could not find CSSPropertyNames.in";
+my @names = ();
+while (<NAMES>) {
+ next if (m/#/);
+ chomp $_;
+ next if ($_ eq "");
+ push @names, $_;
+}
+close(NAMES);
+
+open GPERF, ">CSSPropertyNames.gperf" || die "Could not open CSSPropertyNames.gperf for writing";
+print GPERF << "EOF";
+%{
+/* This file is automatically generated from CSSPropertyNames.in by makeprop, do not edit */
+#include \"CSSPropertyNames.h\"
+%}
+struct props {
+ const char* name;
+ int id;
+};
+%%
+EOF
+
+foreach my $name (@names) {
+ my $id = $name;
+ $id =~ s/-/_/g;
+ print GPERF $name . ", CSS_PROP_" . uc($id) . "\n";
+}
+print GPERF "%%\n";
+close GPERF;
+
+open HEADER, ">CSSPropertyNames.h" || die "Could not open CSSPropertyNames.h for writing";
+print HEADER << "EOF";
+/* This file is automatically generated from CSSPropertyNames.in by makeprop, do not edit */
+
+#ifndef CSSPropertyNames_h
+#define CSSPropertyNames_h
+
+enum CSSPropertyID {
+ CSS_PROP_INVALID = 0,
+EOF
+
+my $i = 1;
+my $maxLen = 0;
+foreach my $name (@names) {
+ my $id = $name;
+ $id =~ s/-/_/g;
+ print HEADER " CSS_PROP_" . uc($id) . " = " . $i . ",\n";
+ $i = $i + 1;
+ if (length($name) > $maxLen) {
+ $maxLen = length($name);
+ }
+}
+print HEADER "};\n\n";
+print HEADER "const int numCSSProperties = " . $i . ";\n";
+print HEADER "const size_t maxCSSPropertyNameLength = " . $maxLen . ";\n";
+
+print HEADER << "EOF";
+
+const char* getPropertyName(CSSPropertyID);
+
+#endif
+EOF
+
+close HEADER;
+
+system("gperf -a -L ANSI-C -E -C -c -o -t --key-positions=\"*\" -NfindProp -Hhash_prop -Wwordlist_prop -D -s 2 CSSPropertyNames.gperf > CSSPropertyNames.c");
+
+open C, ">>CSSPropertyNames.c" || die "Could not open CSSPropertyNames.c for writing";
+print C "static const char * const propertyList[] = {\n";
+print C "\"\",\n";
+
+foreach my $name (@names) {
+ print C "\"" . $name . "\", \n";
+}
+
+print C << "EOF";
+ 0
+};
+const char* getPropertyName(CSSPropertyID id)
+{
+ if (id >= numCSSProperties || id <= 0)
+ return 0;
+ return propertyList[id];
+}
+EOF
+
+close C;
+
diff --git a/WebCore/css/maketokenizer b/WebCore/css/maketokenizer
new file mode 100644
index 0000000..7cd3a9c
--- /dev/null
+++ b/WebCore/css/maketokenizer
@@ -0,0 +1,127 @@
+print <<END;
+/*
+ * This file is part of the DOM implementation for KDE.
+ *
+ * Copyright (C) 2003 Lars Knoll (knoll\@kde.org)
+ *
+ *
+ * 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.
+ */
+
+/* This file is mostly data generated by flex. Unfortunately flex
+ can't handle 16bit strings directly, so we just copy the part of
+ the code we need and modify it to our needs.
+
+ Most of the defines below are to make sure we can easily use the
+ flex generated code, using as little editing as possible.
+
+ The flex syntax to generate the lexer are more or less directly
+ copied from the CSS2.1 specs, with some fixes for comments and
+ the important symbol.
+
+ To regenerate, run flex on tokenizer.flex. After this, copy the
+ data tables and the YY_DECL method over to this file. Remove the
+ init code from YY_DECL and change the YY_END_OF_BUFFER to only call
+ yyterminate().
+
+*/
+
+// --------- begin generated code -------------------
+
+END
+
+{
+print<<END
+
+#include "CSSGrammar.h"
+
+#define INITIAL 0
+#define mediaquery 1
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+END
+}
+
+
+while (<>) {
+ last if /YY_NUM_RULES/;
+}
+
+print;
+while (<>) {
+ last if /yy_last_accepting/;
+ print;
+}
+
+# media query, tokenizer state support
+while (<>) {
+ last if /yytext/;
+}
+while (<>) {
+ last if not (/define/ || /line/) ;
+ print;
+}
+
+while (<>) {
+ last if /^YY_DECL/;
+}
+
+print;
+while (<>) {
+ s/char/UChar/;
+ print;
+ last if /yy_act/;
+}
+
+while (<>) {
+ last if /while \( 1 \)/;
+}
+
+print;
+while (<>) {
+ next if /^yy_match:/;
+ next if /^do_action:/;
+ last if /YY_END_OF_BUFFER/;
+ print;
+ print "case YY_END_OF_BUFFER:\n" if /^case YY_STATE_EOF\(INITIAL\):/;
+}
+
+while (<>) {
+ last if /default:/;
+}
+
+print;
+while (<>) {
+ print;
+ last if /end of yylex/;
+}
diff --git a/WebCore/css/makevalues.pl b/WebCore/css/makevalues.pl
new file mode 100644
index 0000000..97f73ae
--- /dev/null
+++ b/WebCore/css/makevalues.pl
@@ -0,0 +1,108 @@
+#! /usr/bin/perl
+#
+# This file is part of the WebKit project
+#
+# Copyright (C) 1999 Waldo Bastian (bastian@kde.org)
+# Copyright (C) 2007 Apple Inc. All rights reserved.
+# Copyright (C) 2007 Trolltech ASA
+#
+# 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.
+use strict;
+use warnings;
+
+open NAMES, "<CSSValueKeywords.in" || die "Could not open CSSValueKeywords.in";
+my @names = ();
+while (<NAMES>) {
+ next if (m/#/);
+ chomp $_;
+ next if ($_ eq "");
+ push @names, $_;
+}
+close(NAMES);
+
+open GPERF, ">CSSValueKeywords.gperf" || die "Could not open CSSValueKeywords.gperf for writing";
+print GPERF << "EOF";
+%{
+/* This file is automatically generated from CSSValueKeywords.in by makevalues, do not edit */
+
+#include \"CSSValueKeywords.h\"
+%}
+struct css_value {
+ const char* name;
+ int id;
+};
+%%
+EOF
+
+foreach my $name (@names) {
+ my $id = $name;
+ $id =~ s/-/_/g;
+ print GPERF $name . ", CSS_VAL_" . uc($id) . "\n";
+}
+print GPERF "%%\n";
+close GPERF;
+
+open HEADER, ">CSSValueKeywords.h" || die "Could not open CSSValueKeywords.h for writing";
+print HEADER << "EOF";
+/* This file is automatically generated from CSSValueKeywords.in by makevalues, do not edit */
+
+#ifndef CSSValues_h
+#define CSSValues_h
+
+const int CSS_VAL_INVALID = 0;
+EOF
+
+my $i = 1;
+my $maxLen = 0;
+foreach my $name (@names) {
+ my $id = $name;
+ $id =~ s/-/_/g;
+ print HEADER "const int CSS_VAL_" . uc($id) . " = " . $i . ";\n";
+ $i = $i + 1;
+ if (length($name) > $maxLen) {
+ $maxLen = length($name);
+ }
+}
+print HEADER "const int numCSSValueKeywords = " . $i . ";\n";
+print HEADER "const size_t maxCSSValueKeywordLength = " . $maxLen . ";\n";
+print HEADER << "EOF";
+
+const char* getValueName(unsigned short id);
+
+#endif
+EOF
+close HEADER;
+
+system("gperf -L ANSI-C -E -C -n -o -t --key-positions=\"*\" -NfindValue -Hhash_val -Wwordlist_value -D CSSValueKeywords.gperf > CSSValueKeywords.c");
+
+open C, ">>CSSValueKeywords.c" || die "Could not open CSSValueKeywords.c for writing";
+print C "static const char * const valueList[] = {\n";
+print C "\"\",\n";
+foreach my $name (@names) {
+ print C "\"" . $name . "\", \n";
+}
+print C << "EOF";
+ 0
+};
+const char* getValueName(unsigned short id)
+{
+ if (id >= numCSSValueKeywords || id <= 0)
+ return 0;
+ return valueList[id];
+}
+EOF
+
+close C;
diff --git a/WebCore/css/quirks.css b/WebCore/css/quirks.css
new file mode 100644
index 0000000..1b79582
--- /dev/null
+++ b/WebCore/css/quirks.css
@@ -0,0 +1,48 @@
+/*
+ * Additonal style sheet used to render HTML pages in quirks mode.
+ *
+ * Copyright (C) 2000-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2006, 2007 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.
+ *
+ */
+
+/* Give floated images margins of 3px */
+img[align="left"] {
+ margin-right: 3px;
+}
+img[align="right"] {
+ margin-left: 3px;
+}
+
+/* Tables reset both line-height and white-space in quirks mode. */
+/* Compatible with WinIE. Note that font-family is *not* reset. */
+table {
+ white-space: normal;
+ line-height: normal;
+ font-weight: normal;
+ font-size: medium;
+ font-variant: normal;
+ font-style: normal;
+ color: -webkit-text;
+ text-align: -webkit-auto
+}
+
+/* This will apply only to text fields, since all other inputs already use border box sizing */
+input:not([type=image]), textarea {
+ -webkit-box-sizing: border-box;
+}
diff --git a/WebCore/css/svg.css b/WebCore/css/svg.css
new file mode 100644
index 0000000..322eda8
--- /dev/null
+++ b/WebCore/css/svg.css
@@ -0,0 +1,65 @@
+/*
+ * The default style sheet used to render SVG.
+ *
+ * Copyright (C) 2005, 2006 Apple Computer, 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 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.
+ */
+
+@namespace "http://www.w3.org/2000/svg";
+
+/*
+ When an outermost SVG 'svg' element is stand-alone or embedded inline within a parent XML grammar
+ which does not use CSS layout [CSS2-LAYOUT] or XSL formatting [XSL], the 'overflow' property on the
+ outermost 'svg' element is ignored for the purposes of visual rendering and the initial clipping path is set
+ to the bounds of the initial viewport.
+*/
+svg:root {
+ overflow: hidden !important
+}
+
+svg {
+ width: 100%;
+ height: 100%;
+}
+
+svg, symbol, marker, pattern {
+ overflow: hidden
+}
+
+text, foreignObject {
+ display: block
+}
+
+text, tspan, textPath {
+ white-space: nowrap
+}
+
+text, tspan, tref {
+ -webkit-text-size-adjust: none;
+}
+
+/* states */
+
+:focus {
+ outline: auto 5px -webkit-focus-ring-color
+}
diff --git a/WebCore/css/tokenizer.flex b/WebCore/css/tokenizer.flex
new file mode 100644
index 0000000..214b5bf
--- /dev/null
+++ b/WebCore/css/tokenizer.flex
@@ -0,0 +1,98 @@
+%option case-insensitive
+%option noyywrap
+%option 8bit
+%option stack
+%s mediaquery
+
+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 \"([\t !#$%&(-~]|\\{nl}|\'|{nonascii}|{escape})*\"
+string2 \'([\t !#$%&(-~]|\\{nl}|\"|{nonascii}|{escape})*\'
+hexcolor {h}{3}|{h}{6}
+
+ident -?{nmstart}{nmchar}*
+name {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 (-?[0-9]*n[\+-][0-9]+)|(-?[0-9]*n)
+
+%%
+
+\/\*[^*]*\*+([^/*][^*]*\*+)*\/ /* ignore comments */
+
+[ \t\r\n\f]+ {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;}
+{nth} {yyTok = NTH; return yyTok;}
+
+"#"{hexcolor} {yyTok = HEX; return yyTok;}
+"#"{ident} {yyTok = IDSEL; return yyTok;}
+
+"@import" {BEGIN(mediaquery); yyTok = IMPORT_SYM; return yyTok;}
+"@page" {yyTok = PAGE_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; }
+
+"!"{w}"important" {yyTok = IMPORTANT_SYM; return yyTok;}
+
+{num}em {yyTok = EMS; 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}ms {yyTok = MSECS; return yyTok;}
+{num}s {yyTok = SECS; return yyTok;}
+{num}Hz {yyTok = HERZ; return yyTok;}
+{num}kHz {yyTok = KHERZ; return yyTok;}
+{num}{ident} {yyTok = DIMEN; return yyTok;}
+{num}%+ {yyTok = PERCENTAGE; return yyTok;}
+{intnum} {yyTok = INTEGER; return yyTok;}
+{num} {yyTok = FLOATTOKEN; return yyTok;}
+
+"not(" {yyTok = NOTFUNCTION; return yyTok;}
+"url("{w}{string}{w}")" {yyTok = URI; return yyTok;}
+"url("{w}{url}{w}")" {yyTok = URI; 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;}
+
+%%
diff --git a/WebCore/css/view-source.css b/WebCore/css/view-source.css
new file mode 100644
index 0000000..8d34211
--- /dev/null
+++ b/WebCore/css/view-source.css
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2006 Apple Computer, 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 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,
+ * 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.
+ */
+
+body {
+ margin: 0
+}
+
+table {
+ border-spacing: 0;
+ counter-reset: lines;
+ white-space: pre-wrap !important;
+ margin: 0;
+ word-break: break-word;
+ font-family: monospace;
+}
+
+td {
+ padding: 0 !important;
+ vertical-align: baseline
+}
+
+.webkit-line-gutter-backdrop, .webkit-line-number {
+ padding: 0 2px !important;
+ min-width: 21px;
+ background-color: rgb(240, 240, 240);
+ border-right: 1px solid rgb(128, 128, 128) !important;
+ -webkit-user-select: none;
+}
+
+.webkit-line-gutter-backdrop {
+ position: absolute;
+ z-index: -1;
+ left: 0;
+ top: 0;
+ height: 100%
+}
+
+.webkit-line-number {
+ text-align: right;
+ color: rgb(128, 128, 128);
+ word-break: normal;
+ white-space: nowrap;
+ font-size: 9px;
+ font-family: Helvetica
+}
+
+.webkit-line-number::before {
+ content: counter(lines);
+ counter-increment: lines;
+ -webkit-user-select: none
+}
+
+.webkit-line-content {
+ padding: 0 5px !important;
+}
+
+.webkit-html-tag {
+ /* Keep this in sync with inspector.css (.webkit-html-tag) */
+ color: rgb(136, 18, 128);
+}
+
+.webkit-html-attribute-name {
+ /* Keep this in sync with inspector.css (.webkit-html-attribute-name) */
+ color: rgb(153, 69, 0);
+}
+
+.webkit-html-attribute-value {
+ /* Keep this in sync with inspector.css (.webkit-html-attribute-value) */
+ color: rgb(26, 26, 166);
+}
+
+.webkit-html-external-link, .webkit-html-resource-link {
+ /* Keep this in sync with inspector.css (.webkit-html-external-link, .webkit-html-resource-link) */
+ color: #00e;
+}
+
+.webkit-html-external-link {
+ /* Keep this in sync with inspector.css (.webkit-html-external-link) */
+ text-decoration: none;
+}
+
+.webkit-html-external-link:hover {
+ /* Keep this in sync with inspector.css (.webkit-html-external-link:hover) */
+ text-decoration: underline;
+}
+
+.webkit-html-comment {
+ /* Keep this in sync with inspector.css (.comment) */
+ color: rgb(35, 110, 37);
+}
+
+.webkit-html-doctype {
+ color: rgb(192, 192, 192);
+}
+
+.webkit-html-entity {
+ rgb(136, 18, 128);
+}
+
+.webkit-html-message-bubble {
+ -webkit-box-shadow: black 0px 2px 5px;
+ -webkit-border-radius: 9px;
+ -webkit-border-fit: lines;
+ font-size: 9px;
+ font-family: Lucida Grande;
+ font-weight: bold;
+ margin: 6px 25px;
+ padding: 0 7px 1px;
+}
+
+.webkit-html-warning-message {
+ background-color: rgb(100%, 62%, 42%);
+ border: 2px solid rgb(100%, 52%, 21%);
+}
+
+.webkit-html-error-message {
+ background-color: rgb(100%, 42%, 42%);
+ border: 2px solid rgb(100%, 31%, 31%);
+}
+
+.webkit-html-message-line {
+ padding-left: 23px;
+ text-indent: -20px;
+}
+
+.webkit-html-message-icon {
+ position: relative;
+ top: 2px;
+ margin: 0 4px;
+}