diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2009-03-23 09:18:55 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-03-23 09:18:55 (GMT) |
commit | e5fcad302d86d316390c6b0f62759a067313e8a9 (patch) | |
tree | c2afbf6f1066b6ce261f14341cf6d310e5595bc1 /src/3rdparty/webkit/WebCore/css | |
download | Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.zip Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.gz Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.bz2 |
Long live Qt 4.5!
Diffstat (limited to 'src/3rdparty/webkit/WebCore/css')
171 files changed, 34790 insertions, 0 deletions
diff --git a/src/3rdparty/webkit/WebCore/css/CSSBorderImageValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSBorderImageValue.cpp new file mode 100644 index 0000000..3260af4 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSBorderImageValue.cpp @@ -0,0 +1,66 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "CSSBorderImageValue.h" + +#include "PlatformString.h" +#include "Rect.h" + +namespace WebCore { + +CSSBorderImageValue::CSSBorderImageValue(PassRefPtr<CSSValue> image, PassRefPtr<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::createIdentifier(m_horizontalSizeRule)->cssText(); + text += " "; + text += CSSPrimitiveValue::createIdentifier(m_verticalSizeRule)->cssText(); + + return text; +} + +void CSSBorderImageValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const CSSStyleSheet* styleSheet) +{ + m_image->addSubresourceStyleURLs(urls, styleSheet); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSBorderImageValue.h b/src/3rdparty/webkit/WebCore/css/CSSBorderImageValue.h new file mode 100644 index 0000000..23832b8 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSBorderImageValue.h @@ -0,0 +1,62 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef CSSBorderImageValue_h +#define CSSBorderImageValue_h + +#include "CSSValue.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class Rect; + +class CSSBorderImageValue : public CSSValue { +public: + static PassRefPtr<CSSBorderImageValue> create(PassRefPtr<CSSValue> image, PassRefPtr<Rect> sliceRect, int horizontalRule, int verticalRule) + { + return adoptRef(new CSSBorderImageValue(image, sliceRect, horizontalRule, verticalRule)); + } + + virtual String cssText() const; + + CSSValue* imageValue() const { return m_image.get(); } + + virtual void addSubresourceStyleURLs(ListHashSet<KURL>&, const CSSStyleSheet*); + + // The border image. + RefPtr<CSSValue> m_image; + + // These four values are used to make "cuts" in the image. They can be numbers + // or percentages. + RefPtr<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 + +private: + CSSBorderImageValue(PassRefPtr<CSSValue> image, PassRefPtr<Rect> sliceRect, int horizontalRule, int verticalRule); +}; + +} // namespace WebCore + +#endif // CSSBorderImageValue_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSCanvasValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSCanvasValue.cpp new file mode 100644 index 0000000..4fd5210 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSCanvasValue.cpp @@ -0,0 +1,89 @@ +/* + * 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 "CSSCanvasValue.h" + +#include "ImageBuffer.h" +#include "RenderObject.h" + +namespace WebCore { + +CSSCanvasValue::~CSSCanvasValue() +{ + if (m_element) + m_element->setObserver(0); +} + +String CSSCanvasValue::cssText() const +{ + String result = "-webkit-canvas("; + result += m_name + ")"; + return result; +} + +void CSSCanvasValue::canvasChanged(HTMLCanvasElement*, const FloatRect& changedRect) +{ + IntRect imageChangeRect = enclosingIntRect(changedRect); + HashMap<RenderObject*, IntSize>::const_iterator end = m_clients.end(); + for (HashMap<RenderObject*, IntSize>::const_iterator curr = m_clients.begin(); curr != end; ++curr) + curr->first->imageChanged(static_cast<WrappedImagePtr>(this), &imageChangeRect); +} + +void CSSCanvasValue::canvasResized(HTMLCanvasElement*) +{ + HashMap<RenderObject*, IntSize>::const_iterator end = m_clients.end(); + for (HashMap<RenderObject*, IntSize>::const_iterator curr = m_clients.begin(); curr != end; ++curr) + curr->first->imageChanged(static_cast<WrappedImagePtr>(this)); +} + +IntSize CSSCanvasValue::fixedSize(const RenderObject* renderer) +{ + if (HTMLCanvasElement* elt = element(renderer->document())) + return IntSize(elt->width(), elt->height()); + return IntSize(); +} + +HTMLCanvasElement* CSSCanvasValue::element(Document* document) +{ + if (!m_element) { + m_element = document->getCSSCanvasElement(m_name); + if (!m_element) + return 0; + m_element->setObserver(this); + } + return m_element; +} + +Image* CSSCanvasValue::image(RenderObject* renderer, const IntSize& /*size*/) +{ + ASSERT(m_clients.contains(renderer)); + HTMLCanvasElement* elt = element(renderer->document()); + if (!elt || !elt->buffer()) + return 0; + return elt->buffer()->image(); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSCanvasValue.h b/src/3rdparty/webkit/WebCore/css/CSSCanvasValue.h new file mode 100644 index 0000000..a698f31 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSCanvasValue.h @@ -0,0 +1,68 @@ +/* + * 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 CSSCanvasValue_h +#define CSSCanvasValue_h + +#include "CSSImageGeneratorValue.h" +#include "HTMLCanvasElement.h" + +namespace WebCore { + +class Document; + +class CSSCanvasValue : public CSSImageGeneratorValue, private CanvasObserver { +public: + static PassRefPtr<CSSCanvasValue> create() { return adoptRef(new CSSCanvasValue); } + virtual ~CSSCanvasValue(); + + virtual String cssText() const; + + virtual Image* image(RenderObject*, const IntSize&); + virtual bool isFixedSize() const { return true; } + virtual IntSize fixedSize(const RenderObject*); + + void setName(const String& name) { m_name = name; } + +private: + CSSCanvasValue() + : m_element(0) + { + } + + virtual void canvasChanged(HTMLCanvasElement* element, const FloatRect& changedRect); + virtual void canvasResized(HTMLCanvasElement* element); + + HTMLCanvasElement* element(Document*); + + // The name of the canvas. + String m_name; + // The document supplies the element and owns it. + HTMLCanvasElement* m_element; +}; + +} // namespace WebCore + +#endif // CSSCanvasValue_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSCharsetRule.cpp b/src/3rdparty/webkit/WebCore/css/CSSCharsetRule.cpp new file mode 100644 index 0000000..48229e4 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSCharsetRule.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + * 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(CSSStyleSheet* parent, const String& encoding) + : CSSRule(parent) + , m_encoding(encoding) +{ +} + +CSSCharsetRule::~CSSCharsetRule() +{ +} + +String CSSCharsetRule::cssText() const +{ + return "@charset \"" + m_encoding + "\";"; +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSCharsetRule.h b/src/3rdparty/webkit/WebCore/css/CSSCharsetRule.h new file mode 100644 index 0000000..07fb075 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSCharsetRule.h @@ -0,0 +1,57 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2002-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. + */ + +#ifndef CSSCharsetRule_h +#define CSSCharsetRule_h + +#include "CSSRule.h" +#include "PlatformString.h" + +namespace WebCore { + +class CSSCharsetRule : public CSSRule { +public: + static PassRefPtr<CSSCharsetRule> create(CSSStyleSheet* parent, const String& encoding) + { + return adoptRef(new CSSCharsetRule(parent, encoding)); + } + + virtual ~CSSCharsetRule(); + + const String& encoding() const { return m_encoding; } + void setEncoding(const String& encoding, ExceptionCode&) { m_encoding = encoding; } + + virtual String cssText() const; + +private: + CSSCharsetRule(CSSStyleSheet* parent, const String& encoding); + + virtual bool isCharsetRule() { return true; } + + // from CSSRule + virtual unsigned short type() const { return CHARSET_RULE; } + + String m_encoding; +}; + +} // namespace WebCore + +#endif // CSSCharsetRule_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSCharsetRule.idl b/src/3rdparty/webkit/WebCore/css/CSSCharsetRule.idl new file mode 100644 index 0000000..ebe659c --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSComputedStyleDeclaration.cpp b/src/3rdparty/webkit/WebCore/css/CSSComputedStyleDeclaration.cpp new file mode 100644 index 0000000..d84fa31 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSComputedStyleDeclaration.cpp @@ -0,0 +1,1381 @@ +/* + * Copyright (C) 2004 Zack Rusin <zack@kde.org> + * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> + * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.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 "CSSComputedStyleDeclaration.h" + +#include "CSSBorderImageValue.h" +#include "CSSMutableStyleDeclaration.h" +#include "CSSPrimitiveValue.h" +#include "CSSPrimitiveValueMappings.h" +#include "CSSPropertyNames.h" +#include "CSSReflectValue.h" +#include "CSSTimingFunctionValue.h" +#include "CSSValueList.h" +#include "CachedImage.h" +#include "Document.h" +#include "ExceptionCode.h" +#include "Pair.h" +#include "Rect.h" +#include "RenderObject.h" +#include "ShadowValue.h" +#include "WebKitCSSTransformValue.h" + +#if ENABLE(DASHBOARD_SUPPORT) +#include "DashboardRegion.h" +#endif + +namespace WebCore { + +// List of all properties we know how to compute, omitting shorthands. +static const int computedProperties[] = { + CSSPropertyBackgroundAttachment, + CSSPropertyBackgroundColor, + CSSPropertyBackgroundImage, + // more specific background-position-x/y are non-standard + CSSPropertyBackgroundPosition, + CSSPropertyBackgroundRepeat, + CSSPropertyBorderBottomColor, + CSSPropertyBorderBottomStyle, + CSSPropertyBorderBottomWidth, + CSSPropertyBorderCollapse, + CSSPropertyBorderLeftColor, + CSSPropertyBorderLeftStyle, + CSSPropertyBorderLeftWidth, + CSSPropertyBorderRightColor, + CSSPropertyBorderRightStyle, + CSSPropertyBorderRightWidth, + CSSPropertyBorderTopColor, + CSSPropertyBorderTopStyle, + CSSPropertyBorderTopWidth, + CSSPropertyBottom, + CSSPropertyCaptionSide, + CSSPropertyClear, + CSSPropertyColor, + CSSPropertyCursor, + CSSPropertyDirection, + CSSPropertyDisplay, + CSSPropertyEmptyCells, + CSSPropertyFloat, + CSSPropertyFontFamily, + CSSPropertyFontSize, + CSSPropertyFontStyle, + CSSPropertyFontVariant, + CSSPropertyFontWeight, + CSSPropertyHeight, + CSSPropertyLeft, + CSSPropertyLetterSpacing, + CSSPropertyLineHeight, + CSSPropertyListStyleImage, + CSSPropertyListStylePosition, + CSSPropertyListStyleType, + CSSPropertyMarginBottom, + CSSPropertyMarginLeft, + CSSPropertyMarginRight, + CSSPropertyMarginTop, + CSSPropertyMaxHeight, + CSSPropertyMaxWidth, + CSSPropertyMinHeight, + CSSPropertyMinWidth, + CSSPropertyOpacity, + CSSPropertyOrphans, + CSSPropertyOutlineColor, + CSSPropertyOutlineStyle, + CSSPropertyOutlineWidth, + CSSPropertyOverflowX, + CSSPropertyOverflowY, + CSSPropertyPaddingBottom, + CSSPropertyPaddingLeft, + CSSPropertyPaddingRight, + CSSPropertyPaddingTop, + CSSPropertyPageBreakAfter, + CSSPropertyPageBreakBefore, + CSSPropertyPageBreakInside, + CSSPropertyPointerEvents, + CSSPropertyPosition, + CSSPropertyResize, + CSSPropertyRight, + CSSPropertyTableLayout, + CSSPropertyTextAlign, + CSSPropertyTextDecoration, + CSSPropertyTextIndent, + CSSPropertyTextShadow, + CSSPropertyTextTransform, + CSSPropertyTop, + CSSPropertyUnicodeBidi, + CSSPropertyVerticalAlign, + CSSPropertyVisibility, + CSSPropertyWhiteSpace, + CSSPropertyWidows, + CSSPropertyWidth, + CSSPropertyWordSpacing, + CSSPropertyWordWrap, + CSSPropertyZIndex, + CSSPropertyZoom, + + CSSPropertyWebkitAnimationDelay, + CSSPropertyWebkitAnimationDirection, + CSSPropertyWebkitAnimationDuration, + CSSPropertyWebkitAnimationIterationCount, + CSSPropertyWebkitAnimationName, + CSSPropertyWebkitAnimationPlayState, + CSSPropertyWebkitAnimationTimingFunction, + CSSPropertyWebkitAppearance, + CSSPropertyWebkitBackgroundClip, + CSSPropertyWebkitBackgroundComposite, + CSSPropertyWebkitBackgroundOrigin, + CSSPropertyWebkitBackgroundSize, + CSSPropertyWebkitBorderFit, + CSSPropertyWebkitBorderImage, + CSSPropertyWebkitBorderHorizontalSpacing, + CSSPropertyWebkitBorderVerticalSpacing, + CSSPropertyWebkitBoxAlign, + CSSPropertyWebkitBoxDirection, + CSSPropertyWebkitBoxFlex, + CSSPropertyWebkitBoxFlexGroup, + CSSPropertyWebkitBoxLines, + CSSPropertyWebkitBoxOrdinalGroup, + CSSPropertyWebkitBoxOrient, + CSSPropertyWebkitBoxPack, + CSSPropertyWebkitBoxReflect, + CSSPropertyWebkitBoxShadow, + CSSPropertyWebkitBoxSizing, + CSSPropertyWebkitColumnBreakAfter, + CSSPropertyWebkitColumnBreakBefore, + CSSPropertyWebkitColumnBreakInside, + CSSPropertyWebkitColumnCount, + CSSPropertyWebkitColumnGap, + CSSPropertyWebkitColumnRuleColor, + CSSPropertyWebkitColumnRuleStyle, + CSSPropertyWebkitColumnRuleWidth, + CSSPropertyWebkitColumnWidth, + CSSPropertyWebkitHighlight, + CSSPropertyWebkitLineBreak, + CSSPropertyWebkitLineClamp, + CSSPropertyWebkitMarginBottomCollapse, + CSSPropertyWebkitMarginTopCollapse, + CSSPropertyWebkitMarqueeDirection, + CSSPropertyWebkitMarqueeIncrement, + CSSPropertyWebkitMarqueeRepetition, + CSSPropertyWebkitMarqueeStyle, + CSSPropertyWebkitMaskAttachment, + CSSPropertyWebkitMaskBoxImage, + CSSPropertyWebkitMaskImage, + CSSPropertyWebkitMaskPosition, + CSSPropertyWebkitMaskRepeat, + CSSPropertyWebkitMaskClip, + CSSPropertyWebkitMaskComposite, + CSSPropertyWebkitMaskOrigin, + CSSPropertyWebkitMaskSize, + CSSPropertyWebkitNbspMode, + CSSPropertyWebkitRtlOrdering, + CSSPropertyWebkitTextDecorationsInEffect, + CSSPropertyWebkitTextFillColor, + CSSPropertyWebkitTextSecurity, + CSSPropertyWebkitTextStrokeColor, + CSSPropertyWebkitTextStrokeWidth, + CSSPropertyWebkitTransform, + CSSPropertyWebkitTransformOrigin, + CSSPropertyWebkitTransitionDelay, + CSSPropertyWebkitTransitionDuration, + CSSPropertyWebkitTransitionProperty, + CSSPropertyWebkitTransitionTimingFunction, + CSSPropertyWebkitUserDrag, + CSSPropertyWebkitUserModify, + CSSPropertyWebkitUserSelect, +#if ENABLE(DASHBOARD_SUPPORT) + CSSPropertyWebkitDashboardRegion, +#endif + CSSPropertyWebkitBorderBottomLeftRadius, + CSSPropertyWebkitBorderBottomRightRadius, + CSSPropertyWebkitBorderTopLeftRadius, + CSSPropertyWebkitBorderTopRightRadius + +#if ENABLE(SVG) + , + CSSPropertyClipPath, + CSSPropertyClipRule, + CSSPropertyMask, + CSSPropertyFilter, + CSSPropertyFloodColor, + CSSPropertyFloodOpacity, + CSSPropertyLightingColor, + CSSPropertyStopColor, + CSSPropertyStopOpacity, + CSSPropertyColorInterpolation, + CSSPropertyColorInterpolationFilters, + CSSPropertyColorRendering, + CSSPropertyFill, + CSSPropertyFillOpacity, + CSSPropertyFillRule, + CSSPropertyImageRendering, + CSSPropertyMarkerEnd, + CSSPropertyMarkerMid, + CSSPropertyMarkerStart, + CSSPropertyShapeRendering, + CSSPropertyStroke, + CSSPropertyStrokeDasharray, + CSSPropertyStrokeDashoffset, + CSSPropertyStrokeLinecap, + CSSPropertyStrokeLinejoin, + CSSPropertyStrokeMiterlimit, + CSSPropertyStrokeOpacity, + CSSPropertyStrokeWidth, + CSSPropertyTextRendering, + CSSPropertyAlignmentBaseline, + CSSPropertyBaselineShift, + CSSPropertyDominantBaseline, + CSSPropertyKerning, + CSSPropertyTextAnchor, + CSSPropertyWritingMode, + CSSPropertyGlyphOrientationHorizontal, + CSSPropertyGlyphOrientationVertical +#endif +}; + +const unsigned numComputedProperties = sizeof(computedProperties) / sizeof(computedProperties[0]); + +static PassRefPtr<CSSValue> valueForShadow(const ShadowData* shadow) +{ + if (!shadow) + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + for (const ShadowData* s = shadow; s; s = s->next) { + RefPtr<CSSPrimitiveValue> x = CSSPrimitiveValue::create(s->x, CSSPrimitiveValue::CSS_PX); + RefPtr<CSSPrimitiveValue> y = CSSPrimitiveValue::create(s->y, CSSPrimitiveValue::CSS_PX); + RefPtr<CSSPrimitiveValue> blur = CSSPrimitiveValue::create(s->blur, CSSPrimitiveValue::CSS_PX); + RefPtr<CSSPrimitiveValue> color = CSSPrimitiveValue::createColor(s->color.rgb()); + list->prepend(ShadowValue::create(x.release(), y.release(), blur.release(), color.release())); + } + return list.release(); +} + +static int valueForRepeatRule(int rule) +{ + switch (rule) { + case RepeatImageRule: + return CSSValueRepeat; + case RoundImageRule: + return CSSValueRound; + default: + return CSSValueStretch; + } +} + +static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image) +{ + if (!image.hasImage()) + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + + // Image first. + RefPtr<CSSValue> imageValue; + if (image.image()) + imageValue = image.image()->cssValue(); + + // Create the slices. + RefPtr<CSSPrimitiveValue> top; + if (image.m_slices.top().isPercent()) + top = CSSPrimitiveValue::create(image.m_slices.top().value(), CSSPrimitiveValue::CSS_PERCENTAGE); + else + top = CSSPrimitiveValue::create(image.m_slices.top().value(), CSSPrimitiveValue::CSS_NUMBER); + + RefPtr<CSSPrimitiveValue> right; + if (image.m_slices.right().isPercent()) + right = CSSPrimitiveValue::create(image.m_slices.right().value(), CSSPrimitiveValue::CSS_PERCENTAGE); + else + right = CSSPrimitiveValue::create(image.m_slices.right().value(), CSSPrimitiveValue::CSS_NUMBER); + + RefPtr<CSSPrimitiveValue> bottom; + if (image.m_slices.bottom().isPercent()) + bottom = CSSPrimitiveValue::create(image.m_slices.bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE); + else + bottom = CSSPrimitiveValue::create(image.m_slices.bottom().value(), CSSPrimitiveValue::CSS_NUMBER); + + RefPtr<CSSPrimitiveValue> left; + if (image.m_slices.left().isPercent()) + left = CSSPrimitiveValue::create(image.m_slices.left().value(), CSSPrimitiveValue::CSS_PERCENTAGE); + else + left = CSSPrimitiveValue::create(image.m_slices.left().value(), CSSPrimitiveValue::CSS_NUMBER); + + RefPtr<Rect> rect = Rect::create(); + rect->setTop(top); + rect->setRight(right); + rect->setBottom(bottom); + rect->setLeft(left); + + return CSSBorderImageValue::create(imageValue, rect, valueForRepeatRule(image.m_horizontalRule), valueForRepeatRule(image.m_verticalRule)); +} + +static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection) +{ + if (!reflection) + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + + RefPtr<CSSPrimitiveValue> offset; + if (reflection->offset().isPercent()) + offset = CSSPrimitiveValue::create(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE); + else + offset = CSSPrimitiveValue::create(reflection->offset().value(), CSSPrimitiveValue::CSS_PX); + + return CSSReflectValue::create(reflection->direction(), offset.release(), valueForNinePieceImage(reflection->mask())); +} + +static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, int propertyID) +{ + if (!style) + return 0; + + Length l; + switch (propertyID) { + case CSSPropertyLeft: + l = style->left(); + break; + case CSSPropertyRight: + l = style->right(); + break; + case CSSPropertyTop: + l = style->top(); + break; + case CSSPropertyBottom: + l = style->bottom(); + break; + default: + return 0; + } + + if (style->position() == AbsolutePosition || style->position() == FixedPosition) + return CSSPrimitiveValue::create(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 CSSPrimitiveValue::create(l); + + return CSSPrimitiveValue::createIdentifier(CSSValueAuto); +} + +static PassRefPtr<CSSPrimitiveValue> currentColorOrValidColor(RenderStyle* style, const Color& color) +{ + if (!color.isValid()) + return CSSPrimitiveValue::createColor(style->color().rgb()); + return CSSPrimitiveValue::createColor(color.rgb()); +} + +static PassRefPtr<CSSValue> getBorderRadiusCornerValue(IntSize radius) +{ + if (radius.width() == radius.height()) + return CSSPrimitiveValue::create(radius.width(), CSSPrimitiveValue::CSS_PX); + + RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + list->append(CSSPrimitiveValue::create(radius.width(), CSSPrimitiveValue::CSS_PX)); + list->append(CSSPrimitiveValue::create(radius.height(), CSSPrimitiveValue::CSS_PX)); + return list.release(); +} + +static IntRect sizingBox(RenderObject* renderer) +{ + return renderer->style()->boxSizing() == CONTENT_BOX ? renderer->contentBox() : renderer->borderBox(); +} + +static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer) +{ + if (!renderer || renderer->style()->transform().operations().isEmpty()) + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + + IntRect box = sizingBox(renderer); + + TransformationMatrix transform; + renderer->style()->applyTransform(transform, box.size(), false); + + RefPtr<WebKitCSSTransformValue> transformVal = WebKitCSSTransformValue::create(WebKitCSSTransformValue::MatrixTransformOperation); + + transformVal->append(CSSPrimitiveValue::create(transform.a(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(CSSPrimitiveValue::create(transform.b(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(CSSPrimitiveValue::create(transform.c(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(CSSPrimitiveValue::create(transform.d(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(CSSPrimitiveValue::create(transform.e(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(CSSPrimitiveValue::create(transform.f(), CSSPrimitiveValue::CSS_NUMBER)); + + RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + list->append(transformVal); + + return list.release(); +} + +static PassRefPtr<CSSValue> getDelayValue(const AnimationList* animList) +{ + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + if (animList) { + for (size_t i = 0; i < animList->size(); ++i) + list->append(CSSPrimitiveValue::create(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S)); + } else { + // Note that initialAnimationDelay() is used for both transitions and animations + list->append(CSSPrimitiveValue::create(Animation::initialAnimationDelay(), CSSPrimitiveValue::CSS_S)); + } + return list.release(); +} + +static PassRefPtr<CSSValue> getDurationValue(const AnimationList* animList) +{ + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + if (animList) { + for (size_t i = 0; i < animList->size(); ++i) + list->append(CSSPrimitiveValue::create(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S)); + } else { + // Note that initialAnimationDuration() is used for both transitions and animations + list->append(CSSPrimitiveValue::create(Animation::initialAnimationDuration(), CSSPrimitiveValue::CSS_S)); + } + return list.release(); +} + +static PassRefPtr<CSSValue> getTimingFunctionValue(const AnimationList* animList) +{ + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + if (animList) { + for (size_t i = 0; i < animList->size(); ++i) { + const TimingFunction& tf = animList->animation(i)->timingFunction(); + list->append(CSSTimingFunctionValue::create(tf.x1(), tf.y1(), tf.x2(), tf.y2())); + } + } else { + // Note that initialAnimationTimingFunction() is used for both transitions and animations + const TimingFunction& tf = Animation::initialAnimationTimingFunction(); + list->append(CSSTimingFunctionValue::create(tf.x1(), tf.y1(), tf.x2(), tf.y2())); + } + return list.release(); +} + +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 CSSPropertyInvalid: + break; + + case CSSPropertyBackgroundColor: + return CSSPrimitiveValue::createColor(style->backgroundColor().rgb()); + case CSSPropertyBackgroundImage: + if (style->backgroundImage()) + return style->backgroundImage()->cssValue(); + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + case CSSPropertyWebkitBackgroundSize: { + RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + list->append(CSSPrimitiveValue::create(style->backgroundSize().width())); + list->append(CSSPrimitiveValue::create(style->backgroundSize().height())); + return list.release(); + } + case CSSPropertyBackgroundRepeat: + return CSSPrimitiveValue::create(style->backgroundRepeat()); + case CSSPropertyWebkitBackgroundComposite: + return CSSPrimitiveValue::create(style->backgroundComposite()); + case CSSPropertyBackgroundAttachment: + if (style->backgroundAttachment()) + return CSSPrimitiveValue::createIdentifier(CSSValueScroll); + return CSSPrimitiveValue::createIdentifier(CSSValueFixed); + case CSSPropertyWebkitBackgroundClip: + case CSSPropertyWebkitBackgroundOrigin: { + EFillBox box = (propertyID == CSSPropertyWebkitBackgroundClip ? style->backgroundClip() : style->backgroundOrigin()); + return CSSPrimitiveValue::create(box); + } + case CSSPropertyBackgroundPosition: { + RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + + list->append(CSSPrimitiveValue::create(style->backgroundXPosition())); + list->append(CSSPrimitiveValue::create(style->backgroundYPosition())); + + return list.release(); + } + case CSSPropertyBackgroundPositionX: + return CSSPrimitiveValue::create(style->backgroundXPosition()); + case CSSPropertyBackgroundPositionY: + return CSSPrimitiveValue::create(style->backgroundYPosition()); + case CSSPropertyBorderCollapse: + if (style->borderCollapse()) + return CSSPrimitiveValue::createIdentifier(CSSValueCollapse); + return CSSPrimitiveValue::createIdentifier(CSSValueSeparate); + case CSSPropertyBorderSpacing: { + RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + list->append(CSSPrimitiveValue::create(style->horizontalBorderSpacing(), CSSPrimitiveValue::CSS_PX)); + list->append(CSSPrimitiveValue::create(style->verticalBorderSpacing(), CSSPrimitiveValue::CSS_PX)); + return list.release(); + } + case CSSPropertyWebkitBorderHorizontalSpacing: + return CSSPrimitiveValue::create(style->horizontalBorderSpacing(), CSSPrimitiveValue::CSS_PX); + case CSSPropertyWebkitBorderVerticalSpacing: + return CSSPrimitiveValue::create(style->verticalBorderSpacing(), CSSPrimitiveValue::CSS_PX); + case CSSPropertyBorderTopColor: + return currentColorOrValidColor(style, style->borderTopColor()); + case CSSPropertyBorderRightColor: + return currentColorOrValidColor(style, style->borderRightColor()); + case CSSPropertyBorderBottomColor: + return currentColorOrValidColor(style, style->borderBottomColor()); + case CSSPropertyBorderLeftColor: + return currentColorOrValidColor(style, style->borderLeftColor()); + case CSSPropertyBorderTopStyle: + return CSSPrimitiveValue::create(style->borderTopStyle()); + case CSSPropertyBorderRightStyle: + return CSSPrimitiveValue::create(style->borderRightStyle()); + case CSSPropertyBorderBottomStyle: + return CSSPrimitiveValue::create(style->borderBottomStyle()); + case CSSPropertyBorderLeftStyle: + return CSSPrimitiveValue::create(style->borderLeftStyle()); + case CSSPropertyBorderTopWidth: + return CSSPrimitiveValue::create(style->borderTopWidth(), CSSPrimitiveValue::CSS_PX); + case CSSPropertyBorderRightWidth: + return CSSPrimitiveValue::create(style->borderRightWidth(), CSSPrimitiveValue::CSS_PX); + case CSSPropertyBorderBottomWidth: + return CSSPrimitiveValue::create(style->borderBottomWidth(), CSSPrimitiveValue::CSS_PX); + case CSSPropertyBorderLeftWidth: + return CSSPrimitiveValue::create(style->borderLeftWidth(), CSSPrimitiveValue::CSS_PX); + case CSSPropertyBottom: + return getPositionOffsetValue(style, CSSPropertyBottom); + case CSSPropertyWebkitBoxAlign: + return CSSPrimitiveValue::create(style->boxAlign()); + case CSSPropertyWebkitBoxDirection: + return CSSPrimitiveValue::create(style->boxDirection()); + case CSSPropertyWebkitBoxFlex: + return CSSPrimitiveValue::create(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyWebkitBoxFlexGroup: + return CSSPrimitiveValue::create(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyWebkitBoxLines: + return CSSPrimitiveValue::create(style->boxLines()); + case CSSPropertyWebkitBoxOrdinalGroup: + return CSSPrimitiveValue::create(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyWebkitBoxOrient: + return CSSPrimitiveValue::create(style->boxOrient()); + case CSSPropertyWebkitBoxPack: { + EBoxAlignment boxPack = style->boxPack(); + ASSERT(boxPack != BSTRETCH); + ASSERT(boxPack != BBASELINE); + if (boxPack == BJUSTIFY || boxPack== BBASELINE) + return 0; + return CSSPrimitiveValue::create(boxPack); + } + case CSSPropertyWebkitBoxReflect: + return valueForReflection(style->boxReflect()); + case CSSPropertyWebkitBoxShadow: + return valueForShadow(style->boxShadow()); + case CSSPropertyCaptionSide: + return CSSPrimitiveValue::create(style->captionSide()); + case CSSPropertyClear: + return CSSPrimitiveValue::create(style->clear()); + case CSSPropertyColor: + return CSSPrimitiveValue::createColor(style->color().rgb()); + case CSSPropertyWebkitColumnCount: + if (style->hasAutoColumnCount()) + return CSSPrimitiveValue::createIdentifier(CSSValueAuto); + return CSSPrimitiveValue::create(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyWebkitColumnGap: + if (style->hasNormalColumnGap()) + return CSSPrimitiveValue::createIdentifier(CSSValueNormal); + return CSSPrimitiveValue::create(style->columnGap(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyWebkitColumnRuleColor: + return currentColorOrValidColor(style, style->columnRuleColor()); + case CSSPropertyWebkitColumnRuleStyle: + return CSSPrimitiveValue::create(style->columnRuleStyle()); + case CSSPropertyWebkitColumnRuleWidth: + return CSSPrimitiveValue::create(style->columnRuleWidth(), CSSPrimitiveValue::CSS_PX); + case CSSPropertyWebkitColumnBreakAfter: + return CSSPrimitiveValue::create(style->columnBreakAfter()); + case CSSPropertyWebkitColumnBreakBefore: + return CSSPrimitiveValue::create(style->columnBreakBefore()); + case CSSPropertyWebkitColumnBreakInside: + return CSSPrimitiveValue::create(style->columnBreakInside()); + case CSSPropertyWebkitColumnWidth: + if (style->hasAutoColumnWidth()) + return CSSPrimitiveValue::createIdentifier(CSSValueAuto); + return CSSPrimitiveValue::create(style->columnWidth(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyCursor: { + RefPtr<CSSValueList> list; + CursorList* cursors = style->cursors(); + if (cursors && cursors->size() > 0) { + list = CSSValueList::createCommaSeparated(); + for (unsigned i = 0; i < cursors->size(); ++i) + list->append(CSSPrimitiveValue::create((*cursors)[i].cursorImage->url(), CSSPrimitiveValue::CSS_URI)); + } + RefPtr<CSSValue> value = CSSPrimitiveValue::create(style->cursor()); + if (list) { + list->append(value); + return list.release(); + } + return value.release(); + } + case CSSPropertyDirection: + return CSSPrimitiveValue::create(style->direction()); + case CSSPropertyDisplay: + return CSSPrimitiveValue::create(style->display()); + case CSSPropertyEmptyCells: + return CSSPrimitiveValue::create(style->emptyCells()); + case CSSPropertyFloat: + return CSSPrimitiveValue::create(style->floating()); + case CSSPropertyFontFamily: + // FIXME: This only returns the first family. + return CSSPrimitiveValue::create(style->fontDescription().family().family().string(), CSSPrimitiveValue::CSS_STRING); + case CSSPropertyFontSize: + return CSSPrimitiveValue::create(style->fontDescription().computedPixelSize(), CSSPrimitiveValue::CSS_PX); + case CSSPropertyWebkitBinding: + break; + case CSSPropertyFontStyle: + if (style->fontDescription().italic()) + return CSSPrimitiveValue::createIdentifier(CSSValueItalic); + return CSSPrimitiveValue::createIdentifier(CSSValueNormal); + case CSSPropertyFontVariant: + if (style->fontDescription().smallCaps()) + return CSSPrimitiveValue::createIdentifier(CSSValueSmallCaps); + return CSSPrimitiveValue::createIdentifier(CSSValueNormal); + case CSSPropertyFontWeight: + switch (style->fontDescription().weight()) { + case FontWeight100: + return CSSPrimitiveValue::createIdentifier(CSSValue100); + case FontWeight200: + return CSSPrimitiveValue::createIdentifier(CSSValue200); + case FontWeight300: + return CSSPrimitiveValue::createIdentifier(CSSValue300); + case FontWeightNormal: + return CSSPrimitiveValue::createIdentifier(CSSValueNormal); + case FontWeight500: + return CSSPrimitiveValue::createIdentifier(CSSValue500); + case FontWeight600: + return CSSPrimitiveValue::createIdentifier(CSSValue600); + case FontWeightBold: + return CSSPrimitiveValue::createIdentifier(CSSValueBold); + case FontWeight800: + return CSSPrimitiveValue::createIdentifier(CSSValue800); + case FontWeight900: + return CSSPrimitiveValue::createIdentifier(CSSValue900); + } + ASSERT_NOT_REACHED(); + return CSSPrimitiveValue::createIdentifier(CSSValueNormal); + case CSSPropertyHeight: + if (renderer) + return CSSPrimitiveValue::create(sizingBox(renderer).height(), CSSPrimitiveValue::CSS_PX); + return CSSPrimitiveValue::create(style->height()); + case CSSPropertyWebkitHighlight: + if (style->highlight() == nullAtom) + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return CSSPrimitiveValue::create(style->highlight(), CSSPrimitiveValue::CSS_STRING); + case CSSPropertyWebkitBorderFit: + if (style->borderFit() == BorderFitBorder) + return CSSPrimitiveValue::createIdentifier(CSSValueBorder); + return CSSPrimitiveValue::createIdentifier(CSSValueLines); + case CSSPropertyLeft: + return getPositionOffsetValue(style, CSSPropertyLeft); + case CSSPropertyLetterSpacing: + if (!style->letterSpacing()) + return CSSPrimitiveValue::createIdentifier(CSSValueNormal); + return CSSPrimitiveValue::create(style->letterSpacing(), CSSPrimitiveValue::CSS_PX); + case CSSPropertyWebkitLineClamp: + if (style->lineClamp() == -1) + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return CSSPrimitiveValue::create(style->lineClamp(), CSSPrimitiveValue::CSS_PERCENTAGE); + case CSSPropertyLineHeight: { + Length length = style->lineHeight(); + if (length.isNegative()) + return CSSPrimitiveValue::createIdentifier(CSSValueNormal); + 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 CSSPrimitiveValue::create(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, CSSPrimitiveValue::CSS_PX); + return CSSPrimitiveValue::create(length.value(), CSSPrimitiveValue::CSS_PX); + } + case CSSPropertyListStyleImage: + if (style->listStyleImage()) + return style->listStyleImage()->cssValue(); + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + case CSSPropertyListStylePosition: + return CSSPrimitiveValue::create(style->listStylePosition()); + case CSSPropertyListStyleType: + return CSSPrimitiveValue::create(style->listStyleType()); + case CSSPropertyMarginTop: + if (renderer) + // FIXME: Supposed to return the percentage if percentage was specified. + return CSSPrimitiveValue::create(renderer->marginTop(), CSSPrimitiveValue::CSS_PX); + return CSSPrimitiveValue::create(style->marginTop()); + case CSSPropertyMarginRight: + if (renderer) + // FIXME: Supposed to return the percentage if percentage was specified. + return CSSPrimitiveValue::create(renderer->marginRight(), CSSPrimitiveValue::CSS_PX); + return CSSPrimitiveValue::create(style->marginRight()); + case CSSPropertyMarginBottom: + if (renderer) + // FIXME: Supposed to return the percentage if percentage was specified. + return CSSPrimitiveValue::create(renderer->marginBottom(), CSSPrimitiveValue::CSS_PX); + return CSSPrimitiveValue::create(style->marginBottom()); + case CSSPropertyMarginLeft: + if (renderer) + // FIXME: Supposed to return the percentage if percentage was specified. + return CSSPrimitiveValue::create(renderer->marginLeft(), CSSPrimitiveValue::CSS_PX); + return CSSPrimitiveValue::create(style->marginLeft()); + case CSSPropertyWebkitMarqueeDirection: + return CSSPrimitiveValue::create(style->marqueeDirection()); + case CSSPropertyWebkitMarqueeIncrement: + return CSSPrimitiveValue::create(style->marqueeIncrement()); + case CSSPropertyWebkitMarqueeRepetition: + if (style->marqueeLoopCount() < 0) + return CSSPrimitiveValue::createIdentifier(CSSValueInfinite); + return CSSPrimitiveValue::create(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyWebkitMarqueeStyle: + return CSSPrimitiveValue::create(style->marqueeBehavior()); + case CSSPropertyWebkitMaskImage: + if (style->maskImage()) + return style->maskImage()->cssValue(); + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + case CSSPropertyWebkitMaskSize: { + RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + list->append(CSSPrimitiveValue::create(style->maskSize().width())); + list->append(CSSPrimitiveValue::create(style->maskSize().height())); + return list.release(); + } + case CSSPropertyWebkitMaskRepeat: + return CSSPrimitiveValue::create(style->maskRepeat()); + case CSSPropertyWebkitMaskAttachment: + if (style->maskAttachment()) + return CSSPrimitiveValue::createIdentifier(CSSValueScroll); + return CSSPrimitiveValue::createIdentifier(CSSValueFixed); + case CSSPropertyWebkitMaskComposite: + return CSSPrimitiveValue::create(style->maskComposite()); + case CSSPropertyWebkitMaskClip: + case CSSPropertyWebkitMaskOrigin: { + EFillBox box = (propertyID == CSSPropertyWebkitMaskClip ? style->maskClip() : style->maskOrigin()); + return CSSPrimitiveValue::create(box); + } + case CSSPropertyWebkitMaskPosition: { + RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + + list->append(CSSPrimitiveValue::create(style->maskXPosition())); + list->append(CSSPrimitiveValue::create(style->maskYPosition())); + + return list.release(); + } + case CSSPropertyWebkitMaskPositionX: + return CSSPrimitiveValue::create(style->maskXPosition()); + case CSSPropertyWebkitMaskPositionY: + return CSSPrimitiveValue::create(style->maskYPosition()); + case CSSPropertyWebkitUserModify: + return CSSPrimitiveValue::create(style->userModify()); + case CSSPropertyMaxHeight: { + const Length& maxHeight = style->maxHeight(); + if (maxHeight.isFixed() && maxHeight.value() == undefinedLength) + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return CSSPrimitiveValue::create(maxHeight); + } + case CSSPropertyMaxWidth: { + const Length& maxWidth = style->maxWidth(); + if (maxWidth.isFixed() && maxWidth.value() == undefinedLength) + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return CSSPrimitiveValue::create(maxWidth); + } + case CSSPropertyMinHeight: + return CSSPrimitiveValue::create(style->minHeight()); + case CSSPropertyMinWidth: + return CSSPrimitiveValue::create(style->minWidth()); + case CSSPropertyOpacity: + return CSSPrimitiveValue::create(style->opacity(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyOrphans: + return CSSPrimitiveValue::create(style->orphans(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyOutlineColor: + return currentColorOrValidColor(style, style->outlineColor()); + case CSSPropertyOutlineStyle: + if (style->outlineStyleIsAuto()) + return CSSPrimitiveValue::createIdentifier(CSSValueAuto); + return CSSPrimitiveValue::create(style->outlineStyle()); + case CSSPropertyOutlineWidth: + return CSSPrimitiveValue::create(style->outlineWidth(), CSSPrimitiveValue::CSS_PX); + case CSSPropertyOverflow: + return CSSPrimitiveValue::create(max(style->overflowX(), style->overflowY())); + case CSSPropertyOverflowX: + return CSSPrimitiveValue::create(style->overflowX()); + case CSSPropertyOverflowY: + return CSSPrimitiveValue::create(style->overflowY()); + case CSSPropertyPaddingTop: + if (renderer) + return CSSPrimitiveValue::create(renderer->paddingTop(), CSSPrimitiveValue::CSS_PX); + return CSSPrimitiveValue::create(style->paddingTop()); + case CSSPropertyPaddingRight: + if (renderer) + return CSSPrimitiveValue::create(renderer->paddingRight(), CSSPrimitiveValue::CSS_PX); + return CSSPrimitiveValue::create(style->paddingRight()); + case CSSPropertyPaddingBottom: + if (renderer) + return CSSPrimitiveValue::create(renderer->paddingBottom(), CSSPrimitiveValue::CSS_PX); + return CSSPrimitiveValue::create(style->paddingBottom()); + case CSSPropertyPaddingLeft: + if (renderer) + return CSSPrimitiveValue::create(renderer->paddingLeft(), CSSPrimitiveValue::CSS_PX); + return CSSPrimitiveValue::create(style->paddingLeft()); + case CSSPropertyPageBreakAfter: + return CSSPrimitiveValue::create(style->pageBreakAfter()); + case CSSPropertyPageBreakBefore: + return CSSPrimitiveValue::create(style->pageBreakBefore()); + case CSSPropertyPageBreakInside: { + EPageBreak pageBreak = style->pageBreakInside(); + ASSERT(pageBreak != PBALWAYS); + if (pageBreak == PBALWAYS) + return 0; + return CSSPrimitiveValue::create(style->pageBreakInside()); + } + case CSSPropertyPosition: + return CSSPrimitiveValue::create(style->position()); + case CSSPropertyRight: + return getPositionOffsetValue(style, CSSPropertyRight); + case CSSPropertyTableLayout: + return CSSPrimitiveValue::create(style->tableLayout()); + case CSSPropertyTextAlign: + return CSSPrimitiveValue::create(style->textAlign()); + case CSSPropertyTextDecoration: { + 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 CSSPrimitiveValue::createIdentifier(CSSValueNone); + return CSSPrimitiveValue::create(string, CSSPrimitiveValue::CSS_STRING); + } + case CSSPropertyWebkitTextDecorationsInEffect: { + 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 CSSPrimitiveValue::createIdentifier(CSSValueNone); + return CSSPrimitiveValue::create(string, CSSPrimitiveValue::CSS_STRING); + } + case CSSPropertyWebkitTextFillColor: + return currentColorOrValidColor(style, style->textFillColor()); + case CSSPropertyTextIndent: + return CSSPrimitiveValue::create(style->textIndent()); + case CSSPropertyTextShadow: + return valueForShadow(style->textShadow()); + case CSSPropertyWebkitTextSecurity: + return CSSPrimitiveValue::create(style->textSecurity()); + case CSSPropertyWebkitTextSizeAdjust: + if (style->textSizeAdjust()) + return CSSPrimitiveValue::createIdentifier(CSSValueAuto); + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + case CSSPropertyWebkitTextStrokeColor: + return currentColorOrValidColor(style, style->textStrokeColor()); + case CSSPropertyWebkitTextStrokeWidth: + return CSSPrimitiveValue::create(style->textStrokeWidth(), CSSPrimitiveValue::CSS_PX); + case CSSPropertyTextTransform: + return CSSPrimitiveValue::create(style->textTransform()); + case CSSPropertyTop: + return getPositionOffsetValue(style, CSSPropertyTop); + case CSSPropertyUnicodeBidi: + return CSSPrimitiveValue::create(style->unicodeBidi()); + case CSSPropertyVerticalAlign: + switch (style->verticalAlign()) { + case BASELINE: + return CSSPrimitiveValue::createIdentifier(CSSValueBaseline); + case MIDDLE: + return CSSPrimitiveValue::createIdentifier(CSSValueMiddle); + case SUB: + return CSSPrimitiveValue::createIdentifier(CSSValueSub); + case SUPER: + return CSSPrimitiveValue::createIdentifier(CSSValueSuper); + case TEXT_TOP: + return CSSPrimitiveValue::createIdentifier(CSSValueTextTop); + case TEXT_BOTTOM: + return CSSPrimitiveValue::createIdentifier(CSSValueTextBottom); + case TOP: + return CSSPrimitiveValue::createIdentifier(CSSValueTop); + case BOTTOM: + return CSSPrimitiveValue::createIdentifier(CSSValueBottom); + case BASELINE_MIDDLE: + return CSSPrimitiveValue::createIdentifier(CSSValueWebkitBaselineMiddle); + case LENGTH: + return CSSPrimitiveValue::create(style->verticalAlignLength()); + } + ASSERT_NOT_REACHED(); + return 0; + case CSSPropertyVisibility: + return CSSPrimitiveValue::create(style->visibility()); + case CSSPropertyWhiteSpace: + return CSSPrimitiveValue::create(style->whiteSpace()); + case CSSPropertyWidows: + return CSSPrimitiveValue::create(style->widows(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyWidth: + if (renderer) + return CSSPrimitiveValue::create(sizingBox(renderer).width(), CSSPrimitiveValue::CSS_PX); + return CSSPrimitiveValue::create(style->width()); + case CSSPropertyWordBreak: + return CSSPrimitiveValue::create(style->wordBreak()); + case CSSPropertyWordSpacing: + return CSSPrimitiveValue::create(style->wordSpacing(), CSSPrimitiveValue::CSS_PX); + case CSSPropertyWordWrap: + return CSSPrimitiveValue::create(style->wordWrap()); + case CSSPropertyWebkitLineBreak: + return CSSPrimitiveValue::create(style->khtmlLineBreak()); + case CSSPropertyWebkitNbspMode: + return CSSPrimitiveValue::create(style->nbspMode()); + case CSSPropertyWebkitMatchNearestMailBlockquoteColor: + return CSSPrimitiveValue::create(style->matchNearestMailBlockquoteColor()); + case CSSPropertyResize: + return CSSPrimitiveValue::create(style->resize()); + case CSSPropertyZIndex: + if (style->hasAutoZIndex()) + return CSSPrimitiveValue::createIdentifier(CSSValueAuto); + return CSSPrimitiveValue::create(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyZoom: + return CSSPrimitiveValue::create(style->zoom(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyWebkitBoxSizing: + if (style->boxSizing() == CONTENT_BOX) + return CSSPrimitiveValue::createIdentifier(CSSValueContentBox); + return CSSPrimitiveValue::createIdentifier(CSSValueBorderBox); +#if ENABLE(DASHBOARD_SUPPORT) + case CSSPropertyWebkitDashboardRegion: + { + const Vector<StyleDashboardRegion>& regions = style->dashboardRegions(); + unsigned count = regions.size(); + if (count == 1 && regions[0].type == StyleDashboardRegion::None) + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + + RefPtr<DashboardRegion> firstRegion; + DashboardRegion* previousRegion = 0; + for (unsigned i = 0; i < count; i++) { + RefPtr<DashboardRegion> region = DashboardRegion::create(); + StyleDashboardRegion styleRegion = regions[i]; + + region->m_label = styleRegion.label; + LengthBox offset = styleRegion.offset; + region->setTop(CSSPrimitiveValue::create(offset.top().value(), CSSPrimitiveValue::CSS_PX)); + region->setRight(CSSPrimitiveValue::create(offset.right().value(), CSSPrimitiveValue::CSS_PX)); + region->setBottom(CSSPrimitiveValue::create(offset.bottom().value(), CSSPrimitiveValue::CSS_PX)); + region->setLeft(CSSPrimitiveValue::create(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 CSSPrimitiveValue::create(firstRegion.release()); + } +#endif + case CSSPropertyWebkitAnimationDelay: + return getDelayValue(style->animations()); + case CSSPropertyWebkitAnimationDirection: { + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + const AnimationList* t = style->animations(); + if (t) { + for (size_t i = 0; i < t->size(); ++i) { + if (t->animation(i)->direction()) + list->append(CSSPrimitiveValue::createIdentifier(CSSValueAlternate)); + else + list->append(CSSPrimitiveValue::createIdentifier(CSSValueNormal)); + } + } else + list->append(CSSPrimitiveValue::createIdentifier(CSSValueNormal)); + return list.release(); + } + case CSSPropertyWebkitAnimationDuration: + return getDurationValue(style->animations()); + case CSSPropertyWebkitAnimationIterationCount: { + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + const AnimationList* t = style->animations(); + if (t) { + for (size_t i = 0; i < t->size(); ++i) { + int iterationCount = t->animation(i)->iterationCount(); + if (iterationCount < 0) + list->append(CSSPrimitiveValue::createIdentifier(CSSValueInfinite)); + else + list->append(CSSPrimitiveValue::create(iterationCount, CSSPrimitiveValue::CSS_NUMBER)); + } + } else + list->append(CSSPrimitiveValue::create(Animation::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER)); + return list.release(); + } + case CSSPropertyWebkitAnimationName: { + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + const AnimationList* t = style->animations(); + if (t) { + for (size_t i = 0; i < t->size(); ++i) { + list->append(CSSPrimitiveValue::create(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING)); + } + } else + list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone)); + return list.release(); + } + case CSSPropertyWebkitAnimationPlayState: { + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + const AnimationList* t = style->animations(); + if (t) { + for (size_t i = 0; i < t->size(); ++i) { + int prop = t->animation(i)->playState(); + if (prop == AnimPlayStatePlaying) + list->append(CSSPrimitiveValue::createIdentifier(CSSValueRunning)); + else + list->append(CSSPrimitiveValue::createIdentifier(CSSValuePaused)); + } + } else + list->append(CSSPrimitiveValue::createIdentifier(CSSValueRunning)); + return list.release(); + } + case CSSPropertyWebkitAnimationTimingFunction: + return getTimingFunctionValue(style->animations()); + case CSSPropertyWebkitAppearance: + return CSSPrimitiveValue::create(style->appearance()); + case CSSPropertyWebkitBorderImage: + return valueForNinePieceImage(style->borderImage()); + case CSSPropertyWebkitMaskBoxImage: + return valueForNinePieceImage(style->maskBoxImage()); + case CSSPropertyWebkitFontSizeDelta: + // Not a real style property -- used by the editing engine -- so has no computed value. + break; + case CSSPropertyWebkitMarginBottomCollapse: + return CSSPrimitiveValue::create(style->marginBottomCollapse()); + case CSSPropertyWebkitMarginTopCollapse: + return CSSPrimitiveValue::create(style->marginTopCollapse()); + case CSSPropertyWebkitRtlOrdering: + if (style->visuallyOrdered()) + return CSSPrimitiveValue::createIdentifier(CSSValueVisual); + return CSSPrimitiveValue::createIdentifier(CSSValueLogical); + case CSSPropertyWebkitUserDrag: + return CSSPrimitiveValue::create(style->userDrag()); + case CSSPropertyWebkitUserSelect: + return CSSPrimitiveValue::create(style->userSelect()); + case CSSPropertyWebkitBorderBottomLeftRadius: + return getBorderRadiusCornerValue(style->borderBottomLeftRadius()); + case CSSPropertyWebkitBorderBottomRightRadius: + return getBorderRadiusCornerValue(style->borderBottomRightRadius()); + case CSSPropertyWebkitBorderTopLeftRadius: + return getBorderRadiusCornerValue(style->borderTopLeftRadius()); + case CSSPropertyWebkitBorderTopRightRadius: + return getBorderRadiusCornerValue(style->borderTopRightRadius()); + case CSSPropertyClip: + { + if (style->hasClip()) { + RefPtr<Rect> rect = Rect::create(); + rect->setTop(CSSPrimitiveValue::create(style->clip().top().value(), CSSPrimitiveValue::CSS_PX)); + rect->setRight(CSSPrimitiveValue::create(style->clip().right().value(), CSSPrimitiveValue::CSS_PX)); + rect->setBottom(CSSPrimitiveValue::create(style->clip().bottom().value(), CSSPrimitiveValue::CSS_PX)); + rect->setLeft(CSSPrimitiveValue::create(style->clip().left().value(), CSSPrimitiveValue::CSS_PX)); + return CSSPrimitiveValue::create(rect.release()); + } + return 0; + } + case CSSPropertyWebkitTransform: + return computedTransform(renderer); + case CSSPropertyWebkitTransformOrigin: { + RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + if (renderer) { + IntRect box = sizingBox(renderer); + list->append(CSSPrimitiveValue::create(style->transformOriginX().calcMinValue(box.width()), CSSPrimitiveValue::CSS_PX)); + list->append(CSSPrimitiveValue::create(style->transformOriginY().calcMinValue(box.height()), CSSPrimitiveValue::CSS_PX)); + } else { + list->append(CSSPrimitiveValue::create(style->transformOriginX())); + list->append(CSSPrimitiveValue::create(style->transformOriginY())); + } + return list.release(); + } + case CSSPropertyWebkitTransitionDelay: + return getDelayValue(style->transitions()); + case CSSPropertyWebkitTransitionDuration: + return getDurationValue(style->transitions()); + case CSSPropertyWebkitTransitionProperty: { + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + const AnimationList* t = style->transitions(); + if (t) { + for (size_t i = 0; i < t->size(); ++i) { + int prop = t->animation(i)->property(); + RefPtr<CSSValue> propertyValue; + if (prop == cAnimateNone) + propertyValue = CSSPrimitiveValue::createIdentifier(CSSValueNone); + else if (prop == cAnimateAll) + propertyValue = CSSPrimitiveValue::createIdentifier(CSSValueAll); + else + propertyValue = CSSPrimitiveValue::create(getPropertyName(static_cast<CSSPropertyID>(prop)), CSSPrimitiveValue::CSS_STRING); + list->append(propertyValue); + } + } else + list->append(CSSPrimitiveValue::createIdentifier(CSSValueAll)); + return list.release(); + } + case CSSPropertyWebkitTransitionTimingFunction: + return getTimingFunctionValue(style->transitions()); + case CSSPropertyPointerEvents: + return CSSPrimitiveValue::create(style->pointerEvents()); + case CSSPropertyBackground: + case CSSPropertyBorder: + case CSSPropertyBorderBottom: + case CSSPropertyBorderColor: + case CSSPropertyBorderLeft: + case CSSPropertyBorderRight: + case CSSPropertyBorderStyle: + case CSSPropertyBorderTop: + case CSSPropertyBorderWidth: + case CSSPropertyContent: + case CSSPropertyCounterIncrement: + case CSSPropertyCounterReset: + case CSSPropertyFont: + case CSSPropertyFontStretch: + case CSSPropertyListStyle: + case CSSPropertyMargin: + case CSSPropertyOutline: + case CSSPropertyOutlineOffset: + case CSSPropertyPadding: + case CSSPropertyPage: + case CSSPropertyQuotes: + case CSSPropertyScrollbar3dlightColor: + case CSSPropertyScrollbarArrowColor: + case CSSPropertyScrollbarDarkshadowColor: + case CSSPropertyScrollbarFaceColor: + case CSSPropertyScrollbarHighlightColor: + case CSSPropertyScrollbarShadowColor: + case CSSPropertyScrollbarTrackColor: + case CSSPropertySrc: // Only used in @font-face rules. + case CSSPropertySize: + case CSSPropertyTextLineThrough: + case CSSPropertyTextLineThroughColor: + case CSSPropertyTextLineThroughMode: + case CSSPropertyTextLineThroughStyle: + case CSSPropertyTextLineThroughWidth: + case CSSPropertyTextOverflow: + case CSSPropertyTextOverline: + case CSSPropertyTextOverlineColor: + case CSSPropertyTextOverlineMode: + case CSSPropertyTextOverlineStyle: + case CSSPropertyTextOverlineWidth: + case CSSPropertyTextUnderline: + case CSSPropertyTextUnderlineColor: + case CSSPropertyTextUnderlineMode: + case CSSPropertyTextUnderlineStyle: + case CSSPropertyTextUnderlineWidth: + case CSSPropertyUnicodeRange: // Only used in @font-face rules. + case CSSPropertyWebkitAnimation: + case CSSPropertyWebkitBorderRadius: + case CSSPropertyWebkitColumns: + case CSSPropertyWebkitColumnRule: + case CSSPropertyWebkitMarginCollapse: + case CSSPropertyWebkitMarginStart: + case CSSPropertyWebkitMarquee: + case CSSPropertyWebkitMarqueeSpeed: + case CSSPropertyWebkitMask: + case CSSPropertyWebkitPaddingStart: + case CSSPropertyWebkitTextStroke: + case CSSPropertyWebkitTransition: + case CSSPropertyWebkitVariableDeclarationBlock: + // FIXME: The above are unimplemented. + break; +#if ENABLE(SVG) + // FIXME: This default case ruins the point of using an enum for + // properties -- it prevents us from getting a warning when we + // forget to list a property above. + 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[] = { + CSSPropertyBorderCollapse, + CSSPropertyColor, + CSSPropertyFontFamily, + CSSPropertyFontSize, + CSSPropertyFontStyle, + CSSPropertyFontVariant, + CSSPropertyFontWeight, + CSSPropertyLetterSpacing, + CSSPropertyLineHeight, + CSSPropertyOrphans, + CSSPropertyTextAlign, + CSSPropertyTextIndent, + CSSPropertyTextTransform, + CSSPropertyWhiteSpace, + CSSPropertyWidows, + CSSPropertyWordSpacing, + CSSPropertyWebkitBorderHorizontalSpacing, + CSSPropertyWebkitBorderVerticalSpacing, + CSSPropertyWebkitTextDecorationsInEffect, + CSSPropertyWebkitTextFillColor, + CSSPropertyWebkitTextSizeAdjust, + CSSPropertyWebkitTextStrokeColor, + CSSPropertyWebkitTextStrokeWidth, +}; + +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(CSSPropertyWebkitTextFillColor, ec); + if (!m_node->computedStyle()->textStrokeColor().isValid()) + style->removeProperty(CSSPropertyWebkitTextStrokeColor, ec); + ASSERT(ec == 0); + } + return style.release(); +} + +PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::copy() const +{ + return copyPropertiesInSet(computedProperties, numComputedProperties); +} + +PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::makeMutable() +{ + return copy(); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSComputedStyleDeclaration.h b/src/3rdparty/webkit/WebCore/css/CSSComputedStyleDeclaration.h new file mode 100644 index 0000000..487c02b --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSComputedStyleDeclaration.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2004 Zack Rusin <zack@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 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; + +enum EUpdateLayout { DoNotUpdateLayout = false, UpdateLayout = true }; + +class CSSComputedStyleDeclaration : public CSSStyleDeclaration { +public: + friend PassRefPtr<CSSComputedStyleDeclaration> computedStyle(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: + CSSComputedStyleDeclaration(PassRefPtr<Node>); + + 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; +}; + +inline PassRefPtr<CSSComputedStyleDeclaration> computedStyle(PassRefPtr<Node> node) +{ + return adoptRef(new CSSComputedStyleDeclaration(node)); +} + +} // namespace WebCore + +#endif // CSSComputedStyleDeclaration_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSCursorImageValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSCursorImageValue.cpp new file mode 100644 index 0000000..ddd3e6b --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSCursorImageValue.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2006 Rob Buis <buis@kde.org> + * (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 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 "CSSCursorImageValue.h" + +#include "DocLoader.h" +#include "Document.h" +#include "PlatformString.h" +#include "RenderStyle.h" +#include <wtf/MathExtras.h> + +#if ENABLE(SVG) +#include "SVGCursorElement.h" +#include "SVGURIReference.h" +#endif + +namespace WebCore { + +#if ENABLE(SVG) +static inline bool isSVGCursorIdentifier(const String& url) +{ + KURL kurl(url); + return kurl.hasRef(); +} + +static 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) + : CSSImageValue(url) + , 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; + referencedElement->setCursorImageValue(0); + 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())) { + float x = roundf(cursorElement->x().value(0)); + m_hotspot.setX(static_cast<int>(x)); + + float y = roundf(cursorElement->y().value(0)); + m_hotspot.setY(static_cast<int>(y)); + + if (cachedImageURL() != element->document()->completeURL(cursorElement->href())) + clearCachedImage(); + + SVGElement* svgElement = static_cast<SVGElement*>(element); + m_referencedElements.add(svgElement); + svgElement->setCursorImageValue(this); + cursorElement->addClient(svgElement); + return true; + } +#endif + + return false; +} + +StyleCachedImage* CSSCursorImageValue::cachedImage(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::cachedImage(loader, url); +} + +#if ENABLE(SVG) +void CSSCursorImageValue::removeReferencedElement(SVGElement* element) +{ + m_referencedElements.remove(element); +} +#endif + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSCursorImageValue.h b/src/3rdparty/webkit/WebCore/css/CSSCursorImageValue.h new file mode 100644 index 0000000..efcdda6 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSCursorImageValue.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2006 Rob Buis <buis@kde.org> + * Copyright (C) 2008 Apple Inc. All right 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 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: + static PassRefPtr<CSSCursorImageValue> create(const String& url, const IntPoint& hotspot) + { + return adoptRef(new CSSCursorImageValue(url, hotspot)); + } + + virtual ~CSSCursorImageValue(); + + IntPoint hotspot() const { return m_hotspot; } + + bool updateIfSVGCursorIsUsed(Element*); + virtual StyleCachedImage* cachedImage(DocLoader*); + +#if ENABLE(SVG) + void removeReferencedElement(SVGElement*); +#endif + +private: + CSSCursorImageValue(const String& url, const IntPoint& hotspot); + + IntPoint m_hotspot; + +#if ENABLE(SVG) + HashSet<SVGElement*> m_referencedElements; +#endif +}; + +} // namespace WebCore + +#endif // CSSCursorImageValue_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSFontFace.cpp b/src/3rdparty/webkit/WebCore/css/CSSFontFace.cpp new file mode 100644 index 0000000..4d8da59 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSFontFace.cpp @@ -0,0 +1,114 @@ +/* + * 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 "CSSFontSelector.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::addedToSegmentedFontFace(CSSSegmentedFontFace* segmentedFontFace) +{ + m_segmentedFontFaces.add(segmentedFontFace); +} + +void CSSFontFace::removedFromSegmentedFontFace(CSSSegmentedFontFace* segmentedFontFace) +{ + m_segmentedFontFaces.remove(segmentedFontFace); +} + +void CSSFontFace::addSource(CSSFontFaceSource* source) +{ + m_sources.append(source); + source->setFontFace(this); +} + +void CSSFontFace::fontLoaded(CSSFontFaceSource*) +{ + // FIXME: Can we assert that m_segmentedFontFaces is not empty? That may + // require stopping in-progress font loading when the last + // CSSSegmentedFontFace is removed. + if (m_segmentedFontFaces.isEmpty()) + return; + + HashSet<CSSSegmentedFontFace*>::iterator end = m_segmentedFontFaces.end(); + for (HashSet<CSSSegmentedFontFace*>::iterator it = m_segmentedFontFaces.begin(); it != end; ++it) + (*it)->fontLoaded(this); + + // Use one of the CSSSegmentedFontFaces' font selector. They all have + // the same font selector, so it's wasteful to store it in the CSSFontFace. + CSSFontSelector* fontSelector = (*m_segmentedFontFaces.begin())->fontSelector(); + fontSelector->fontLoaded(); +} + +SimpleFontData* CSSFontFace::getFontData(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic) +{ + if (!isValid()) + return 0; + + ASSERT(!m_segmentedFontFaces.isEmpty()); + CSSFontSelector* fontSelector = (*m_segmentedFontFaces.begin())->fontSelector(); + + SimpleFontData* result = 0; + unsigned size = m_sources.size(); + for (unsigned i = 0; i < size && !result; i++) + result = m_sources[i]->getFontData(fontDescription, syntheticBold, syntheticItalic, fontSelector); + return result; +} + +} + diff --git a/src/3rdparty/webkit/WebCore/css/CSSFontFace.h b/src/3rdparty/webkit/WebCore/css/CSSFontFace.h new file mode 100644 index 0000000..41c9c55 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSFontFace.h @@ -0,0 +1,96 @@ +/* + * 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 "FontTraitsMask.h" +#include <wtf/HashSet.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> +#include <wtf/Vector.h> +#include <wtf/unicode/Unicode.h> + +namespace WebCore { + +class CSSFontFaceSource; +class CSSSegmentedFontFace; +class FontDescription; +class SimpleFontData; + +class CSSFontFace : public RefCounted<CSSFontFace> { +public: + static PassRefPtr<CSSFontFace> create(FontTraitsMask traitsMask) { return adoptRef(new CSSFontFace(traitsMask)); } + ~CSSFontFace(); + + FontTraitsMask traitsMask() const { return m_traitsMask; } + + struct UnicodeRange; + + void addRange(UChar32 from, UChar32 to) { m_ranges.append(UnicodeRange(from, to)); } + const Vector<UnicodeRange>& ranges() const { return m_ranges; } + + void addedToSegmentedFontFace(CSSSegmentedFontFace*); + void removedFromSegmentedFontFace(CSSSegmentedFontFace*); + + bool isLoaded() const; + bool isValid() const; + + void addSource(CSSFontFaceSource*); + + void fontLoaded(CSSFontFaceSource*); + + SimpleFontData* getFontData(const FontDescription&, bool syntheticBold, bool syntheticItalic); + + struct UnicodeRange { + UnicodeRange(UChar32 from, UChar32 to) + : m_from(from) + , m_to(to) + { + } + + UChar32 from() const { return m_from; } + UChar32 to() const { return m_to; } + + private: + UChar32 m_from; + UChar32 m_to; + }; + +private: + CSSFontFace(FontTraitsMask traitsMask) + : m_traitsMask(traitsMask) + { + } + + FontTraitsMask m_traitsMask; + Vector<UnicodeRange> m_ranges; + HashSet<CSSSegmentedFontFace*> m_segmentedFontFaces; + Vector<CSSFontFaceSource*> m_sources; +}; + +} + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/CSSFontFaceRule.cpp b/src/3rdparty/webkit/WebCore/css/CSSFontFaceRule.cpp new file mode 100644 index 0000000..75e9a36 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSFontFaceRule.cpp @@ -0,0 +1,58 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2002-2003 Dirk Mueller (mueller@kde.org) + * Copyright (C) 2002, 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 "CSSFontFaceRule.h" + +#include "CSSMutableStyleDeclaration.h" + +namespace WebCore { + +CSSFontFaceRule::CSSFontFaceRule(CSSStyleSheet* 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; +} + +void CSSFontFaceRule::addSubresourceStyleURLs(ListHashSet<KURL>& urls) +{ + if (m_style) + m_style->addSubresourceStyleURLs(urls); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSFontFaceRule.h b/src/3rdparty/webkit/WebCore/css/CSSFontFaceRule.h new file mode 100644 index 0000000..5148d0c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSFontFaceRule.h @@ -0,0 +1,67 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2002-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. + */ + +#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: + static PassRefPtr<CSSFontFaceRule> create() + { + return adoptRef(new CSSFontFaceRule(0)); + } + static PassRefPtr<CSSFontFaceRule> create(CSSStyleSheet* parent) + { + return adoptRef(new CSSFontFaceRule(parent)); + } + + virtual ~CSSFontFaceRule(); + + CSSMutableStyleDeclaration* style() const { return m_style.get(); } + + virtual String cssText() const; + + void setDeclaration(PassRefPtr<CSSMutableStyleDeclaration>); + + virtual void addSubresourceStyleURLs(ListHashSet<KURL>& urls); + +private: + CSSFontFaceRule(CSSStyleSheet* parent); + + virtual bool isFontFaceRule() { return true; } + + // Inherited from CSSRule + virtual unsigned short type() const { return FONT_FACE_RULE; } + + RefPtr<CSSMutableStyleDeclaration> m_style; +}; + +} // namespace WebCore + +#endif // CSSFontFaceRule_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSFontFaceRule.idl b/src/3rdparty/webkit/WebCore/css/CSSFontFaceRule.idl new file mode 100644 index 0000000..514c7dd --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSFontFaceSource.cpp b/src/3rdparty/webkit/WebCore/css/CSSFontFaceSource.cpp new file mode 100644 index 0000000..5e4b69c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSFontFaceSource.cpp @@ -0,0 +1,193 @@ +/* + * 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 ENABLE(SVG_FONTS) + , m_svgFontFaceElement(0) +#endif +{ + if (m_font) + m_font->addClient(this); +} + +CSSFontFaceSource::~CSSFontFaceSource() +{ + if (m_font) + m_font->removeClient(this); + pruneTable(); +} + +void CSSFontFaceSource::pruneTable() +{ + if (m_fontDataTable.isEmpty()) + return; + HashMap<unsigned, SimpleFontData*>::iterator end = m_fontDataTable.end(); + for (HashMap<unsigned, 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. + unsigned hashKey = fontDescription.computedPixelSize() << 2 | (syntheticBold ? 2 : 0) | (syntheticItalic ? 1 : 0); + if (SimpleFontData* cachedData = m_fontDataTable.get(hashKey)) + 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, fontDescription.renderingMode()), 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, fontDescription.renderingMode()), true, false)); + } + } else { +#if ENABLE(SVG_FONTS) + // In-Document SVG Fonts + if (m_svgFontFaceElement) { + SVGFontData* svgFontData = new SVGFontData(m_svgFontFaceElement); + fontData.set(new SimpleFontData(FontPlatformData(fontDescription.computedPixelSize(), syntheticBold, syntheticItalic), true, false, svgFontData)); + } +#endif + } + } else { + // Kick off the load now. + if (DocLoader* docLoader = fontSelector->docLoader()) + m_font->beginLoadIfNeeded(docLoader); + // FIXME: m_string is a URL so it makes no sense to pass it as a family name. + FontPlatformData* tempData = FontCache::getCachedFontPlatformData(fontDescription, m_string); + if (!tempData) + tempData = FontCache::getLastResortFallbackFont(fontDescription); + fontData.set(new SimpleFontData(*tempData, true, true)); + } + + m_fontDataTable.set(hashKey, fontData.get()); + return fontData.release(); +} + +} + diff --git a/src/3rdparty/webkit/WebCore/css/CSSFontFaceSource.h b/src/3rdparty/webkit/WebCore/css/CSSFontFaceSource.h new file mode 100644 index 0000000..c6baef2 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSFontFaceSource.h @@ -0,0 +1,83 @@ +/* + * 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 CSSFontFaceSource_h +#define CSSFontFaceSource_h + +#include "AtomicString.h" +#include "CachedResourceClient.h" +#include "CachedResourceHandle.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; } + void setSVGFontFaceElement(SVGFontFaceElement* element) { m_svgFontFaceElement = element; } +#endif + +private: + AtomicString m_string; // URI for remote, built-in font name for local. + CachedResourceHandle<CachedFont> m_font; // For remote fonts, a pointer to our cached resource. + CSSFontFace* m_face; // Our owning font face. + HashMap<unsigned, SimpleFontData*> m_fontDataTable; // The hash key is composed of size synthetic styles. + +#if ENABLE(SVG_FONTS) + SVGFontFaceElement* m_svgFontFaceElement; + RefPtr<SVGFontElement> m_externalSVGFontElement; +#endif +}; + +} + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/CSSFontFaceSrcValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSFontFaceSrcValue.cpp new file mode 100644 index 0000000..308ff31 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSFontFaceSrcValue.cpp @@ -0,0 +1,79 @@ +/* + * 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" +#include "CSSStyleSheet.h" +#include "Node.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; +} + +void CSSFontFaceSrcValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const CSSStyleSheet* styleSheet) +{ + if (!isLocal()) + addSubresourceURL(urls, styleSheet->completeURL(m_resource)); +} + +} + diff --git a/src/3rdparty/webkit/WebCore/css/CSSFontFaceSrcValue.h b/src/3rdparty/webkit/WebCore/css/CSSFontFaceSrcValue.h new file mode 100644 index 0000000..22f1be7 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSFontFaceSrcValue.h @@ -0,0 +1,92 @@ +/* + * 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 CSSFontFaceSrcValue_h +#define CSSFontFaceSrcValue_h + +#include "CSSValue.h" +#include "PlatformString.h" +#include <wtf/PassRefPtr.h> + +#if ENABLE(SVG_FONTS) +#include "SVGFontFaceElement.h" +#endif + +namespace WebCore { + +class CSSFontFaceSrcValue : public CSSValue { +public: + static PassRefPtr<CSSFontFaceSrcValue> create(const String& resource) + { + return adoptRef(new CSSFontFaceSrcValue(resource, false)); + } + static PassRefPtr<CSSFontFaceSrcValue> createLocal(const String& resource) + { + return adoptRef(new CSSFontFaceSrcValue(resource, true)); + } + + 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; } + void setSVGFontFaceElement(SVGFontFaceElement* element) { m_svgFontFaceElement = element; } +#endif + + virtual String cssText() const; + + virtual void addSubresourceStyleURLs(ListHashSet<KURL>&, const CSSStyleSheet*); + +private: + CSSFontFaceSrcValue(const String& resource, bool local) + : m_resource(resource) + , m_isLocal(local) +#if ENABLE(SVG_FONTS) + , m_svgFontFaceElement(0) +#endif + { + } + + String m_resource; + String m_format; + bool m_isLocal; + +#if ENABLE(SVG_FONTS) + SVGFontFaceElement* m_svgFontFaceElement; +#endif +}; + +} + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/CSSFontSelector.cpp b/src/3rdparty/webkit/WebCore/css/CSSFontSelector.cpp new file mode 100644 index 0000000..714be47 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSFontSelector.cpp @@ -0,0 +1,537 @@ +/* + * 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) +{ + // FIXME: An old comment used to say there was no need to hold a reference to m_document + // because "we are guaranteed to be destroyed before the document". But there does not + // seem to be any such guarantee. + + ASSERT(m_document); + FontCache::addClient(this); +} + +CSSFontSelector::~CSSFontSelector() +{ + FontCache::removeClient(this); + deleteAllValues(m_fontFaces); + deleteAllValues(m_locallyInstalledFontFaces); + deleteAllValues(m_fonts); +} + +bool CSSFontSelector::isEmpty() const +{ + return m_fonts.isEmpty(); +} + +DocLoader* CSSFontSelector::docLoader() const +{ + return m_document ? m_document->docLoader() : 0; +} + +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(CSSPropertyFontFamily); + RefPtr<CSSValue> src = style->getPropertyCSSValue(CSSPropertySrc); + RefPtr<CSSValue> unicodeRange = style->getPropertyCSSValue(CSSPropertyUnicodeRange); + 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()); + + unsigned traitsMask = 0; + + if (RefPtr<CSSValue> fontStyle = style->getPropertyCSSValue(CSSPropertyFontStyle)) { + if (fontStyle->isPrimitiveValue()) { + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + list->append(fontStyle); + fontStyle = list; + } else if (!fontStyle->isValueList()) + return; + + CSSValueList* styleList = static_cast<CSSValueList*>(fontStyle.get()); + unsigned numStyles = styleList->length(); + if (!numStyles) + return; + + for (unsigned i = 0; i < numStyles; ++i) { + switch (static_cast<CSSPrimitiveValue*>(styleList->itemWithoutBoundsCheck(i))->getIdent()) { + case CSSValueAll: + traitsMask |= FontStyleMask; + break; + case CSSValueNormal: + traitsMask |= FontStyleNormalMask; + break; + case CSSValueItalic: + case CSSValueOblique: + traitsMask |= FontStyleItalicMask; + break; + default: + break; + } + } + } else + traitsMask |= FontStyleMask; + + if (RefPtr<CSSValue> fontWeight = style->getPropertyCSSValue(CSSPropertyFontWeight)) { + if (fontWeight->isPrimitiveValue()) { + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + list->append(fontWeight); + fontWeight = list; + } else if (!fontWeight->isValueList()) + return; + + CSSValueList* weightList = static_cast<CSSValueList*>(fontWeight.get()); + unsigned numWeights = weightList->length(); + if (!numWeights) + return; + + for (unsigned i = 0; i < numWeights; ++i) { + switch (static_cast<CSSPrimitiveValue*>(weightList->itemWithoutBoundsCheck(i))->getIdent()) { + case CSSValueAll: + traitsMask |= FontWeightMask; + break; + case CSSValueBolder: + case CSSValueBold: + case CSSValue700: + traitsMask |= FontWeight700Mask; + break; + case CSSValueNormal: + case CSSValue400: + traitsMask |= FontWeight400Mask; + break; + case CSSValue900: + traitsMask |= FontWeight900Mask; + break; + case CSSValue800: + traitsMask |= FontWeight800Mask; + break; + case CSSValue600: + traitsMask |= FontWeight600Mask; + break; + case CSSValue500: + traitsMask |= FontWeight500Mask; + break; + case CSSValue300: + traitsMask |= FontWeight300Mask; + break; + case CSSValueLighter: + case CSSValue200: + traitsMask |= FontWeight200Mask; + break; + case CSSValue100: + traitsMask |= FontWeight100Mask; + break; + default: + break; + } + } + } else + traitsMask |= FontWeightMask; + + if (RefPtr<CSSValue> fontVariant = style->getPropertyCSSValue(CSSPropertyFontVariant)) { + if (fontVariant->isPrimitiveValue()) { + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + list->append(fontVariant); + fontVariant = list; + } else if (!fontVariant->isValueList()) + return; + + CSSValueList* variantList = static_cast<CSSValueList*>(fontVariant.get()); + unsigned numVariants = variantList->length(); + if (!numVariants) + return; + + for (unsigned i = 0; i < numVariants; ++i) { + switch (static_cast<CSSPrimitiveValue*>(variantList->itemWithoutBoundsCheck(i))->getIdent()) { + case CSSValueAll: + traitsMask |= FontVariantMask; + break; + case CSSValueNormal: + traitsMask |= FontVariantNormalMask; + break; + case CSSValueSmallCaps: + traitsMask |= FontVariantSmallCapsMask; + break; + default: + break; + } + } + } else + traitsMask |= FontVariantNormalMask; + + // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace. + RefPtr<CSSFontFace> fontFace; + + int srcLength = srcList->length(); + + bool foundLocal = false; + +#if ENABLE(SVG_FONTS) + bool foundSVGFont = false; +#endif + + for (int 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->itemWithoutBoundsCheck(i)); + CSSFontFaceSource* source = 0; + +#if ENABLE(SVG_FONTS) + foundSVGFont = item->isSVGFontFaceSrc() || item->svgFontFaceElement(); +#endif + + if (!item->isLocal()) { + if (item->isSupportedFormat() && m_document) { + 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 { + source = new CSSFontFaceSource(item->resource()); + foundLocal = true; + } + + if (!fontFace) + fontFace = CSSFontFace::create(static_cast<FontTraitsMask>(traitsMask)); + + if (source) { +#if ENABLE(SVG_FONTS) + source->setSVGFontFaceElement(item->svgFontFaceElement()); +#endif + fontFace->addSource(source); + } + } + + ASSERT(fontFace); + + if (fontFace && !fontFace->isValid()) + return; + + if (rangeList) { + unsigned numRanges = rangeList->length(); + for (unsigned i = 0; i < numRanges; i++) { + CSSUnicodeRangeValue* range = static_cast<CSSUnicodeRangeValue*>(rangeList->itemWithoutBoundsCheck(i)); + fontFace->addRange(range->from(), range->to()); + } + } + + // Hash under every single family name. + int familyLength = familyList->length(); + for (int i = 0; i < familyLength; i++) { + CSSPrimitiveValue* item = static_cast<CSSPrimitiveValue*>(familyList->itemWithoutBoundsCheck(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 CSSValueSerif: + familyName = "-webkit-serif"; + break; + case CSSValueSansSerif: + familyName = "-webkit-sans-serif"; + break; + case CSSValueCursive: + familyName = "-webkit-cursive"; + break; + case CSSValueFantasy: + familyName = "-webkit-fantasy"; + break; + case CSSValueMonospace: + 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 && (traitsMask & FontVariantSmallCapsMask)) + familyName += "-webkit-svg-small-caps"; +#endif + + Vector<RefPtr<CSSFontFace> >* familyFontFaces = m_fontFaces.get(familyName); + if (!familyFontFaces) { + familyFontFaces = new Vector<RefPtr<CSSFontFace> >; + m_fontFaces.set(familyName, familyFontFaces); + + ASSERT(!m_locallyInstalledFontFaces.contains(familyName)); + Vector<RefPtr<CSSFontFace> >* familyLocallyInstalledFaces; + + Vector<unsigned> locallyInstalledFontsTraitsMasks; + FontCache::getTraitsInFamily(familyName, locallyInstalledFontsTraitsMasks); + unsigned numLocallyInstalledFaces = locallyInstalledFontsTraitsMasks.size(); + if (numLocallyInstalledFaces) { + familyLocallyInstalledFaces = new Vector<RefPtr<CSSFontFace> >; + m_locallyInstalledFontFaces.set(familyName, familyLocallyInstalledFaces); + + for (unsigned i = 0; i < numLocallyInstalledFaces; ++i) { + RefPtr<CSSFontFace> locallyInstalledFontFace = CSSFontFace::create(static_cast<FontTraitsMask>(locallyInstalledFontsTraitsMasks[i])); + locallyInstalledFontFace->addSource(new CSSFontFaceSource(familyName)); + ASSERT(locallyInstalledFontFace->isValid()); + familyLocallyInstalledFaces->append(locallyInstalledFontFace); + } + } + } + + familyFontFaces->append(fontFace); + } +} + +void CSSFontSelector::fontLoaded() +{ + if (!m_document || m_document->inPageCache() || !m_document->renderer()) + return; + m_document->recalcStyle(Document::Force); + m_document->renderer()->setNeedsLayoutAndPrefWidthsRecalc(); +} + +void CSSFontSelector::fontCacheInvalidated() +{ + if (!m_document || m_document->inPageCache() || !m_document->renderer()) + return; + m_document->recalcStyle(Document::Force); + m_document->renderer()->setNeedsLayoutAndPrefWidthsRecalc(); +} + +static FontData* fontDataForGenericFamily(Document* document, const FontDescription& fontDescription, const AtomicString& familyName) +{ + if (!document || !document->frame()) + return 0; + + const Settings* settings = document->frame()->settings(); + if (!settings) + return 0; + + 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; +} + +static FontTraitsMask desiredTraitsMaskForComparison; + +static inline bool compareFontFaces(CSSFontFace* first, CSSFontFace* second) +{ + FontTraitsMask firstTraitsMask = first->traitsMask(); + FontTraitsMask secondTraitsMask = second->traitsMask(); + + bool firstHasDesiredVariant = firstTraitsMask & desiredTraitsMaskForComparison & FontVariantMask; + bool secondHasDesiredVariant = secondTraitsMask & desiredTraitsMaskForComparison & FontVariantMask; + + if (firstHasDesiredVariant != secondHasDesiredVariant) + return firstHasDesiredVariant; + + bool firstHasDesiredStyle = firstTraitsMask & desiredTraitsMaskForComparison & FontStyleMask; + bool secondHasDesiredStyle = secondTraitsMask & desiredTraitsMaskForComparison & FontStyleMask; + + if (firstHasDesiredStyle != secondHasDesiredStyle) + return firstHasDesiredStyle; + + if (secondTraitsMask & desiredTraitsMaskForComparison & FontWeightMask) + return false; + if (firstTraitsMask & desiredTraitsMaskForComparison & FontWeightMask) + return true; + + // http://www.w3.org/TR/2002/WD-css3-webfonts-20020802/#q46 says: "If there are fewer then 9 weights in the family, the default algorithm + // for filling the "holes" is as follows. If '500' is unassigned, it will be assigned the same font as '400'. If any of the values '600', + // '700', '800', or '900' remains unassigned, they are assigned to the same face as the next darker assigned keyword, if any, or the next + // lighter one otherwise. If any of '300', '200', or '100' remains unassigned, it is assigned to the next lighter assigned keyword, if any, + // or the next darker otherwise." + // For '400', we made up our own rule (which then '500' follows). + + static const FontTraitsMask weightFallbackRules[9][8] = { + { FontWeight200Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask }, + { FontWeight100Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask }, + { FontWeight200Mask, FontWeight100Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask }, + { FontWeight500Mask, FontWeight300Mask, FontWeight600Mask, FontWeight200Mask, FontWeight700Mask, FontWeight100Mask, FontWeight800Mask, FontWeight900Mask }, + { FontWeight400Mask, FontWeight300Mask, FontWeight600Mask, FontWeight200Mask, FontWeight700Mask, FontWeight100Mask, FontWeight800Mask, FontWeight900Mask }, + { FontWeight700Mask, FontWeight800Mask, FontWeight900Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask }, + { FontWeight800Mask, FontWeight900Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask }, + { FontWeight900Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask }, + { FontWeight800Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask } + }; + + const FontTraitsMask* weightFallbackRule = weightFallbackRules[0]; + unsigned w = FontWeight100Bit; + while (!(desiredTraitsMaskForComparison & (1 << w))) { + w++; + weightFallbackRule += 8; + } + + for (unsigned i = 0; i < 8; ++i) { + if (secondTraitsMask & weightFallbackRule[i]) + return false; + if (firstTraitsMask & weightFallbackRule[i]) + return true; + } + + return false; +} + +FontData* CSSFontSelector::getFontData(const FontDescription& fontDescription, const AtomicString& familyName) +{ + if (m_fontFaces.isEmpty()) { + if (familyName.startsWith("-webkit-")) + return fontDataForGenericFamily(m_document, fontDescription, familyName); + return 0; + } + + String family = familyName.string(); + +#if ENABLE(SVG_FONTS) + if (fontDescription.smallCaps()) + family += "-webkit-svg-small-caps"; +#endif + + Vector<RefPtr<CSSFontFace> >* familyFontFaces = m_fontFaces.get(family); + // If no face was found, then return 0 and let the OS come up with its best match for the name. + if (!familyFontFaces || familyFontFaces->isEmpty()) { + // If we were handed a generic family, but there was no match, go ahead and return the correct font based off our + // settings. + return fontDataForGenericFamily(m_document, fontDescription, familyName); + } + + HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >* segmentedFontFaceCache = m_fonts.get(family); + if (!segmentedFontFaceCache) { + segmentedFontFaceCache = new HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >; + m_fonts.set(family, segmentedFontFaceCache); + } + + FontTraitsMask traitsMask = fontDescription.traitsMask(); + + RefPtr<CSSSegmentedFontFace> face = segmentedFontFaceCache->get(traitsMask); + + if (!face) { + face = CSSSegmentedFontFace::create(this); + segmentedFontFaceCache->set(traitsMask, face); + // Collect all matching faces and sort them in order of preference. + Vector<CSSFontFace*, 32> candidateFontFaces; + for (int i = familyFontFaces->size() - 1; i >= 0; --i) { + CSSFontFace* candidate = familyFontFaces->at(i).get(); + unsigned candidateTraitsMask = candidate->traitsMask(); + if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask)) + continue; + if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask)) + continue; + candidateFontFaces.append(candidate); + } + + if (Vector<RefPtr<CSSFontFace> >* familyLocallyInstalledFontFaces = m_locallyInstalledFontFaces.get(family)) { + unsigned numLocallyInstalledFontFaces = familyLocallyInstalledFontFaces->size(); + for (unsigned i = 0; i < numLocallyInstalledFontFaces; ++i) { + CSSFontFace* candidate = familyLocallyInstalledFontFaces->at(i).get(); + unsigned candidateTraitsMask = candidate->traitsMask(); + if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask)) + continue; + if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask)) + continue; + candidateFontFaces.append(candidate); + } + } + + desiredTraitsMaskForComparison = traitsMask; + std::stable_sort(candidateFontFaces.begin(), candidateFontFaces.end(), compareFontFaces); + unsigned numCandidates = candidateFontFaces.size(); + for (unsigned i = 0; i < numCandidates; ++i) + face->appendFontFace(candidateFontFaces[i]); + } + + // 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); +} + +} diff --git a/src/3rdparty/webkit/WebCore/css/CSSFontSelector.h b/src/3rdparty/webkit/WebCore/css/CSSFontSelector.h new file mode 100644 index 0000000..af454bd --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSFontSelector.h @@ -0,0 +1,77 @@ +/* + * 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 CSSFontSelector_h +#define CSSFontSelector_h + +#include "FontSelector.h" +#include "StringHash.h" +#include <wtf/HashMap.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class AtomicString; +class CSSFontFace; +class CSSFontFaceRule; +class CSSSegmentedFontFace; +class Document; +class DocLoader; +class FontDescription; +class String; + +class CSSFontSelector : public FontSelector { +public: + static PassRefPtr<CSSFontSelector> create(Document* document) + { + return adoptRef(new CSSFontSelector(document)); + } + virtual ~CSSFontSelector(); + + virtual FontData* getFontData(const FontDescription& fontDescription, const AtomicString& familyName); + + void clearDocument() { m_document = 0; } + + void addFontFaceRule(const CSSFontFaceRule*); + + void fontLoaded(); + virtual void fontCacheInvalidated(); + + bool isEmpty() const; + + DocLoader* docLoader() const; + +private: + CSSFontSelector(Document*); + + Document* m_document; + HashMap<String, Vector<RefPtr<CSSFontFace> >*, CaseFoldingHash> m_fontFaces; + HashMap<String, Vector<RefPtr<CSSFontFace> >*, CaseFoldingHash> m_locallyInstalledFontFaces; + HashMap<String, HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >*, CaseFoldingHash> m_fonts; +}; + +} // namespace WebCore + +#endif // CSSFontSelector_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSFunctionValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSFunctionValue.cpp new file mode 100644 index 0000000..cb938ed --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSFunctionValue.cpp @@ -0,0 +1,64 @@ +/* + * 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 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 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 "CSSFunctionValue.h" +#include "CSSValueList.h" + +namespace WebCore { + +CSSFunctionValue::CSSFunctionValue(CSSParserFunction* function) +{ + m_name = function->name; + if (function->args) + m_args = CSSValueList::createFromParserValueList(function->args); +} + +CSSFunctionValue::~CSSFunctionValue() +{ +} + +String CSSFunctionValue::cssText() const +{ + String result = m_name; // Includes the '(' + if (m_args) + result += m_args->cssText(); + result += ")"; + return result; +} + +CSSParserValue CSSFunctionValue::parserValue() const +{ + CSSParserValue val; + val.id = 0; + val.unit = CSSParserValue::Function; + val.function = new CSSParserFunction; + val.function->name.characters = const_cast<UChar*>(m_name.characters()); + val.function->name.length = m_name.length(); + val.function->args = m_args ? m_args->createParserValueList() : 0; + return val; +} + +} diff --git a/src/3rdparty/webkit/WebCore/css/CSSFunctionValue.h b/src/3rdparty/webkit/WebCore/css/CSSFunctionValue.h new file mode 100644 index 0000000..e9545a1 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSFunctionValue.h @@ -0,0 +1,58 @@ +/* + * 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 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 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 CSSFunctionValue_h +#define CSSFunctionValue_h + +#include "CSSValue.h" + +namespace WebCore { + +class CSSValueList; +struct CSSParserFunction; + +class CSSFunctionValue : public CSSValue { +public: + static PassRefPtr<CSSFunctionValue> create(CSSParserFunction* function) + { + return adoptRef(new CSSFunctionValue(function)); + } + + ~CSSFunctionValue(); + + virtual String cssText() const; + + virtual CSSParserValue parserValue() const; + +private: + CSSFunctionValue(CSSParserFunction*); + + String m_name; + RefPtr<CSSValueList> m_args; +}; + +} +#endif + diff --git a/src/3rdparty/webkit/WebCore/css/CSSGradientValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSGradientValue.cpp new file mode 100644 index 0000000..3f45e47 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSGradientValue.cpp @@ -0,0 +1,164 @@ +/* + * 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 "CSSGradientValue.h" + +#include "CSSStyleSelector.h" +#include "GeneratedImage.h" +#include "Gradient.h" +#include "GraphicsContext.h" +#include "Image.h" +#include "ImageBuffer.h" +#include "IntSize.h" +#include "IntSizeHash.h" +#include "PlatformString.h" +#include "RenderObject.h" + +using namespace std; + +namespace WebCore { + +String CSSGradientValue::cssText() const +{ + String result = "-webkit-gradient("; + if (m_type == CSSLinearGradient) + result += "linear, "; + else + result += "radial, "; + result += m_firstX->cssText() + " "; + result += m_firstY->cssText() + ", "; + if (m_type == CSSRadialGradient) + result += m_firstRadius->cssText() + ", "; + result += m_secondX->cssText() + " "; + result += m_secondY->cssText(); + if (m_type == CSSRadialGradient) { + result += ", "; + result += m_secondRadius->cssText(); + } + for (unsigned i = 0; i < m_stops.size(); i++) { + result += ", "; + if (m_stops[i].m_stop == 0) + result += "from(" + m_stops[i].m_color->cssText() + ")"; + else if (m_stops[i].m_stop == 1) + result += "to(" + m_stops[i].m_color->cssText() + ")"; + else + result += "color-stop(" + String::number(m_stops[i].m_stop) + ", " + m_stops[i].m_color->cssText() + ")"; + } + result += ")"; + return result; +} + +PassRefPtr<Gradient> CSSGradientValue::createGradient(RenderObject* renderer, const IntSize& size) +{ + ASSERT(!size.isEmpty()); + + float zoomFactor = renderer->style()->effectiveZoom(); + + FloatPoint firstPoint = resolvePoint(m_firstX.get(), m_firstY.get(), size, zoomFactor); + FloatPoint secondPoint = resolvePoint(m_secondX.get(), m_secondY.get(), size, zoomFactor); + + RefPtr<Gradient> gradient; + if (m_type == CSSLinearGradient) + gradient = Gradient::create(firstPoint, secondPoint); + else { + float firstRadius = resolveRadius(m_firstRadius.get(), zoomFactor); + float secondRadius = resolveRadius(m_secondRadius.get(), zoomFactor); + gradient = Gradient::create(firstPoint, firstRadius, secondPoint, secondRadius); + } + + // Now add the stops. + sortStopsIfNeeded(); + + // We have to resolve colors. + for (unsigned i = 0; i < m_stops.size(); i++) { + Color color = renderer->document()->styleSelector()->getColorFromPrimitiveValue(m_stops[i].m_color.get()); + gradient->addColorStop(m_stops[i].m_stop, color); + } + + // The back end already sorted the stops. + gradient->setStopsSorted(true); + + return gradient.release(); +} + +Image* CSSGradientValue::image(RenderObject* renderer, const IntSize& size) +{ + ASSERT(m_clients.contains(renderer)); + + // Need to look up our size. Create a string of width*height to use as a hash key. + Image* result = getImage(renderer, size); + if (result) + return result; + + if (size.isEmpty()) + return 0; + + // We need to create an image. + RefPtr<Image> newImage = GeneratedImage::create(createGradient(renderer, size), size); + result = newImage.get(); + putImage(size, newImage.release()); + + return result; +} + +static inline bool compareStops(const CSSGradientColorStop& a, const CSSGradientColorStop& b) +{ + return a.m_stop < b.m_stop; +} + +void CSSGradientValue::sortStopsIfNeeded() +{ + if (!m_stopsSorted) { + if (m_stops.size()) + std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); + m_stopsSorted = true; + } +} + +FloatPoint CSSGradientValue::resolvePoint(CSSPrimitiveValue* first, CSSPrimitiveValue* second, const IntSize& size, float zoomFactor) +{ + FloatPoint result; + if (first->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) + result.setX(first->getFloatValue() * zoomFactor); + else if (first->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE) + result.setX(first->getFloatValue() / 100.f * size.width()); + if (second->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) + result.setY(second->getFloatValue() * zoomFactor); + else if (second->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE) + result.setY(second->getFloatValue() / 100.f * size.height()); + + return result; +} + +float CSSGradientValue::resolveRadius(CSSPrimitiveValue* radius, float zoomFactor) +{ + float result = 0.f; + if (radius->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) + result = radius->getFloatValue() * zoomFactor; + return result; +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSGradientValue.h b/src/3rdparty/webkit/WebCore/css/CSSGradientValue.h new file mode 100644 index 0000000..83c1815 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSGradientValue.h @@ -0,0 +1,112 @@ +/* + * 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 CSSGradientValue_h +#define CSSGradientValue_h + +#include "CSSImageGeneratorValue.h" +#include "CSSPrimitiveValue.h" +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class FloatPoint; +class Gradient; + +enum CSSGradientType { CSSLinearGradient, CSSRadialGradient }; + +struct CSSGradientColorStop { + CSSGradientColorStop() + : m_stop(0) + { + } + + float m_stop; + RefPtr<CSSPrimitiveValue> m_color; +}; + +class CSSGradientValue : public CSSImageGeneratorValue { +public: + static PassRefPtr<CSSGradientValue> create() + { + return adoptRef(new CSSGradientValue); + } + + virtual String cssText() const; + + virtual Image* image(RenderObject*, const IntSize&); + + CSSGradientType type() const { return m_type; } + void setType(CSSGradientType type) { m_type = type; } + + void setFirstX(PassRefPtr<CSSPrimitiveValue> val) { m_firstX = val; } + void setFirstY(PassRefPtr<CSSPrimitiveValue> val) { m_firstY = val; } + void setSecondX(PassRefPtr<CSSPrimitiveValue> val) { m_secondX = val; } + void setSecondY(PassRefPtr<CSSPrimitiveValue> val) { m_secondY = val; } + + void setFirstRadius(PassRefPtr<CSSPrimitiveValue> val) { m_firstRadius = val; } + void setSecondRadius(PassRefPtr<CSSPrimitiveValue> val) { m_secondRadius = val; } + + void addStop(const CSSGradientColorStop& stop) { m_stops.append(stop); } + + void sortStopsIfNeeded(); + +private: + CSSGradientValue() + : m_type(CSSLinearGradient) + , m_stopsSorted(false) + { + } + + // Create the gradient for a given size. + PassRefPtr<Gradient> createGradient(RenderObject*, const IntSize&); + + // Resolve points/radii to front end values. + FloatPoint resolvePoint(CSSPrimitiveValue*, CSSPrimitiveValue*, const IntSize&, float zoomFactor); + float resolveRadius(CSSPrimitiveValue*, float zoomFactor); + + // Type + CSSGradientType m_type; + + // Points + RefPtr<CSSPrimitiveValue> m_firstX; + RefPtr<CSSPrimitiveValue> m_firstY; + + RefPtr<CSSPrimitiveValue> m_secondX; + RefPtr<CSSPrimitiveValue> m_secondY; + + // Radii (for radial gradients only) + RefPtr<CSSPrimitiveValue> m_firstRadius; + RefPtr<CSSPrimitiveValue> m_secondRadius; + + // Stops + Vector<CSSGradientColorStop> m_stops; + bool m_stopsSorted; +}; + +} // namespace WebCore + +#endif // CSSGradientValue_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSGrammar.y b/src/3rdparty/webkit/WebCore/css/CSSGrammar.y new file mode 100644 index 0000000..9ee9c93 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSGrammar.y @@ -0,0 +1,1501 @@ +%{ + +/* + * 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) + * Copyright (C) 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 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 "CSSPropertyNames.h" +#include "CSSRuleList.h" +#include "CSSSelector.h" +#include "CSSStyleSheet.h" +#include "Document.h" +#include "HTMLNames.h" +#include "MediaList.h" +#include "WebKitCSSKeyframeRule.h" +#include "WebKitCSSKeyframesRule.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 +#define YYLEX_PARAM parser + +%} + +%pure_parser + +%union { + bool boolean; + char character; + int integer; + double number; + CSSParserString string; + + CSSRule* rule; + CSSRuleList* ruleList; + CSSSelector* selector; + Vector<CSSSelector*>* selectorList; + CSSSelector::Relation relation; + MediaList* mediaList; + MediaQuery* mediaQuery; + MediaQuery::Restrictor mediaQueryRestrictor; + MediaQueryExp* mediaQueryExp; + CSSParserValue value; + CSSParserValueList* valueList; + Vector<MediaQueryExp*>* mediaQueryExpList; + WebKitCSSKeyframeRule* keyframeRule; + WebKitCSSKeyframesRule* keyframesRule; + float val; +} + +%{ + +static inline int cssyyerror(const char*) +{ + return 1; +} + +static int cssyylex(YYSTYPE* yylval, void* parser) +{ + return static_cast<CSSParser*>(parser)->lex(yylval); +} + +%} + +%expect 49 + +%left UNIMPORTANT_TOK + +%token WHITESPACE SGML_CD +%token TOKEN_EOF 0 + +%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_KEYFRAME_RULE_SYM +%token WEBKIT_KEYFRAMES_SYM +%token WEBKIT_VALUE_SYM +%token WEBKIT_MEDIAQUERY_SYM +%token WEBKIT_SELECTOR_SYM +%token WEBKIT_VARIABLES_SYM +%token WEBKIT_DEFINE_SYM +%token VARIABLES_FOR +%token WEBKIT_VARIABLES_DECLS_SYM +%token ATKEYWORD + +%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> TURNS +%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 + +%token <string> VARCALL + +%type <relation> combinator + +%type <rule> charset +%type <rule> ruleset +%type <rule> valid_rule_or_import +%type <rule> media +%type <rule> import +%type <rule> page +%type <rule> font_face +%type <rule> keyframes +%type <rule> invalid_rule +%type <rule> save_block +%type <rule> invalid_at +%type <rule> invalid_at_list +%type <rule> invalid_import +%type <rule> invalid_media +%type <rule> rule +%type <rule> valid_rule +%type <ruleList> block_rule_list +%type <rule> block_rule +%type <rule> block_valid_rule +%type <rule> variables_rule +%type <mediaList> variables_media_list + +%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_and_media_query_exp_list + +%type <string> keyframe_name +%type <keyframeRule> keyframe_rule +%type <keyframesRule> keyframes_rule +%type <valueList> key_list +%type <value> key + +%type <integer> property + +%type <selector> specifier +%type <selector> specifier_list +%type <selector> simple_selector +%type <selector> selector +%type <selectorList> 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 + +%type <string> variable_name +%type <boolean> variables_declaration_list +%type <boolean> variables_decl_list +%type <boolean> variables_declaration +%type <value> variable_reference + +%% + +stylesheet: + maybe_charset maybe_sgml import_list variables_list namespace_list rule_list + | webkit_rule maybe_space + | webkit_decls maybe_space + | webkit_value maybe_space + | webkit_mediaquery maybe_space + | webkit_selector maybe_space + | webkit_variables_decls maybe_space + | webkit_keyframe_rule maybe_space + ; + +valid_rule_or_import: + valid_rule + | import + ; + +webkit_rule: + WEBKIT_RULE_SYM '{' maybe_space valid_rule_or_import maybe_space '}' { + static_cast<CSSParser*>(parser)->m_rule = $4; + } +; + +webkit_keyframe_rule: + WEBKIT_KEYFRAME_RULE_SYM '{' maybe_space keyframe_rule maybe_space '}' { + static_cast<CSSParser*>(parser)->m_keyframe = $4; + } +; + +webkit_decls: + WEBKIT_DECLS_SYM '{' maybe_space declaration_list '}' { + /* can be empty */ + } +; + +webkit_variables_decls: + WEBKIT_VARIABLES_DECLS_SYM '{' maybe_space variables_declaration_list '}' { + /* can be empty */ + } +; + +webkit_value: + WEBKIT_VALUE_SYM '{' maybe_space expr '}' { + CSSParser* p = static_cast<CSSParser*>(parser); + if ($4) { + p->m_valueList = p->sinkFloatingValueList($4); + int oldParsedProperties = p->m_numParsedProperties; + if (!p->parseValue(p->m_id, p->m_important)) + p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties); + delete p->m_valueList; + p->m_valueList = 0; + } + } +; + +webkit_mediaquery: + WEBKIT_MEDIAQUERY_SYM WHITESPACE maybe_space media_query '}' { + CSSParser* p = static_cast<CSSParser*>(parser); + p->m_mediaQuery = p->sinkFloatingMediaQuery($4); + } +; + +webkit_selector: + WEBKIT_SELECTOR_SYM '{' maybe_space selector_list '}' { + if ($4) { + CSSParser* p = static_cast<CSSParser*>(parser); + if (p->m_selectorListForParseSelector) + p->m_selectorListForParseSelector->adoptSelectorVector(*$4); + } + } +; + +maybe_space: + /* empty */ %prec UNIMPORTANT_TOK + | maybe_space WHITESPACE + ; + +maybe_sgml: + /* empty */ + | maybe_sgml SGML_CD + | maybe_sgml WHITESPACE + ; + +maybe_charset: + /* empty */ + | charset { + } + ; + +closing_brace: + '}' + | %prec maybe_sgml TOKEN_EOF + ; + +charset: + CHARSET_SYM maybe_space STRING maybe_space ';' { + CSSParser* p = static_cast<CSSParser*>(parser); + $$ = static_cast<CSSParser*>(parser)->createCharsetRule($3); + if ($$ && p->m_styleSheet) + p->m_styleSheet->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->m_styleSheet) + p->m_styleSheet->append($2); + } + | invalid_at_list { + } + ; + +variables_list: +/* empty */ +| variables_list variables_rule maybe_sgml { + CSSParser* p = static_cast<CSSParser*>(parser); + if ($2 && p->m_styleSheet) + p->m_styleSheet->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->m_styleSheet) + p->m_styleSheet->append($2); + } + ; + +valid_rule: + ruleset + | media + | page + | font_face + | keyframes + ; + +rule: + valid_rule + | invalid_rule + | invalid_at + | invalid_import + ; + +block_rule_list: + /* empty */ { $$ = 0; } + | block_rule_list block_rule maybe_sgml { + $$ = $1; + if ($2) { + if (!$$) + $$ = static_cast<CSSParser*>(parser)->createRuleList(); + $$->append($2); + } + } + ; + +block_valid_rule: + ruleset + | page + | font_face + | keyframes + ; + +block_rule: + block_valid_rule + | invalid_rule + | invalid_at + | invalid_import + | invalid_media + ; + + +import: + IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list ';' { + $$ = static_cast<CSSParser*>(parser)->createImportRule($3, $5); + } + | IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list invalid_block { + $$ = 0; + } + | IMPORT_SYM error ';' { + $$ = 0; + } + | IMPORT_SYM error invalid_block { + $$ = 0; + } + ; + +variables_rule: + WEBKIT_VARIABLES_SYM maybe_space maybe_media_list '{' maybe_space variables_declaration_list '}' { + $$ = static_cast<CSSParser*>(parser)->createVariablesRule($3, true); + } + | + WEBKIT_DEFINE_SYM maybe_space variables_media_list '{' maybe_space variables_declaration_list '}' { + $$ = static_cast<CSSParser*>(parser)->createVariablesRule($3, false); + } + ; + +variables_media_list: + /* empty */ { + $$ = static_cast<CSSParser*>(parser)->createMediaList(); + } + | + VARIABLES_FOR WHITESPACE media_list { + $$ = $3; + } + ; + +variables_declaration_list: + variables_declaration { + $$ = $1; + } + | variables_decl_list variables_declaration { + $$ = $1; + if ($2) + $$ = $2; + } + | variables_decl_list { + $$ = $1; + } + | error invalid_block_list error { + $$ = false; + } + | error { + $$ = false; + } + | variables_decl_list error { + $$ = $1; + } + ; + +variables_decl_list: + variables_declaration ';' maybe_space { + $$ = $1; + } + | variables_declaration invalid_block_list ';' maybe_space { + $$ = false; + } + | error ';' maybe_space { + $$ = false; + } + | error invalid_block_list error ';' maybe_space { + $$ = false; + } + | variables_decl_list variables_declaration ';' maybe_space { + $$ = $1; + if ($2) + $$ = $2; + } + | variables_decl_list error ';' maybe_space { + $$ = $1; + } + | variables_decl_list error invalid_block_list error ';' maybe_space { + $$ = $1; + } + ; + +variables_declaration: + variable_name ':' maybe_space expr { + $$ = static_cast<CSSParser*>(parser)->addVariable($1, $4); + } + | + variable_name maybe_space '{' maybe_space declaration_list '}' maybe_space { + $$ = static_cast<CSSParser*>(parser)->addVariableDeclarationBlock($1); + } + | + variable_name error { + $$ = false; + } + | + variable_name ':' maybe_space error expr { + $$ = false; + } + | + variable_name ':' maybe_space { + /* @variables { varname: } Just reduce away this variable with no value. */ + $$ = false; + } + | + variable_name ':' maybe_space error { + /* if we come across rules with invalid values like this case: @variables { varname: *; }, just discard the property/value pair */ + $$ = false; + } + ; + +variable_name: + IDENT maybe_space { + $$ = $1; + } + ; + +namespace: +NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' { + CSSParser* p = static_cast<CSSParser*>(parser); + if (p->m_styleSheet) + p->m_styleSheet->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: + '(' maybe_space media_feature maybe_space maybe_media_value ')' maybe_space { + $3.lower(); + $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExp($3, $5); + } + ; + +media_query_exp_list: + media_query_exp { + CSSParser* p = static_cast<CSSParser*>(parser); + $$ = p->createFloatingMediaQueryExpList(); + $$->append(p->sinkFloatingMediaQueryExp($1)); + } + | media_query_exp_list maybe_space MEDIA_AND maybe_space media_query_exp { + $$ = $1; + $$->append(static_cast<CSSParser*>(parser)->sinkFloatingMediaQueryExp($5)); + } + ; + +maybe_and_media_query_exp_list: + /*empty*/ { + $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExpList(); + } + | MEDIA_AND maybe_space media_query_exp_list { + $$ = $3; + } + ; + +maybe_media_restrictor: + /*empty*/ { + $$ = MediaQuery::None; + } + | MEDIA_ONLY { + $$ = MediaQuery::Only; + } + | MEDIA_NOT { + $$ = MediaQuery::Not; + } + ; + +media_query: + media_query_exp_list { + CSSParser* p = static_cast<CSSParser*>(parser); + $$ = p->createFloatingMediaQuery(p->sinkFloatingMediaQueryExpList($1)); + } + | + maybe_media_restrictor maybe_space medium maybe_and_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 block_rule_list save_block { + $$ = static_cast<CSSParser*>(parser)->createMediaRule($3, $6); + } + | MEDIA_SYM maybe_space '{' maybe_space block_rule_list save_block { + $$ = static_cast<CSSParser*>(parser)->createMediaRule(0, $5); + } + ; + +medium: + IDENT maybe_space { + $$ = $1; + } + ; + +keyframes: + WEBKIT_KEYFRAMES_SYM maybe_space keyframe_name maybe_space '{' maybe_space keyframes_rule '}' { + $$ = $7; + $7->setNameInternal($3); + } + ; + +keyframe_name: + IDENT + | STRING + ; + +keyframes_rule: + /* empty */ { $$ = static_cast<CSSParser*>(parser)->createKeyframesRule(); } + | keyframes_rule keyframe_rule maybe_space { + $$ = $1; + if ($2) + $$->append($2); + } + ; + +keyframe_rule: + key_list maybe_space '{' maybe_space declaration_list '}' { + $$ = static_cast<CSSParser*>(parser)->createKeyframeRule($1); + } + ; + +key_list: + key { + CSSParser* p = static_cast<CSSParser*>(parser); + $$ = p->createFloatingValueList(); + $$->addValue(p->sinkFloatingValue($1)); + } + | key_list maybe_space ',' maybe_space key { + CSSParser* p = static_cast<CSSParser*>(parser); + $$ = $1; + if ($$) + $$->addValue(p->sinkFloatingValue($5)); + } + ; + +key: + PERCENTAGE { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; } + | IDENT { + $$.id = 0; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_NUMBER; + CSSParserString& str = $1; + if (equalIgnoringCase(static_cast<const String&>(str), "from")) + $$.fValue = 0; + else if (equalIgnoringCase(static_cast<const String&>(str), "to")) + $$.fValue = 100; + else + YYERROR; + } + ; + +/* +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 closing_brace { + $$ = static_cast<CSSParser*>(parser)->createStyleRule($1); + } + ; + +selector_list: + selector %prec UNIMPORTANT_TOK { + if ($1) { + CSSParser* p = static_cast<CSSParser*>(parser); + $$ = p->reusableSelectorVector(); + deleteAllValues(*$$); + $$->shrink(0); + $$->append(p->sinkFloatingSelector($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->tagHistory()) + end = end->tagHistory(); + end->m_relation = CSSSelector::Descendant; + end->setTagHistory(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->tagHistory()) + end = end->tagHistory(); + end->m_relation = $2; + end->setTagHistory(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 = ☆ $$.length = 1; } + | IDENT '|' { $$ = $1; } +; + +simple_selector: + element_name { + CSSParser* p = static_cast<CSSParser*>(parser); + $$ = p->createFloatingSelector(); + $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace); + } + | element_name specifier_list { + $$ = $2; + if ($$) { + CSSParser* p = static_cast<CSSParser*>(parser); + $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace); + } + } + | specifier_list { + $$ = $1; + CSSParser* p = static_cast<CSSParser*>(parser); + if ($$ && p->m_defaultNamespace != starAtom) + $$->m_tag = QualifiedName(nullAtom, starAtom, p->m_defaultNamespace); + } + | namespace_selector element_name { + AtomicString namespacePrefix = $1; + CSSParser* p = static_cast<CSSParser*>(parser); + $$ = p->createFloatingSelector(); + if (p->m_styleSheet) + $$->m_tag = QualifiedName(namespacePrefix, $2, + p->m_styleSheet->determineNamespace(namespacePrefix)); + else // FIXME: Shouldn't this case be an error? + $$->m_tag = QualifiedName(nullAtom, $2, p->m_defaultNamespace); + } + | namespace_selector element_name specifier_list { + $$ = $3; + if ($$) { + AtomicString namespacePrefix = $1; + CSSParser* p = static_cast<CSSParser*>(parser); + if (p->m_styleSheet) + $$->m_tag = QualifiedName(namespacePrefix, $2, + p->m_styleSheet->determineNamespace(namespacePrefix)); + else // FIXME: Shouldn't this case be an error? + $$->m_tag = QualifiedName(nullAtom, $2, p->m_defaultNamespace); + } + } + | namespace_selector specifier_list { + $$ = $2; + if ($$) { + AtomicString namespacePrefix = $1; + CSSParser* p = static_cast<CSSParser*>(parser); + if (p->m_styleSheet) + $$->m_tag = QualifiedName(namespacePrefix, starAtom, + p->m_styleSheet->determineNamespace(namespacePrefix)); + } + } + ; + +element_name: + IDENT { + CSSParserString& str = $1; + CSSParser* p = static_cast<CSSParser*>(parser); + Document* doc = p->document(); + if (doc && doc->isHTMLDocument()) + str.lower(); + $$ = str; + } + | '*' { + static UChar star = '*'; + $$.characters = ☆ + $$.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->tagHistory()) + end = end->tagHistory(); + end->m_relation = CSSSelector::SubSelector; + end->setTagHistory(p->sinkFloatingSelector($2)); + } + } + | specifier_list error { + $$ = 0; + } +; + +specifier: + IDSEL { + CSSParser* p = static_cast<CSSParser*>(parser); + $$ = p->createFloatingSelector(); + $$->m_match = CSSSelector::Id; + if (!p->m_strict) + $1.lower(); + $$->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->m_strict) + $1.lower(); + $$->m_value = $1; + } + } + | class + | attrib + | pseudo + ; + +class: + '.' IDENT { + CSSParser* p = static_cast<CSSParser*>(parser); + $$ = p->createFloatingSelector(); + $$->m_match = CSSSelector::Class; + if (!p->m_strict) + $2.lower(); + $$->m_value = $2; + } + ; + +attr_name: + IDENT maybe_space { + CSSParserString& 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(); + $$->setAttribute(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(); + $$->setAttribute(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(); + $$->setAttribute(QualifiedName(namespacePrefix, $4, + p->m_styleSheet->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(); + $$->setAttribute(QualifiedName(namespacePrefix, $4, + p->m_styleSheet->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; + $$->setArgument($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; + $$->setArgument(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; + $$->setArgument($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; + $$->setSimpleSelector(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 invalid_block_list { + $$ = $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->m_valueList = p->sinkFloatingValueList($4); + int oldParsedProperties = p->m_numParsedProperties; + $$ = p->parseValue($1, $5); + if (!$$) + p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties); + delete p->m_valueList; + p->m_valueList = 0; + } + } + | + variable_reference maybe_space { + CSSParser* p = static_cast<CSSParser*>(parser); + p->m_valueList = new CSSParserValueList; + p->m_valueList->addValue(p->sinkFloatingValue($1)); + int oldParsedProperties = p->m_numParsedProperties; + $$ = p->parseValue(CSSPropertyWebkitVariableDeclarationBlock, false); + if (!$$) + p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties); + delete p->m_valueList; + p->m_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; + } + | + property ':' maybe_space expr prio error { + /* When we encounter something like p {color: red !important fail;} we should drop the declaration */ + $$ = 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 invalid_block { + /* if we come across: div { color{;color:maroon} }, ignore everything within curly brackets */ + $$ = 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) { + CSSParserValue v; + v.id = 0; + v.unit = CSSParserValue::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_PARSER_HEXCOLOR; } + | '#' maybe_space { $$.id = 0; $$.string = CSSParserString(); $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* 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; + } + | variable_reference maybe_space { + $$ = $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; } + | TURNS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_TURN; } + | 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 = CSSParserValue::Q_EMS; } + | EXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EXS; } + ; + +variable_reference: + VARCALL { + $$.id = 0; + $$.string = $1; + $$.unit = CSSPrimitiveValue::CSS_PARSER_VARIABLE_FUNCTION_SYNTAX; + } + ; + +function: + FUNCTION maybe_space expr ')' maybe_space { + CSSParser* p = static_cast<CSSParser*>(parser); + CSSParserFunction* f = p->createFloatingFunction(); + f->name = $1; + f->args = p->sinkFloatingValueList($3); + $$.id = 0; + $$.unit = CSSParserValue::Function; + $$.function = f; + } | + FUNCTION maybe_space error { + CSSParser* p = static_cast<CSSParser*>(parser); + CSSParserFunction* f = p->createFloatingFunction(); + f->name = $1; + f->args = 0; + $$.id = 0; + $$.unit = CSSParserValue::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 */ + +save_block: + closing_brace { + $$ = 0; + } + | error closing_brace { + $$ = 0; + } + ; + +invalid_at: + ATKEYWORD error invalid_block { + $$ = 0; + } + | ATKEYWORD error ';' { + $$ = 0; + } + ; + +invalid_at_list: + invalid_at maybe_sgml + | invalid_at_list invalid_at maybe_sgml + ; + +invalid_import: + import { + $$ = 0; + } + ; + +invalid_media: + media { + $$ = 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 closing_brace + | '{' error closing_brace + ; + +invalid_block_list: + invalid_block + | invalid_block_list error invalid_block +; + +%% diff --git a/src/3rdparty/webkit/WebCore/css/CSSHelper.cpp b/src/3rdparty/webkit/WebCore/css/CSSHelper.cpp new file mode 100644 index 0000000..aa1186c --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSHelper.h b/src/3rdparty/webkit/WebCore/css/CSSHelper.h new file mode 100644 index 0000000..7f32d88 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSHelper.h @@ -0,0 +1,42 @@ +/* + * 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; + +} // namespace WebCore + +#endif // CSSHelper_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSImageGeneratorValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSImageGeneratorValue.cpp new file mode 100644 index 0000000..6e23d95 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSImageGeneratorValue.cpp @@ -0,0 +1,97 @@ +/* + * 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 "CSSImageGeneratorValue.h" + +#include "Image.h" +#include "IntSize.h" +#include "IntSizeHash.h" +#include "PlatformString.h" +#include "RenderObject.h" +#include "StyleGeneratedImage.h" + +namespace WebCore { + +CSSImageGeneratorValue::CSSImageGeneratorValue() +: m_accessedImage(false) +{ +} + +CSSImageGeneratorValue::~CSSImageGeneratorValue() +{ +} + +void CSSImageGeneratorValue::addClient(RenderObject* renderer, const IntSize& size) +{ + ref(); + if (!size.isEmpty()) + m_sizes.add(size); + m_clients.add(renderer, size); +} + +void CSSImageGeneratorValue::removeClient(RenderObject* renderer) +{ + IntSize size = m_clients.get(renderer); + if (!size.isEmpty()) { + m_sizes.remove(size); + if (!m_sizes.contains(size)) + m_images.remove(size); + } + m_clients.remove(renderer); + deref(); +} + +Image* CSSImageGeneratorValue::getImage(RenderObject* renderer, const IntSize& size) +{ + IntSize oldSize = m_clients.get(renderer); + if (oldSize != size) { + removeClient(renderer); + addClient(renderer, size); + } + + // Don't generate an image for empty sizes. + if (size.isEmpty()) + return 0; + + // Look up the image in our cache. + return m_images.get(size).get(); +} + +void CSSImageGeneratorValue::putImage(const IntSize& size, PassRefPtr<Image> image) +{ + m_images.add(size, image); +} + +StyleGeneratedImage* CSSImageGeneratorValue::generatedImage() +{ + if (!m_accessedImage) { + m_accessedImage = true; + m_image = StyleGeneratedImage::create(this, isFixedSize()); + } + return m_image.get(); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSImageGeneratorValue.h b/src/3rdparty/webkit/WebCore/css/CSSImageGeneratorValue.h new file mode 100644 index 0000000..661fd37 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSImageGeneratorValue.h @@ -0,0 +1,73 @@ +/* + * 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 CSSImageGeneratorValue_h +#define CSSImageGeneratorValue_h + +#include "CSSValue.h" +#include "IntSizeHash.h" +#include <wtf/HashMap.h> +#include <wtf/HashCountedSet.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class Image; +class StyleGeneratedImage; +class RenderObject; + +class CSSImageGeneratorValue : public CSSValue { +public: + virtual ~CSSImageGeneratorValue(); + + void addClient(RenderObject*, const IntSize&); + void removeClient(RenderObject*); + virtual Image* image(RenderObject*, const IntSize&) = 0; + + StyleGeneratedImage* generatedImage(); + + virtual bool isFixedSize() const { return false; } + virtual IntSize fixedSize(const RenderObject*) { return IntSize(); } + +protected: + CSSImageGeneratorValue(); + + Image* getImage(RenderObject*, const IntSize&); + void putImage(const IntSize&, PassRefPtr<Image>); + + HashCountedSet<IntSize> m_sizes; // A count of how many times a given image size is in use. + HashMap<RenderObject*, IntSize> m_clients; // A map from RenderObjects to image sizes. + HashMap<IntSize, RefPtr<Image> > m_images; // A cache of Image objects by image size. + + RefPtr<StyleGeneratedImage> m_image; + bool m_accessedImage; + +private: + virtual bool isImageGeneratorValue() const { return true; } +}; + +} // namespace WebCore + +#endif // CSSImageGeneratorValue_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSImageValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSImageValue.cpp new file mode 100644 index 0000000..7fc99bb --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSImageValue.cpp @@ -0,0 +1,93 @@ +/* + * (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" +#include "RenderStyle.h" +#include "StyleCachedImage.h" + +namespace WebCore { + +CSSImageValue::CSSImageValue(const String& url) + : CSSPrimitiveValue(url, CSS_URI) + , m_accessedImage(false) +{ +} + +CSSImageValue::CSSImageValue() + : CSSPrimitiveValue(CSSValueNone) + , m_accessedImage(true) +{ +} + +CSSImageValue::~CSSImageValue() +{ + if (m_image) + m_image->cachedImage()->removeClient(this); +} + +StyleCachedImage* CSSImageValue::cachedImage(DocLoader* loader) +{ + return cachedImage(loader, getStringValue()); +} + +StyleCachedImage* CSSImageValue::cachedImage(DocLoader* loader, const String& url) +{ + if (!m_accessedImage) { + m_accessedImage = true; + + CachedImage* cachedImage = 0; + if (loader) + cachedImage = 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. + cachedImage = static_cast<CachedImage*>(cache()->requestResource(0, CachedResource::ImageResource, KURL(url), String())); + } + + if (cachedImage) { + cachedImage->addClient(this); + m_image = StyleCachedImage::create(cachedImage); + } + } + + return m_image.get(); +} + +String CSSImageValue::cachedImageURL() +{ + if (!m_image) + return String(); + return m_image->cachedImage()->url(); +} + +void CSSImageValue::clearCachedImage() +{ + if (m_image) + m_image->cachedImage()->removeClient(this); + m_image = 0; + m_accessedImage = false; +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSImageValue.h b/src/3rdparty/webkit/WebCore/css/CSSImageValue.h new file mode 100644 index 0000000..a1715cd --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSImageValue.h @@ -0,0 +1,59 @@ +/* + * (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 CSSImageValue_h +#define CSSImageValue_h + +#include "CSSPrimitiveValue.h" +#include "CachedResourceClient.h" +#include <wtf/RefPtr.h> + +namespace WebCore { + +class DocLoader; +class StyleCachedImage; + +class CSSImageValue : public CSSPrimitiveValue, private CachedResourceClient { +public: + static PassRefPtr<CSSImageValue> create() { return adoptRef(new CSSImageValue); } + static PassRefPtr<CSSImageValue> create(const String& url) { return adoptRef(new CSSImageValue(url)); } + virtual ~CSSImageValue(); + + virtual StyleCachedImage* cachedImage(DocLoader*); + + virtual bool isImageValue() const { return true; } + +protected: + CSSImageValue(const String& url); + + StyleCachedImage* cachedImage(DocLoader*, const String& url); + String cachedImageURL(); + void clearCachedImage(); + +private: + CSSImageValue(); + + RefPtr<StyleCachedImage> m_image; + bool m_accessedImage; +}; + +} // namespace WebCore + +#endif // CSSImageValue_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSImportRule.cpp b/src/3rdparty/webkit/WebCore/css/CSSImportRule.cpp new file mode 100644 index 0000000..50e60f4 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSImportRule.cpp @@ -0,0 +1,132 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2002-2003 Dirk Mueller (mueller@kde.org) + * Copyright (C) 2002, 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 "CSSImportRule.h" + +#include "CachedCSSStyleSheet.h" +#include "DocLoader.h" +#include "Document.h" +#include "MediaList.h" + +namespace WebCore { + +CSSImportRule::CSSImportRule(CSSStyleSheet* parent, const String& href, PassRefPtr<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 = MediaList::create(this, String()); +} + +CSSImportRule::~CSSImportRule() +{ + if (m_lstMedia) + m_lstMedia->setParent(0); + if (m_styleSheet) + m_styleSheet->setParent(0); + if (m_cachedSheet) + m_cachedSheet->removeClient(this); +} + +void CSSImportRule::setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet* sheet) +{ + if (m_styleSheet) + m_styleSheet->setParent(0); + m_styleSheet = CSSStyleSheet::create(this, url, charset); + + CSSStyleSheet* parent = parentStyleSheet(); + bool strict = !parent || parent->useStrictParsing(); + m_styleSheet->parseString(sheet->sheetText(strict), strict); + m_loading = false; + + if (parent) + parent->checkLoaded(); +} + +bool CSSImportRule::isLoading() const +{ + return m_loading || (m_styleSheet && m_styleSheet->isLoading()); +} + +void CSSImportRule::insertedIntoParent() +{ + CSSStyleSheet* parentSheet = parentStyleSheet(); + if (!parentSheet) + return; + + DocLoader* docLoader = parentSheet->doc()->docLoader(); + if (!docLoader) + return; + + String absHref = m_strHref; + 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. + StyleBase* root = this; + for (StyleBase* curr = parent(); curr; curr = curr->parent()) { + if (curr->isCSSStyleSheet() && absHref == static_cast<CSSStyleSheet*>(curr)->href()) + return; + root = curr; + } + + 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() && root == parentSheet) + parentSheet->doc()->addPendingSheet(); + m_loading = true; + m_cachedSheet->addClient(this); + } +} + +String CSSImportRule::cssText() const +{ + String result = "@import url(\""; + result += m_strHref; + result += "\")"; + + if (m_lstMedia) { + result += " "; + result += m_lstMedia->mediaText(); + } + result += ";"; + + return result; +} + +void CSSImportRule::addSubresourceStyleURLs(ListHashSet<KURL>& urls) +{ + if (m_styleSheet) + addSubresourceURL(urls, m_styleSheet->baseURL()); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSImportRule.h b/src/3rdparty/webkit/WebCore/css/CSSImportRule.h new file mode 100644 index 0000000..f546006 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSImportRule.h @@ -0,0 +1,77 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2002-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. + */ + +#ifndef CSSImportRule_h +#define CSSImportRule_h + +#include "CSSRule.h" +#include "CachedResourceClient.h" +#include "CachedResourceHandle.h" +#include "MediaList.h" +#include "PlatformString.h" + +namespace WebCore { + +class CachedCSSStyleSheet; +class MediaList; + +class CSSImportRule : public CSSRule, private CachedResourceClient { +public: + static PassRefPtr<CSSImportRule> create(CSSStyleSheet* parent, const String& href, PassRefPtr<MediaList> media) + { + return adoptRef(new CSSImportRule(parent, href, media)); + } + + virtual ~CSSImportRule(); + + String href() const { return m_strHref; } + MediaList* media() const { return m_lstMedia.get(); } + CSSStyleSheet* styleSheet() const { return m_styleSheet.get(); } + + virtual String cssText() const; + + // Not part of the CSSOM + bool isLoading() const; + + virtual void addSubresourceStyleURLs(ListHashSet<KURL>& urls); + +private: + CSSImportRule(CSSStyleSheet* parent, const String& href, PassRefPtr<MediaList>); + + virtual bool isImportRule() { return true; } + virtual void insertedIntoParent(); + + // from CSSRule + virtual unsigned short type() const { return IMPORT_RULE; } + + // from CachedResourceClient + virtual void setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet*); + + String m_strHref; + RefPtr<MediaList> m_lstMedia; + RefPtr<CSSStyleSheet> m_styleSheet; + CachedResourceHandle<CachedCSSStyleSheet> m_cachedSheet; + bool m_loading; +}; + +} // namespace WebCore + +#endif // CSSImportRule_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSImportRule.idl b/src/3rdparty/webkit/WebCore/css/CSSImportRule.idl new file mode 100644 index 0000000..454553e --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSInheritedValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSInheritedValue.cpp new file mode 100644 index 0000000..08d3db3 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSInheritedValue.h b/src/3rdparty/webkit/WebCore/css/CSSInheritedValue.h new file mode 100644 index 0000000..e015a98 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSInheritedValue.h @@ -0,0 +1,45 @@ +/* + * (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 CSSInheritedValue_h +#define CSSInheritedValue_h + +#include "CSSValue.h" +#include <wtf/PassRefPtr.h> + +namespace WebCore { + +class CSSInheritedValue : public CSSValue { +public: + static PassRefPtr<CSSInheritedValue> create() + { + return adoptRef(new CSSInheritedValue); + } + + virtual String cssText() const; + +private: + CSSInheritedValue() { } + virtual unsigned short cssValueType() const; +}; + +} // namespace WebCore + +#endif // CSSInheritedValue_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSInitialValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSInitialValue.cpp new file mode 100644 index 0000000..9c2bb23 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSInitialValue.h b/src/3rdparty/webkit/WebCore/css/CSSInitialValue.h new file mode 100644 index 0000000..96bc2a5 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSInitialValue.h @@ -0,0 +1,58 @@ +/* + * (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 CSSInitialValue_h +#define CSSInitialValue_h + +#include "CSSValue.h" +#include <wtf/PassRefPtr.h> + +namespace WebCore { + +class CSSInitialValue : public CSSValue { +public: + static PassRefPtr<CSSInitialValue> createExplicit() + { + static CSSInitialValue* explicitValue = new CSSInitialValue(false); + return explicitValue; + } + static PassRefPtr<CSSInitialValue> createImplicit() + { + static CSSInitialValue* explicitValue = new CSSInitialValue(true); + return explicitValue; + } + + virtual String cssText() const; + +private: + CSSInitialValue(bool implicit) + : m_implicit(implicit) + { + } + + virtual unsigned short cssValueType() const; + virtual bool isImplicitInitialValue() const { return m_implicit; } + + bool m_implicit; +}; + +} // namespace WebCore + +#endif // CSSInitialValue_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSMediaRule.cpp b/src/3rdparty/webkit/WebCore/css/CSSMediaRule.cpp new file mode 100644 index 0000000..610e988 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSMediaRule.cpp @@ -0,0 +1,133 @@ +/** + * 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 "ExceptionCode.h" + +namespace WebCore { + +CSSMediaRule::CSSMediaRule(CSSStyleSheet* parent, PassRefPtr<MediaList> media, PassRefPtr<CSSRuleList> rules) + : CSSRule(parent) + , m_lstMedia(media) + , m_lstCSSRules(rules) +{ +} + +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/src/3rdparty/webkit/WebCore/css/CSSMediaRule.h b/src/3rdparty/webkit/WebCore/css/CSSMediaRule.h new file mode 100644 index 0000000..5eead7c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSMediaRule.h @@ -0,0 +1,69 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2002-2003 Dirk Mueller (mueller@kde.org) + * Copyright (C) 2002, 2006, 2008 Apple Inc. All rights reserved. + * 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 "CSSRuleList.h" +#include "MediaList.h" +#include "PlatformString.h" // needed so bindings will compile + +namespace WebCore { + +class CSSRuleList; +class MediaList; + +class CSSMediaRule : public CSSRule { +public: + static PassRefPtr<CSSMediaRule> create(CSSStyleSheet* parent, PassRefPtr<MediaList> media, PassRefPtr<CSSRuleList> rules) + { + return adoptRef(new CSSMediaRule(parent, media, rules)); + } + virtual ~CSSMediaRule(); + + 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&); + + virtual String cssText() const; + + // Not part of the CSSOM + unsigned append(CSSRule*); + +private: + CSSMediaRule(CSSStyleSheet* parent, PassRefPtr<MediaList>, PassRefPtr<CSSRuleList>); + + virtual bool isMediaRule() { return true; } + + // Inherited from CSSRule + virtual unsigned short type() const { return MEDIA_RULE; } + + RefPtr<MediaList> m_lstMedia; + RefPtr<CSSRuleList> m_lstCSSRules; +}; + +} // namespace WebCore + +#endif // CSSMediaRule_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSMediaRule.idl b/src/3rdparty/webkit/WebCore/css/CSSMediaRule.idl new file mode 100644 index 0000000..1347171 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSMutableStyleDeclaration.cpp b/src/3rdparty/webkit/WebCore/css/CSSMutableStyleDeclaration.cpp new file mode 100644 index 0000000..6b12ced --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSMutableStyleDeclaration.cpp @@ -0,0 +1,951 @@ +/* + * (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 "CSSRule.h" +#include "CSSStyleSheet.h" +#include "CSSValueList.h" +#include "Document.h" +#include "ExceptionCode.h" +#include "StyledElement.h" +#include <wtf/StdLibExtras.h> + +using namespace std; + +namespace WebCore { + +CSSMutableStyleDeclaration::CSSMutableStyleDeclaration() + : m_node(0) + , m_variableDependentValueCount(0) + , m_strictParsing(false) +#ifndef NDEBUG + , m_iteratorCount(0) +#endif +{ +} + +CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent) + : CSSStyleDeclaration(parent) + , m_node(0) + , m_variableDependentValueCount(0) + , m_strictParsing(!parent || parent->useStrictParsing()) +#ifndef NDEBUG + , m_iteratorCount(0) +#endif +{ +} + +CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const Vector<CSSProperty>& properties, unsigned variableDependentValueCount) + : CSSStyleDeclaration(parent) + , m_properties(properties) + , m_node(0) + , m_variableDependentValueCount(variableDependentValueCount) + , m_strictParsing(!parent || parent->useStrictParsing()) +#ifndef NDEBUG + , m_iteratorCount(0) +#endif +{ + m_properties.shrinkToFit(); + // FIXME: This allows duplicate properties. +} + +CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const CSSProperty* const * properties, int numProperties) + : CSSStyleDeclaration(parent) + , m_node(0) + , m_variableDependentValueCount(0) + , m_strictParsing(!parent || parent->useStrictParsing()) +#ifndef NDEBUG + , m_iteratorCount(0) +#endif +{ + m_properties.reserveCapacity(numProperties); + for (int i = 0; i < numProperties; ++i) { + ASSERT(properties[i]); + m_properties.append(*properties[i]); + if (properties[i]->value()->isVariableDependentValue()) + m_variableDependentValueCount++; + } + // FIXME: This allows duplicate properties. +} + +CSSMutableStyleDeclaration& CSSMutableStyleDeclaration::operator=(const CSSMutableStyleDeclaration& other) +{ + ASSERT(!m_iteratorCount); + // don't attach it to the same node, just leave the current m_node value + m_properties = other.m_properties; + m_strictParsing = other.m_strictParsing; + 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 CSSPropertyBackgroundPosition: { + // FIXME: Is this correct? The code in cssparser.cpp is confusing + const int properties[2] = { CSSPropertyBackgroundPositionX, + CSSPropertyBackgroundPositionY }; + return getLayeredShorthandValue(properties, 2); + } + case CSSPropertyBackground: { + const int properties[7] = { CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat, + CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition, CSSPropertyWebkitBackgroundClip, + CSSPropertyWebkitBackgroundOrigin, CSSPropertyBackgroundColor }; + return getLayeredShorthandValue(properties, 7); + } + case CSSPropertyBorder: { + const int properties[3][4] = {{ CSSPropertyBorderTopWidth, + CSSPropertyBorderRightWidth, + CSSPropertyBorderBottomWidth, + CSSPropertyBorderLeftWidth }, + { CSSPropertyBorderTopStyle, + CSSPropertyBorderRightStyle, + CSSPropertyBorderBottomStyle, + CSSPropertyBorderLeftStyle }, + { CSSPropertyBorderTopColor, + CSSPropertyBorderRightColor, + CSSPropertyBorderBottomColor, + CSSPropertyBorderLeftColor }}; + String res; + const int nrprops = sizeof(properties) / sizeof(properties[0]); + for (int i = 0; i < nrprops; ++i) { + String value = getCommonValue(properties[i], 4); + if (!value.isNull()) { + if (!res.isNull()) + res += " "; + res += value; + } + } + return res; + } + case CSSPropertyBorderTop: { + const int properties[3] = { CSSPropertyBorderTopWidth, CSSPropertyBorderTopStyle, + CSSPropertyBorderTopColor}; + return getShorthandValue(properties, 3); + } + case CSSPropertyBorderRight: { + const int properties[3] = { CSSPropertyBorderRightWidth, CSSPropertyBorderRightStyle, + CSSPropertyBorderRightColor}; + return getShorthandValue(properties, 3); + } + case CSSPropertyBorderBottom: { + const int properties[3] = { CSSPropertyBorderBottomWidth, CSSPropertyBorderBottomStyle, + CSSPropertyBorderBottomColor}; + return getShorthandValue(properties, 3); + } + case CSSPropertyBorderLeft: { + const int properties[3] = { CSSPropertyBorderLeftWidth, CSSPropertyBorderLeftStyle, + CSSPropertyBorderLeftColor}; + return getShorthandValue(properties, 3); + } + case CSSPropertyOutline: { + const int properties[3] = { CSSPropertyOutlineWidth, CSSPropertyOutlineStyle, + CSSPropertyOutlineColor }; + return getShorthandValue(properties, 3); + } + case CSSPropertyBorderColor: { + const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, + CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor }; + return get4Values(properties); + } + case CSSPropertyBorderWidth: { + const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, + CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth }; + return get4Values(properties); + } + case CSSPropertyBorderStyle: { + const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, + CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle }; + return get4Values(properties); + } + case CSSPropertyMargin: { + const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, + CSSPropertyMarginBottom, CSSPropertyMarginLeft }; + return get4Values(properties); + } + case CSSPropertyOverflow: { + const int properties[2] = { CSSPropertyOverflowX, CSSPropertyOverflowY }; + return getCommonValue(properties, 2); + } + case CSSPropertyPadding: { + const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, + CSSPropertyPaddingBottom, CSSPropertyPaddingLeft }; + return get4Values(properties); + } + case CSSPropertyListStyle: { + const int properties[3] = { CSSPropertyListStyleType, CSSPropertyListStylePosition, + CSSPropertyListStyleImage }; + return getShorthandValue(properties, 3); + } + case CSSPropertyWebkitMaskPosition: { + // FIXME: Is this correct? The code in cssparser.cpp is confusing + const int properties[2] = { CSSPropertyWebkitMaskPositionX, + CSSPropertyWebkitMaskPositionY }; + return getLayeredShorthandValue(properties, 2); + } + case CSSPropertyWebkitMask: { + const int properties[] = { CSSPropertyWebkitMaskImage, CSSPropertyWebkitMaskRepeat, + CSSPropertyWebkitMaskAttachment, CSSPropertyWebkitMaskPosition, CSSPropertyWebkitMaskClip, + CSSPropertyWebkitMaskOrigin }; + return getLayeredShorthandValue(properties, 6); + } + case CSSPropertyWebkitTransformOrigin: { + const int properties[2] = { CSSPropertyWebkitTransformOriginX, + CSSPropertyWebkitTransformOriginY }; + return getShorthandValue(properties, 2); + } + case CSSPropertyWebkitTransition: { + const int properties[4] = { CSSPropertyWebkitTransitionProperty, CSSPropertyWebkitTransitionDuration, + CSSPropertyWebkitTransitionTimingFunction, CSSPropertyWebkitTransitionDelay }; + return getLayeredShorthandValue(properties, 4); + } + case CSSPropertyWebkitAnimation: { + const int properties[6] = { CSSPropertyWebkitAnimationName, CSSPropertyWebkitAnimationDuration, + CSSPropertyWebkitAnimationTimingFunction, CSSPropertyWebkitAnimationDelay, + CSSPropertyWebkitAnimationIterationCount, CSSPropertyWebkitAnimationDirection }; + return getLayeredShorthandValue(properties, 6); + } +#if ENABLE(SVG) + case CSSPropertyMarker: { + RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyMarkerStart); + if (value) + return value->cssText(); + } +#endif + } + 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; + + // Begin by collecting the properties into an array. + Vector< RefPtr<CSSValue> > values(number); + size_t numLayers = 0; + + for (size_t 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<size_t>(1U, numLayers); + } + } + + // Now stitch the properties together. Implicit initial values are flagged as such and + // can safely be omitted. + for (size_t i = 0; i < numLayers; i++) { + String layerRes; + for (size_t j = 0; j < number; j++) { + RefPtr<CSSValue> value; + if (values[j]) { + if (values[j]->isValueList()) + value = static_cast<CSSValueList*>(values[j].get())->itemWithoutBoundsCheck(i); + else { + value = values[j]; + + // Color only belongs in the last layer. + if (properties[j] == CSSPropertyBackgroundColor) { + 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; +} + +// only returns a non-null value if all properties have the same, non-null value +String CSSMutableStyleDeclaration::getCommonValue(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]); + if (!value) + return String(); + String text = value->cssText(); + if (text.isNull()) + return String(); + if (res.isNull()) + res = text; + else if (res != text) + return String(); + } + } + return res; +} + +PassRefPtr<CSSValue> CSSMutableStyleDeclaration::getPropertyCSSValue(int propertyID) const +{ + const CSSProperty* property = findPropertyWithId(propertyID); + return property ? property->value() : 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; +}; + +typedef HashMap<int, PropertyLonghand> ShorthandMap; + +static void initShorthandMap(ShorthandMap& 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] = { + { CSSPropertyBorderTopColor, CSSPropertyBorderTopStyle, CSSPropertyBorderTopWidth }, + { CSSPropertyBorderRightColor, CSSPropertyBorderRightStyle, CSSPropertyBorderRightWidth }, + { CSSPropertyBorderBottomColor, CSSPropertyBorderBottomStyle, CSSPropertyBorderBottomWidth }, + { CSSPropertyBorderLeftColor, CSSPropertyBorderLeftStyle, CSSPropertyBorderLeftWidth } + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderTop, borderProperties[0]); + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderRight, borderProperties[1]); + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderBottom, borderProperties[2]); + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderLeft, borderProperties[3]); + + shorthandMap.set(CSSPropertyBorder, PropertyLonghand(borderProperties[0], sizeof(borderProperties) / sizeof(borderProperties[0][0]))); + + static const int borderColorProperties[] = { + CSSPropertyBorderTopColor, + CSSPropertyBorderRightColor, + CSSPropertyBorderBottomColor, + CSSPropertyBorderLeftColor + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderColor, borderColorProperties); + + static const int borderStyleProperties[] = { + CSSPropertyBorderTopStyle, + CSSPropertyBorderRightStyle, + CSSPropertyBorderBottomStyle, + CSSPropertyBorderLeftStyle + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderStyle, borderStyleProperties); + + static const int borderWidthProperties[] = { + CSSPropertyBorderTopWidth, + CSSPropertyBorderRightWidth, + CSSPropertyBorderBottomWidth, + CSSPropertyBorderLeftWidth + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderWidth, borderWidthProperties); + + static const int backgroundPositionProperties[] = { CSSPropertyBackgroundPositionX, CSSPropertyBackgroundPositionY }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBackgroundPosition, backgroundPositionProperties); + + static const int borderSpacingProperties[] = { CSSPropertyWebkitBorderHorizontalSpacing, CSSPropertyWebkitBorderVerticalSpacing }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderSpacing, borderSpacingProperties); + + static const int listStyleProperties[] = { + CSSPropertyListStyleImage, + CSSPropertyListStylePosition, + CSSPropertyListStyleType + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyListStyle, listStyleProperties); + + static const int marginProperties[] = { + CSSPropertyMarginTop, + CSSPropertyMarginRight, + CSSPropertyMarginBottom, + CSSPropertyMarginLeft + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyMargin, marginProperties); + + static const int marginCollapseProperties[] = { CSSPropertyWebkitMarginTopCollapse, CSSPropertyWebkitMarginBottomCollapse }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitMarginCollapse, marginCollapseProperties); + + static const int marqueeProperties[] = { + CSSPropertyWebkitMarqueeDirection, + CSSPropertyWebkitMarqueeIncrement, + CSSPropertyWebkitMarqueeRepetition, + CSSPropertyWebkitMarqueeStyle, + CSSPropertyWebkitMarqueeSpeed + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitMarquee, marqueeProperties); + + static const int outlineProperties[] = { + CSSPropertyOutlineColor, + CSSPropertyOutlineOffset, + CSSPropertyOutlineStyle, + CSSPropertyOutlineWidth + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyOutline, outlineProperties); + + static const int paddingProperties[] = { + CSSPropertyPaddingTop, + CSSPropertyPaddingRight, + CSSPropertyPaddingBottom, + CSSPropertyPaddingLeft + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyPadding, paddingProperties); + + static const int textStrokeProperties[] = { CSSPropertyWebkitTextStrokeColor, CSSPropertyWebkitTextStrokeWidth }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitTextStroke, textStrokeProperties); + + static const int backgroundProperties[] = { + CSSPropertyBackgroundAttachment, + CSSPropertyWebkitBackgroundClip, + CSSPropertyBackgroundColor, + CSSPropertyBackgroundImage, + CSSPropertyWebkitBackgroundOrigin, + CSSPropertyBackgroundPositionX, + CSSPropertyBackgroundPositionY, + CSSPropertyBackgroundRepeat, + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBackground, backgroundProperties); + + static const int columnsProperties[] = { CSSPropertyWebkitColumnWidth, CSSPropertyWebkitColumnCount }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitColumns, columnsProperties); + + static const int columnRuleProperties[] = { + CSSPropertyWebkitColumnRuleColor, + CSSPropertyWebkitColumnRuleStyle, + CSSPropertyWebkitColumnRuleWidth + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitColumnRule, columnRuleProperties); + + static const int overflowProperties[] = { CSSPropertyOverflowX, CSSPropertyOverflowY }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyOverflow, overflowProperties); + + static const int borderRadiusProperties[] = { + CSSPropertyWebkitBorderTopRightRadius, + CSSPropertyWebkitBorderTopLeftRadius, + CSSPropertyWebkitBorderBottomLeftRadius, + CSSPropertyWebkitBorderBottomRightRadius + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitBorderRadius, borderRadiusProperties); + + static const int maskPositionProperties[] = { CSSPropertyWebkitMaskPositionX, CSSPropertyWebkitMaskPositionY }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitMaskPosition, maskPositionProperties); + + static const int maskProperties[] = { + CSSPropertyWebkitMaskAttachment, + CSSPropertyWebkitMaskClip, + CSSPropertyWebkitMaskImage, + CSSPropertyWebkitMaskOrigin, + CSSPropertyWebkitMaskPositionX, + CSSPropertyWebkitMaskPositionY, + CSSPropertyWebkitMaskRepeat, + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitMask, maskProperties); + + static const int animationProperties[] = { + CSSPropertyWebkitAnimationName, + CSSPropertyWebkitAnimationDuration, + CSSPropertyWebkitAnimationTimingFunction, + CSSPropertyWebkitAnimationDelay, + CSSPropertyWebkitAnimationIterationCount, + CSSPropertyWebkitAnimationDirection + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitAnimation, animationProperties); + + static const int transitionProperties[] = { + CSSPropertyWebkitTransitionProperty, + CSSPropertyWebkitTransitionDuration, + CSSPropertyWebkitTransitionTimingFunction, + CSSPropertyWebkitTransitionDelay + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitTransition, transitionProperties); + + static const int transformOriginProperties[] = { + CSSPropertyWebkitTransformOriginX, + CSSPropertyWebkitTransformOriginY + }; + SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitTransformOrigin, transformOriginProperties); + + #undef SET_SHORTHAND_MAP_ENTRY +} + +bool CSSMutableStyleDeclaration::removeShorthandProperty(int propertyID, bool notifyChanged) +{ + DEFINE_STATIC_LOCAL(ShorthandMap, shorthandMap, ()); + if (shorthandMap.isEmpty()) + initShorthandMap(shorthandMap); + + PropertyLonghand longhand = shorthandMap.get(propertyID); + if (longhand.length()) { + removePropertiesInSet(longhand.properties(), longhand.length(), notifyChanged); + return true; + } + return false; +} + +String CSSMutableStyleDeclaration::removeProperty(int propertyID, bool notifyChanged, bool returnText) +{ + ASSERT(!m_iteratorCount); + + if (removeShorthandProperty(propertyID, notifyChanged)) { + // FIXME: Return an equivalent shorthand when possible. + return String(); + } + + CSSProperty* foundProperty = findPropertyWithId(propertyID); + if (!foundProperty) + return String(); + + String value = returnText ? foundProperty->value()->cssText() : String(); + + if (foundProperty->value()->isVariableDependentValue()) + m_variableDependentValueCount--; + + // A more efficient removal strategy would involve marking entries as empty + // and sweeping them when the vector grows too big. + m_properties.remove(foundProperty - m_properties.data()); + + if (notifyChanged) + setChanged(); + + return value; +} + +void CSSMutableStyleDeclaration::setChanged() +{ + if (m_node) { + // FIXME: Ideally, this should be factored better and there + // should be a subclass of CSSMutableStyleDeclaration just + // for inline style declarations that handles this + bool isInlineStyleDeclaration = m_node->isStyledElement() && this == static_cast<StyledElement*>(m_node)->inlineStyleDecl(); + if (isInlineStyleDeclaration) { + m_node->setChanged(InlineStyleChange); + static_cast<StyledElement*>(m_node)->invalidateStyleAttribute(); + } else + m_node->setChanged(FullStyleChange); + 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 +{ + const CSSProperty* property = findPropertyWithId(propertyID); + return property ? property->isImportant() : false; +} + +int CSSMutableStyleDeclaration::getPropertyShorthand(int propertyID) const +{ + const CSSProperty* property = findPropertyWithId(propertyID); + return property ? property->shorthandID() : 0; +} + +bool CSSMutableStyleDeclaration::isPropertyImplicit(int propertyID) const +{ + const CSSProperty* property = findPropertyWithId(propertyID); + return property ? property->isImplicit() : false; +} + +void CSSMutableStyleDeclaration::setProperty(int propertyID, const String& value, bool important, ExceptionCode& ec) +{ + ec = 0; + setProperty(propertyID, value, important, true); +} + +String CSSMutableStyleDeclaration::removeProperty(int propertyID, ExceptionCode& ec) +{ + ec = 0; + return removeProperty(propertyID, true, true); +} + +bool CSSMutableStyleDeclaration::setProperty(int propertyID, const String& value, bool important, bool notifyChanged) +{ + ASSERT(!m_iteratorCount); + + // 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); + return true; + } + + // 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(); + + return success; +} + +void CSSMutableStyleDeclaration::setPropertyInternal(const CSSProperty& property, CSSProperty* slot) +{ + ASSERT(!m_iteratorCount); + + if (!removeShorthandProperty(property.id(), false)) { + CSSProperty* toReplace = slot ? slot : findPropertyWithId(property.id()); + if (toReplace) { + *toReplace = property; + return; + } + } + m_properties.append(property); +} + +bool CSSMutableStyleDeclaration::setProperty(int propertyID, int value, bool important, bool notifyChanged) +{ + CSSProperty property(propertyID, CSSPrimitiveValue::createIdentifier(value), important); + setPropertyInternal(property); + if (notifyChanged) + setChanged(); + return true; +} + +void CSSMutableStyleDeclaration::setStringProperty(int propertyId, const String &value, CSSPrimitiveValue::UnitTypes type, bool important) +{ + ASSERT(!m_iteratorCount); + + setPropertyInternal(CSSProperty(propertyId, CSSPrimitiveValue::create(value, type), important)); + setChanged(); +} + +void CSSMutableStyleDeclaration::setImageProperty(int propertyId, const String& url, bool important) +{ + ASSERT(!m_iteratorCount); + + setPropertyInternal(CSSProperty(propertyId, CSSImageValue::create(url), important)); + setChanged(); +} + +void CSSMutableStyleDeclaration::parseDeclaration(const String& styleDeclaration) +{ + ASSERT(!m_iteratorCount); + + m_properties.clear(); + CSSParser parser(useStrictParsing()); + parser.parseDeclaration(this, styleDeclaration); + setChanged(); +} + +void CSSMutableStyleDeclaration::addParsedProperties(const CSSProperty* const* properties, int numProperties) +{ + ASSERT(!m_iteratorCount); + + m_properties.reserveCapacity(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_properties.append(*properties[i]); + if (properties[i]->value()->isVariableDependentValue()) + m_variableDependentValueCount++; + } + } + // 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::addParsedProperty(const CSSProperty& property) +{ + ASSERT(!m_iteratorCount); + + setPropertyInternal(property); +} + +void CSSMutableStyleDeclaration::setLengthProperty(int propertyId, const String& value, bool important, bool /*multiLength*/) +{ + ASSERT(!m_iteratorCount); + + bool parseMode = useStrictParsing(); + setStrictParsing(false); + setProperty(propertyId, value, important); + setStrictParsing(parseMode); +} + +unsigned CSSMutableStyleDeclaration::length() const +{ + return m_properties.size(); +} + +String CSSMutableStyleDeclaration::item(unsigned i) const +{ + if (i >= m_properties.size()) + return String(); + return getPropertyName(static_cast<CSSPropertyID>(m_properties[i].id())); +} + +String CSSMutableStyleDeclaration::cssText() const +{ + String result = ""; + + const CSSProperty* positionXProp = 0; + const CSSProperty* positionYProp = 0; + + unsigned size = m_properties.size(); + for (unsigned n = 0; n < size; ++n) { + const CSSProperty& prop = m_properties[n]; + if (prop.id() == CSSPropertyBackgroundPositionX) + positionXProp = ∝ + else if (prop.id() == CSSPropertyBackgroundPositionY) + positionYProp = ∝ + 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] = { CSSPropertyBackgroundPositionX, CSSPropertyBackgroundPositionY }; + 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) +{ + ASSERT(!m_iteratorCount); + + ec = 0; + m_properties.clear(); + CSSParser parser(useStrictParsing()); + parser.parseDeclaration(this, text); + // FIXME: Detect syntax errors and set ec. + setChanged(); +} + +void CSSMutableStyleDeclaration::merge(CSSMutableStyleDeclaration* other, bool argOverridesOnConflict) +{ + ASSERT(!m_iteratorCount); + + unsigned size = other->m_properties.size(); + for (unsigned n = 0; n < size; ++n) { + CSSProperty& toMerge = other->m_properties[n]; + CSSProperty* old = findPropertyWithId(toMerge.id()); + if (old) { + if (!argOverridesOnConflict && old->value()) + continue; + setPropertyInternal(toMerge, old); + } else + m_properties.append(toMerge); + } + // 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::addSubresourceStyleURLs(ListHashSet<KURL>& urls) +{ + CSSStyleSheet* sheet = static_cast<CSSStyleSheet*>(stylesheet()); + size_t size = m_properties.size(); + for (size_t i = 0; i < size; ++i) + m_properties[i].value()->addSubresourceStyleURLs(urls, sheet); +} + +// 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[] = { + CSSPropertyOrphans, + CSSPropertyOverflow, // This can be also be applied to replaced elements + CSSPropertyWebkitColumnCount, + CSSPropertyWebkitColumnGap, + CSSPropertyWebkitColumnRuleColor, + CSSPropertyWebkitColumnRuleStyle, + CSSPropertyWebkitColumnRuleWidth, + CSSPropertyWebkitColumnBreakBefore, + CSSPropertyWebkitColumnBreakAfter, + CSSPropertyWebkitColumnBreakInside, + CSSPropertyWebkitColumnWidth, + CSSPropertyPageBreakAfter, + CSSPropertyPageBreakBefore, + CSSPropertyPageBreakInside, + CSSPropertyTextAlign, + CSSPropertyTextIndent, + CSSPropertyWidows +}; + +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) +{ + ASSERT(!m_iteratorCount); + + if (m_properties.isEmpty()) + return; + + // FIXME: This is always used with static sets and in that case constructing the hash repeatedly is pretty pointless. + HashSet<int> toRemove; + for (unsigned i = 0; i < length; ++i) + toRemove.add(set[i]); + + Vector<CSSProperty> newProperties; + newProperties.reserveCapacity(m_properties.size()); + + unsigned size = m_properties.size(); + for (unsigned n = 0; n < size; ++n) { + const CSSProperty& property = m_properties[n]; + // Not quite sure if the isImportant test is needed but it matches the existing behavior. + if (!property.isImportant()) { + if (toRemove.contains(property.id())) + continue; + } + newProperties.append(property); + } + + bool changed = newProperties.size() != m_properties.size(); + m_properties = newProperties; + + if (changed && notifyChanged) + setChanged(); +} + +PassRefPtr<CSSMutableStyleDeclaration> CSSMutableStyleDeclaration::makeMutable() +{ + return this; +} + +PassRefPtr<CSSMutableStyleDeclaration> CSSMutableStyleDeclaration::copy() const +{ + return adoptRef(new CSSMutableStyleDeclaration(0, m_properties, m_variableDependentValueCount)); +} + +const CSSProperty* CSSMutableStyleDeclaration::findPropertyWithId(int propertyID) const +{ + for (int n = m_properties.size() - 1 ; n >= 0; --n) { + if (propertyID == m_properties[n].m_id) + return &m_properties[n]; + } + return 0; +} + +CSSProperty* CSSMutableStyleDeclaration::findPropertyWithId(int propertyID) +{ + for (int n = m_properties.size() - 1 ; n >= 0; --n) { + if (propertyID == m_properties[n].m_id) + return &m_properties[n]; + } + return 0; +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSMutableStyleDeclaration.h b/src/3rdparty/webkit/WebCore/css/CSSMutableStyleDeclaration.h new file mode 100644 index 0000000..9c84916 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSMutableStyleDeclaration.h @@ -0,0 +1,222 @@ +/* + * (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 CSSMutableStyleDeclaration_h +#define CSSMutableStyleDeclaration_h + +#include "CSSStyleDeclaration.h" +#include "CSSPrimitiveValue.h" +#include "CSSProperty.h" +#include "KURLHash.h" +#include "PlatformString.h" +#include <wtf/ListHashSet.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class Node; + +class CSSMutableStyleDeclarationConstIterator { +public: + CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclaration* decl, CSSProperty* current); + CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclarationConstIterator& o); + ~CSSMutableStyleDeclarationConstIterator(); + + const CSSProperty& operator*() const { return *m_current; } + const CSSProperty* operator->() const { return m_current; } + + bool operator!=(const CSSMutableStyleDeclarationConstIterator& o) { ASSERT(m_decl == o.m_decl); return m_current != o.m_current; } + bool operator==(const CSSMutableStyleDeclarationConstIterator& o) { ASSERT(m_decl == o.m_decl); return m_current == o.m_current; } + + CSSMutableStyleDeclarationConstIterator& operator=(const CSSMutableStyleDeclarationConstIterator& o); + + CSSMutableStyleDeclarationConstIterator& operator++(); + CSSMutableStyleDeclarationConstIterator& operator--(); + +private: + const CSSMutableStyleDeclaration* m_decl; + CSSProperty* m_current; +}; + +class CSSMutableStyleDeclaration : public CSSStyleDeclaration { +public: + static PassRefPtr<CSSMutableStyleDeclaration> create() + { + return adoptRef(new CSSMutableStyleDeclaration); + } + static PassRefPtr<CSSMutableStyleDeclaration> create(CSSRule* parentRule) + { + return adoptRef(new CSSMutableStyleDeclaration(parentRule)); + } + static PassRefPtr<CSSMutableStyleDeclaration> create(CSSRule* parentRule, const CSSProperty* const* properties, int numProperties) + { + return adoptRef(new CSSMutableStyleDeclaration(parentRule, properties, numProperties)); + } + static PassRefPtr<CSSMutableStyleDeclaration> create(const Vector<CSSProperty>& properties, unsigned variableDependentValueCount) + { + return adoptRef(new CSSMutableStyleDeclaration(0, properties, variableDependentValueCount)); + } + + CSSMutableStyleDeclaration& operator=(const CSSMutableStyleDeclaration&); + + typedef CSSMutableStyleDeclarationConstIterator const_iterator; + + const_iterator begin() { return const_iterator(this, m_properties.begin()); } + const_iterator end() { return const_iterator(this, m_properties.end()); } + + void setNode(Node* node) { m_node = node; } + + virtual bool isMutableStyleDeclaration() const { return true; } + + 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; + + bool setProperty(int propertyID, int value, bool important = false, bool notifyChanged = true); + bool setProperty(int propertyID, const String& value, bool important = false, bool notifyChanged = true); + + String removeProperty(int propertyID, bool notifyChanged = true, bool returnText = false); + + // 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); + // This does no change notifications since it's only called by createMarkup. + void addParsedProperty(const CSSProperty&); + + PassRefPtr<CSSMutableStyleDeclaration> copyBlockProperties() const; + void removeBlockProperties(); + void removePropertiesInSet(const int* set, unsigned length, bool notifyChanged = true); + + void merge(CSSMutableStyleDeclaration*, bool argOverridesOnConflict = true); + + bool hasVariableDependentValue() const { return m_variableDependentValueCount > 0; } + + void setStrictParsing(bool b) { m_strictParsing = b; } + bool useStrictParsing() const { return m_strictParsing; } + + void addSubresourceStyleURLs(ListHashSet<KURL>&); + +protected: + CSSMutableStyleDeclaration(CSSRule* parentRule); + +private: + CSSMutableStyleDeclaration(); + CSSMutableStyleDeclaration(CSSRule* parentRule, const Vector<CSSProperty>&, unsigned variableDependentValueCount); + CSSMutableStyleDeclaration(CSSRule* parentRule, const CSSProperty* const *, int numProperties); + + virtual PassRefPtr<CSSMutableStyleDeclaration> makeMutable(); + + void setChanged(); + + String getShorthandValue(const int* properties, int number) const; + String getCommonValue(const int* properties, int number) const; + String getLayeredShorthandValue(const int* properties, unsigned number) const; + String get4Values(const int* properties) const; + + void setPropertyInternal(const CSSProperty&, CSSProperty* slot = 0); + bool removeShorthandProperty(int propertyID, bool notifyChanged); + + Vector<CSSProperty>::const_iterator findPropertyWithId(int propertyId) const; + Vector<CSSProperty>::iterator findPropertyWithId(int propertyId); + + Vector<CSSProperty> m_properties; + + Node* m_node; + unsigned m_variableDependentValueCount : 24; + bool m_strictParsing : 1; +#ifndef NDEBUG + unsigned m_iteratorCount : 4; +#endif + + friend class CSSMutableStyleDeclarationConstIterator; +}; + +inline CSSMutableStyleDeclarationConstIterator::CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclaration* decl, CSSProperty* current) +: m_decl(decl) +, m_current(current) +{ +#ifndef NDEBUG + const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount++; +#endif +} + +inline CSSMutableStyleDeclarationConstIterator::CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclarationConstIterator& o) +: m_decl(o.m_decl) +, m_current(o.m_current) +{ +#ifndef NDEBUG + const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount++; +#endif +} + +inline CSSMutableStyleDeclarationConstIterator::~CSSMutableStyleDeclarationConstIterator() +{ +#ifndef NDEBUG + const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount--; +#endif +} + +inline CSSMutableStyleDeclarationConstIterator& CSSMutableStyleDeclarationConstIterator::operator=(const CSSMutableStyleDeclarationConstIterator& o) +{ + m_decl = o.m_decl; + m_current = o.m_current; +#ifndef NDEBUG + const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount++; +#endif + return *this; +} + +inline CSSMutableStyleDeclarationConstIterator& CSSMutableStyleDeclarationConstIterator::operator++() +{ + ASSERT(m_current != const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_properties.end()); + ++m_current; + return *this; +} + +inline CSSMutableStyleDeclarationConstIterator& CSSMutableStyleDeclarationConstIterator::operator--() +{ + --m_current; + return *this; +} + +} // namespace WebCore + +#endif // CSSMutableStyleDeclaration_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSNamespace.h b/src/3rdparty/webkit/WebCore/css/CSSNamespace.h new file mode 100644 index 0000000..9194be8 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSPageRule.cpp b/src/3rdparty/webkit/WebCore/css/CSSPageRule.cpp new file mode 100644 index 0000000..6a37963 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSPageRule.cpp @@ -0,0 +1,55 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2002-2003 Dirk Mueller (mueller@kde.org) + * Copyright (C) 2002, 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 "CSSPageRule.h" + +#include "CSSMutableStyleDeclaration.h" + +namespace WebCore { + +CSSPageRule::CSSPageRule(CSSStyleSheet* 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/src/3rdparty/webkit/WebCore/css/CSSPageRule.h b/src/3rdparty/webkit/WebCore/css/CSSPageRule.h new file mode 100644 index 0000000..8e374a5 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSPageRule.h @@ -0,0 +1,60 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2002-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. + */ + +#ifndef CSSPageRule_h +#define CSSPageRule_h + +#include "CSSRule.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class CSSMutableStyleDeclaration; + +class CSSPageRule : public CSSRule { +public: + static PassRefPtr<CSSPageRule> create(CSSStyleSheet* parent) + { + return adoptRef(new CSSPageRule(parent)); + } + + virtual ~CSSPageRule(); + + String selectorText() const; + void setSelectorText(const String&, ExceptionCode&); + + CSSMutableStyleDeclaration* style() const { return m_style.get(); } + + virtual String cssText() const; + +private: + CSSPageRule(CSSStyleSheet* parent); + + // Inherited from CSSRule + virtual unsigned short type() const { return PAGE_RULE; } + + RefPtr<CSSMutableStyleDeclaration> m_style; +}; + +} // namespace WebCore + +#endif // CSSPageRule_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSPageRule.idl b/src/3rdparty/webkit/WebCore/css/CSSPageRule.idl new file mode 100644 index 0000000..3ad570e --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSParser.cpp b/src/3rdparty/webkit/WebCore/css/CSSParser.cpp new file mode 100644 index 0000000..36b86a4 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSParser.cpp @@ -0,0 +1,4849 @@ +/* + * 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. + * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> + * Copyright (C) 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 "CSSParser.h" + +#include "CString.h" +#include "CSSTimingFunctionValue.h" +#include "CSSBorderImageValue.h" +#include "CSSCanvasValue.h" +#include "CSSCharsetRule.h" +#include "CSSCursorImageValue.h" +#include "CSSHelper.h" +#include "CSSImageValue.h" +#include "CSSFontFaceRule.h" +#include "CSSFontFaceSrcValue.h" +#include "CSSGradientValue.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 "CSSReflectValue.h" +#include "CSSRuleList.h" +#include "CSSSelector.h" +#include "CSSStyleRule.h" +#include "CSSStyleSheet.h" +#include "CSSUnicodeRangeValue.h" +#include "CSSValueKeywords.h" +#include "CSSValueList.h" +#include "CSSVariableDependentValue.h" +#include "CSSVariablesDeclaration.h" +#include "CSSVariablesRule.h" +#include "Counter.h" +#include "Document.h" +#include "FloatConversion.h" +#include "FontFamilyValue.h" +#include "FontValue.h" +#include "MediaList.h" +#include "MediaQueryExp.h" +#include "Pair.h" +#include "Rect.h" +#include "ShadowValue.h" +#include "WebKitCSSKeyframeRule.h" +#include "WebKitCSSKeyframesRule.h" +#include "WebKitCSSTransformValue.h" +#include <wtf/dtoa.h> + +#if ENABLE(DASHBOARD_SUPPORT) +#include "DashboardRegion.h" +#endif + +#define YYDEBUG 0 + +#if YYDEBUG > 0 +extern int cssyydebug; +#endif + +extern int cssyyparse(void* parser); + +using namespace std; +using namespace WTF; + +#include "CSSPropertyNames.cpp" +#include "CSSValueKeywords.c" + +namespace WebCore { + +static bool equal(const CSSParserString& 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 CSSParserString& 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; +} + +CSSParser::CSSParser(bool strictParsing) + : m_strict(strictParsing) + , m_important(false) + , m_id(0) + , m_styleSheet(0) + , m_mediaQuery(0) + , m_valueList(0) + , m_parsedProperties(static_cast<CSSProperty**>(fastMalloc(32 * sizeof(CSSProperty*)))) + , m_numParsedProperties(0) + , m_maxParsedProperties(32) + , m_inParseShorthand(0) + , m_currentShorthand(0) + , m_implicitShorthand(false) + , m_hasFontFaceOnlyValues(false) + , m_defaultNamespace(starAtom) + , m_data(0) + , yy_start(1) + , m_floatingMediaQuery(0) + , m_floatingMediaQueryExp(0) + , m_floatingMediaQueryExpList(0) +{ +#if YYDEBUG > 0 + cssyydebug = 1; +#endif +} + +CSSParser::~CSSParser() +{ + clearProperties(); + fastFree(m_parsedProperties); + + clearVariables(); + + delete m_valueList; + + fastFree(m_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); + deleteAllValues(m_reusableSelectorVector); +} + +void CSSParserString::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; + + fastFree(m_data); + m_data = static_cast<UChar*>(fastMalloc(length * sizeof(UChar))); + for (unsigned i = 0; i < strlen(prefix); i++) + m_data[i] = prefix[i]; + + memcpy(m_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++) + m_data[i] = suffix[i - start]; + + m_data[length - 1] = 0; + m_data[length - 2] = 0; + + yy_hold_char = 0; + yyleng = 0; + yytext = yy_c_buf_p = m_data; + yy_hold_char = *yy_c_buf_p; +} + +void CSSParser::parseSheet(CSSStyleSheet* sheet, const String& string) +{ + m_styleSheet = sheet; + m_defaultNamespace = starAtom; // Reset the default namespace. + + setupParser("", string, ""); + cssyyparse(this); + m_rule = 0; +} + +PassRefPtr<CSSRule> CSSParser::parseRule(CSSStyleSheet* sheet, const String& string) +{ + m_styleSheet = sheet; + setupParser("@-webkit-rule{", string, "} "); + cssyyparse(this); + return m_rule.release(); +} + +PassRefPtr<CSSRule> CSSParser::parseKeyframeRule(CSSStyleSheet *sheet, const String &string) +{ + m_styleSheet = sheet; + setupParser("@-webkit-keyframe-rule{ ", string, "} "); + cssyyparse(this); + return m_keyframe.release(); +} + +bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int id, const String& string, bool important) +{ + ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet()); + m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet()); + + setupParser("@-webkit-value{", string, "} "); + + m_id = id; + m_important = important; + + cssyyparse(this); + + m_rule = 0; + + bool ok = false; + if (m_hasFontFaceOnlyValues) + deleteFontFaceOnlyValues(); + if (m_numParsedProperties) { + ok = true; + declaration->addParsedProperties(m_parsedProperties, m_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 = CSSMutableStyleDeclaration::create(); + + // Now try to create a color from the rgb() or rgba() syntax. + if (parser.parseColor(dummyStyleDeclaration.get(), string)) { + CSSValue* value = parser.m_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) +{ + ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet()); + m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet()); + + setupParser("@-webkit-decls{color:", string, "} "); + cssyyparse(this); + m_rule = 0; + + return (m_numParsedProperties && m_parsedProperties[0]->m_id == CSSPropertyColor); +} + +void CSSParser::parseSelector(const String& string, Document* doc, CSSSelectorList& selectorList) +{ + RefPtr<CSSStyleSheet> dummyStyleSheet = CSSStyleSheet::create(doc); + + m_styleSheet = dummyStyleSheet.get(); + m_selectorListForParseSelector = &selectorList; + + setupParser("@-webkit-selector{", string, "}"); + + cssyyparse(this); + + m_selectorListForParseSelector = 0; +} + +bool CSSParser::parseDeclaration(CSSMutableStyleDeclaration* declaration, const String& string) +{ + ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet()); + m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet()); + + setupParser("@-webkit-decls{", string, "} "); + cssyyparse(this); + m_rule = 0; + + bool ok = false; + if (m_hasFontFaceOnlyValues) + deleteFontFaceOnlyValues(); + if (m_numParsedProperties) { + ok = true; + declaration->addParsedProperties(m_parsedProperties, m_numParsedProperties); + clearProperties(); + } + + return ok; +} + +bool CSSParser::parseMediaQuery(MediaList* queries, const String& string) +{ + if (string.isEmpty()) + return true; + + m_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, "} "); + cssyyparse(this); + + bool ok = false; + if (m_mediaQuery) { + ok = true; + queries->appendMediaQuery(m_mediaQuery); + m_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 (m_numParsedProperties >= m_maxParsedProperties) { + m_maxParsedProperties += 32; + m_parsedProperties = static_cast<CSSProperty**>(fastRealloc(m_parsedProperties, + m_maxParsedProperties * sizeof(CSSProperty*))); + } + m_parsedProperties[m_numParsedProperties++] = prop; +} + +void CSSParser::rollbackLastProperties(int num) +{ + ASSERT(num >= 0); + ASSERT(m_numParsedProperties >= num); + + for (int i = 0; i < num; ++i) + delete m_parsedProperties[--m_numParsedProperties]; +} + +void CSSParser::clearProperties() +{ + for (int i = 0; i < m_numParsedProperties; i++) + delete m_parsedProperties[i]; + m_numParsedProperties = 0; + m_hasFontFaceOnlyValues = false; +} + +Document* CSSParser::document() const +{ + StyleBase* root = m_styleSheet; + Document* doc = 0; + while (root && root->parent()) + root = root->parent(); + if (root && root->isCSSStyleSheet()) + doc = static_cast<CSSStyleSheet*>(root)->doc(); + return doc; +} + +bool CSSParser::validUnit(CSSParserValue* 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 | FTime)) && (value->fValue == 0 || !strict))) { + value->unit = (unitflags & FLength) ? CSSPrimitiveValue::CSS_PX : + ((unitflags & FAngle) ? CSSPrimitiveValue::CSS_DEG : CSSPrimitiveValue::CSS_MS); + b = true; + } + if (!b && (unitflags & FInteger) && value->isInt) + b = true; + break; + case CSSPrimitiveValue::CSS_PERCENTAGE: + b = (unitflags & FPercent); + break; + case CSSParserValue::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: + case CSSPrimitiveValue::CSS_TURN: + b = (unitflags & FAngle); + break; + case CSSPrimitiveValue::CSS_HZ: + case CSSPrimitiveValue::CSS_KHZ: + case CSSPrimitiveValue::CSS_DIMENSION: + default: + break; + } + return b; +} + +static int unitFromString(CSSParserValue* 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, "turn")) + return CSSPrimitiveValue::CSS_TURN; + 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 (m_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. + CSSParserValue* numericVal = 0; + unsigned size = m_valueList->size(); + for (unsigned i = 0; i < size; i++) { + CSSParserValue* value = m_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. + m_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 (!m_valueList) + return false; + + CSSParserValue *value = m_valueList->current(); + + if (!value) + return false; + + int id = value->id; + + // 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(); + + int num = inShorthand() ? 1 : m_valueList->size(); + + if (id == CSSValueInherit) { + if (num != 1) + return false; + addProperty(propId, CSSInheritedValue::create(), important); + return true; + } + else if (id == CSSValueInitial) { + if (num != 1) + return false; + addProperty(propId, CSSInitialValue::createExplicit(), important); + return true; + } + + // If we have any variables, then we don't parse the list of values yet. We add them to the declaration + // as unresolved, and allow them to be parsed later. The parse is considered "successful" for now, even though + // it might ultimately fail once the variable has been resolved. + if (!inShorthand() && checkForVariables(m_valueList)) { + addUnresolvedProperty(propId, important); + return true; + } + + bool valid_primitive = false; + RefPtr<CSSValue> parsedValue; + + 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 CSSPropertySize: // <length>{1,2} | auto | portrait | landscape | inherit + case CSSPropertyQuotes: // [<string> <string>]+ | none | inherit + if (id) + valid_primitive = true; + break; + case CSSPropertyUnicodeBidi: // normal | embed | bidi-override | inherit + if (id == CSSValueNormal || + id == CSSValueEmbed || + id == CSSValueBidiOverride) + valid_primitive = true; + break; + + case CSSPropertyPosition: // static | relative | absolute | fixed | inherit + if (id == CSSValueStatic || + id == CSSValueRelative || + id == CSSValueAbsolute || + id == CSSValueFixed) + valid_primitive = true; + break; + + case CSSPropertyPageBreakAfter: // auto | always | avoid | left | right | inherit + case CSSPropertyPageBreakBefore: + case CSSPropertyWebkitColumnBreakAfter: + case CSSPropertyWebkitColumnBreakBefore: + if (id == CSSValueAuto || + id == CSSValueAlways || + id == CSSValueAvoid || + id == CSSValueLeft || + id == CSSValueRight) + valid_primitive = true; + break; + + case CSSPropertyPageBreakInside: // avoid | auto | inherit + case CSSPropertyWebkitColumnBreakInside: + if (id == CSSValueAuto || id == CSSValueAvoid) + valid_primitive = true; + break; + + case CSSPropertyEmptyCells: // show | hide | inherit + if (id == CSSValueShow || + id == CSSValueHide) + valid_primitive = true; + break; + + case CSSPropertyContent: // [ <string> | <uri> | <counter> | attr(X) | open-quote | + // close-quote | no-open-quote | no-close-quote ]+ | inherit + return parseContent(propId, important); + break; + + case CSSPropertyWhiteSpace: // normal | pre | nowrap | inherit + if (id == CSSValueNormal || + id == CSSValuePre || + id == CSSValuePreWrap || + id == CSSValuePreLine || + id == CSSValueNowrap) + valid_primitive = true; + break; + + case CSSPropertyClip: // <shape> | auto | inherit + if (id == CSSValueAuto) + valid_primitive = true; + else if (value->unit == CSSParserValue::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 CSSPropertyCaptionSide: // top | bottom | left | right | inherit + if (id == CSSValueLeft || id == CSSValueRight || + id == CSSValueTop || id == CSSValueBottom) + valid_primitive = true; + break; + + case CSSPropertyBorderCollapse: // collapse | separate | inherit + if (id == CSSValueCollapse || id == CSSValueSeparate) + valid_primitive = true; + break; + + case CSSPropertyVisibility: // visible | hidden | collapse | inherit + if (id == CSSValueVisible || id == CSSValueHidden || id == CSSValueCollapse) + valid_primitive = true; + break; + + case CSSPropertyOverflow: { + ShorthandScope scope(this, propId); + if (num != 1 || !parseValue(CSSPropertyOverflowX, important)) + return false; + CSSValue* value = m_parsedProperties[m_numParsedProperties - 1]->value(); + addProperty(CSSPropertyOverflowY, value, important); + return true; + } + case CSSPropertyOverflowX: + case CSSPropertyOverflowY: // visible | hidden | scroll | auto | marquee | overlay | inherit + if (id == CSSValueVisible || id == CSSValueHidden || id == CSSValueScroll || id == CSSValueAuto || + id == CSSValueOverlay || id == CSSValueWebkitMarquee) + valid_primitive = true; + break; + + case CSSPropertyListStylePosition: // inside | outside | inherit + if (id == CSSValueInside || id == CSSValueOutside) + valid_primitive = true; + break; + + case CSSPropertyListStyleType: + // 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 >= CSSValueDisc && id <= CSSValueKatakanaIroha) || id == CSSValueNone) + valid_primitive = true; + break; + + case CSSPropertyDisplay: + // 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 >= CSSValueInline && id <= CSSValueWebkitInlineBox) || id == CSSValueNone) + valid_primitive = true; + break; + + case CSSPropertyDirection: // ltr | rtl | inherit + if (id == CSSValueLtr || id == CSSValueRtl) + valid_primitive = true; + break; + + case CSSPropertyTextTransform: // capitalize | uppercase | lowercase | none | inherit + if ((id >= CSSValueCapitalize && id <= CSSValueLowercase) || id == CSSValueNone) + valid_primitive = true; + break; + + case CSSPropertyFloat: // left | right | none | inherit + center for buggy CSS + if (id == CSSValueLeft || id == CSSValueRight || + id == CSSValueNone || id == CSSValueCenter) + valid_primitive = true; + break; + + case CSSPropertyClear: // none | left | right | both | inherit + if (id == CSSValueNone || id == CSSValueLeft || + id == CSSValueRight|| id == CSSValueBoth) + valid_primitive = true; + break; + + case CSSPropertyTextAlign: + // left | right | center | justify | webkit_left | webkit_right | webkit_center | start | end | <string> | inherit + if ((id >= CSSValueWebkitAuto && id <= CSSValueWebkitCenter) || id == CSSValueStart || id == CSSValueEnd || + value->unit == CSSPrimitiveValue::CSS_STRING) + valid_primitive = true; + break; + + case CSSPropertyOutlineStyle: // (<border-style> except hidden) | auto | inherit + if (id == CSSValueAuto || id == CSSValueNone || (id >= CSSValueInset && id <= CSSValueDouble)) + valid_primitive = true; + break; + + case CSSPropertyBorderTopStyle: //// <border-style> | inherit + case CSSPropertyBorderRightStyle: // Defined as: none | hidden | dotted | dashed | + case CSSPropertyBorderBottomStyle: // solid | double | groove | ridge | inset | outset + case CSSPropertyBorderLeftStyle: + case CSSPropertyWebkitColumnRuleStyle: + if (id >= CSSValueNone && id <= CSSValueDouble) + valid_primitive = true; + break; + + case CSSPropertyFontWeight: // normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit + return parseFontWeight(important); + + case CSSPropertyBorderSpacing: { + const int properties[2] = { CSSPropertyWebkitBorderHorizontalSpacing, + CSSPropertyWebkitBorderVerticalSpacing }; + if (num == 1) { + ShorthandScope scope(this, CSSPropertyBorderSpacing); + if (!parseValue(properties[0], important)) + return false; + CSSValue* value = m_parsedProperties[m_numParsedProperties-1]->value(); + addProperty(properties[1], value, important); + return true; + } + else if (num == 2) { + ShorthandScope scope(this, CSSPropertyBorderSpacing); + if (!parseValue(properties[0], important) || !parseValue(properties[1], important)) + return false; + return true; + } + return false; + } + case CSSPropertyWebkitBorderHorizontalSpacing: + case CSSPropertyWebkitBorderVerticalSpacing: + valid_primitive = validUnit(value, FLength|FNonNeg, m_strict); + break; + case CSSPropertyScrollbarFaceColor: // IE5.5 + case CSSPropertyScrollbarShadowColor: // IE5.5 + case CSSPropertyScrollbarHighlightColor: // IE5.5 + case CSSPropertyScrollbar3dlightColor: // IE5.5 + case CSSPropertyScrollbarDarkshadowColor: // IE5.5 + case CSSPropertyScrollbarTrackColor: // IE5.5 + case CSSPropertyScrollbarArrowColor: // IE5.5 + if (m_strict) + break; + /* nobreak */ + case CSSPropertyOutlineColor: // <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 == CSSPropertyOutlineColor && (id == CSSValueInvert || id == CSSValueWebkitFocusRingColor)) { + valid_primitive = true; + break; + } + /* nobreak */ + case CSSPropertyBackgroundColor: // <color> | inherit + case CSSPropertyBorderTopColor: // <color> | inherit + case CSSPropertyBorderRightColor: // <color> | inherit + case CSSPropertyBorderBottomColor: // <color> | inherit + case CSSPropertyBorderLeftColor: // <color> | inherit + case CSSPropertyColor: // <color> | inherit + case CSSPropertyTextLineThroughColor: // CSS3 text decoration colors + case CSSPropertyTextUnderlineColor: + case CSSPropertyTextOverlineColor: + case CSSPropertyWebkitColumnRuleColor: + case CSSPropertyWebkitTextFillColor: + case CSSPropertyWebkitTextStrokeColor: + if (id == CSSValueWebkitText) + valid_primitive = true; // Always allow this, even when strict parsing is on, + // since we use this in our UA sheets. + else if (id == CSSValueCurrentcolor) + valid_primitive = true; + else if (id >= CSSValueAqua && id <= CSSValueWindowtext || id == CSSValueMenu || + (id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && !m_strict)) { + valid_primitive = true; + } else { + parsedValue = parseColor(); + if (parsedValue) + m_valueList->next(); + } + break; + + case CSSPropertyCursor: { + // [<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 | + // vertical-text | cell | context-menu | alias | copy | no-drop | not-allowed | -webkit-zoom-in + // -webkit-zoom-in | -webkit-zoom-out | all-scroll | -webkit-grab | -webkit-grabbing ] ] | inherit + RefPtr<CSSValueList> list; + while (value && value->unit == CSSPrimitiveValue::CSS_URI) { + if (!list) + list = CSSValueList::createCommaSeparated(); + String uri = parseURL(value->string); + Vector<int> coords; + value = m_valueList->next(); + while (value && value->unit == CSSPrimitiveValue::CSS_NUMBER) { + coords.append(int(value->fValue)); + value = m_valueList->next(); + } + IntPoint hotspot; + int nrcoords = coords.size(); + if (nrcoords > 0 && nrcoords != 2) { + if (m_strict) // only support hotspot pairs in strict mode + return false; + } else if (m_strict && nrcoords == 2) + hotspot = IntPoint(coords[0], coords[1]); + if (m_strict || coords.size() == 0) { + if (!uri.isNull()) + list->append(CSSCursorImageValue::create(m_styleSheet->completeURL(uri), hotspot)); + } + if ((m_strict && !value) || (value && !(value->unit == CSSParserValue::Operator && value->iValue == ','))) + return false; + value = m_valueList->next(); // comma + } + if (list) { + if (!value) { // no value after url list (MSIE 5 compatibility) + if (list->length() != 1) + return false; + } else if (!m_strict && value->id == CSSValueHand) // MSIE 5 compatibility :/ + list->append(CSSPrimitiveValue::createIdentifier(CSSValuePointer)); + else if (value && ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone)) + list->append(CSSPrimitiveValue::createIdentifier(value->id)); + m_valueList->next(); + parsedValue = list.release(); + break; + } + id = value->id; + if (!m_strict && value->id == CSSValueHand) { // MSIE 5 compatibility :/ + id = CSSValuePointer; + valid_primitive = true; + } else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone) + valid_primitive = true; + break; + } + + case CSSPropertyBackgroundAttachment: + case CSSPropertyWebkitBackgroundClip: + case CSSPropertyWebkitBackgroundComposite: + case CSSPropertyBackgroundImage: + case CSSPropertyWebkitBackgroundOrigin: + case CSSPropertyBackgroundPosition: + case CSSPropertyBackgroundPositionX: + case CSSPropertyBackgroundPositionY: + case CSSPropertyWebkitBackgroundSize: + case CSSPropertyBackgroundRepeat: + case CSSPropertyWebkitMaskAttachment: + case CSSPropertyWebkitMaskClip: + case CSSPropertyWebkitMaskComposite: + case CSSPropertyWebkitMaskImage: + case CSSPropertyWebkitMaskOrigin: + case CSSPropertyWebkitMaskPosition: + case CSSPropertyWebkitMaskPositionX: + case CSSPropertyWebkitMaskPositionY: + case CSSPropertyWebkitMaskSize: + case CSSPropertyWebkitMaskRepeat: { + RefPtr<CSSValue> val1; + RefPtr<CSSValue> val2; + int propId1, propId2; + if (parseFillProperty(propId, propId1, propId2, val1, val2)) { + addProperty(propId1, val1.release(), important); + if (val2) + addProperty(propId2, val2.release(), important); + return true; + } + return false; + } + case CSSPropertyListStyleImage: // <uri> | none | inherit + if (id == CSSValueNone) { + parsedValue = CSSImageValue::create(); + m_valueList->next(); + } else if (value->unit == CSSPrimitiveValue::CSS_URI) { + // ### allow string in non strict mode? + String uri = parseURL(value->string); + if (!uri.isNull()) { + parsedValue = CSSImageValue::create(m_styleSheet->completeURL(uri)); + m_valueList->next(); + } + } else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "-webkit-gradient(")) { + if (parseGradient(parsedValue)) + m_valueList->next(); + else + return false; + } + break; + + case CSSPropertyWebkitTextStrokeWidth: + case CSSPropertyOutlineWidth: // <border-width> | inherit + case CSSPropertyBorderTopWidth: //// <border-width> | inherit + case CSSPropertyBorderRightWidth: // Which is defined as + case CSSPropertyBorderBottomWidth: // thin | medium | thick | <length> + case CSSPropertyBorderLeftWidth: + case CSSPropertyWebkitColumnRuleWidth: + if (id == CSSValueThin || id == CSSValueMedium || id == CSSValueThick) + valid_primitive = true; + else + valid_primitive = validUnit(value, FLength, m_strict); + break; + + case CSSPropertyLetterSpacing: // normal | <length> | inherit + case CSSPropertyWordSpacing: // normal | <length> | inherit + if (id == CSSValueNormal) + valid_primitive = true; + else + valid_primitive = validUnit(value, FLength, m_strict); + break; + + case CSSPropertyWordBreak: // normal | break-all | break-word (this is a custom extension) + if (id == CSSValueNormal || id == CSSValueBreakAll || id == CSSValueBreakWord) + valid_primitive = true; + break; + + case CSSPropertyWordWrap: // normal | break-word + if (id == CSSValueNormal || id == CSSValueBreakWord) + valid_primitive = true; + break; + + case CSSPropertyTextIndent: // <length> | <percentage> | inherit + case CSSPropertyPaddingTop: //// <padding-width> | inherit + case CSSPropertyPaddingRight: // Which is defined as + case CSSPropertyPaddingBottom: // <length> | <percentage> + case CSSPropertyPaddingLeft: //// + case CSSPropertyWebkitPaddingStart: + valid_primitive = (!id && validUnit(value, FLength|FPercent, m_strict)); + break; + + case CSSPropertyMaxHeight: // <length> | <percentage> | none | inherit + case CSSPropertyMaxWidth: // <length> | <percentage> | none | inherit + if (id == CSSValueNone || id == CSSValueIntrinsic || id == CSSValueMinIntrinsic) { + valid_primitive = true; + break; + } + /* nobreak */ + case CSSPropertyMinHeight: // <length> | <percentage> | inherit + case CSSPropertyMinWidth: // <length> | <percentage> | inherit + if (id == CSSValueIntrinsic || id == CSSValueMinIntrinsic) + valid_primitive = true; + else + valid_primitive = (!id && validUnit(value, FLength|FPercent|FNonNeg, m_strict)); + break; + + case CSSPropertyFontSize: + // <absolute-size> | <relative-size> | <length> | <percentage> | inherit + if (id >= CSSValueXxSmall && id <= CSSValueLarger) + valid_primitive = true; + else + valid_primitive = (validUnit(value, FLength|FPercent|FNonNeg, m_strict)); + break; + + case CSSPropertyFontStyle: // normal | italic | oblique | inherit + return parseFontStyle(important); + + case CSSPropertyFontVariant: // normal | small-caps | inherit + return parseFontVariant(important); + + case CSSPropertyVerticalAlign: + // baseline | sub | super | top | text-top | middle | bottom | text-bottom | + // <percentage> | <length> | inherit + + if (id >= CSSValueBaseline && id <= CSSValueWebkitBaselineMiddle) + valid_primitive = true; + else + valid_primitive = (!id && validUnit(value, FLength|FPercent, m_strict)); + break; + + case CSSPropertyHeight: // <length> | <percentage> | auto | inherit + case CSSPropertyWidth: // <length> | <percentage> | auto | inherit + if (id == CSSValueAuto || id == CSSValueIntrinsic || id == CSSValueMinIntrinsic) + valid_primitive = true; + else + // ### handle multilength case where we allow relative units + valid_primitive = (!id && validUnit(value, FLength|FPercent|FNonNeg, m_strict)); + break; + + case CSSPropertyBottom: // <length> | <percentage> | auto | inherit + case CSSPropertyLeft: // <length> | <percentage> | auto | inherit + case CSSPropertyRight: // <length> | <percentage> | auto | inherit + case CSSPropertyTop: // <length> | <percentage> | auto | inherit + case CSSPropertyMarginTop: //// <margin-width> | inherit + case CSSPropertyMarginRight: // Which is defined as + case CSSPropertyMarginBottom: // <length> | <percentage> | auto | inherit + case CSSPropertyMarginLeft: //// + case CSSPropertyWebkitMarginStart: + if (id == CSSValueAuto) + valid_primitive = true; + else + valid_primitive = (!id && validUnit(value, FLength|FPercent, m_strict)); + break; + + case CSSPropertyZIndex: // auto | <integer> | inherit + if (id == CSSValueAuto) { + valid_primitive = true; + break; + } + /* nobreak */ + case CSSPropertyOrphans: // <integer> | inherit + case CSSPropertyWidows: // <integer> | inherit + // ### not supported later on + valid_primitive = (!id && validUnit(value, FInteger, false)); + break; + + case CSSPropertyLineHeight: // normal | <number> | <length> | <percentage> | inherit + if (id == CSSValueNormal) + valid_primitive = true; + else + valid_primitive = (!id && validUnit(value, FNumber|FLength|FPercent|FNonNeg, m_strict)); + break; + case CSSPropertyCounterIncrement: // [ <identifier> <integer>? ]+ | none | inherit + if (id != CSSValueNone) + return parseCounter(propId, 1, important); + valid_primitive = true; + break; + case CSSPropertyCounterReset: // [ <identifier> <integer>? ]+ | none | inherit + if (id != CSSValueNone) + return parseCounter(propId, 0, important); + valid_primitive = true; + break; + case CSSPropertyFontFamily: + // [[ <family-name> | <generic-family> ],]* [<family-name> | <generic-family>] | inherit + { + parsedValue = parseFontFamily(); + break; + } + + case CSSPropertyTextDecoration: + case CSSPropertyWebkitTextDecorationsInEffect: + // none | [ underline || overline || line-through || blink ] | inherit + if (id == CSSValueNone) { + valid_primitive = true; + } else { + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + bool is_valid = true; + while(is_valid && value) { + switch (value->id) { + case CSSValueBlink: + break; + case CSSValueUnderline: + case CSSValueOverline: + case CSSValueLineThrough: + list->append(CSSPrimitiveValue::createIdentifier(value->id)); + break; + default: + is_valid = false; + } + value = m_valueList->next(); + } + if (list->length() && is_valid) { + parsedValue = list.release(); + m_valueList->next(); + } + } + break; + + case CSSPropertyZoom: // normal | reset | document | <number> | <percentage> | inherit + if (id == CSSValueNormal || id == CSSValueReset || id == CSSValueDocument) + valid_primitive = true; + else + valid_primitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg, true)); + break; + + case CSSPropertyTableLayout: // auto | fixed | inherit + if (id == CSSValueAuto || id == CSSValueFixed) + valid_primitive = true; + break; + + case CSSPropertySrc: // 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 CSSPropertyUnicodeRange: + return parseFontFaceUnicodeRange(); + + /* CSS3 properties */ + case CSSPropertyWebkitAppearance: + if ((id >= CSSValueCheckbox && id <= CSSValueTextarea) || id == CSSValueNone) + valid_primitive = true; + break; + + case CSSPropertyWebkitBinding: +#if ENABLE(XBL) + if (id == CSSValueNone) + valid_primitive = true; + else { + RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated(); + CSSParserValue* val; + RefPtr<CSSValue> parsedValue; + while ((val = m_valueList->current())) { + if (val->unit == CSSPrimitiveValue::CSS_URI) { + String value = parseURL(val->string); + parsedValue = CSSPrimitiveValue::create(m_styleSheet->completeURL(value), 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()); + m_valueList->next(); + } + if (!values->length()) + return false; + + addProperty(propId, values.release(), important); + m_valueList->next(); + return true; + } +#endif + break; + case CSSPropertyWebkitBorderImage: + case CSSPropertyWebkitMaskBoxImage: + if (id == CSSValueNone) + valid_primitive = true; + else { + RefPtr<CSSValue> result; + if (parseBorderImage(propId, important, result)) { + addProperty(propId, result, important); + return true; + } + } + break; + case CSSPropertyWebkitBorderTopRightRadius: + case CSSPropertyWebkitBorderTopLeftRadius: + case CSSPropertyWebkitBorderBottomLeftRadius: + case CSSPropertyWebkitBorderBottomRightRadius: + case CSSPropertyWebkitBorderRadius: { + if (num != 1 && num != 2) + return false; + valid_primitive = validUnit(value, FLength, m_strict); + if (!valid_primitive) + return false; + RefPtr<CSSPrimitiveValue> parsedValue1 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + RefPtr<CSSPrimitiveValue> parsedValue2; + if (num == 2) { + value = m_valueList->next(); + valid_primitive = validUnit(value, FLength, m_strict); + if (!valid_primitive) + return false; + parsedValue2 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + } else + parsedValue2 = parsedValue1; + + RefPtr<Pair> pair = Pair::create(parsedValue1.release(), parsedValue2.release()); + RefPtr<CSSPrimitiveValue> val = CSSPrimitiveValue::create(pair.release()); + if (propId == CSSPropertyWebkitBorderRadius) { + const int properties[4] = { CSSPropertyWebkitBorderTopRightRadius, + CSSPropertyWebkitBorderTopLeftRadius, + CSSPropertyWebkitBorderBottomLeftRadius, + CSSPropertyWebkitBorderBottomRightRadius }; + for (int i = 0; i < 4; i++) + addProperty(properties[i], val.get(), important); + } else + addProperty(propId, val.release(), important); + return true; + } + case CSSPropertyOutlineOffset: + valid_primitive = validUnit(value, FLength, m_strict); + break; + case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3 + case CSSPropertyWebkitBoxShadow: + if (id == CSSValueNone) + valid_primitive = true; + else + return parseShadow(propId, important); + break; + case CSSPropertyWebkitBoxReflect: + if (id == CSSValueNone) + valid_primitive = true; + else + return parseReflect(propId, important); + break; + case CSSPropertyOpacity: + valid_primitive = validUnit(value, FNumber, m_strict); + break; + case CSSPropertyWebkitBoxAlign: + if (id == CSSValueStretch || id == CSSValueStart || id == CSSValueEnd || + id == CSSValueCenter || id == CSSValueBaseline) + valid_primitive = true; + break; + case CSSPropertyWebkitBoxDirection: + if (id == CSSValueNormal || id == CSSValueReverse) + valid_primitive = true; + break; + case CSSPropertyWebkitBoxLines: + if (id == CSSValueSingle || id == CSSValueMultiple) + valid_primitive = true; + break; + case CSSPropertyWebkitBoxOrient: + if (id == CSSValueHorizontal || id == CSSValueVertical || + id == CSSValueInlineAxis || id == CSSValueBlockAxis) + valid_primitive = true; + break; + case CSSPropertyWebkitBoxPack: + if (id == CSSValueStart || id == CSSValueEnd || + id == CSSValueCenter || id == CSSValueJustify) + valid_primitive = true; + break; + case CSSPropertyWebkitBoxFlex: + valid_primitive = validUnit(value, FNumber, m_strict); + break; + case CSSPropertyWebkitBoxFlexGroup: + case CSSPropertyWebkitBoxOrdinalGroup: + valid_primitive = validUnit(value, FInteger|FNonNeg, true); + break; + case CSSPropertyWebkitBoxSizing: + valid_primitive = id == CSSValueBorderBox || id == CSSValueContentBox; + break; + case CSSPropertyWebkitMarquee: { + const int properties[5] = { CSSPropertyWebkitMarqueeDirection, CSSPropertyWebkitMarqueeIncrement, + CSSPropertyWebkitMarqueeRepetition, + CSSPropertyWebkitMarqueeStyle, CSSPropertyWebkitMarqueeSpeed }; + return parseShorthand(propId, properties, 5, important); + } + case CSSPropertyWebkitMarqueeDirection: + if (id == CSSValueForwards || id == CSSValueBackwards || id == CSSValueAhead || + id == CSSValueReverse || id == CSSValueLeft || id == CSSValueRight || id == CSSValueDown || + id == CSSValueUp || id == CSSValueAuto) + valid_primitive = true; + break; + case CSSPropertyWebkitMarqueeIncrement: + if (id == CSSValueSmall || id == CSSValueLarge || id == CSSValueMedium) + valid_primitive = true; + else + valid_primitive = validUnit(value, FLength|FPercent, m_strict); + break; + case CSSPropertyWebkitMarqueeStyle: + if (id == CSSValueNone || id == CSSValueSlide || id == CSSValueScroll || id == CSSValueAlternate) + valid_primitive = true; + break; + case CSSPropertyWebkitMarqueeRepetition: + if (id == CSSValueInfinite) + valid_primitive = true; + else + valid_primitive = validUnit(value, FInteger|FNonNeg, m_strict); + break; + case CSSPropertyWebkitMarqueeSpeed: + if (id == CSSValueNormal || id == CSSValueSlow || id == CSSValueFast) + valid_primitive = true; + else + valid_primitive = validUnit(value, FTime|FInteger|FNonNeg, m_strict); + break; + case CSSPropertyWebkitUserDrag: // auto | none | element + if (id == CSSValueAuto || id == CSSValueNone || id == CSSValueElement) + valid_primitive = true; + break; + case CSSPropertyWebkitUserModify: // read-only | read-write + if (id == CSSValueReadOnly || id == CSSValueReadWrite || id == CSSValueReadWritePlaintextOnly) + valid_primitive = true; + break; + case CSSPropertyWebkitUserSelect: // auto | none | text + if (id == CSSValueAuto || id == CSSValueNone || id == CSSValueText) + valid_primitive = true; + break; + case CSSPropertyTextOverflow: // clip | ellipsis + if (id == CSSValueClip || id == CSSValueEllipsis) + valid_primitive = true; + break; + case CSSPropertyWebkitTransform: + if (id == CSSValueNone) + valid_primitive = true; + else { + PassRefPtr<CSSValue> val = parseTransform(); + if (val) { + addProperty(propId, val, important); + return true; + } + return false; + } + break; + case CSSPropertyWebkitTransformOrigin: + case CSSPropertyWebkitTransformOriginX: + case CSSPropertyWebkitTransformOriginY: { + 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 CSSPropertyWebkitAnimationDelay: + case CSSPropertyWebkitAnimationDirection: + case CSSPropertyWebkitAnimationDuration: + case CSSPropertyWebkitAnimationName: + case CSSPropertyWebkitAnimationPlayState: + case CSSPropertyWebkitAnimationIterationCount: + case CSSPropertyWebkitAnimationTimingFunction: + case CSSPropertyWebkitTransitionDelay: + case CSSPropertyWebkitTransitionDuration: + case CSSPropertyWebkitTransitionTimingFunction: + case CSSPropertyWebkitTransitionProperty: { + RefPtr<CSSValue> val; + if (parseAnimationProperty(propId, val)) { + addProperty(propId, val.release(), important); + return true; + } + return false; + } + case CSSPropertyWebkitMarginCollapse: { + const int properties[2] = { CSSPropertyWebkitMarginTopCollapse, + CSSPropertyWebkitMarginBottomCollapse }; + if (num == 1) { + ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse); + if (!parseValue(properties[0], important)) + return false; + CSSValue* value = m_parsedProperties[m_numParsedProperties-1]->value(); + addProperty(properties[1], value, important); + return true; + } + else if (num == 2) { + ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse); + if (!parseValue(properties[0], important) || !parseValue(properties[1], important)) + return false; + return true; + } + return false; + } + case CSSPropertyWebkitMarginTopCollapse: + case CSSPropertyWebkitMarginBottomCollapse: + if (id == CSSValueCollapse || id == CSSValueSeparate || id == CSSValueDiscard) + valid_primitive = true; + break; + case CSSPropertyTextLineThroughMode: + case CSSPropertyTextOverlineMode: + case CSSPropertyTextUnderlineMode: + if (id == CSSValueContinuous || id == CSSValueSkipWhiteSpace) + valid_primitive = true; + break; + case CSSPropertyTextLineThroughStyle: + case CSSPropertyTextOverlineStyle: + case CSSPropertyTextUnderlineStyle: + if (id == CSSValueNone || id == CSSValueSolid || id == CSSValueDouble || + id == CSSValueDashed || id == CSSValueDotDash || id == CSSValueDotDotDash || + id == CSSValueWave) + valid_primitive = true; + break; + case CSSPropertyTextLineThroughWidth: + case CSSPropertyTextOverlineWidth: + case CSSPropertyTextUnderlineWidth: + if (id == CSSValueAuto || id == CSSValueNormal || id == CSSValueThin || + id == CSSValueMedium || id == CSSValueThick) + valid_primitive = true; + else + valid_primitive = !id && validUnit(value, FNumber|FLength|FPercent, m_strict); + break; + case CSSPropertyResize: // none | both | horizontal | vertical | auto + if (id == CSSValueNone || id == CSSValueBoth || id == CSSValueHorizontal || id == CSSValueVertical || id == CSSValueAuto) + valid_primitive = true; + break; + case CSSPropertyWebkitColumnCount: + if (id == CSSValueAuto) + valid_primitive = true; + else + valid_primitive = !id && validUnit(value, FInteger | FNonNeg, false); + break; + case CSSPropertyWebkitColumnGap: // normal | <length> + if (id == CSSValueNormal) + valid_primitive = true; + else + valid_primitive = validUnit(value, FLength | FNonNeg, m_strict); + break; + case CSSPropertyWebkitColumnWidth: // auto | <length> + if (id == CSSValueAuto) + 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; + case CSSPropertyPointerEvents: + // none | visiblePainted | visibleFill | visibleStroke | visible | + // painted | fill | stroke | auto | all | inherit + if (id == CSSValueVisible || id == CSSValueNone || id == CSSValueAll || id == CSSValueAuto || + (id >= CSSValueVisiblepainted && id <= CSSValueStroke)) + valid_primitive = 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 CSSPropertyWebkitLineClamp: + valid_primitive = (!id && validUnit(value, FPercent, false)); + break; + case CSSPropertyWebkitTextSizeAdjust: + if (id == CSSValueAuto || id == CSSValueNone) + valid_primitive = true; + break; + case CSSPropertyWebkitRtlOrdering: + if (id == CSSValueLogical || id == CSSValueVisual) + valid_primitive = true; + break; + + case CSSPropertyWebkitFontSizeDelta: // <length> + valid_primitive = validUnit(value, FLength, m_strict); + break; + + case CSSPropertyWebkitNbspMode: // normal | space + if (id == CSSValueNormal || id == CSSValueSpace) + valid_primitive = true; + break; + + case CSSPropertyWebkitLineBreak: // normal | after-white-space + if (id == CSSValueNormal || id == CSSValueAfterWhiteSpace) + valid_primitive = true; + break; + + case CSSPropertyWebkitMatchNearestMailBlockquoteColor: // normal | match + if (id == CSSValueNormal || id == CSSValueMatch) + valid_primitive = true; + break; + + case CSSPropertyWebkitHighlight: + if (id == CSSValueNone || value->unit == CSSPrimitiveValue::CSS_STRING) + valid_primitive = true; + break; + + case CSSPropertyWebkitBorderFit: + if (id == CSSValueBorder || id == CSSValueLines) + valid_primitive = true; + break; + + case CSSPropertyWebkitTextSecurity: + // disc | circle | square | none | inherit + if (id == CSSValueDisc || id == CSSValueCircle || id == CSSValueSquare|| id == CSSValueNone) + valid_primitive = true; + break; + +#if ENABLE(DASHBOARD_SUPPORT) + case CSSPropertyWebkitDashboardRegion: // <dashboard-region> | <dashboard-region> + if (value->unit == CSSParserValue::Function || id == CSSValueNone) + return parseDashboardRegions(propId, important); + break; +#endif + // End Apple-specific properties + + /* shorthand properties */ + case CSSPropertyBackground: { + // 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 CSSPropertyWebkitBackgroundSize to the shorthand. + const int properties[] = { CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat, + CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition, CSSPropertyWebkitBackgroundClip, + CSSPropertyWebkitBackgroundOrigin, CSSPropertyBackgroundColor }; + return parseFillShorthand(propId, properties, 7, important); + } + case CSSPropertyWebkitMask: { + const int properties[] = { CSSPropertyWebkitMaskImage, CSSPropertyWebkitMaskRepeat, + CSSPropertyWebkitMaskAttachment, CSSPropertyWebkitMaskPosition, CSSPropertyWebkitMaskClip, + CSSPropertyWebkitMaskOrigin }; + return parseFillShorthand(propId, properties, 6, important); + } + case CSSPropertyBorder: + // [ 'border-width' || 'border-style' || <color> ] | inherit + { + const int properties[3] = { CSSPropertyBorderWidth, CSSPropertyBorderStyle, + CSSPropertyBorderColor }; + return parseShorthand(propId, properties, 3, important); + } + case CSSPropertyBorderTop: + // [ 'border-top-width' || 'border-style' || <color> ] | inherit + { + const int properties[3] = { CSSPropertyBorderTopWidth, CSSPropertyBorderTopStyle, + CSSPropertyBorderTopColor}; + return parseShorthand(propId, properties, 3, important); + } + case CSSPropertyBorderRight: + // [ 'border-right-width' || 'border-style' || <color> ] | inherit + { + const int properties[3] = { CSSPropertyBorderRightWidth, CSSPropertyBorderRightStyle, + CSSPropertyBorderRightColor }; + return parseShorthand(propId, properties, 3, important); + } + case CSSPropertyBorderBottom: + // [ 'border-bottom-width' || 'border-style' || <color> ] | inherit + { + const int properties[3] = { CSSPropertyBorderBottomWidth, CSSPropertyBorderBottomStyle, + CSSPropertyBorderBottomColor }; + return parseShorthand(propId, properties, 3, important); + } + case CSSPropertyBorderLeft: + // [ 'border-left-width' || 'border-style' || <color> ] | inherit + { + const int properties[3] = { CSSPropertyBorderLeftWidth, CSSPropertyBorderLeftStyle, + CSSPropertyBorderLeftColor }; + return parseShorthand(propId, properties, 3, important); + } + case CSSPropertyOutline: + // [ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit + { + const int properties[3] = { CSSPropertyOutlineWidth, CSSPropertyOutlineStyle, + CSSPropertyOutlineColor }; + return parseShorthand(propId, properties, 3, important); + } + case CSSPropertyBorderColor: + // <color>{1,4} | inherit + { + const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, + CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor }; + return parse4Values(propId, properties, important); + } + case CSSPropertyBorderWidth: + // <border-width>{1,4} | inherit + { + const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, + CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth }; + return parse4Values(propId, properties, important); + } + case CSSPropertyBorderStyle: + // <border-style>{1,4} | inherit + { + const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, + CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle }; + return parse4Values(propId, properties, important); + } + case CSSPropertyMargin: + // <margin-width>{1,4} | inherit + { + const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, + CSSPropertyMarginBottom, CSSPropertyMarginLeft }; + return parse4Values(propId, properties, important); + } + case CSSPropertyPadding: + // <padding-width>{1,4} | inherit + { + const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, + CSSPropertyPaddingBottom, CSSPropertyPaddingLeft }; + return parse4Values(propId, properties, important); + } + case CSSPropertyFont: + // [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? + // 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit + if (id >= CSSValueCaption && id <= CSSValueStatusBar) + valid_primitive = true; + else + return parseFont(important); + break; + case CSSPropertyListStyle: + { + const int properties[3] = { CSSPropertyListStyleType, CSSPropertyListStylePosition, + CSSPropertyListStyleImage }; + return parseShorthand(propId, properties, 3, important); + } + case CSSPropertyWebkitColumns: { + const int properties[2] = { CSSPropertyWebkitColumnWidth, CSSPropertyWebkitColumnCount }; + return parseShorthand(propId, properties, 2, important); + } + case CSSPropertyWebkitColumnRule: { + const int properties[3] = { CSSPropertyWebkitColumnRuleWidth, CSSPropertyWebkitColumnRuleStyle, + CSSPropertyWebkitColumnRuleColor }; + return parseShorthand(propId, properties, 3, important); + } + case CSSPropertyWebkitTextStroke: { + const int properties[2] = { CSSPropertyWebkitTextStrokeWidth, CSSPropertyWebkitTextStrokeColor }; + return parseShorthand(propId, properties, 2, important); + } + case CSSPropertyWebkitAnimation: + return parseAnimationShorthand(important); + case CSSPropertyWebkitTransition: + return parseTransitionShorthand(important); + case CSSPropertyInvalid: + return false; + case CSSPropertyFontStretch: + case CSSPropertyPage: + case CSSPropertyTextLineThrough: + case CSSPropertyTextOverline: + case CSSPropertyTextUnderline: + return false; +#if ENABLE(SVG) + default: + return parseSVGValue(propId, important); +#endif + } + + if (valid_primitive) { + if (id != 0) + parsedValue = CSSPrimitiveValue::createIdentifier(id); + else if (value->unit == CSSPrimitiveValue::CSS_STRING) + parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit); + else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ) + parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit); + else if (value->unit >= CSSParserValue::Q_EMS) + parsedValue = CSSQuirkPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_EMS); + m_valueList->next(); + } + if (parsedValue) { + if (!m_valueList->current() || inShorthand()) { + addProperty(propId, parsedValue.release(), important); + return true; + } + } + return false; +} + +void CSSParser::addFillValue(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 = CSSValueList::createCommaSeparated(); + list->append(oldlVal); + list->append(rval); + lval = list; + } + } + else + lval = rval; +} + +const int cMaxFillProperties = 7; + +bool CSSParser::parseFillShorthand(int propId, const int* properties, int numProperties, bool important) +{ + ASSERT(numProperties <= cMaxFillProperties); + if (numProperties > cMaxFillProperties) + return false; + + ShorthandScope scope(this, propId); + + bool parsedProperty[cMaxFillProperties] = { false }; + RefPtr<CSSValue> values[cMaxFillProperties]; + RefPtr<CSSValue> positionYValue; + int i; + + while (m_valueList->current()) { + CSSParserValue* val = m_valueList->current(); + if (val->unit == CSSParserValue::Operator && val->iValue == ',') { + // We hit the end. Fill in all remaining values with the initial value. + m_valueList->next(); + for (i = 0; i < numProperties; ++i) { + if (properties[i] == CSSPropertyBackgroundColor && parsedProperty[i]) + // Color is not allowed except as the last item in a list for backgrounds. + // Reject the entire property. + return false; + + if (!parsedProperty[i] && properties[i] != CSSPropertyBackgroundColor) { + addFillValue(values[i], CSSInitialValue::createImplicit()); + if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition) + addFillValue(positionYValue, CSSInitialValue::createImplicit()); + } + parsedProperty[i] = false; + } + if (!m_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 (parseFillProperty(properties[i], propId1, propId2, val1, val2)) { + parsedProperty[i] = found = true; + addFillValue(values[i], val1.release()); + if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition) + addFillValue(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]) { + addFillValue(values[i], CSSInitialValue::createImplicit()); + if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition) + addFillValue(positionYValue, CSSInitialValue::createImplicit()); + } + } + + // Now add all of the properties we found. + for (i = 0; i < numProperties; i++) { + if (properties[i] == CSSPropertyBackgroundPosition) { + addProperty(CSSPropertyBackgroundPositionX, values[i].release(), important); + // it's OK to call positionYValue.release() since we only see CSSPropertyBackgroundPosition once + addProperty(CSSPropertyBackgroundPositionY, positionYValue.release(), important); + } else if (properties[i] == CSSPropertyWebkitMaskPosition) { + addProperty(CSSPropertyWebkitMaskPositionX, values[i].release(), important); + // it's OK to call positionYValue.release() since we only see CSSPropertyWebkitMaskPosition once + addProperty(CSSPropertyWebkitMaskPositionY, positionYValue.release(), important); + } else + addProperty(properties[i], values[i].release(), important); + } + + return true; +} + +void CSSParser::addAnimationValue(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 = CSSValueList::createCommaSeparated(); + list->append(oldVal); + list->append(rval); + lval = list; + } + } + else + lval = rval; +} + +bool CSSParser::parseAnimationShorthand(bool important) +{ + const int properties[] = { CSSPropertyWebkitAnimationName, + CSSPropertyWebkitAnimationDuration, + CSSPropertyWebkitAnimationTimingFunction, + CSSPropertyWebkitAnimationDelay, + CSSPropertyWebkitAnimationIterationCount, + CSSPropertyWebkitAnimationDirection }; + const int numProperties = sizeof(properties) / sizeof(properties[0]); + + ShorthandScope scope(this, CSSPropertyWebkitAnimation); + + bool parsedProperty[numProperties] = { false }; // compiler will repeat false as necessary + RefPtr<CSSValue> values[numProperties]; + + int i; + while (m_valueList->current()) { + CSSParserValue* val = m_valueList->current(); + if (val->unit == CSSParserValue::Operator && val->iValue == ',') { + // We hit the end. Fill in all remaining values with the initial value. + m_valueList->next(); + for (i = 0; i < numProperties; ++i) { + if (!parsedProperty[i]) + addAnimationValue(values[i], CSSInitialValue::createImplicit()); + parsedProperty[i] = false; + } + if (!m_valueList->current()) + break; + } + + bool found = false; + for (i = 0; !found && i < numProperties; ++i) { + if (!parsedProperty[i]) { + RefPtr<CSSValue> val; + if (parseAnimationProperty(properties[i], val)) { + parsedProperty[i] = found = true; + addAnimationValue(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]) + addAnimationValue(values[i], CSSInitialValue::createImplicit()); + } + + // 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::parseTransitionShorthand(bool important) +{ + const int properties[] = { CSSPropertyWebkitTransitionProperty, + CSSPropertyWebkitTransitionDuration, + CSSPropertyWebkitTransitionTimingFunction, + CSSPropertyWebkitTransitionDelay }; + const int numProperties = sizeof(properties) / sizeof(properties[0]); + + ShorthandScope scope(this, CSSPropertyWebkitTransition); + + bool parsedProperty[numProperties] = { false }; // compiler will repeat false as necessary + RefPtr<CSSValue> values[numProperties]; + + int i; + while (m_valueList->current()) { + CSSParserValue* val = m_valueList->current(); + if (val->unit == CSSParserValue::Operator && val->iValue == ',') { + // We hit the end. Fill in all remaining values with the initial value. + m_valueList->next(); + for (i = 0; i < numProperties; ++i) { + if (!parsedProperty[i]) + addAnimationValue(values[i], CSSInitialValue::createImplicit()); + parsedProperty[i] = false; + } + if (!m_valueList->current()) + break; + } + + bool found = false; + for (i = 0; !found && i < numProperties; ++i) { + if (!parsedProperty[i]) { + RefPtr<CSSValue> val; + if (parseAnimationProperty(properties[i], val)) { + parsedProperty[i] = found = true; + addAnimationValue(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]) + addAnimationValue(values[i], CSSInitialValue::createImplicit()); + } + + // 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 (m_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], CSSInitialValue::createImplicit(), 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 : m_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 = m_parsedProperties[m_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 = m_parsedProperties[m_numParsedProperties-2]->value(); + m_implicitShorthand = true; + addProperty(properties[2], value, important); + value = m_parsedProperties[m_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 = m_parsedProperties[m_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 = CSSValueList::createCommaSeparated(); + + while (CSSParserValue* val = m_valueList->current()) { + RefPtr<CSSValue> parsedValue; + if (val->unit == CSSPrimitiveValue::CSS_URI) { + // url + String value = parseURL(val->string); + parsedValue = CSSImageValue::create(m_styleSheet->completeURL(value)); + } else if (val->unit == CSSParserValue::Function) { + // attr(X) | counter(X [,Y]) | counters(X, Y, [,Z]) | -webkit-gradient(...) + CSSParserValueList* args = val->function->args; + if (!args) + return false; + if (equalIgnoringCase(val->function->name, "attr(")) { + if (args->size() != 1) + return false; + CSSParserValue* a = args->current(); + String attrName = a->string; + if (document()->isHTMLDocument()) + attrName = attrName.lower(); + parsedValue = CSSPrimitiveValue::create(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 if (equalIgnoringCase(val->function->name, "-webkit-gradient(")) { + if (!parseGradient(parsedValue)) + return false; + } else if (equalIgnoringCase(val->function->name, "-webkit-canvas(")) { + if (!parseCanvas(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 = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING); + } + if (!parsedValue) + break; + values->append(parsedValue.release()); + m_valueList->next(); + } + + if (values->length()) { + addProperty(propId, values.release(), important); + m_valueList->next(); + return true; + } + + return false; +} + +PassRefPtr<CSSValue> CSSParser::parseBackgroundColor() +{ + int id = m_valueList->current()->id; + if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor || + (id >= CSSValueGrey && id < CSSValueWebkitText && !m_strict)) + return CSSPrimitiveValue::createIdentifier(id); + return parseColor(); +} + +bool CSSParser::parseFillImage(RefPtr<CSSValue>& value) +{ + if (m_valueList->current()->id == CSSValueNone) { + value = CSSImageValue::create(); + return true; + } + if (m_valueList->current()->unit == CSSPrimitiveValue::CSS_URI) { + String uri = parseURL(m_valueList->current()->string); + if (!uri.isNull()) + value = CSSImageValue::create(m_styleSheet->completeURL(uri)); + return true; + } + + if (m_valueList->current()->unit == CSSParserValue::Function) { + if (equalIgnoringCase(m_valueList->current()->function->name, "-webkit-gradient(")) + return parseGradient(value); + if (equalIgnoringCase(m_valueList->current()->function->name, "-webkit-canvas(")) + return parseCanvas(value); + } + return false; +} + +PassRefPtr<CSSValue> CSSParser::parseFillPositionXY(bool& xFound, bool& yFound) +{ + int id = m_valueList->current()->id; + if (id == CSSValueLeft || id == CSSValueTop || id == CSSValueRight || id == CSSValueBottom || id == CSSValueCenter) { + int percent = 0; + if (id == CSSValueLeft || id == CSSValueRight) { + if (xFound) + return 0; + xFound = true; + if (id == CSSValueRight) + percent = 100; + } + else if (id == CSSValueTop || id == CSSValueBottom) { + if (yFound) + return 0; + yFound = true; + if (id == CSSValueBottom) + percent = 100; + } + else if (id == CSSValueCenter) + // Center is ambiguous, so we're not sure which position we've found yet, an x or a y. + percent = 50; + return CSSPrimitiveValue::create(percent, CSSPrimitiveValue::CSS_PERCENTAGE); + } + if (validUnit(m_valueList->current(), FPercent|FLength, m_strict)) + return CSSPrimitiveValue::create(m_valueList->current()->fValue, + (CSSPrimitiveValue::UnitTypes)m_valueList->current()->unit); + + return 0; +} + +void CSSParser::parseFillPosition(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2) +{ + CSSParserValue* value = m_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 = parseFillPositionXY(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 = m_valueList->next(); + + // First check for the comma. If so, we are finished parsing this value or value pair. + if (value && value->unit == CSSParserValue::Operator && value->iValue == ',') + value = 0; + + bool value2IsX = false, value2IsY = false; + if (value) { + value2 = parseFillPositionXY(value2IsX, value2IsY); + if (value2) + m_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 = CSSPrimitiveValue::create(50, CSSPrimitiveValue::CSS_PERCENTAGE); + + if (value1IsY || value2IsX) + value1.swap(value2); +} + +PassRefPtr<CSSValue> CSSParser::parseFillSize() +{ + CSSParserValue* value = m_valueList->current(); + RefPtr<CSSPrimitiveValue> parsedValue1; + + if (value->id == CSSValueAuto) + parsedValue1 = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_UNKNOWN); + else { + if (!validUnit(value, FLength|FPercent, m_strict)) + return 0; + parsedValue1 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + } + + RefPtr<CSSPrimitiveValue> parsedValue2 = parsedValue1; + if ((value = m_valueList->next())) { + if (value->id == CSSValueAuto) + parsedValue2 = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_UNKNOWN); + else { + if (!validUnit(value, FLength|FPercent, m_strict)) + return 0; + parsedValue2 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + } + } + + return CSSPrimitiveValue::create(Pair::create(parsedValue1.release(), parsedValue2.release())); +} + +bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2, + RefPtr<CSSValue>& retValue1, RefPtr<CSSValue>& retValue2) +{ + RefPtr<CSSValueList> values; + RefPtr<CSSValueList> values2; + CSSParserValue* val; + RefPtr<CSSValue> value; + RefPtr<CSSValue> value2; + + bool allowComma = false; + + retValue1 = retValue2 = 0; + propId1 = propId; + propId2 = propId; + if (propId == CSSPropertyBackgroundPosition) { + propId1 = CSSPropertyBackgroundPositionX; + propId2 = CSSPropertyBackgroundPositionY; + } else if (propId == CSSPropertyWebkitMaskPosition) { + propId1 = CSSPropertyWebkitMaskPositionX; + propId2 = CSSPropertyWebkitMaskPositionY; + } + + while ((val = m_valueList->current())) { + RefPtr<CSSValue> currValue; + RefPtr<CSSValue> currValue2; + + if (allowComma) { + if (val->unit != CSSParserValue::Operator || val->iValue != ',') + return false; + m_valueList->next(); + allowComma = false; + } else { + switch (propId) { + case CSSPropertyBackgroundColor: + currValue = parseBackgroundColor(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyBackgroundAttachment: + case CSSPropertyWebkitMaskAttachment: + if (val->id == CSSValueScroll || val->id == CSSValueFixed) { + currValue = CSSPrimitiveValue::createIdentifier(val->id); + m_valueList->next(); + } + break; + case CSSPropertyBackgroundImage: + case CSSPropertyWebkitMaskImage: + if (parseFillImage(currValue)) + m_valueList->next(); + break; + case CSSPropertyWebkitBackgroundClip: + case CSSPropertyWebkitBackgroundOrigin: + case CSSPropertyWebkitMaskClip: + case CSSPropertyWebkitMaskOrigin: + if (val->id == CSSValueBorder || val->id == CSSValuePadding || val->id == CSSValueContent || val->id == CSSValueText) { + currValue = CSSPrimitiveValue::createIdentifier(val->id); + m_valueList->next(); + } + break; + case CSSPropertyBackgroundPosition: + case CSSPropertyWebkitMaskPosition: + parseFillPosition(currValue, currValue2); + // unlike the other functions, parseFillPosition advances the m_valueList pointer + break; + case CSSPropertyBackgroundPositionX: + case CSSPropertyWebkitMaskPositionX: { + bool xFound = false, yFound = true; + currValue = parseFillPositionXY(xFound, yFound); + if (currValue) + m_valueList->next(); + break; + } + case CSSPropertyBackgroundPositionY: + case CSSPropertyWebkitMaskPositionY: { + bool xFound = true, yFound = false; + currValue = parseFillPositionXY(xFound, yFound); + if (currValue) + m_valueList->next(); + break; + } + case CSSPropertyWebkitBackgroundComposite: + case CSSPropertyWebkitMaskComposite: + if ((val->id >= CSSValueClear && val->id <= CSSValuePlusLighter) || val->id == CSSValueHighlight) { + currValue = CSSPrimitiveValue::createIdentifier(val->id); + m_valueList->next(); + } + break; + case CSSPropertyBackgroundRepeat: + case CSSPropertyWebkitMaskRepeat: + if (val->id >= CSSValueRepeat && val->id <= CSSValueNoRepeat) { + currValue = CSSPrimitiveValue::createIdentifier(val->id); + m_valueList->next(); + } + break; + case CSSPropertyWebkitBackgroundSize: + case CSSPropertyWebkitMaskSize: + currValue = parseFillSize(); + if (currValue) + m_valueList->next(); + break; + } + if (!currValue) + return false; + + if (value && !values) { + values = CSSValueList::createCommaSeparated(); + values->append(value.release()); + } + + if (value2 && !values2) { + values2 = CSSValueList::createCommaSeparated(); + 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 any fill 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::parseAnimationDelay() +{ + CSSParserValue* value = m_valueList->current(); + if (validUnit(value, FTime, m_strict)) + return CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + return 0; +} + +PassRefPtr<CSSValue> CSSParser::parseAnimationDirection() +{ + CSSParserValue* value = m_valueList->current(); + if (value->id == CSSValueNormal || value->id == CSSValueAlternate) + return CSSPrimitiveValue::createIdentifier(value->id); + return 0; +} + +PassRefPtr<CSSValue> CSSParser::parseAnimationDuration() +{ + CSSParserValue* value = m_valueList->current(); + if (validUnit(value, FTime|FNonNeg, m_strict)) + return CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + return 0; +} + +PassRefPtr<CSSValue> CSSParser::parseAnimationIterationCount() +{ + CSSParserValue* value = m_valueList->current(); + if (value->id == CSSValueInfinite) + return CSSPrimitiveValue::createIdentifier(value->id); + if (validUnit(value, FInteger|FNonNeg, m_strict)) + return CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + return 0; +} + +PassRefPtr<CSSValue> CSSParser::parseAnimationName() +{ + CSSParserValue* value = m_valueList->current(); + if (value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT) { + if (value->id == CSSValueNone || (value->unit == CSSPrimitiveValue::CSS_STRING && equalIgnoringCase(value->string, "none"))) { + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + } else { + return CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_STRING); + } + } + return 0; +} + +PassRefPtr<CSSValue> CSSParser::parseAnimationPlayState() +{ + CSSParserValue* value = m_valueList->current(); + if (value->id == CSSValueRunning || value->id == CSSValuePaused) + return CSSPrimitiveValue::createIdentifier(value->id); + return 0; +} + +PassRefPtr<CSSValue> CSSParser::parseAnimationProperty() +{ + CSSParserValue* value = m_valueList->current(); + if (value->unit != CSSPrimitiveValue::CSS_IDENT) + return 0; + int result = cssPropertyID(value->string); + if (result) + return CSSPrimitiveValue::createIdentifier(result); + if (equalIgnoringCase(value->string, "all")) + return CSSPrimitiveValue::createIdentifier(CSSValueAll); + if (equalIgnoringCase(value->string, "none")) + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return 0; +} + +bool CSSParser::parseTimingFunctionValue(CSSParserValueList*& args, double& result) +{ + CSSParserValue* v = args->current(); + if (!validUnit(v, FNumber, m_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 != CSSParserValue::Operator && v->iValue != ',') + return false; + v = args->next(); + return true; +} + +PassRefPtr<CSSValue> CSSParser::parseAnimationTimingFunction() +{ + CSSParserValue* value = m_valueList->current(); + if (value->id == CSSValueEase || value->id == CSSValueLinear || value->id == CSSValueEaseIn || value->id == CSSValueEaseOut || value->id == CSSValueEaseInOut) + return CSSPrimitiveValue::createIdentifier(value->id); + + // We must be a function. + if (value->unit != CSSParserValue::Function) + return 0; + + // The only timing function we accept for now is a cubic bezier function. 4 points must be specified. + CSSParserValueList* 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 CSSTimingFunctionValue::create(x1, y1, x2, y2); +} + +bool CSSParser::parseAnimationProperty(int propId, RefPtr<CSSValue>& result) +{ + RefPtr<CSSValueList> values; + CSSParserValue* val; + RefPtr<CSSValue> value; + bool allowComma = false; + + result = 0; + + while ((val = m_valueList->current())) { + RefPtr<CSSValue> currValue; + if (allowComma) { + if (val->unit != CSSParserValue::Operator || val->iValue != ',') + return false; + m_valueList->next(); + allowComma = false; + } + else { + switch (propId) { + case CSSPropertyWebkitAnimationDelay: + case CSSPropertyWebkitTransitionDelay: + currValue = parseAnimationDelay(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyWebkitAnimationDirection: + currValue = parseAnimationDirection(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyWebkitAnimationDuration: + case CSSPropertyWebkitTransitionDuration: + currValue = parseAnimationDuration(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyWebkitAnimationIterationCount: + currValue = parseAnimationIterationCount(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyWebkitAnimationName: + currValue = parseAnimationName(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyWebkitAnimationPlayState: + currValue = parseAnimationPlayState(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyWebkitTransitionProperty: + currValue = parseAnimationProperty(); + if (currValue) + m_valueList->next(); + break; + case CSSPropertyWebkitAnimationTimingFunction: + case CSSPropertyWebkitTransitionTimingFunction: + currValue = parseAnimationTimingFunction(); + if (currValue) + m_valueList->next(); + break; + } + + if (!currValue) + return false; + + if (value && !values) { + values = CSSValueList::createCommaSeparated(); + 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; +} + + + +#if ENABLE(DASHBOARD_SUPPORT) + +#define DASHBOARD_REGION_NUM_PARAMETERS 6 +#define DASHBOARD_REGION_SHORT_NUM_PARAMETERS 2 + +static CSSParserValue* skipCommaInDashboardRegion (CSSParserValueList *args) +{ + if (args->size() == (DASHBOARD_REGION_NUM_PARAMETERS*2-1) || + args->size() == (DASHBOARD_REGION_SHORT_NUM_PARAMETERS*2-1)) { + CSSParserValue* current = args->current(); + if (current->unit == CSSParserValue::Operator && current->iValue == ',') + return args->next(); + } + return args->current(); +} + +bool CSSParser::parseDashboardRegions(int propId, bool important) +{ + bool valid = true; + + CSSParserValue* value = m_valueList->current(); + + if (value->id == CSSValueNone) { + if (m_valueList->next()) + return false; + addProperty(propId, CSSPrimitiveValue::createIdentifier(value->id), important); + return valid; + } + + RefPtr<DashboardRegion> firstRegion = DashboardRegion::create(); + DashboardRegion* region = 0; + + while (value) { + if (region == 0) { + region = firstRegion.get(); + } else { + RefPtr<DashboardRegion> nextRegion = DashboardRegion::create(); + region->m_next = nextRegion; + region = nextRegion.get(); + } + + if (value->unit != CSSParserValue::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) + CSSParserValueList* 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. + CSSParserValue* 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 CSSValueInvalid by accident. It might be more logical to use something else. + RefPtr<CSSPrimitiveValue> amount = CSSPrimitiveValue::createIdentifier(CSSValueInvalid); + + 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 == CSSValueAuto || validUnit(arg, FLength, m_strict); + if (!valid) + break; + + RefPtr<CSSPrimitiveValue> amount = arg->id == CSSValueAuto ? + CSSPrimitiveValue::createIdentifier(CSSValueAuto) : + CSSPrimitiveValue::create(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 = m_valueList->next(); + } + + if (valid) + addProperty(propId, CSSPrimitiveValue::create(firstRegion.release()), important); + + return valid; +} + +#endif /* ENABLE(DASHBOARD_SUPPORT) */ + +PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bool counters) +{ + unsigned numArgs = args->size(); + if (counters && numArgs != 3 && numArgs != 5) + return 0; + if (!counters && numArgs != 1 && numArgs != 3) + return 0; + + CSSParserValue* i = args->current(); + if (i->unit != CSSPrimitiveValue::CSS_IDENT) + return 0; + RefPtr<CSSPrimitiveValue> identifier = CSSPrimitiveValue::create(i->string, CSSPrimitiveValue::CSS_STRING); + + RefPtr<CSSPrimitiveValue> separator; + if (!counters) + separator = CSSPrimitiveValue::create(String(), CSSPrimitiveValue::CSS_STRING); + else { + i = args->next(); + if (i->unit != CSSParserValue::Operator || i->iValue != ',') + return 0; + + i = args->next(); + if (i->unit != CSSPrimitiveValue::CSS_STRING) + return 0; + + separator = CSSPrimitiveValue::create(i->string, (CSSPrimitiveValue::UnitTypes) i->unit); + } + + RefPtr<CSSPrimitiveValue> listStyle; + i = args->next(); + if (!i) // Make the list style default decimal + listStyle = CSSPrimitiveValue::create(CSSValueDecimal - CSSValueDisc, CSSPrimitiveValue::CSS_NUMBER); + else { + if (i->unit != CSSParserValue::Operator || i->iValue != ',') + return 0; + + i = args->next(); + if (i->unit != CSSPrimitiveValue::CSS_IDENT) + return 0; + + short ls = 0; + if (i->id == CSSValueNone) + ls = CSSValueKatakanaIroha - CSSValueDisc + 1; + else if (i->id >= CSSValueDisc && i->id <= CSSValueKatakanaIroha) + ls = i->id - CSSValueDisc; + else + return 0; + + listStyle = CSSPrimitiveValue::create(ls, (CSSPrimitiveValue::UnitTypes) i->unit); + } + + return CSSPrimitiveValue::create(Counter::create(identifier.release(), listStyle.release(), separator.release())); +} + +bool CSSParser::parseShape(int propId, bool important) +{ + CSSParserValue* value = m_valueList->current(); + CSSParserValueList* 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; + RefPtr<Rect> rect = Rect::create(); + bool valid = true; + int i = 0; + CSSParserValue* a = args->current(); + while (a) { + valid = a->id == CSSValueAuto || validUnit(a, FLength, m_strict); + if (!valid) + break; + RefPtr<CSSPrimitiveValue> length = a->id == CSSValueAuto ? + CSSPrimitiveValue::createIdentifier(CSSValueAuto) : + CSSPrimitiveValue::create(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 == CSSParserValue::Operator && a->iValue == ',') { + a = args->next(); + } else { + valid = false; + break; + } + } + i++; + } + if (valid) { + addProperty(propId, CSSPrimitiveValue::create(rect.release()), important); + m_valueList->next(); + return true; + } + return false; +} + +// [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? 'font-family' +bool CSSParser::parseFont(bool important) +{ + bool valid = true; + CSSParserValue *value = m_valueList->current(); + RefPtr<FontValue> font = FontValue::create(); + // optional font-style, font-variant and font-weight + while (value) { + int id = value->id; + if (id) { + if (id == CSSValueNormal) { + // do nothing, it's the inital value for all three + } else if (id == CSSValueItalic || id == CSSValueOblique) { + if (font->style) + return false; + font->style = CSSPrimitiveValue::createIdentifier(id); + } else if (id == CSSValueSmallCaps) { + if (font->variant) + return false; + font->variant = CSSPrimitiveValue::createIdentifier(id); + } else if (id >= CSSValueBold && id <= CSSValueLighter) { + if (font->weight) + return false; + font->weight = CSSPrimitiveValue::createIdentifier(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 = CSSValue100; + else if (weight == 200) + val = CSSValue200; + else if (weight == 300) + val = CSSValue300; + else if (weight == 400) + val = CSSValue400; + else if (weight == 500) + val = CSSValue500; + else if (weight == 600) + val = CSSValue600; + else if (weight == 700) + val = CSSValue700; + else if (weight == 800) + val = CSSValue800; + else if (weight == 900) + val = CSSValue900; + + if (val) + font->weight = CSSPrimitiveValue::createIdentifier(val); + else + valid = false; + } else { + valid = false; + } + if (!valid) + break; + value = m_valueList->next(); + } + if (!value) + return false; + + // set undefined values to default + if (!font->style) + font->style = CSSPrimitiveValue::createIdentifier(CSSValueNormal); + if (!font->variant) + font->variant = CSSPrimitiveValue::createIdentifier(CSSValueNormal); + if (!font->weight) + font->weight = CSSPrimitiveValue::createIdentifier(CSSValueNormal); + + // now a font size _must_ come + // <absolute-size> | <relative-size> | <length> | <percentage> | inherit + if (value->id >= CSSValueXxSmall && value->id <= CSSValueLarger) + font->size = CSSPrimitiveValue::createIdentifier(value->id); + else if (validUnit(value, FLength|FPercent|FNonNeg, m_strict)) + font->size = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit); + value = m_valueList->next(); + if (!font->size || !value) + return false; + + if (value->unit == CSSParserValue::Operator && value->iValue == '/') { + // line-height + value = m_valueList->next(); + if (!value) + return false; + if (value->id == CSSValueNormal) { + // default value, nothing to do + } else if (validUnit(value, FNumber|FLength|FPercent|FNonNeg, m_strict)) + font->lineHeight = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit); + else + return false; + value = m_valueList->next(); + if (!value) + return false; + } + + if (!font->lineHeight) + font->lineHeight = CSSPrimitiveValue::createIdentifier(CSSValueNormal); + + // font family must come now + font->family = parseFontFamily(); + + if (m_valueList->current() || !font->family) + return false; + + addProperty(CSSPropertyFont, font.release(), important); + return true; +} + +PassRefPtr<CSSValueList> CSSParser::parseFontFamily() +{ + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + CSSParserValue* value = m_valueList->current(); + + FontFamilyValue* currFamily = 0; + while (value) { + CSSParserValue* nextValue = m_valueList->next(); + bool nextValBreaksFont = !nextValue || + (nextValue->unit == CSSParserValue::Operator && nextValue->iValue == ','); + bool nextValIsFontName = nextValue && + ((nextValue->id >= CSSValueSerif && nextValue->id <= CSSValueWebkitBody) || + (nextValue->unit == CSSPrimitiveValue::CSS_STRING || nextValue->unit == CSSPrimitiveValue::CSS_IDENT)); + + if (value->id >= CSSValueSerif && value->id <= CSSValueWebkitBody) { + if (currFamily) + currFamily->appendSpaceSeparated(value->string.characters, value->string.length); + else if (nextValBreaksFont || !nextValIsFontName) + list->append(CSSPrimitiveValue::createIdentifier(value->id)); + else { + RefPtr<FontFamilyValue> newFamily = FontFamilyValue::create(value->string); + currFamily = newFamily.get(); + list->append(newFamily.release()); + } + } else if (value->unit == CSSPrimitiveValue::CSS_STRING) { + // Strings never share in a family name. + currFamily = 0; + list->append(FontFamilyValue::create(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(FontFamilyValue::create(value->string)); + else { + RefPtr<FontFamilyValue> newFamily = FontFamilyValue::create(value->string); + currFamily = newFamily.get(); + list->append(newFamily.release()); + } + } else { + break; + } + + if (!nextValue) + break; + + if (nextValBreaksFont) { + value = m_valueList->next(); + currFamily = 0; + } + else if (nextValIsFontName) + value = nextValue; + else + break; + } + if (!list->length()) + list = 0; + return list.release(); +} + +bool CSSParser::parseFontStyle(bool important) +{ + RefPtr<CSSValueList> values; + if (m_valueList->size() > 1) + values = CSSValueList::createCommaSeparated(); + CSSParserValue* val; + bool expectComma = false; + while ((val = m_valueList->current())) { + RefPtr<CSSPrimitiveValue> parsedValue; + if (!expectComma) { + expectComma = true; + if (val->id == CSSValueNormal || val->id == CSSValueItalic || val->id == CSSValueOblique) + parsedValue = CSSPrimitiveValue::createIdentifier(val->id); + else if (val->id == CSSValueAll && !values) { + // 'all' is only allowed in @font-face and with no other values. Make a value list to + // indicate that we are in the @font-face case. + values = CSSValueList::createCommaSeparated(); + parsedValue = CSSPrimitiveValue::createIdentifier(val->id); + } + } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') { + expectComma = false; + m_valueList->next(); + continue; + } + + if (!parsedValue) + return false; + + m_valueList->next(); + + if (values) + values->append(parsedValue.release()); + else { + addProperty(CSSPropertyFontStyle, parsedValue.release(), important); + return true; + } + } + + if (values && values->length()) { + m_hasFontFaceOnlyValues = true; + addProperty(CSSPropertyFontStyle, values.release(), important); + return true; + } + + return false; +} + +bool CSSParser::parseFontVariant(bool important) +{ + RefPtr<CSSValueList> values; + if (m_valueList->size() > 1) + values = CSSValueList::createCommaSeparated(); + CSSParserValue* val; + bool expectComma = false; + while ((val = m_valueList->current())) { + RefPtr<CSSPrimitiveValue> parsedValue; + if (!expectComma) { + expectComma = true; + if (val->id == CSSValueNormal || val->id == CSSValueSmallCaps) + parsedValue = CSSPrimitiveValue::createIdentifier(val->id); + else if (val->id == CSSValueAll && !values) { + // 'all' is only allowed in @font-face and with no other values. Make a value list to + // indicate that we are in the @font-face case. + values = CSSValueList::createCommaSeparated(); + parsedValue = CSSPrimitiveValue::createIdentifier(val->id); + } + } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') { + expectComma = false; + m_valueList->next(); + continue; + } + + if (!parsedValue) + return false; + + m_valueList->next(); + + if (values) + values->append(parsedValue.release()); + else { + addProperty(CSSPropertyFontVariant, parsedValue.release(), important); + return true; + } + } + + if (values && values->length()) { + m_hasFontFaceOnlyValues = true; + addProperty(CSSPropertyFontVariant, values.release(), important); + return true; + } + + return false; +} + +bool CSSParser::parseFontWeight(bool important) +{ + RefPtr<CSSValueList> values; + if (m_valueList->size() > 1) + values = CSSValueList::createCommaSeparated(); + CSSParserValue* val; + bool expectComma = false; + while ((val = m_valueList->current())) { + RefPtr<CSSPrimitiveValue> parsedValue; + if (!expectComma) { + expectComma = true; + if (val->unit == CSSPrimitiveValue::CSS_IDENT) { + if (val->id >= CSSValueNormal && val->id <= CSSValue900) + parsedValue = CSSPrimitiveValue::createIdentifier(val->id); + else if (val->id == CSSValueAll && !values) { + // 'all' is only allowed in @font-face and with no other values. Make a value list to + // indicate that we are in the @font-face case. + values = CSSValueList::createCommaSeparated(); + parsedValue = CSSPrimitiveValue::createIdentifier(val->id); + } + } else if (validUnit(val, FInteger | FNonNeg, false)) { + int weight = static_cast<int>(val->fValue); + if (!(weight % 100) && weight >= 100 && weight <= 900) + parsedValue = CSSPrimitiveValue::createIdentifier(CSSValue100 + weight / 100 - 1); + } + } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') { + expectComma = false; + m_valueList->next(); + continue; + } + + if (!parsedValue) + return false; + + m_valueList->next(); + + if (values) + values->append(parsedValue.release()); + else { + addProperty(CSSPropertyFontWeight, parsedValue.release(), important); + return true; + } + } + + if (values && values->length()) { + m_hasFontFaceOnlyValues = true; + addProperty(CSSPropertyFontWeight, values.release(), important); + return true; + } + + return false; +} + +bool CSSParser::parseFontFaceSrc() +{ + RefPtr<CSSValueList> values(CSSValueList::createCommaSeparated()); + CSSParserValue* val; + bool expectComma = false; + bool allowFormat = false; + bool failed = false; + RefPtr<CSSFontFaceSrcValue> uriValue; + while ((val = m_valueList->current())) { + RefPtr<CSSFontFaceSrcValue> parsedValue; + if (val->unit == CSSPrimitiveValue::CSS_URI && !expectComma) { + String value = parseURL(val->string); + parsedValue = CSSFontFaceSrcValue::create(m_styleSheet->completeURL(value)); + uriValue = parsedValue; + allowFormat = true; + expectComma = true; + } else if (val->unit == CSSParserValue::Function) { + // There are two allowed functions: local() and format(). + CSSParserValueList* args = val->function->args; + if (args && args->size() == 1) { + if (equalIgnoringCase(val->function->name, "local(") && !expectComma) { + expectComma = true; + allowFormat = false; + CSSParserValue* a = args->current(); + uriValue.clear(); + parsedValue = CSSFontFaceSrcValue::createLocal(a->string); + } else if (equalIgnoringCase(val->function->name, "format(") && allowFormat && uriValue) { + expectComma = true; + allowFormat = false; + uriValue->setFormat(args->current()->string); + uriValue.clear(); + m_valueList->next(); + continue; + } + } + } else if (val->unit == CSSParserValue::Operator && val->iValue == ',' && expectComma) { + expectComma = false; + allowFormat = false; + uriValue.clear(); + m_valueList->next(); + continue; + } + + if (parsedValue) + values->append(parsedValue.release()); + else { + failed = true; + break; + } + m_valueList->next(); + } + + if (values->length() && !failed) { + addProperty(CSSPropertySrc, values.release(), m_important); + m_valueList->next(); + return true; + } + + return false; +} + +bool CSSParser::parseFontFaceUnicodeRange() +{ + RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated(); + CSSParserValue* currentValue; + bool failed = false; + while ((currentValue = m_valueList->current())) { + if (m_valueList->current()->unit != CSSPrimitiveValue::CSS_UNICODE_RANGE) { + failed = true; + break; + } + + String rangeString = m_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(CSSUnicodeRangeValue::create(from, to)); + m_valueList->next(); + } + if (failed || !values->length()) + return false; + addProperty(CSSPropertyUnicodeRange, values.release(), m_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(CSSParserValue* value, int* colorArray, bool parseAlpha) +{ + CSSParserValueList* args = value->function->args; + CSSParserValue* v = args->current(); + Units unitType = FUnknown; + // Get the first value and its type + if (validUnit(v, FInteger, true)) + unitType = FInteger; + else if (validUnit(v, FPercent, true)) + unitType = FPercent; + else + 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 != CSSParserValue::Operator && v->iValue != ',') + return false; + v = args->next(); + if (!validUnit(v, unitType, 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 != CSSParserValue::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; +} + +// The CSS3 specification 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(CSSParserValue* value, double* colorArray, bool parseAlpha) +{ + CSSParserValueList* args = value->function->args; + CSSParserValue* 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 != CSSParserValue::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 != CSSParserValue::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(CSSParserValue* value) +{ + RGBA32 c = Color::transparent; + if (!parseColorFromValue(value ? value : m_valueList->current(), c)) + return 0; + return CSSPrimitiveValue::createColor(c); +} + +bool CSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c, bool svg) +{ + if (!m_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, m_strict)) + return false; + } else if (value->unit == CSSPrimitiveValue::CSS_PARSER_HEXCOLOR || + value->unit == CSSPrimitiveValue::CSS_IDENT || + (!m_strict && value->unit == CSSPrimitiveValue::CSS_DIMENSION)) { + if (!CSSParser::parseColor(value->string, c, m_strict && value->unit == CSSPrimitiveValue::CSS_IDENT)) + return false; + } else if (value->unit == CSSParserValue::Function && + value->function->args != 0 && + value->function->args->size() == 5 /* rgb + two commas */ && + equalIgnoringCase(value->function->name, "rgb(")) { + int colorValues[3]; + if (!parseColorParameters(value, colorValues, false)) + return false; + c = makeRGB(colorValues[0], colorValues[1], colorValues[2]); + } else if (!svg) { + if (value->unit == CSSParserValue::Function && + value->function->args != 0 && + value->function->args->size() == 7 /* rgba + three commas */ && + equalIgnoringCase(value->function->name, "rgba(")) { + int colorValues[4]; + if (!parseColorParameters(value, colorValues, true)) + return false; + c = makeRGBA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]); + } else if (value->unit == CSSParserValue::Function && + value->function->args != 0 && + value->function->args->size() == 5 /* hsl + two commas */ && + equalIgnoringCase(value->function->name, "hsl(")) { + double colorValues[3]; + if (!parseHSLParameters(value, colorValues, false)) + return false; + c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], 1.0); + } else if (value->unit == CSSParserValue::Function && + value->function->args != 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 = CSSValueList::createCommaSeparated(); + + // Construct the current shadow value and add it to the list. + values->append(ShadowValue::create(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(CSSParserValue* v) { + RefPtr<CSSPrimitiveValue> val = CSSPrimitiveValue::create(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; + CSSParserValue* val; + while ((val = m_valueList->current())) { + // Check for a comma break first. + if (val->unit == CSSParserValue::Operator) { + if (val->iValue != ',' || !context.allowBreak) + // Other operators aren't legal or we aren't done with the current shadow + // value. Treat as invalid. + return 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 >= CSSValueAqua && val->id <= CSSValueWindowtext || val->id == CSSValueMenu || + (val->id >= CSSValueWebkitFocusRingColor && val->id <= CSSValueWebkitText && !m_strict)); + if (isColor) { + if (!context.allowColor) + return false; + parsedColor = CSSPrimitiveValue::createIdentifier(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()); + } + + m_valueList->next(); + } + + if (context.allowBreak) { + context.commitValue(); + if (context.values->length()) { + addProperty(propId, context.values.release(), important); + m_valueList->next(); + return true; + } + } + + return false; +} + +bool CSSParser::parseReflect(int propId, bool important) +{ + // box-reflect: <direction> <offset> <mask> + + // Direction comes first. + CSSParserValue* val = m_valueList->current(); + CSSReflectionDirection direction; + switch (val->id) { + case CSSValueAbove: + direction = ReflectionAbove; + break; + case CSSValueBelow: + direction = ReflectionBelow; + break; + case CSSValueLeft: + direction = ReflectionLeft; + break; + case CSSValueRight: + direction = ReflectionRight; + break; + default: + return false; + } + + // The offset comes next. + val = m_valueList->next(); + RefPtr<CSSPrimitiveValue> offset; + if (!val) + offset = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_PX); + else { + if (!validUnit(val, FLength | FPercent, m_strict)) + return false; + offset = CSSPrimitiveValue::create(val->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(val->unit)); + } + + // Now for the mask. + RefPtr<CSSValue> mask; + val = m_valueList->next(); + if (val) { + if (!parseBorderImage(propId, important, mask)) + return false; + } + + RefPtr<CSSReflectValue> reflectValue = CSSReflectValue::create(direction, offset.release(), mask.release()); + addProperty(propId, reflectValue.release(), important); + m_valueList->next(); + return true; +} + +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(PassRefPtr<CSSValue> image) { m_image = image; m_allowNumber = true; } + void commitNumber(CSSParserValue* v) { + PassRefPtr<CSSPrimitiveValue> val = CSSPrimitiveValue::create(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(CSSParserValue* 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; + } + PassRefPtr<CSSValue> commitBorderImage(CSSParser* p, bool important) { + // We need to clone and repeat values for any omissions. + if (!m_right) { + m_right = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType()); + m_bottom = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType()); + m_left = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType()); + } + if (!m_bottom) { + m_bottom = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType()); + m_left = CSSPrimitiveValue::create(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType()); + } + if (!m_left) + m_left = CSSPrimitiveValue::create(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType()); + + // Now build a rect value to hold all four of our primitive values. + RefPtr<Rect> rect = Rect::create(); + 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 = CSSValueStretch; + + // The vertical rule should match the horizontal rule if unspecified. + if (!m_verticalRule) + m_verticalRule = m_horizontalRule; + + // 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) { + CSSParserValueList 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); + CSSParserValueList* oldList = p->m_valueList; + p->m_valueList = &newList; + p->parseValue(CSSPropertyBorderWidth, important); + p->m_valueList = oldList; + } + + // Make our new border image value now. + return CSSBorderImageValue::create(m_image, rect.release(), m_horizontalRule, m_verticalRule); + } + + bool m_allowBreak; + bool m_allowNumber; + bool m_allowSlash; + bool m_allowWidth; + bool m_allowRule; + + RefPtr<CSSValue> m_image; + + RefPtr<CSSPrimitiveValue> m_top; + RefPtr<CSSPrimitiveValue> m_right; + RefPtr<CSSPrimitiveValue> m_bottom; + RefPtr<CSSPrimitiveValue> m_left; + + CSSParserValue* m_borderTop; + CSSParserValue* m_borderRight; + CSSParserValue* m_borderBottom; + CSSParserValue* m_borderLeft; + + int m_horizontalRule; + int m_verticalRule; +}; + +bool CSSParser::parseBorderImage(int propId, bool important, RefPtr<CSSValue>& result) +{ + // Look for an image initially. If the first value is not a URI, then we're done. + BorderImageParseContext context; + CSSParserValue* val = m_valueList->current(); + if (val->unit == CSSPrimitiveValue::CSS_URI) { + String uri = parseURL(val->string); + if (uri.isNull()) + return false; + context.commitImage(CSSImageValue::create(m_styleSheet->completeURL(uri))); + } else if (val->unit == CSSParserValue::Function) { + RefPtr<CSSValue> value; + if ((equalIgnoringCase(val->function->name, "-webkit-gradient(") && parseGradient(value)) || + (equalIgnoringCase(val->function->name, "-webkit-canvas(") && parseCanvas(value))) + context.commitImage(value); + else + return false; + } else + return false; + + while ((val = m_valueList->next())) { + if (context.allowNumber() && validUnit(val, FInteger|FNonNeg|FPercent, true)) { + context.commitNumber(val); + } else if (propId == CSSPropertyWebkitBorderImage && context.allowSlash() && val->unit == CSSParserValue::Operator && val->iValue == '/') { + context.commitSlash(); + } else if (context.allowWidth() && + (val->id == CSSValueThin || val->id == CSSValueMedium || val->id == CSSValueThick || validUnit(val, FLength, m_strict))) { + context.commitWidth(val); + } else if (context.allowRule() && + (val->id == CSSValueStretch || val->id == CSSValueRound || val->id == CSSValueRepeat)) { + context.commitRule(val->id); + } else { + // Something invalid was encountered. + return false; + } + } + + if (context.allowNumber() && propId != CSSPropertyWebkitBorderImage) { + // Allow the slices to be omitted for images that don't fit to a border. We just set the slices to be 0. + context.m_top = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_NUMBER); + context.m_allowBreak = true; + } + + if (context.allowBreak()) { + // Need to fully commit as a single value. + result = context.commitBorderImage(this, important); + return true; + } + + return false; +} + +bool CSSParser::parseCounter(int propId, int defaultValue, bool important) +{ + enum { ID, VAL } state = ID; + + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + RefPtr<CSSPrimitiveValue> counterName; + + while (true) { + CSSParserValue* val = m_valueList->current(); + switch (state) { + case ID: + if (val && val->unit == CSSPrimitiveValue::CSS_IDENT) { + counterName = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING); + state = VAL; + m_valueList->next(); + continue; + } + break; + case VAL: { + int i = defaultValue; + if (val && val->unit == CSSPrimitiveValue::CSS_NUMBER) { + i = (int)val->fValue; + m_valueList->next(); + } + + list->append(CSSPrimitiveValue::create(Pair::create(counterName.release(), + CSSPrimitiveValue::create(i, CSSPrimitiveValue::CSS_NUMBER)))); + state = ID; + continue; + } + } + break; + } + + if (list->length() > 0) { + addProperty(propId, list.release(), important); + return true; + } + + return false; +} + +static PassRefPtr<CSSPrimitiveValue> parseGradientPoint(CSSParserValue* a, bool horizontal) +{ + RefPtr<CSSPrimitiveValue> result; + if (a->unit == CSSPrimitiveValue::CSS_IDENT) { + if ((equalIgnoringCase(a->string, "left") && horizontal) || + (equalIgnoringCase(a->string, "top") && !horizontal)) + result = CSSPrimitiveValue::create(0., CSSPrimitiveValue::CSS_PERCENTAGE); + else if ((equalIgnoringCase(a->string, "right") && horizontal) || + (equalIgnoringCase(a->string, "bottom") && !horizontal)) + result = CSSPrimitiveValue::create(100., CSSPrimitiveValue::CSS_PERCENTAGE); + else if (equalIgnoringCase(a->string, "center")) + result = CSSPrimitiveValue::create(50., CSSPrimitiveValue::CSS_PERCENTAGE); + } else if (a->unit == CSSPrimitiveValue::CSS_NUMBER || a->unit == CSSPrimitiveValue::CSS_PERCENTAGE) + result = CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit); + return result; +} + +bool parseGradientColorStop(CSSParser* p, CSSParserValue* a, CSSGradientColorStop& stop) +{ + if (a->unit != CSSParserValue::Function) + return false; + + if (!equalIgnoringCase(a->function->name, "from(") && + !equalIgnoringCase(a->function->name, "to(") && + !equalIgnoringCase(a->function->name, "color-stop(")) + return false; + + CSSParserValueList* args = a->function->args; + if (!args) + return false; + + if (equalIgnoringCase(a->function->name, "from(") || + equalIgnoringCase(a->function->name, "to(")) { + // The "from" and "to" stops expect 1 argument. + if (args->size() != 1) + return false; + + if (equalIgnoringCase(a->function->name, "from(")) + stop.m_stop = 0.f; + else + stop.m_stop = 1.f; + + int id = args->current()->id; + if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu) + stop.m_color = CSSPrimitiveValue::createIdentifier(id); + else + stop.m_color = p->parseColor(args->current()); + if (!stop.m_color) + return false; + } + + // The "color-stop" function expects 3 arguments. + if (equalIgnoringCase(a->function->name, "color-stop(")) { + if (args->size() != 3) + return false; + + CSSParserValue* stopArg = args->current(); + if (stopArg->unit == CSSPrimitiveValue::CSS_PERCENTAGE) + stop.m_stop = (float)stopArg->fValue / 100.f; + else if (stopArg->unit == CSSPrimitiveValue::CSS_NUMBER) + stop.m_stop = (float)stopArg->fValue; + else + return false; + + stopArg = args->next(); + if (stopArg->unit != CSSParserValue::Operator || stopArg->iValue != ',') + return false; + + stopArg = args->next(); + int id = stopArg->id; + if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu) + stop.m_color = CSSPrimitiveValue::createIdentifier(id); + else + stop.m_color = p->parseColor(stopArg); + if (!stop.m_color) + return false; + } + + return true; +} + +bool CSSParser::parseGradient(RefPtr<CSSValue>& gradient) +{ + RefPtr<CSSGradientValue> result = CSSGradientValue::create(); + + // Walk the arguments. + CSSParserValueList* args = m_valueList->current()->function->args; + if (!args || args->size() == 0) + return false; + + // The first argument is the gradient type. It is an identifier. + CSSParserValue* a = args->current(); + if (!a || a->unit != CSSPrimitiveValue::CSS_IDENT) + return false; + if (equalIgnoringCase(a->string, "linear")) + result->setType(CSSLinearGradient); + else if (equalIgnoringCase(a->string, "radial")) + result->setType(CSSRadialGradient); + else + return false; + + // Comma. + a = args->next(); + if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',') + return false; + + // Next comes the starting point for the gradient as an x y pair. There is no + // comma between the x and the y values. + // First X. It can be left, right, number or percent. + a = args->next(); + if (!a) + return false; + RefPtr<CSSPrimitiveValue> point = parseGradientPoint(a, true); + if (!point) + return false; + result->setFirstX(point.release()); + + // First Y. It can be top, bottom, number or percent. + a = args->next(); + if (!a) + return false; + point = parseGradientPoint(a, false); + if (!point) + return false; + result->setFirstY(point.release()); + + // Comma after the first point. + a = args->next(); + if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',') + return false; + + // For radial gradients only, we now expect a numeric radius. + if (result->type() == CSSRadialGradient) { + a = args->next(); + if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER) + return false; + result->setFirstRadius(CSSPrimitiveValue::create(a->fValue, CSSPrimitiveValue::CSS_NUMBER)); + + // Comma after the first radius. + a = args->next(); + if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',') + return false; + } + + // Next is the ending point for the gradient as an x, y pair. + // Second X. It can be left, right, number or percent. + a = args->next(); + if (!a) + return false; + point = parseGradientPoint(a, true); + if (!point) + return false; + result->setSecondX(point.release()); + + // Second Y. It can be top, bottom, number or percent. + a = args->next(); + if (!a) + return false; + point = parseGradientPoint(a, false); + if (!point) + return false; + result->setSecondY(point.release()); + + // For radial gradients only, we now expect the second radius. + if (result->type() == CSSRadialGradient) { + // Comma after the second point. + a = args->next(); + if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',') + return false; + + a = args->next(); + if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER) + return false; + result->setSecondRadius(CSSPrimitiveValue::create(a->fValue, CSSPrimitiveValue::CSS_NUMBER)); + } + + // We now will accept any number of stops (0 or more). + a = args->next(); + while (a) { + // Look for the comma before the next stop. + if (a->unit != CSSParserValue::Operator || a->iValue != ',') + return false; + + // Now examine the stop itself. + a = args->next(); + if (!a) + return false; + + // The function name needs to be one of "from", "to", or "color-stop." + CSSGradientColorStop stop; + if (!parseGradientColorStop(this, a, stop)) + return false; + result->addStop(stop); + + // Advance + a = args->next(); + } + + gradient = result.release(); + return true; +} + +bool CSSParser::parseCanvas(RefPtr<CSSValue>& canvas) +{ + RefPtr<CSSCanvasValue> result = CSSCanvasValue::create(); + + // Walk the arguments. + CSSParserValueList* args = m_valueList->current()->function->args; + if (!args || args->size() != 1) + return false; + + // The first argument is the canvas name. It is an identifier. + CSSParserValue* a = args->current(); + if (!a || a->unit != CSSPrimitiveValue::CSS_IDENT) + return false; + result->setName(a->string); + canvas = result; + return true; +} + +class TransformOperationInfo { +public: + TransformOperationInfo(const CSSParserString& name) + : m_type(WebKitCSSTransformValue::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 = WebKitCSSTransformValue::ScaleTransformOperation; + else if (equalIgnoringCase(name, "scalex(")) + m_type = WebKitCSSTransformValue::ScaleXTransformOperation; + else + m_type = WebKitCSSTransformValue::ScaleYTransformOperation; + } else if (equalIgnoringCase(name, "rotate(")) { + m_type = WebKitCSSTransformValue::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 = WebKitCSSTransformValue::SkewTransformOperation; + else if (equalIgnoringCase(name, "skewx(")) + m_type = WebKitCSSTransformValue::SkewXTransformOperation; + else + m_type = WebKitCSSTransformValue::SkewYTransformOperation; + } else if (equalIgnoringCase(name, "translate(") || equalIgnoringCase(name, "translatex(") || equalIgnoringCase(name, "translatey(")) { + m_unit = CSSParser::FLength | CSSParser::FPercent; + if (equalIgnoringCase(name, "translate(")) + m_type = WebKitCSSTransformValue::TranslateTransformOperation; + else if (equalIgnoringCase(name, "translatex(")) + m_type = WebKitCSSTransformValue::TranslateXTransformOperation; + else + m_type = WebKitCSSTransformValue::TranslateYTransformOperation; + } else if (equalIgnoringCase(name, "matrix(")) { + m_type = WebKitCSSTransformValue::MatrixTransformOperation; + m_argCount = 11; + m_unit = CSSParser::FNumber; + } + + if (equalIgnoringCase(name, "scale(") || equalIgnoringCase(name, "skew(") || equalIgnoringCase(name, "translate(")) { + m_allowSingleArgument = true; + m_argCount = 3; + } + } + + WebKitCSSTransformValue::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 == WebKitCSSTransformValue::UnknownTransformOperation; } + bool hasCorrectArgCount(unsigned argCount) { return m_argCount == argCount || (m_allowSingleArgument && argCount == 1); } + +private: + WebKitCSSTransformValue::TransformOperationType m_type; + unsigned m_argCount; + bool m_allowSingleArgument; + CSSParser::Units m_unit; +}; + +PassRefPtr<CSSValueList> CSSParser::parseTransform() +{ + if (!m_valueList) + return 0; + + // The transform is a list of functional primitives that specify transform operations. + // We collect a list of WebKitCSSTransformValues, where each value specifies a single operation. + RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) { + if (value->unit != CSSParserValue::Function || !value->function) + return 0; + + // Every primitive requires at least one argument. + CSSParserValueList* 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 WebKitCSSTransformValue for this operation and add it to our list. + RefPtr<WebKitCSSTransformValue> transformValue = WebKitCSSTransformValue::create(info.type()); + list->append(transformValue); + + // Snag our values. + CSSParserValue* 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->append(CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit)); + + a = args->next(); + if (!a) + break; + if (a->unit != CSSParserValue::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 == CSSPropertyWebkitTransformOrigin) { + propId1 = CSSPropertyWebkitTransformOriginX; + propId2 = CSSPropertyWebkitTransformOriginY; + } + + switch (propId) { + case CSSPropertyWebkitTransformOrigin: + parseFillPosition(value, value2); + // Unlike the other functions, parseFillPosition advances the m_valueList pointer + break; + case CSSPropertyWebkitTransformOriginX: { + bool xFound = false, yFound = true; + value = parseFillPositionXY(xFound, yFound); + if (value) + m_valueList->next(); + break; + } + case CSSPropertyWebkitTransformOriginY: { + bool xFound = true, yFound = false; + value = parseFillPositionXY(xFound, yFound); + if (value) + m_valueList->next(); + break; + } + } + + return value; +} + +static inline int yyerror(const char*) { return 1; } + +#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: + case VARCALL: + yylval->string.characters = t; + yylval->string.length = length; + break; + + case IMPORT_SYM: + case PAGE_SYM: + case MEDIA_SYM: + case FONT_FACE_SYM: + case CHARSET_SYM: + case NAMESPACE_SYM: + case WEBKIT_KEYFRAMES_SYM: + + case IMPORTANT_SYM: + break; + + case QEMS: + length--; + case GRADS: + case TURNS: + length--; + case DEGS: + case RADS: + case 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--; + + break; + case VARCALL: + // "-webkit-var("{w}{ident}{w}")" + // strip "-webkit-var(" and ")" + start += 12; + l -= 13; + // strip {w} + while (l && + (*start == ' ' || *start == '\t' || *start == '\r' || + *start == '\n' || *start == '\f')) { + start++; l--; + } + while (l && + (start[l-1] == ' ' || start[l-1] == '\t' || start[l-1] == '\r' || + start[l-1] == '\n' || start[l-1] == '\f')) { + 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; +} + +CSSParserValueList* CSSParser::createFloatingValueList() +{ + CSSParserValueList* list = new CSSParserValueList; + m_floatingValueLists.add(list); + return list; +} + +CSSParserValueList* CSSParser::sinkFloatingValueList(CSSParserValueList* list) +{ + if (list) { + ASSERT(m_floatingValueLists.contains(list)); + m_floatingValueLists.remove(list); + } + return list; +} + +CSSParserFunction* CSSParser::createFloatingFunction() +{ + CSSParserFunction* function = new CSSParserFunction; + m_floatingFunctions.add(function); + return function; +} + +CSSParserFunction* CSSParser::sinkFloatingFunction(CSSParserFunction* function) +{ + if (function) { + ASSERT(m_floatingFunctions.contains(function)); + m_floatingFunctions.remove(function); + } + return function; +} + +CSSParserValue& CSSParser::sinkFloatingValue(CSSParserValue& value) +{ + if (value.unit == CSSParserValue::Function) { + ASSERT(m_floatingFunctions.contains(value.function)); + m_floatingFunctions.remove(value.function); + } + return value; +} + +MediaQueryExp* CSSParser::createFloatingMediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* 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::createFloatingMediaQuery(Vector<MediaQueryExp*>* exprs) +{ + return createFloatingMediaQuery(MediaQuery::None, "all", exprs); +} + +MediaQuery* CSSParser::sinkFloatingMediaQuery(MediaQuery* mq) +{ + ASSERT(mq == m_floatingMediaQuery); + m_floatingMediaQuery = 0; + return mq; +} + +MediaList* CSSParser::createMediaList() +{ + RefPtr<MediaList> list = MediaList::create(); + MediaList* result = list.get(); + m_parsedStyleObjects.append(list.release()); + return result; +} + +CSSRule* CSSParser::createCharsetRule(const CSSParserString& charset) +{ + if (!m_styleSheet) + return 0; + RefPtr<CSSCharsetRule> rule = CSSCharsetRule::create(m_styleSheet, charset); + CSSCharsetRule* result = rule.get(); + m_parsedStyleObjects.append(rule.release()); + return result; +} + +CSSRule* CSSParser::createImportRule(const CSSParserString& url, MediaList* media) +{ + if (!media || !m_styleSheet) + return 0; + RefPtr<CSSImportRule> rule = CSSImportRule::create(m_styleSheet, url, media); + CSSImportRule* result = rule.get(); + m_parsedStyleObjects.append(rule.release()); + return result; +} + +CSSRule* CSSParser::createMediaRule(MediaList* media, CSSRuleList* rules) +{ + if (!media || !rules || !m_styleSheet) + return 0; + RefPtr<CSSMediaRule> rule = CSSMediaRule::create(m_styleSheet, media, rules); + CSSMediaRule* result = rule.get(); + m_parsedStyleObjects.append(rule.release()); + return result; +} + +CSSRuleList* CSSParser::createRuleList() +{ + RefPtr<CSSRuleList> list = CSSRuleList::create(); + CSSRuleList* listPtr = list.get(); + + m_parsedRuleLists.append(list.release()); + return listPtr; +} + +WebKitCSSKeyframesRule* CSSParser::createKeyframesRule() +{ + RefPtr<WebKitCSSKeyframesRule> rule = WebKitCSSKeyframesRule::create(m_styleSheet); + WebKitCSSKeyframesRule* rulePtr = rule.get(); + m_parsedStyleObjects.append(rule.release()); + return rulePtr; +} + +CSSRule* CSSParser::createStyleRule(Vector<CSSSelector*>* selectors) +{ + CSSStyleRule* result = 0; + if (selectors) { + RefPtr<CSSStyleRule> rule = CSSStyleRule::create(m_styleSheet); + rule->adoptSelectorVector(*selectors); + if (m_hasFontFaceOnlyValues) + deleteFontFaceOnlyValues(); + rule->setDeclaration(CSSMutableStyleDeclaration::create(rule.get(), m_parsedProperties, m_numParsedProperties)); + result = rule.get(); + m_parsedStyleObjects.append(rule.release()); + } + clearProperties(); + return result; +} + +CSSRule* CSSParser::createFontFaceRule() +{ + RefPtr<CSSFontFaceRule> rule = CSSFontFaceRule::create(m_styleSheet); + for (int i = 0; i < m_numParsedProperties; ++i) { + CSSProperty* property = m_parsedProperties[i]; + int id = property->id(); + if ((id == CSSPropertyFontWeight || id == CSSPropertyFontStyle || id == CSSPropertyFontVariant) && property->value()->isPrimitiveValue()) { + RefPtr<CSSValue> value = property->m_value.release(); + property->m_value = CSSValueList::createCommaSeparated(); + static_cast<CSSValueList*>(property->m_value.get())->append(value.release()); + } + } + rule->setDeclaration(CSSMutableStyleDeclaration::create(rule.get(), m_parsedProperties, m_numParsedProperties)); + clearProperties(); + CSSFontFaceRule* result = rule.get(); + m_parsedStyleObjects.append(rule.release()); + return result; +} + +#if !ENABLE(CSS_VARIABLES) + +CSSRule* CSSParser::createVariablesRule(MediaList*, bool) +{ + return 0; +} + +bool CSSParser::addVariable(const CSSParserString&, CSSParserValueList*) +{ + return false; +} + +bool CSSParser::addVariableDeclarationBlock(const CSSParserString&) +{ + return false; +} + +#else + +CSSRule* CSSParser::createVariablesRule(MediaList* mediaList, bool variablesKeyword) +{ + RefPtr<CSSVariablesRule> rule = CSSVariablesRule::create(m_styleSheet, mediaList, variablesKeyword); + rule->setDeclaration(CSSVariablesDeclaration::create(rule.get(), m_variableNames, m_variableValues)); + clearVariables(); + CSSRule* result = rule.get(); + m_parsedStyleObjects.append(rule.release()); + return result; +} + +bool CSSParser::addVariable(const CSSParserString& name, CSSParserValueList* valueList) +{ + if (checkForVariables(valueList)) { + delete valueList; + return false; + } + m_variableNames.append(String(name)); + m_variableValues.append(CSSValueList::createFromParserValueList(valueList)); + return true; +} + +bool CSSParser::addVariableDeclarationBlock(const CSSParserString&) +{ +// FIXME: Disabling declarations as variable values for now since they no longer have a common base class with CSSValues. +#if 0 + m_variableNames.append(String(name)); + m_variableValues.append(CSSMutableStyleDeclaration::create(0, m_parsedProperties, m_numParsedProperties)); + clearProperties(); +#endif + return true; +} + +#endif + +void CSSParser::clearVariables() +{ + m_variableNames.clear(); + m_variableValues.clear(); +} + +bool CSSParser::parseVariable(CSSVariablesDeclaration* declaration, const String& variableName, const String& variableValue) +{ + m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet()); + + String nameValuePair = variableName + ": "; + nameValuePair += variableValue; + + setupParser("@-webkit-variables-decls{", nameValuePair, "} "); + cssyyparse(this); + m_rule = 0; + + bool ok = false; + if (m_variableNames.size()) { + ok = true; + declaration->addParsedVariable(variableName, m_variableValues[0]); + } + + clearVariables(); + + return ok; +} + +void CSSParser::parsePropertyWithResolvedVariables(int propId, bool isImportant, CSSMutableStyleDeclaration* declaration, CSSParserValueList* list) +{ + m_valueList = list; + m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet()); + + if (parseValue(propId, isImportant)) + declaration->addParsedProperties(m_parsedProperties, m_numParsedProperties); + + clearProperties(); + m_valueList = 0; +} + +bool CSSParser::checkForVariables(CSSParserValueList* valueList) +{ + if (!valueList || !valueList->containsVariables()) + return false; + + bool hasVariables = false; + for (unsigned i = 0; i < valueList->size(); ++i) { + if (valueList->valueAt(i)->isVariable()) { + hasVariables = true; + break; + } + + if (valueList->valueAt(i)->unit == CSSParserValue::Function && checkForVariables(valueList->valueAt(i)->function->args)) { + hasVariables = true; + break; + } + } + + return hasVariables; +} + +void CSSParser::addUnresolvedProperty(int propId, bool important) +{ + RefPtr<CSSVariableDependentValue> val = CSSVariableDependentValue::create(CSSValueList::createFromParserValueList(m_valueList)); + addProperty(propId, val.release(), important); +} + +void CSSParser::deleteFontFaceOnlyValues() +{ + ASSERT(m_hasFontFaceOnlyValues); + int deletedProperties = 0; + + for (int i = 0; i < m_numParsedProperties; ++i) { + CSSProperty* property = m_parsedProperties[i]; + int id = property->id(); + if ((id == CSSPropertyFontWeight || id == CSSPropertyFontStyle || id == CSSPropertyFontVariant) && property->value()->isValueList()) { + delete property; + deletedProperties++; + } else if (deletedProperties) + m_parsedProperties[i - deletedProperties] = m_parsedProperties[i]; + } + + m_numParsedProperties -= deletedProperties; +} + +WebKitCSSKeyframeRule* CSSParser::createKeyframeRule(CSSParserValueList* keys) +{ + // Create a key string from the passed keys + String keyString; + for (unsigned i = 0; i < keys->size(); ++i) { + float key = (float) keys->valueAt(i)->fValue; + if (i != 0) + keyString += ","; + keyString += String::number(key); + keyString += "%"; + } + + RefPtr<WebKitCSSKeyframeRule> keyframe = WebKitCSSKeyframeRule::create(m_styleSheet); + keyframe->setKeyText(keyString); + keyframe->setDeclaration(CSSMutableStyleDeclaration::create(0, m_parsedProperties, m_numParsedProperties)); + + clearProperties(); + + WebKitCSSKeyframeRule* keyframePtr = keyframe.get(); + m_parsedStyleObjects.append(keyframe.release()); + return keyframePtr; +} + +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 CSSParserString& string) +{ + return cssPropertyID(string.characters, string.length); +} + +int cssValueKeywordID(const CSSParserString& 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/src/3rdparty/webkit/WebCore/css/CSSParser.h b/src/3rdparty/webkit/WebCore/css/CSSParser.h new file mode 100644 index 0000000..83aafa4 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSParser.h @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2003 Lars Knoll (knoll@kde.org) + * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 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. + */ + +#ifndef CSSParser_h +#define CSSParser_h + +#include "AtomicString.h" +#include "Color.h" +#include "CSSParserValues.h" +#include "CSSSelectorList.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 CSSVariablesDeclaration; + class Document; + class MediaList; + class MediaQueryExp; + class StyleBase; + class StyleList; + class WebKitCSSKeyframeRule; + class WebKitCSSKeyframesRule; + + class CSSParser { + public: + CSSParser(bool strictParsing = true); + ~CSSParser(); + + void parseSheet(CSSStyleSheet*, const String&); + PassRefPtr<CSSRule> parseRule(CSSStyleSheet*, const String&); + PassRefPtr<CSSRule> parseKeyframeRule(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&); + + Document* document() const; + + void addProperty(int propId, PassRefPtr<CSSValue>, bool important); + void rollbackLastProperties(int num); + bool hasProperties() const { return m_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 parseFillImage(RefPtr<CSSValue>&); + PassRefPtr<CSSValue> parseFillPositionXY(bool& xFound, bool& yFound); + void parseFillPosition(RefPtr<CSSValue>&, RefPtr<CSSValue>&); + PassRefPtr<CSSValue> parseFillSize(); + + bool parseFillProperty(int propId, int& propId1, int& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&); + bool parseFillShorthand(int propId, const int* properties, int numProperties, bool important); + + void addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval); + + void addAnimationValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval); + + PassRefPtr<CSSValue> parseAnimationDelay(); + PassRefPtr<CSSValue> parseAnimationDirection(); + PassRefPtr<CSSValue> parseAnimationDuration(); + PassRefPtr<CSSValue> parseAnimationIterationCount(); + PassRefPtr<CSSValue> parseAnimationName(); + PassRefPtr<CSSValue> parseAnimationPlayState(); + PassRefPtr<CSSValue> parseAnimationProperty(); + PassRefPtr<CSSValue> parseAnimationTimingFunction(); + + bool parseTimingFunctionValue(CSSParserValueList*& args, double& result); + bool parseAnimationProperty(int propId, RefPtr<CSSValue>&); + bool parseTransitionShorthand(bool important); + bool parseAnimationShorthand(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(CSSParserValueList* args, bool counters); + + bool parseColorParameters(CSSParserValue*, int* colorValues, bool parseAlpha); + bool parseHSLParameters(CSSParserValue*, double* colorValues, bool parseAlpha); + PassRefPtr<CSSPrimitiveValue> parseColor(CSSParserValue* = 0); + bool parseColorFromValue(CSSParserValue*, RGBA32&, bool = false); + void parseSelector(const String&, Document* doc, CSSSelectorList&); + + static bool parseColor(const String&, RGBA32& rgb, bool strict); + + bool parseFontStyle(bool important); + bool parseFontVariant(bool important); + bool parseFontWeight(bool important); + 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, RefPtr<CSSValue>&); + + bool parseReflect(int propId, bool important); + + // Image generators + bool parseCanvas(RefPtr<CSSValue>&); + bool parseGradient(RefPtr<CSSValue>&); + + PassRefPtr<CSSValueList> parseTransform(); + bool parseTransformOrigin(int propId, int& propId1, int& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&); + + bool parseVariable(CSSVariablesDeclaration*, const String& variableName, const String& variableValue); + void parsePropertyWithResolvedVariables(int propId, bool important, CSSMutableStyleDeclaration*, CSSParserValueList*); + + int yyparse(); + + CSSSelector* createFloatingSelector(); + CSSSelector* sinkFloatingSelector(CSSSelector*); + + CSSParserValueList* createFloatingValueList(); + CSSParserValueList* sinkFloatingValueList(CSSParserValueList*); + + CSSParserFunction* createFloatingFunction(); + CSSParserFunction* sinkFloatingFunction(CSSParserFunction*); + + CSSParserValue& sinkFloatingValue(CSSParserValue&); + + MediaList* createMediaList(); + CSSRule* createCharsetRule(const CSSParserString&); + CSSRule* createImportRule(const CSSParserString&, MediaList*); + WebKitCSSKeyframeRule* createKeyframeRule(CSSParserValueList*); + WebKitCSSKeyframesRule* createKeyframesRule(); + CSSRule* createMediaRule(MediaList*, CSSRuleList*); + CSSRuleList* createRuleList(); + CSSRule* createStyleRule(Vector<CSSSelector*>* selectors); + CSSRule* createFontFaceRule(); + CSSRule* createVariablesRule(MediaList*, bool variablesKeyword); + + MediaQueryExp* createFloatingMediaQueryExp(const AtomicString&, CSSParserValueList*); + MediaQueryExp* sinkFloatingMediaQueryExp(MediaQueryExp*); + Vector<MediaQueryExp*>* createFloatingMediaQueryExpList(); + Vector<MediaQueryExp*>* sinkFloatingMediaQueryExpList(Vector<MediaQueryExp*>*); + MediaQuery* createFloatingMediaQuery(MediaQuery::Restrictor, const String&, Vector<MediaQueryExp*>*); + MediaQuery* createFloatingMediaQuery(Vector<MediaQueryExp*>*); + MediaQuery* sinkFloatingMediaQuery(MediaQuery*); + + bool addVariable(const CSSParserString&, CSSParserValueList*); + bool addVariableDeclarationBlock(const CSSParserString&); + bool checkForVariables(CSSParserValueList*); + void addUnresolvedProperty(int propId, bool important); + + Vector<CSSSelector*>* reusableSelectorVector() { return &m_reusableSelectorVector; } + + public: + bool m_strict; + bool m_important; + int m_id; + CSSStyleSheet* m_styleSheet; + RefPtr<CSSRule> m_rule; + RefPtr<CSSRule> m_keyframe; + MediaQuery* m_mediaQuery; + CSSParserValueList* m_valueList; + CSSProperty** m_parsedProperties; + CSSSelectorList* m_selectorListForParseSelector; + int m_numParsedProperties; + int m_maxParsedProperties; + + int m_inParseShorthand; + int m_currentShorthand; + bool m_implicitShorthand; + + bool m_hasFontFaceOnlyValues; + + Vector<String> m_variableNames; + Vector<RefPtr<CSSValue> > m_variableValues; + + AtomicString m_defaultNamespace; + + // 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(); + + void clearVariables(); + + void deleteFontFaceOnlyValues(); + + UChar* m_data; + UChar* yytext; + UChar* yy_c_buf_p; + UChar yy_hold_char; + int yy_last_accepting_state; + UChar* yy_last_accepting_cpos; + int yyleng; + int yyTok; + int yy_start; + + Vector<RefPtr<StyleBase> > m_parsedStyleObjects; + Vector<RefPtr<CSSRuleList> > m_parsedRuleLists; + HashSet<CSSSelector*> m_floatingSelectors; + HashSet<CSSParserValueList*> m_floatingValueLists; + HashSet<CSSParserFunction*> m_floatingFunctions; + + MediaQuery* m_floatingMediaQuery; + MediaQueryExp* m_floatingMediaQueryExp; + Vector<MediaQueryExp*>* m_floatingMediaQueryExpList; + + Vector<CSSSelector*> m_reusableSelectorVector; + + // 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(CSSParserValue*, Units, bool strict); + + friend class TransformOperationInfo; + }; + + int cssPropertyID(const CSSParserString&); + int cssPropertyID(const String&); + int cssValueKeywordID(const CSSParserString&); + + 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; + }; + +} // namespace WebCore + +#endif // CSSParser_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSParserValues.cpp b/src/3rdparty/webkit/WebCore/css/CSSParserValues.cpp new file mode 100644 index 0000000..6baa5b0 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSParserValues.cpp @@ -0,0 +1,82 @@ +/* + * 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. + */ + +#include "config.h" +#include "CSSParserValues.h" +#include "CSSPrimitiveValue.h" +#include "CSSFunctionValue.h" +#include "CSSQuirkPrimitiveValue.h" + +namespace WebCore { + +bool CSSParserValue::isVariable() const +{ + return unit == CSSPrimitiveValue::CSS_PARSER_VARIABLE_FUNCTION_SYNTAX; +} + +CSSParserValueList::~CSSParserValueList() +{ + size_t numValues = m_values.size(); + for (size_t i = 0; i < numValues; i++) { + if (m_values[i].unit == CSSParserValue::Function) + delete m_values[i].function; + } +} + +void CSSParserValueList::addValue(const CSSParserValue& v) +{ + if (v.isVariable()) + m_variablesCount++; + m_values.append(v); +} + +void CSSParserValueList::deleteValueAt(unsigned i) +{ + if (m_values[i].isVariable()) + m_variablesCount--; + m_values.remove(i); +} + +PassRefPtr<CSSValue> CSSParserValue::createCSSValue() +{ + RefPtr<CSSValue> parsedValue; + if (id) + parsedValue = CSSPrimitiveValue::createIdentifier(id); + else if (unit == CSSPrimitiveValue::CSS_IDENT) + parsedValue = CSSPrimitiveValue::create(string, CSSPrimitiveValue::CSS_PARSER_IDENTIFIER); + else if (unit == CSSPrimitiveValue::CSS_NUMBER && isInt) + parsedValue = CSSPrimitiveValue::create(fValue, CSSPrimitiveValue::CSS_PARSER_INTEGER); + else if (unit == CSSParserValue::Operator) { + RefPtr<CSSPrimitiveValue> primitiveValue = CSSPrimitiveValue::createIdentifier(iValue); + primitiveValue->setPrimitiveType(CSSPrimitiveValue::CSS_PARSER_OPERATOR); + parsedValue = primitiveValue; + } else if (unit == CSSParserValue::Function) + parsedValue = CSSFunctionValue::create(function); + else if (unit == CSSPrimitiveValue::CSS_STRING || unit == CSSPrimitiveValue::CSS_URI || unit == CSSPrimitiveValue::CSS_PARSER_HEXCOLOR || isVariable()) + parsedValue = CSSPrimitiveValue::create(string, (CSSPrimitiveValue::UnitTypes)unit); + else if (unit >= CSSPrimitiveValue::CSS_NUMBER && unit <= CSSPrimitiveValue::CSS_KHZ) + parsedValue = CSSPrimitiveValue::create(fValue, (CSSPrimitiveValue::UnitTypes)unit); + else if (unit >= CSSParserValue::Q_EMS) + parsedValue = CSSQuirkPrimitiveValue::create(fValue, CSSPrimitiveValue::CSS_EMS); + return parsedValue; +} + +} + diff --git a/src/3rdparty/webkit/WebCore/css/CSSParserValues.h b/src/3rdparty/webkit/WebCore/css/CSSParserValues.h new file mode 100644 index 0000000..4e0a280 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSParserValues.h @@ -0,0 +1,100 @@ +/* + * 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 CSSParserValues_h +#define CSSParserValues_h + +#include "AtomicString.h" + +namespace WebCore { + +class CSSValue; + +struct CSSParserString { + UChar* characters; + int length; + + void lower(); + + operator String() const { return String(characters, length); } + operator AtomicString() const { return AtomicString(characters, length); } +}; + +struct CSSParserFunction; + +struct CSSParserValue { + int id; + bool isInt; + union { + double fValue; + int iValue; + CSSParserString string; + CSSParserFunction* function; + }; + enum { + Operator = 0x100000, + Function = 0x100001, + Q_EMS = 0x100002 + }; + int unit; + + bool isVariable() const; + + PassRefPtr<CSSValue> createCSSValue(); +}; + +class CSSParserValueList { +public: + CSSParserValueList() + : m_current(0) + , m_variablesCount(0) + { + } + ~CSSParserValueList(); + + void addValue(const CSSParserValue&); + void deleteValueAt(unsigned); + + unsigned size() const { return m_values.size(); } + CSSParserValue* current() { return m_current < m_values.size() ? &m_values[m_current] : 0; } + CSSParserValue* next() { ++m_current; return current(); } + + CSSParserValue* valueAt(unsigned i) { return i < m_values.size() ? &m_values[i] : 0; } + + void clear() { m_values.clear(); } + + bool containsVariables() const { return m_variablesCount; } + +private: + Vector<CSSParserValue, 16> m_values; + unsigned m_current; + unsigned m_variablesCount; +}; + +struct CSSParserFunction { + CSSParserString name; + CSSParserValueList* args; + + ~CSSParserFunction() { delete args; } +}; + +} + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValue.cpp new file mode 100644 index 0000000..a160454 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValue.cpp @@ -0,0 +1,955 @@ +/* + * (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 "CSSPropertyNames.h" +#include "CSSStyleSheet.h" +#include "CSSValueKeywords.h" +#include "Color.h" +#include "Counter.h" +#include "ExceptionCode.h" +#include "Node.h" +#include "Pair.h" +#include "Rect.h" +#include "RenderStyle.h" +#include <wtf/ASCIICType.h> +#include <wtf/StdLibExtras.h> + +#if ENABLE(DASHBOARD_SUPPORT) +#include "DashboardRegion.h" +#endif + +using namespace WTF; + +namespace WebCore { + +// A more stylish solution than sharing would be to turn CSSPrimitiveValue (or CSSValues in general) into non-virtual, +// non-refcounted simple type with value semantics. In practice these sharing tricks get similar memory benefits +// with less need for refactoring. + +PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createIdentifier(int ident) +{ + static RefPtr<CSSPrimitiveValue>* identValueCache = new RefPtr<CSSPrimitiveValue>[numCSSValueKeywords]; + if (ident >= 0 && ident < numCSSValueKeywords) { + RefPtr<CSSPrimitiveValue> primitiveValue = identValueCache[ident]; + if (!primitiveValue) { + primitiveValue = adoptRef(new CSSPrimitiveValue(ident)); + identValueCache[ident] = primitiveValue; + } + return primitiveValue.release(); + } + return adoptRef(new CSSPrimitiveValue(ident)); +} + +PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createColor(unsigned rgbValue) +{ + typedef HashMap<unsigned, RefPtr<CSSPrimitiveValue> > ColorValueCache; + static ColorValueCache* colorValueCache = new ColorValueCache; + // These are the empty and deleted values of the hash table. + if (rgbValue == Color::transparent) { + static CSSPrimitiveValue* colorTransparent = new CSSPrimitiveValue(Color::transparent); + return colorTransparent; + } + if (rgbValue == Color::white) { + static CSSPrimitiveValue* colorWhite = new CSSPrimitiveValue(Color::white); + return colorWhite; + } + RefPtr<CSSPrimitiveValue> primitiveValue = colorValueCache->get(rgbValue); + if (primitiveValue) + return primitiveValue.release(); + primitiveValue = adoptRef(new CSSPrimitiveValue(rgbValue)); + // Just wipe out the cache and start rebuilding when it gets too big. + const int maxColorCacheSize = 512; + if (colorValueCache->size() >= maxColorCacheSize) + colorValueCache->clear(); + colorValueCache->add(rgbValue, primitiveValue); + + return primitiveValue.release(); +} + +PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::create(double value, UnitTypes type) +{ + // Small integers are very common. Try to share them. + const int cachedIntegerCount = 128; + // Other common primitive types have UnitTypes smaller than this. + const int maxCachedUnitType = CSS_PX; + typedef RefPtr<CSSPrimitiveValue>(* IntegerValueCache)[maxCachedUnitType + 1]; + static IntegerValueCache integerValueCache = new RefPtr<CSSPrimitiveValue>[cachedIntegerCount][maxCachedUnitType + 1]; + if (type <= maxCachedUnitType && value >= 0 && value < cachedIntegerCount) { + int intValue = static_cast<int>(value); + if (value == intValue) { + RefPtr<CSSPrimitiveValue> primitiveValue = integerValueCache[intValue][type]; + if (!primitiveValue) { + primitiveValue = adoptRef(new CSSPrimitiveValue(value, type)); + integerValueCache[intValue][type] = primitiveValue; + } + return primitiveValue.release(); + } + } + + return adoptRef(new CSSPrimitiveValue(value, type)); +} + +PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::create(const String& value, UnitTypes type) +{ + return adoptRef(new CSSPrimitiveValue(value, type)); +} + +static const char* valueOrPropertyName(int valueOrPropertyID) +{ + if (const char* valueName = getValueName(valueOrPropertyID)) + return valueName; + return getPropertyName(static_cast<CSSPropertyID>(valueOrPropertyID)); +} + +// "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 = CSSValueAuto; + break; + case WebCore::Fixed: + m_type = CSS_PX; + m_value.num = length.value(); + break; + case Intrinsic: + m_type = CSS_IDENT; + m_value.ident = CSSValueIntrinsic; + break; + case MinIntrinsic: + m_type = CSS_IDENT; + m_value.ident = CSSValueMinIntrinsic; + 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(); +} + +#if ENABLE(DASHBOARD_SUPPORT) +void CSSPrimitiveValue::init(PassRefPtr<DashboardRegion> r) +{ + m_type = CSS_DASHBOARD_REGION; + m_value.region = r.releaseRef(); +} +#endif + +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: + case CSS_PARSER_VARIABLE_FUNCTION_SYNTAX: + case CSS_PARSER_HEXCOLOR: + 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; +#if ENABLE(DASHBOARD_SUPPORT) + case CSS_DASHBOARD_REGION: + if (m_value.region) + m_value.region->deref(); + break; +#endif + 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 = computeLengthDouble(style, multiplier); + + // 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 = computeLengthDouble(style, multiplier); + + // 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 = computeLengthDouble(style, multiplier); + + // 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 computingFontSize) +{ + return static_cast<float>(computeLengthDouble(style, 1.0, computingFontSize)); +} + +float CSSPrimitiveValue::computeLengthFloat(RenderStyle* style, double multiplier, bool computingFontSize) +{ + return static_cast<float>(computeLengthDouble(style, multiplier, computingFontSize)); +} + +double CSSPrimitiveValue::computeLengthDouble(RenderStyle* style, double multiplier, bool computingFontSize) +{ + unsigned short type = primitiveType(); + + // We do not apply the zoom factor when we are computing the value of the font-size property. The zooming + // for font sizes is much more complicated, since we have to worry about enforcing the minimum font size preference + // as well as enforcing the implicit "smart minimum." In addition the CSS property text-size-adjust is used to + // prevent text from zooming at all. Therefore we will not apply the zoom here if we are computing font-size. + bool applyZoomMultiplier = !computingFontSize; + + double factor = 1.0; + switch (type) { + case CSS_EMS: + applyZoomMultiplier = false; + factor = computingFontSize ? style->fontDescription().specifiedSize() : style->fontDescription().computedSize(); + break; + case CSS_EXS: + // FIXME: We have a bug right now where the zoom will be applied twice to EX units. + // We really need to compute EX using fontMetrics for the original specifiedSize and not use + // our actual constructed rendering font. + applyZoomMultiplier = false; + 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; + } + + double result = getDoubleValue() * factor; + if (!applyZoomMultiplier || multiplier == 1.0) + return result; + + // Any original result that was >= 1 should not be allowed to fall below 1. This keeps border lines from + // vanishing. + double zoomedResult = result * multiplier; + if (result >= 1.0) + zoomedResult = max(1.0, zoomedResult); + return zoomedResult; +} + +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: + case CSS_PARSER_VARIABLE_FUNCTION_SYNTAX: + return m_value.string; + case CSS_IDENT: + return valueOrPropertyName(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: + case CSS_PARSER_VARIABLE_FUNCTION_SYNTAX: + return m_value.string; + case CSS_IDENT: + return valueOrPropertyName(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: + case CSS_PARSER_INTEGER: + 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_TURN: + text = String::format("%.6lgturn", 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 = valueOrPropertyName(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: { + DEFINE_STATIC_LOCAL(const String, rectParen, ("rect(")); + + Rect* rectVal = getRectValue(); + Vector<UChar> result; + result.reserveCapacity(32); + append(result, rectParen); + + append(result, rectVal->top()->cssText()); + result.append(' '); + + append(result, rectVal->right()->cssText()); + result.append(' '); + + append(result, rectVal->bottom()->cssText()); + result.append(' '); + + append(result, rectVal->left()->cssText()); + result.append(')'); + + return String::adopt(result); + } + case CSS_RGBCOLOR: + case CSS_PARSER_HEXCOLOR: { + DEFINE_STATIC_LOCAL(const String, commaSpace, (", ")); + DEFINE_STATIC_LOCAL(const String, rgbParen, ("rgb(")); + DEFINE_STATIC_LOCAL(const String, rgbaParen, ("rgba(")); + + RGBA32 rgbColor = m_value.rgbcolor; + if (m_type == CSS_PARSER_HEXCOLOR) + Color::parseHexColor(m_value.string, rgbColor); + Color color(rgbColor); + + Vector<UChar> result; + result.reserveCapacity(32); + if (color.hasAlpha()) + append(result, rgbaParen); + else + append(result, rgbParen); + + appendNumber(result, static_cast<unsigned char>(color.red())); + append(result, commaSpace); + + appendNumber(result, static_cast<unsigned char>(color.green())); + append(result, commaSpace); + + appendNumber(result, static_cast<unsigned char>(color.blue())); + if (color.hasAlpha()) { + append(result, commaSpace); + append(result, String::number(static_cast<float>(color.alpha()) / 256.0f)); + } + + result.append(')'); + return String::adopt(result); + } + case CSS_PAIR: + text = m_value.pair->first()->cssText(); + text += " "; + text += m_value.pair->second()->cssText(); + break; +#if ENABLE(DASHBOARD_SUPPORT) + 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() == CSSValueInvalid) { + 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() == CSSValueInvalid); + ASSERT(region->bottom()->getIdent() == CSSValueInvalid); + ASSERT(region->left()->getIdent() == CSSValueInvalid); + } else { + text.append(' '); + text += region->top()->cssText() + " "; + text += region->right()->cssText() + " "; + text += region->bottom()->cssText() + " "; + text += region->left()->cssText(); + } + text += ")"; + } + break; +#endif + case CSS_PARSER_VARIABLE_FUNCTION_SYNTAX: + text = "-webkit-var("; + text += m_value.string; + text += ")"; + break; + case CSS_PARSER_OPERATOR: { + char c = static_cast<char>(m_value.ident); + text = String(&c, 1U); + break; + } + case CSS_PARSER_IDENTIFIER: + text = quoteStringIfNeeded(m_value.string); + break; + } + return text; +} + +CSSParserValue CSSPrimitiveValue::parserValue() const +{ + // We only have to handle a subset of types. + CSSParserValue value; + value.id = 0; + value.isInt = false; + value.unit = CSSPrimitiveValue::CSS_IDENT; + switch (m_type) { + case CSS_NUMBER: + case CSS_PERCENTAGE: + case CSS_EMS: + case CSS_EXS: + case CSS_PX: + case CSS_CM: + case CSS_MM: + case CSS_IN: + case CSS_PT: + case CSS_PC: + case CSS_DEG: + case CSS_RAD: + case CSS_GRAD: + case CSS_MS: + case CSS_S: + case CSS_HZ: + case CSS_KHZ: + case CSS_DIMENSION: + case CSS_TURN: + value.fValue = m_value.num; + value.unit = m_type; + break; + case CSS_STRING: + case CSS_URI: + case CSS_PARSER_VARIABLE_FUNCTION_SYNTAX: + case CSS_PARSER_HEXCOLOR: + value.string.characters = const_cast<UChar*>(m_value.string->characters()); + value.string.length = m_value.string->length(); + value.unit = m_type; + break; + case CSS_IDENT: { + value.id = m_value.ident; + String name = valueOrPropertyName(m_value.ident); + value.string.characters = const_cast<UChar*>(name.characters()); + value.string.length = name.length(); + break; + } + case CSS_PARSER_OPERATOR: + value.iValue = m_value.ident; + value.unit = CSSParserValue::Operator; + break; + case CSS_PARSER_INTEGER: + value.fValue = m_value.num; + value.unit = CSSPrimitiveValue::CSS_NUMBER; + value.isInt = true; + break; + case CSS_PARSER_IDENTIFIER: + value.string.characters = const_cast<UChar*>(m_value.string->characters()); + value.string.length = m_value.string->length(); + value.unit = CSSPrimitiveValue::CSS_IDENT; + break; + case CSS_UNKNOWN: + case CSS_ATTR: + case CSS_COUNTER: + case CSS_RECT: + case CSS_RGBCOLOR: + case CSS_PAIR: +#if ENABLE(DASHBOARD_SUPPORT) + case CSS_DASHBOARD_REGION: +#endif + ASSERT_NOT_REACHED(); + break; + } + + return value; +} + +void CSSPrimitiveValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const CSSStyleSheet* styleSheet) +{ + if (m_type == CSS_URI) + addSubresourceURL(urls, styleSheet->completeURL(m_value.string)); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValue.h b/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValue.h new file mode 100644 index 0000000..d552ca0 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValue.h @@ -0,0 +1,212 @@ +/* + * (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; +class Pair; +class Rect; +class RenderStyle; +class StringImpl; + +struct Length; + +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: Dashboard region should not be a primitive value. + CSS_UNICODE_RANGE = 102, + + // These next types are just used internally to allow us to translate back and forth from CSSPrimitiveValues to CSSParserValues. + CSS_PARSER_OPERATOR = 103, + CSS_PARSER_INTEGER = 104, + CSS_PARSER_VARIABLE_FUNCTION_SYNTAX = 105, + CSS_PARSER_HEXCOLOR = 106, + + // This is used internally for unknown identifiers + CSS_PARSER_IDENTIFIER = 107, + + // This unit is in CSS 3, but that isn't a finished standard yet + CSS_TURN = 108 + }; + + static PassRefPtr<CSSPrimitiveValue> createIdentifier(int ident); + static PassRefPtr<CSSPrimitiveValue> createColor(unsigned rgbValue); + static PassRefPtr<CSSPrimitiveValue> create(double value, UnitTypes type); + static PassRefPtr<CSSPrimitiveValue> create(const String& value, UnitTypes type); + + template<typename T> static PassRefPtr<CSSPrimitiveValue> create(T value) + { + return adoptRef(new CSSPrimitiveValue(value)); + } + + virtual ~CSSPrimitiveValue(); + + void cleanup(); + + unsigned short primitiveType() const { return m_type; } + + bool isVariable() const { return m_type == CSS_PARSER_VARIABLE_FUNCTION_SYNTAX; } + + /* + * 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 computingFontSize = false); + float computeLengthFloat(RenderStyle*, double multiplier, bool computingFontSize = false); + double computeLengthDouble(RenderStyle*, double multiplier = 1.0, bool computingFontSize = false); + + // 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; } + + 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; } + + virtual CSSParserValue parserValue() const; + + virtual void addSubresourceStyleURLs(ListHashSet<KURL>&, const CSSStyleSheet*); + +protected: + // FIXME: int vs. unsigned overloading is too subtle to distinguish the color and identifier cases. + CSSPrimitiveValue(int ident); + CSSPrimitiveValue(double, UnitTypes); + CSSPrimitiveValue(const String&, UnitTypes); + +private: + CSSPrimitiveValue(); + 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); } + + static void create(int); // compile-time guard + static void create(unsigned); // compile-time guard + 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: Dashboard region should not be a primitive value. + + virtual bool isPrimitiveValue() const { return true; } + + virtual unsigned short cssValueType() const; + + int m_type; + union { + int ident; + double num; + StringImpl* string; + Counter* counter; + Rect* rect; + unsigned rgbcolor; + Pair* pair; + DashboardRegion* region; + } m_value; +}; + +} // namespace WebCore + +#endif // CSSPrimitiveValue_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValue.idl b/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValue.idl new file mode 100644 index 0000000..b049c29 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValueMappings.h b/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValueMappings.h new file mode 100644 index 0000000..fcbf06a --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSPrimitiveValueMappings.h @@ -0,0 +1,2204 @@ +/* + * 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 = CSSValueNone; + break; + case BHIDDEN: + m_value.ident = CSSValueHidden; + break; + case INSET: + m_value.ident = CSSValueInset; + break; + case GROOVE: + m_value.ident = CSSValueGroove; + break; + case RIDGE: + m_value.ident = CSSValueRidge; + break; + case OUTSET: + m_value.ident = CSSValueOutset; + break; + case DOTTED: + m_value.ident = CSSValueDotted; + break; + case DASHED: + m_value.ident = CSSValueDashed; + break; + case SOLID: + m_value.ident = CSSValueSolid; + break; + case DOUBLE: + m_value.ident = CSSValueDouble; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EBorderStyle() const +{ + return (EBorderStyle)(m_value.ident - CSSValueNone); +} + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(CompositeOperator e) + : m_type(CSS_IDENT) +{ + switch (e) { + case CompositeClear: + m_value.ident = CSSValueClear; + break; + case CompositeCopy: + m_value.ident = CSSValueCopy; + break; + case CompositeSourceOver: + m_value.ident = CSSValueSourceOver; + break; + case CompositeSourceIn: + m_value.ident = CSSValueSourceIn; + break; + case CompositeSourceOut: + m_value.ident = CSSValueSourceOut; + break; + case CompositeSourceAtop: + m_value.ident = CSSValueSourceAtop; + break; + case CompositeDestinationOver: + m_value.ident = CSSValueDestinationOver; + break; + case CompositeDestinationIn: + m_value.ident = CSSValueDestinationIn; + break; + case CompositeDestinationOut: + m_value.ident = CSSValueDestinationOut; + break; + case CompositeDestinationAtop: + m_value.ident = CSSValueDestinationAtop; + break; + case CompositeXOR: + m_value.ident = CSSValueXor; + break; + case CompositePlusDarker: + m_value.ident = CSSValuePlusDarker; + break; + case CompositeHighlight: + m_value.ident = CSSValueHighlight; + break; + case CompositePlusLighter: + m_value.ident = CSSValuePlusLighter; + break; + } +} + +template<> inline CSSPrimitiveValue::operator CompositeOperator() const +{ + switch (m_value.ident) { + case CSSValueClear: + return CompositeClear; + case CSSValueCopy: + return CompositeCopy; + case CSSValueSourceOver: + return CompositeSourceOver; + case CSSValueSourceIn: + return CompositeSourceIn; + case CSSValueSourceOut: + return CompositeSourceOut; + case CSSValueSourceAtop: + return CompositeSourceAtop; + case CSSValueDestinationOver: + return CompositeDestinationOver; + case CSSValueDestinationIn: + return CompositeDestinationIn; + case CSSValueDestinationOut: + return CompositeDestinationOut; + case CSSValueDestinationAtop: + return CompositeDestinationAtop; + case CSSValueXor: + return CompositeXOR; + case CSSValuePlusDarker: + return CompositePlusDarker; + case CSSValueHighlight: + return CompositeHighlight; + case CSSValuePlusLighter: + return CompositePlusLighter; + default: + ASSERT_NOT_REACHED(); + return CompositeClear; + } +} + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ControlPart e) + : m_type(CSS_IDENT) +{ + switch (e) { + case NoControlPart: + m_value.ident = CSSValueNone; + break; + case CheckboxPart: + m_value.ident = CSSValueCheckbox; + break; + case RadioPart: + m_value.ident = CSSValueRadio; + break; + case PushButtonPart: + m_value.ident = CSSValuePushButton; + break; + case SquareButtonPart: + m_value.ident = CSSValueSquareButton; + break; + case ButtonPart: + m_value.ident = CSSValueButton; + break; + case ButtonBevelPart: + m_value.ident = CSSValueButtonBevel; + break; + case DefaultButtonPart: + m_value.ident = CSSValueDefaultButton; + break; + case ListboxPart: + m_value.ident = CSSValueListbox; + break; + case ListItemPart: + m_value.ident = CSSValueListitem; + break; + case MediaFullscreenButtonPart: + m_value.ident = CSSValueMediaFullscreenButton; + break; + case MediaPlayButtonPart: + m_value.ident = CSSValueMediaPlayButton; + break; + case MediaMuteButtonPart: + m_value.ident = CSSValueMediaMuteButton; + break; + case MediaSeekBackButtonPart: + m_value.ident = CSSValueMediaSeekBackButton; + break; + case MediaSeekForwardButtonPart: + m_value.ident = CSSValueMediaSeekForwardButton; + break; + case MediaSliderPart: + m_value.ident = CSSValueMediaSlider; + break; + case MediaSliderThumbPart: + m_value.ident = CSSValueMediaSliderthumb; + break; + case MenulistPart: + m_value.ident = CSSValueMenulist; + break; + case MenulistButtonPart: + m_value.ident = CSSValueMenulistButton; + break; + case MenulistTextPart: + m_value.ident = CSSValueMenulistText; + break; + case MenulistTextFieldPart: + m_value.ident = CSSValueMenulistTextfield; + break; + case SliderHorizontalPart: + m_value.ident = CSSValueSliderHorizontal; + break; + case SliderVerticalPart: + m_value.ident = CSSValueSliderVertical; + break; + case SliderThumbHorizontalPart: + m_value.ident = CSSValueSliderthumbHorizontal; + break; + case SliderThumbVerticalPart: + m_value.ident = CSSValueSliderthumbVertical; + break; + case CaretPart: + m_value.ident = CSSValueCaret; + break; + case SearchFieldPart: + m_value.ident = CSSValueSearchfield; + break; + case SearchFieldDecorationPart: + m_value.ident = CSSValueSearchfieldDecoration; + break; + case SearchFieldResultsDecorationPart: + m_value.ident = CSSValueSearchfieldResultsDecoration; + break; + case SearchFieldResultsButtonPart: + m_value.ident = CSSValueSearchfieldResultsButton; + break; + case SearchFieldCancelButtonPart: + m_value.ident = CSSValueSearchfieldCancelButton; + break; + case TextFieldPart: + m_value.ident = CSSValueTextfield; + break; + case TextAreaPart: + m_value.ident = CSSValueTextarea; + break; + case CapsLockIndicatorPart: + m_value.ident = CSSValueCapsLockIndicator; + break; + } +} + +template<> inline CSSPrimitiveValue::operator ControlPart() const +{ + if (m_value.ident == CSSValueNone) + return NoControlPart; + else + return ControlPart(m_value.ident - CSSValueCheckbox + 1); +} + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EFillBox e) + : m_type(CSS_IDENT) +{ + switch (e) { + case BorderFillBox: + m_value.ident = CSSValueBorder; + break; + case PaddingFillBox: + m_value.ident = CSSValuePadding; + break; + case ContentFillBox: + m_value.ident = CSSValueContent; + break; + case TextFillBox: + m_value.ident = CSSValueText; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EFillBox() const +{ + switch (m_value.ident) { + case CSSValueBorder: + return BorderFillBox; + case CSSValuePadding: + return PaddingFillBox; + case CSSValueContent: + return ContentFillBox; + case CSSValueText: + return TextFillBox; + default: + ASSERT_NOT_REACHED(); + return BorderFillBox; + } +} + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EFillRepeat e) + : m_type(CSS_IDENT) +{ + switch (e) { + case RepeatFill: + m_value.ident = CSSValueRepeat; + break; + case RepeatXFill: + m_value.ident = CSSValueRepeatX; + break; + case RepeatYFill: + m_value.ident = CSSValueRepeatY; + break; + case NoRepeatFill: + m_value.ident = CSSValueNoRepeat; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EFillRepeat() const +{ + switch (m_value.ident) { + case CSSValueRepeat: + return RepeatFill; + case CSSValueRepeatX: + return RepeatXFill; + case CSSValueRepeatY: + return RepeatYFill; + case CSSValueNoRepeat: + return NoRepeatFill; + default: + ASSERT_NOT_REACHED(); + return RepeatFill; + } +} + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EBoxAlignment e) + : m_type(CSS_IDENT) +{ + switch (e) { + case BSTRETCH: + m_value.ident = CSSValueStretch; + break; + case BSTART: + m_value.ident = CSSValueStart; + break; + case BCENTER: + m_value.ident = CSSValueCenter; + break; + case BEND: + m_value.ident = CSSValueEnd; + break; + case BBASELINE: + m_value.ident = CSSValueBaseline; + break; + case BJUSTIFY: + m_value.ident = CSSValueJustify; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EBoxAlignment() const +{ + switch (m_value.ident) { + case CSSValueStretch: + return BSTRETCH; + case CSSValueStart: + return BSTART; + case CSSValueEnd: + return BEND; + case CSSValueCenter: + return BCENTER; + case CSSValueBaseline: + return BBASELINE; + case CSSValueJustify: + 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 = CSSValueNormal; + break; + case BREVERSE: + m_value.ident = CSSValueReverse; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EBoxDirection() const +{ + switch (m_value.ident) { + case CSSValueNormal: + return BNORMAL; + case CSSValueReverse: + 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 = CSSValueSingle; + break; + case MULTIPLE: + m_value.ident = CSSValueMultiple; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EBoxLines() const +{ + switch (m_value.ident) { + case CSSValueSingle: + return SINGLE; + case CSSValueMultiple: + 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 = CSSValueHorizontal; + break; + case VERTICAL: + m_value.ident = CSSValueVertical; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EBoxOrient() const +{ + switch (m_value.ident) { + case CSSValueHorizontal: + case CSSValueInlineAxis: + return HORIZONTAL; + case CSSValueVertical: + 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 = CSSValueLeft; + break; + case CAPRIGHT: + m_value.ident = CSSValueRight; + break; + case CAPTOP: + m_value.ident = CSSValueTop; + break; + case CAPBOTTOM: + m_value.ident = CSSValueBottom; + break; + } +} + +template<> inline CSSPrimitiveValue::operator ECaptionSide() const +{ + switch (m_value.ident) { + case CSSValueLeft: + return CAPLEFT; + case CSSValueRight: + return CAPRIGHT; + case CSSValueTop: + return CAPTOP; + case CSSValueBottom: + 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 = CSSValueNone; + break; + case CLEFT: + m_value.ident = CSSValueLeft; + break; + case CRIGHT: + m_value.ident = CSSValueRight; + break; + case CBOTH: + m_value.ident = CSSValueBoth; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EClear() const +{ + switch (m_value.ident) { + case CSSValueNone: + return CNONE; + case CSSValueLeft: + return CLEFT; + case CSSValueRight: + return CRIGHT; + case CSSValueBoth: + 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 = CSSValueAuto; + break; + case CURSOR_CROSS: + m_value.ident = CSSValueCrosshair; + break; + case CURSOR_DEFAULT: + m_value.ident = CSSValueDefault; + break; + case CURSOR_POINTER: + m_value.ident = CSSValuePointer; + break; + case CURSOR_MOVE: + m_value.ident = CSSValueMove; + break; + case CURSOR_CELL: + m_value.ident = CSSValueCell; + break; + case CURSOR_VERTICAL_TEXT: + m_value.ident = CSSValueVerticalText; + break; + case CURSOR_CONTEXT_MENU: + m_value.ident = CSSValueContextMenu; + break; + case CURSOR_ALIAS: + m_value.ident = CSSValueAlias; + break; + case CURSOR_COPY: + m_value.ident = CSSValueCopy; + break; + case CURSOR_NONE: + m_value.ident = CSSValueNone; + break; + case CURSOR_PROGRESS: + m_value.ident = CSSValueProgress; + break; + case CURSOR_NO_DROP: + m_value.ident = CSSValueNoDrop; + break; + case CURSOR_NOT_ALLOWED: + m_value.ident = CSSValueNotAllowed; + break; + case CURSOR_WEBKIT_ZOOM_IN: + m_value.ident = CSSValueWebkitZoomIn; + break; + case CURSOR_WEBKIT_ZOOM_OUT: + m_value.ident = CSSValueWebkitZoomOut; + break; + case CURSOR_E_RESIZE: + m_value.ident = CSSValueEResize; + break; + case CURSOR_NE_RESIZE: + m_value.ident = CSSValueNeResize; + break; + case CURSOR_NW_RESIZE: + m_value.ident = CSSValueNwResize; + break; + case CURSOR_N_RESIZE: + m_value.ident = CSSValueNResize; + break; + case CURSOR_SE_RESIZE: + m_value.ident = CSSValueSeResize; + break; + case CURSOR_SW_RESIZE: + m_value.ident = CSSValueSwResize; + break; + case CURSOR_S_RESIZE: + m_value.ident = CSSValueSResize; + break; + case CURSOR_W_RESIZE: + m_value.ident = CSSValueWResize; + break; + case CURSOR_EW_RESIZE: + m_value.ident = CSSValueEwResize; + break; + case CURSOR_NS_RESIZE: + m_value.ident = CSSValueNsResize; + break; + case CURSOR_NESW_RESIZE: + m_value.ident = CSSValueNeswResize; + break; + case CURSOR_NWSE_RESIZE: + m_value.ident = CSSValueNwseResize; + break; + case CURSOR_COL_RESIZE: + m_value.ident = CSSValueColResize; + break; + case CURSOR_ROW_RESIZE: + m_value.ident = CSSValueRowResize; + break; + case CURSOR_TEXT: + m_value.ident = CSSValueText; + break; + case CURSOR_WAIT: + m_value.ident = CSSValueWait; + break; + case CURSOR_HELP: + m_value.ident = CSSValueHelp; + break; + case CURSOR_ALL_SCROLL: + m_value.ident = CSSValueAllScroll; + break; + case CURSOR_WEBKIT_GRAB: + m_value.ident = CSSValueWebkitGrab; + break; + case CURSOR_WEBKIT_GRABBING: + m_value.ident = CSSValueWebkitGrabbing; + break; + } +} + +template<> inline CSSPrimitiveValue::operator ECursor() const +{ + if (m_value.ident == CSSValueCopy) + return CURSOR_COPY; + if (m_value.ident == CSSValueNone) + return CURSOR_NONE; + return static_cast<ECursor>(m_value.ident - CSSValueAuto); +} + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EDisplay e) + : m_type(CSS_IDENT) +{ + switch (e) { + case INLINE: + m_value.ident = CSSValueInline; + break; + case BLOCK: + m_value.ident = CSSValueBlock; + break; + case LIST_ITEM: + m_value.ident = CSSValueListItem; + break; + case RUN_IN: + m_value.ident = CSSValueRunIn; + break; + case COMPACT: + m_value.ident = CSSValueCompact; + break; + case INLINE_BLOCK: + m_value.ident = CSSValueInlineBlock; + break; + case TABLE: + m_value.ident = CSSValueTable; + break; + case INLINE_TABLE: + m_value.ident = CSSValueInlineTable; + break; + case TABLE_ROW_GROUP: + m_value.ident = CSSValueTableRowGroup; + break; + case TABLE_HEADER_GROUP: + m_value.ident = CSSValueTableHeaderGroup; + break; + case TABLE_FOOTER_GROUP: + m_value.ident = CSSValueTableFooterGroup; + break; + case TABLE_ROW: + m_value.ident = CSSValueTableRow; + break; + case TABLE_COLUMN_GROUP: + m_value.ident = CSSValueTableColumnGroup; + break; + case TABLE_COLUMN: + m_value.ident = CSSValueTableColumn; + break; + case TABLE_CELL: + m_value.ident = CSSValueTableCell; + break; + case TABLE_CAPTION: + m_value.ident = CSSValueTableCaption; + break; + case BOX: + m_value.ident = CSSValueWebkitBox; + break; + case INLINE_BOX: + m_value.ident = CSSValueWebkitInlineBox; + break; + case NONE: + m_value.ident = CSSValueNone; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EDisplay() const +{ + if (m_value.ident == CSSValueNone) + return NONE; + return static_cast<EDisplay>(m_value.ident - CSSValueInline); +} + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EEmptyCell e) + : m_type(CSS_IDENT) +{ + switch (e) { + case SHOW: + m_value.ident = CSSValueShow; + break; + case HIDE: + m_value.ident = CSSValueHide; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EEmptyCell() const +{ + switch (m_value.ident) { + case CSSValueShow: + return SHOW; + case CSSValueHide: + 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 = CSSValueNone; + break; + case FLEFT: + m_value.ident = CSSValueLeft; + break; + case FRIGHT: + m_value.ident = CSSValueRight; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EFloat() const +{ + switch (m_value.ident) { + case CSSValueLeft: + return FLEFT; + case CSSValueRight: + return FRIGHT; + case CSSValueNone: + case CSSValueCenter: // 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 = CSSValueNormal; + break; + case AFTER_WHITE_SPACE: + m_value.ident = CSSValueAfterWhiteSpace; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EKHTMLLineBreak() const +{ + switch (m_value.ident) { + case CSSValueAfterWhiteSpace: + return AFTER_WHITE_SPACE; + case CSSValueNormal: + 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 = CSSValueOutside; + break; + case INSIDE: + m_value.ident = CSSValueInside; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EListStylePosition() const +{ + return (EListStylePosition)(m_value.ident - CSSValueOutside); +} + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EListStyleType e) + : m_type(CSS_IDENT) +{ + switch (e) { + case LNONE: + m_value.ident = CSSValueNone; + break; + case DISC: + m_value.ident = CSSValueDisc; + break; + case CIRCLE: + m_value.ident = CSSValueCircle; + break; + case SQUARE: + m_value.ident = CSSValueSquare; + break; + case LDECIMAL: + m_value.ident = CSSValueDecimal; + break; + case DECIMAL_LEADING_ZERO: + m_value.ident = CSSValueDecimalLeadingZero; + break; + case LOWER_ROMAN: + m_value.ident = CSSValueLowerRoman; + break; + case UPPER_ROMAN: + m_value.ident = CSSValueUpperRoman; + break; + case LOWER_GREEK: + m_value.ident = CSSValueLowerGreek; + break; + case LOWER_ALPHA: + m_value.ident = CSSValueLowerAlpha; + break; + case LOWER_LATIN: + m_value.ident = CSSValueLowerLatin; + break; + case UPPER_ALPHA: + m_value.ident = CSSValueUpperAlpha; + break; + case UPPER_LATIN: + m_value.ident = CSSValueUpperLatin; + break; + case HEBREW: + m_value.ident = CSSValueHebrew; + break; + case ARMENIAN: + m_value.ident = CSSValueArmenian; + break; + case GEORGIAN: + m_value.ident = CSSValueGeorgian; + break; + case CJK_IDEOGRAPHIC: + m_value.ident = CSSValueCjkIdeographic; + break; + case HIRAGANA: + m_value.ident = CSSValueHiragana; + break; + case KATAKANA: + m_value.ident = CSSValueKatakana; + break; + case HIRAGANA_IROHA: + m_value.ident = CSSValueHiraganaIroha; + break; + case KATAKANA_IROHA: + m_value.ident = CSSValueKatakanaIroha; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EListStyleType() const +{ + switch (m_value.ident) { + case CSSValueNone: + return LNONE; + default: + return static_cast<EListStyleType>(m_value.ident - CSSValueDisc); + } +} + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EMarginCollapse e) + : m_type(CSS_IDENT) +{ + switch (e) { + case MCOLLAPSE: + m_value.ident = CSSValueCollapse; + break; + case MSEPARATE: + m_value.ident = CSSValueSeparate; + break; + case MDISCARD: + m_value.ident = CSSValueDiscard; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EMarginCollapse() const +{ + switch (m_value.ident) { + case CSSValueCollapse: + return MCOLLAPSE; + case CSSValueSeparate: + return MSEPARATE; + case CSSValueDiscard: + 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 = CSSValueNone; + break; + case MSCROLL: + m_value.ident = CSSValueScroll; + break; + case MSLIDE: + m_value.ident = CSSValueSlide; + break; + case MALTERNATE: + m_value.ident = CSSValueAlternate; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EMarqueeBehavior() const +{ + switch (m_value.ident) { + case CSSValueNone: + return MNONE; + case CSSValueScroll: + return MSCROLL; + case CSSValueSlide: + return MSLIDE; + case CSSValueAlternate: + 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 = CSSValueForwards; + break; + case MBACKWARD: + m_value.ident = CSSValueBackwards; + break; + case MAUTO: + m_value.ident = CSSValueAuto; + break; + case MUP: + m_value.ident = CSSValueUp; + break; + case MDOWN: + m_value.ident = CSSValueDown; + break; + case MLEFT: + m_value.ident = CSSValueLeft; + break; + case MRIGHT: + m_value.ident = CSSValueRight; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EMarqueeDirection() const +{ + switch (m_value.ident) { + case CSSValueForwards: + return MFORWARD; + case CSSValueBackwards: + return MBACKWARD; + case CSSValueAuto: + return MAUTO; + case CSSValueAhead: + case CSSValueUp: // We don't support vertical languages, so AHEAD just maps to UP. + return MUP; + case CSSValueReverse: + case CSSValueDown: // REVERSE just maps to DOWN, since we don't do vertical text. + return MDOWN; + case CSSValueLeft: + return MLEFT; + case CSSValueRight: + 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 = CSSValueNormal; + break; + case MATCH: + m_value.ident = CSSValueMatch; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EMatchNearestMailBlockquoteColor() const +{ + switch (m_value.ident) { + case CSSValueNormal: + return BCNORMAL; + case CSSValueMatch: + 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 = CSSValueNormal; + break; + case SPACE: + m_value.ident = CSSValueSpace; + break; + } +} + +template<> inline CSSPrimitiveValue::operator ENBSPMode() const +{ + switch (m_value.ident) { + case CSSValueSpace: + return SPACE; + case CSSValueNormal: + 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 = CSSValueVisible; + break; + case OHIDDEN: + m_value.ident = CSSValueHidden; + break; + case OSCROLL: + m_value.ident = CSSValueScroll; + break; + case OAUTO: + m_value.ident = CSSValueAuto; + break; + case OMARQUEE: + m_value.ident = CSSValueWebkitMarquee; + break; + case OOVERLAY: + m_value.ident = CSSValueOverlay; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EOverflow() const +{ + switch (m_value.ident) { + case CSSValueVisible: + return OVISIBLE; + case CSSValueHidden: + return OHIDDEN; + case CSSValueScroll: + return OSCROLL; + case CSSValueAuto: + return OAUTO; + case CSSValueWebkitMarquee: + return OMARQUEE; + case CSSValueOverlay: + 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 = CSSValueAuto; + break; + case PBALWAYS: + m_value.ident = CSSValueAlways; + break; + case PBAVOID: + m_value.ident = CSSValueAvoid; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EPageBreak() const +{ + switch (m_value.ident) { + case CSSValueAuto: + return PBAUTO; + case CSSValueLeft: + case CSSValueRight: + case CSSValueAlways: + return PBALWAYS; // CSS2.1: "Conforming user agents may map left/right to always." + case CSSValueAvoid: + 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 = CSSValueStatic; + break; + case RelativePosition: + m_value.ident = CSSValueRelative; + break; + case AbsolutePosition: + m_value.ident = CSSValueAbsolute; + break; + case FixedPosition: + m_value.ident = CSSValueFixed; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EPosition() const +{ + switch (m_value.ident) { + case CSSValueStatic: + return StaticPosition; + case CSSValueRelative: + return RelativePosition; + case CSSValueAbsolute: + return AbsolutePosition; + case CSSValueFixed: + 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 = CSSValueBoth; + break; + case RESIZE_HORIZONTAL: + m_value.ident = CSSValueHorizontal; + break; + case RESIZE_VERTICAL: + m_value.ident = CSSValueVertical; + break; + case RESIZE_NONE: + m_value.ident = CSSValueNone; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EResize() const +{ + switch (m_value.ident) { + case CSSValueBoth: + return RESIZE_BOTH; + case CSSValueHorizontal: + return RESIZE_HORIZONTAL; + case CSSValueVertical: + return RESIZE_VERTICAL; + case CSSValueAuto: + ASSERT_NOT_REACHED(); // Depends on settings, thus should be handled by the caller. + return RESIZE_NONE; + case CSSValueNone: + 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 = CSSValueAuto; + break; + case TFIXED: + m_value.ident = CSSValueFixed; + break; + } +} + +template<> inline CSSPrimitiveValue::operator ETableLayout() const +{ + switch (m_value.ident) { + case CSSValueFixed: + return TFIXED; + case CSSValueAuto: + 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 = CSSValueAuto; + break; + case LEFT: + m_value.ident = CSSValueLeft; + break; + case RIGHT: + m_value.ident = CSSValueRight; + break; + case CENTER: + m_value.ident = CSSValueCenter; + break; + case JUSTIFY: + m_value.ident = CSSValueJustify; + break; + case WEBKIT_LEFT: + m_value.ident = CSSValueWebkitLeft; + break; + case WEBKIT_RIGHT: + m_value.ident = CSSValueWebkitRight; + break; + case WEBKIT_CENTER: + m_value.ident = CSSValueWebkitCenter; + break; + } +} + +template<> inline CSSPrimitiveValue::operator ETextAlign() const +{ + switch (m_value.ident) { + case CSSValueStart: + case CSSValueEnd: + ASSERT_NOT_REACHED(); // Depends on direction, thus should be handled by the caller. + return LEFT; + default: + return static_cast<ETextAlign>(m_value.ident - CSSValueWebkitAuto); + } +} + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ETextSecurity e) + : m_type(CSS_IDENT) +{ + switch (e) { + case TSNONE: + m_value.ident = CSSValueNone; + break; + case TSDISC: + m_value.ident = CSSValueDisc; + break; + case TSCIRCLE: + m_value.ident = CSSValueCircle; + break; + case TSSQUARE: + m_value.ident = CSSValueSquare; + break; + } +} + +template<> inline CSSPrimitiveValue::operator ETextSecurity() const +{ + switch (m_value.ident) { + case CSSValueNone: + return TSNONE; + case CSSValueDisc: + return TSDISC; + case CSSValueCircle: + return TSCIRCLE; + case CSSValueSquare: + 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 = CSSValueCapitalize; + break; + case UPPERCASE: + m_value.ident = CSSValueUppercase; + break; + case LOWERCASE: + m_value.ident = CSSValueLowercase; + break; + case TTNONE: + m_value.ident = CSSValueNone; + break; + } +} + +template<> inline CSSPrimitiveValue::operator ETextTransform() const +{ + switch (m_value.ident) { + case CSSValueCapitalize: + return CAPITALIZE; + case CSSValueUppercase: + return UPPERCASE; + case CSSValueLowercase: + return LOWERCASE; + case CSSValueNone: + 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 = CSSValueNormal; + break; + case Embed: + m_value.ident = CSSValueEmbed; + break; + case Override: + m_value.ident = CSSValueBidiOverride; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EUnicodeBidi() const +{ + switch (m_value.ident) { + case CSSValueNormal: + return UBNormal; + case CSSValueEmbed: + return Embed; + case CSSValueBidiOverride: + 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 = CSSValueAuto; + break; + case DRAG_NONE: + m_value.ident = CSSValueNone; + break; + case DRAG_ELEMENT: + m_value.ident = CSSValueElement; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EUserDrag() const +{ + switch (m_value.ident) { + case CSSValueAuto: + return DRAG_AUTO; + case CSSValueNone: + return DRAG_NONE; + case CSSValueElement: + 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 = CSSValueReadOnly; + break; + case READ_WRITE: + m_value.ident = CSSValueReadWrite; + break; + case READ_WRITE_PLAINTEXT_ONLY: + m_value.ident = CSSValueReadWritePlaintextOnly; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EUserModify() const +{ + return static_cast<EUserModify>(m_value.ident - CSSValueReadOnly); +} + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EUserSelect e) + : m_type(CSS_IDENT) +{ + switch (e) { + case SELECT_NONE: + m_value.ident = CSSValueNone; + break; + case SELECT_TEXT: + m_value.ident = CSSValueText; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EUserSelect() const +{ + switch (m_value.ident) { + case CSSValueAuto: + return SELECT_TEXT; + case CSSValueNone: + return SELECT_NONE; + case CSSValueText: + 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 = CSSValueVisible; + break; + case HIDDEN: + m_value.ident = CSSValueHidden; + break; + case COLLAPSE: + m_value.ident = CSSValueCollapse; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EVisibility() const +{ + switch (m_value.ident) { + case CSSValueHidden: + return HIDDEN; + case CSSValueVisible: + return VISIBLE; + case CSSValueCollapse: + 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 = CSSValueNormal; + break; + case PRE: + m_value.ident = CSSValuePre; + break; + case PRE_WRAP: + m_value.ident = CSSValuePreWrap; + break; + case PRE_LINE: + m_value.ident = CSSValuePreLine; + break; + case NOWRAP: + m_value.ident = CSSValueNowrap; + break; + case KHTML_NOWRAP: + m_value.ident = CSSValueWebkitNowrap; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EWhiteSpace() const +{ + switch (m_value.ident) { + case CSSValueWebkitNowrap: + return KHTML_NOWRAP; + case CSSValueNowrap: + return NOWRAP; + case CSSValuePre: + return PRE; + case CSSValuePreWrap: + return PRE_WRAP; + case CSSValuePreLine: + return PRE_LINE; + case CSSValueNormal: + 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 = CSSValueNormal; + break; + case BreakAllWordBreak: + m_value.ident = CSSValueBreakAll; + break; + case BreakWordBreak: + m_value.ident = CSSValueBreakWord; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EWordBreak() const +{ + switch (m_value.ident) { + case CSSValueBreakAll: + return BreakAllWordBreak; + case CSSValueBreakWord: + return BreakWordBreak; + case CSSValueNormal: + 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 = CSSValueNormal; + break; + case BreakWordWrap: + m_value.ident = CSSValueBreakWord; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EWordWrap() const +{ + switch (m_value.ident) { + case CSSValueBreakWord: + return BreakWordWrap; + case CSSValueNormal: + 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 = CSSValueLtr; + break; + case RTL: + m_value.ident = CSSValueRtl; + break; + } +} + +template<> inline CSSPrimitiveValue::operator TextDirection() const +{ + switch (m_value.ident) { + case CSSValueLtr: + return LTR; + case CSSValueRtl: + return RTL; + default: + ASSERT_NOT_REACHED(); + return LTR; + } +} + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EPointerEvents e) + : m_type(CSS_IDENT) +{ + switch (e) { + case PE_NONE: + m_value.ident = CSSValueNone; + break; + case PE_STROKE: + m_value.ident = CSSValueStroke; + break; + case PE_FILL: + m_value.ident = CSSValueFill; + break; + case PE_PAINTED: + m_value.ident = CSSValuePainted; + break; + case PE_VISIBLE: + m_value.ident = CSSValueVisible; + break; + case PE_VISIBLE_STROKE: + m_value.ident = CSSValueVisiblestroke; + break; + case PE_VISIBLE_FILL: + m_value.ident = CSSValueVisiblefill; + break; + case PE_VISIBLE_PAINTED: + m_value.ident = CSSValueVisiblepainted; + break; + case PE_AUTO: + m_value.ident = CSSValueAuto; + break; + case PE_ALL: + m_value.ident = CSSValueAll; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EPointerEvents() const +{ + switch (m_value.ident) { + case CSSValueAll: + return PE_ALL; + case CSSValueAuto: + return PE_AUTO; + case CSSValueNone: + return PE_NONE; + case CSSValueVisiblepainted: + return PE_VISIBLE_PAINTED; + case CSSValueVisiblefill: + return PE_VISIBLE_FILL; + case CSSValueVisiblestroke: + return PE_VISIBLE_STROKE; + case CSSValueVisible: + return PE_VISIBLE; + case CSSValuePainted: + return PE_PAINTED; + case CSSValueFill: + return PE_FILL; + case CSSValueStroke: + return PE_STROKE; + default: + ASSERT_NOT_REACHED(); + return PE_ALL; + } +} + +#if ENABLE(SVG) + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineCap e) + : m_type(CSS_IDENT) +{ + switch (e) { + case ButtCap: + m_value.ident = CSSValueButt; + break; + case RoundCap: + m_value.ident = CSSValueRound; + break; + case SquareCap: + m_value.ident = CSSValueSquare; + break; + } +} + +template<> inline CSSPrimitiveValue::operator LineCap() const +{ + switch (m_value.ident) { + case CSSValueButt: + return ButtCap; + case CSSValueRound: + return RoundCap; + case CSSValueSquare: + 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 = CSSValueMiter; + break; + case RoundJoin: + m_value.ident = CSSValueRound; + break; + case BevelJoin: + m_value.ident = CSSValueBevel; + break; + } +} + +template<> inline CSSPrimitiveValue::operator LineJoin() const +{ + switch (m_value.ident) { + case CSSValueMiter: + return MiterJoin; + case CSSValueRound: + return RoundJoin; + case CSSValueBevel: + 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 = CSSValueNonzero; + break; + case RULE_EVENODD: + m_value.ident = CSSValueEvenodd; + break; + } +} + +template<> inline CSSPrimitiveValue::operator WindRule() const +{ + switch (m_value.ident) { + case CSSValueNonzero: + return RULE_NONZERO; + case CSSValueEvenodd: + 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 = CSSValueAuto; + break; + case AB_BASELINE: + m_value.ident = CSSValueBaseline; + break; + case AB_BEFORE_EDGE: + m_value.ident = CSSValueBeforeEdge; + break; + case AB_TEXT_BEFORE_EDGE: + m_value.ident = CSSValueTextBeforeEdge; + break; + case AB_MIDDLE: + m_value.ident = CSSValueMiddle; + break; + case AB_CENTRAL: + m_value.ident = CSSValueCentral; + break; + case AB_AFTER_EDGE: + m_value.ident = CSSValueAfterEdge; + break; + case AB_TEXT_AFTER_EDGE: + m_value.ident = CSSValueTextAfterEdge; + break; + case AB_IDEOGRAPHIC: + m_value.ident = CSSValueIdeographic; + break; + case AB_ALPHABETIC: + m_value.ident = CSSValueAlphabetic; + break; + case AB_HANGING: + m_value.ident = CSSValueHanging; + break; + case AB_MATHEMATICAL: + m_value.ident = CSSValueMathematical; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EAlignmentBaseline() const +{ + switch (m_value.ident) { + case CSSValueAuto: + return AB_AUTO; + case CSSValueBaseline: + return AB_BASELINE; + case CSSValueBeforeEdge: + return AB_BEFORE_EDGE; + case CSSValueTextBeforeEdge: + return AB_TEXT_BEFORE_EDGE; + case CSSValueMiddle: + return AB_MIDDLE; + case CSSValueCentral: + return AB_CENTRAL; + case CSSValueAfterEdge: + return AB_AFTER_EDGE; + case CSSValueTextAfterEdge: + return AB_TEXT_AFTER_EDGE; + case CSSValueIdeographic: + return AB_IDEOGRAPHIC; + case CSSValueAlphabetic: + return AB_ALPHABETIC; + case CSSValueHanging: + return AB_HANGING; + case CSSValueMathematical: + 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 = CSSValueAuto; + break; + case CI_SRGB: + m_value.ident = CSSValueSrgb; + break; + case CI_LINEARRGB: + m_value.ident = CSSValueLinearrgb; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EColorInterpolation() const +{ + switch (m_value.ident) { + case CSSValueSrgb: + return CI_SRGB; + case CSSValueLinearrgb: + return CI_LINEARRGB; + case CSSValueAuto: + 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 = CSSValueAuto; + break; + case CR_OPTIMIZESPEED: + m_value.ident = CSSValueOptimizespeed; + break; + case CR_OPTIMIZEQUALITY: + m_value.ident = CSSValueOptimizequality; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EColorRendering() const +{ + switch (m_value.ident) { + case CSSValueOptimizespeed: + return CR_OPTIMIZESPEED; + case CSSValueOptimizequality: + return CR_OPTIMIZEQUALITY; + case CSSValueAuto: + 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 = CSSValueAuto; + break; + case DB_USE_SCRIPT: + m_value.ident = CSSValueUseScript; + break; + case DB_NO_CHANGE: + m_value.ident = CSSValueNoChange; + break; + case DB_RESET_SIZE: + m_value.ident = CSSValueResetSize; + break; + case DB_CENTRAL: + m_value.ident = CSSValueCentral; + break; + case DB_MIDDLE: + m_value.ident = CSSValueMiddle; + break; + case DB_TEXT_BEFORE_EDGE: + m_value.ident = CSSValueTextBeforeEdge; + break; + case DB_TEXT_AFTER_EDGE: + m_value.ident = CSSValueTextAfterEdge; + break; + case DB_IDEOGRAPHIC: + m_value.ident = CSSValueIdeographic; + break; + case DB_ALPHABETIC: + m_value.ident = CSSValueAlphabetic; + break; + case DB_HANGING: + m_value.ident = CSSValueHanging; + break; + case DB_MATHEMATICAL: + m_value.ident = CSSValueMathematical; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EDominantBaseline() const +{ + switch (m_value.ident) { + case CSSValueAuto: + return DB_AUTO; + case CSSValueUseScript: + return DB_USE_SCRIPT; + case CSSValueNoChange: + return DB_NO_CHANGE; + case CSSValueResetSize: + return DB_RESET_SIZE; + case CSSValueIdeographic: + return DB_IDEOGRAPHIC; + case CSSValueAlphabetic: + return DB_ALPHABETIC; + case CSSValueHanging: + return DB_HANGING; + case CSSValueMathematical: + return DB_MATHEMATICAL; + case CSSValueCentral: + return DB_CENTRAL; + case CSSValueMiddle: + return DB_MIDDLE; + case CSSValueTextAfterEdge: + return DB_TEXT_AFTER_EDGE; + case CSSValueTextBeforeEdge: + 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 = CSSValueAuto; + break; + case IR_OPTIMIZESPEED: + m_value.ident = CSSValueOptimizespeed; + break; + case IR_OPTIMIZEQUALITY: + m_value.ident = CSSValueOptimizequality; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EImageRendering() const +{ + switch (m_value.ident) { + case CSSValueAuto: + return IR_AUTO; + case CSSValueOptimizespeed: + return IR_OPTIMIZESPEED; + case CSSValueOptimizequality: + return IR_OPTIMIZEQUALITY; + default: + ASSERT_NOT_REACHED(); + return IR_AUTO; + } +} + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EShapeRendering e) + : m_type(CSS_IDENT) +{ + switch (e) { + case IR_AUTO: + m_value.ident = CSSValueAuto; + break; + case IR_OPTIMIZESPEED: + m_value.ident = CSSValueOptimizespeed; + break; + case SR_CRISPEDGES: + m_value.ident = CSSValueCrispedges; + break; + case SR_GEOMETRICPRECISION: + m_value.ident = CSSValueGeometricprecision; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EShapeRendering() const +{ + switch (m_value.ident) { + case CSSValueAuto: + return SR_AUTO; + case CSSValueOptimizespeed: + return SR_OPTIMIZESPEED; + case CSSValueCrispedges: + return SR_CRISPEDGES; + case CSSValueGeometricprecision: + 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 = CSSValueStart; + break; + case TA_MIDDLE: + m_value.ident = CSSValueMiddle; + break; + case TA_END: + m_value.ident = CSSValueEnd; + break; + } +} + +template<> inline CSSPrimitiveValue::operator ETextAnchor() const +{ + switch (m_value.ident) { + case CSSValueStart: + return TA_START; + case CSSValueMiddle: + return TA_MIDDLE; + case CSSValueEnd: + 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 = CSSValueAuto; + break; + case TR_OPTIMIZESPEED: + m_value.ident = CSSValueOptimizespeed; + break; + case TR_OPTIMIZELEGIBILITY: + m_value.ident = CSSValueOptimizelegibility; + break; + case TR_GEOMETRICPRECISION: + m_value.ident = CSSValueGeometricprecision; + break; + } +} + +template<> inline CSSPrimitiveValue::operator ETextRendering() const +{ + switch (m_value.ident) { + case CSSValueAuto: + return TR_AUTO; + case CSSValueOptimizespeed: + return TR_OPTIMIZESPEED; + case CSSValueOptimizelegibility: + return TR_OPTIMIZELEGIBILITY; + case CSSValueGeometricprecision: + 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 = CSSValueLrTb; + break; + case WM_LR: + m_value.ident = CSSValueLr; + break; + case WM_RLTB: + m_value.ident = CSSValueRlTb; + break; + case WM_RL: + m_value.ident = CSSValueRl; + break; + case WM_TBRL: + m_value.ident = CSSValueTbRl; + break; + case WM_TB: + m_value.ident = CSSValueTb; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EWritingMode() const +{ + return static_cast<EWritingMode>(m_value.ident - CSSValueLrTb); +} + +#endif + +} + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/CSSProperty.cpp b/src/3rdparty/webkit/WebCore/css/CSSProperty.cpp new file mode 100644 index 0000000..9b21a3f --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSProperty.cpp @@ -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. + */ + +#include "config.h" +#include "CSSProperty.h" + +#include "CSSPropertyNames.h" +#include "PlatformString.h" + +namespace WebCore { + +String CSSProperty::cssText() const +{ + if (id() == CSSPropertyWebkitVariableDeclarationBlock) + return m_value->cssText() + ";"; + 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/src/3rdparty/webkit/WebCore/css/CSSProperty.h b/src/3rdparty/webkit/WebCore/css/CSSProperty.h new file mode 100644 index 0000000..7af8348 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSProperty.h @@ -0,0 +1,81 @@ +/* + * 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_implicit = other.m_implicit; + 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. Really. + int m_id : 15; + int m_shorthandID : 15; // 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 + +namespace WTF { + // Properties in Vector can be initialized with memset and moved using memcpy. + template<> struct VectorTraits<WebCore::CSSProperty> : SimpleClassVectorTraits { }; +} + +#endif // CSSProperty_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSPropertyNames.in b/src/3rdparty/webkit/WebCore/css/CSSPropertyNames.in new file mode 100644 index 0000000..3ca14bc --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSPropertyNames.in @@ -0,0 +1,240 @@ +# +# 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 +pointer-events +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 +zoom +-webkit-animation +-webkit-animation-delay +-webkit-animation-direction +-webkit-animation-duration +-webkit-animation-iteration-count +-webkit-animation-name +-webkit-animation-play-state +-webkit-animation-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-reflect +-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-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-mask +-webkit-mask-attachment +-webkit-mask-box-image +-webkit-mask-clip +-webkit-mask-composite +-webkit-mask-image +-webkit-mask-origin +-webkit-mask-position +-webkit-mask-position-x +-webkit-mask-position-y +-webkit-mask-repeat +-webkit-mask-size +-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-transition +-webkit-transition-delay +-webkit-transition-duration +-webkit-transition-property +-webkit-transition-timing-function +-webkit-user-drag +-webkit-user-modify +-webkit-user-select +-webkit-variable-declaration-block diff --git a/src/3rdparty/webkit/WebCore/css/CSSQuirkPrimitiveValue.h b/src/3rdparty/webkit/WebCore/css/CSSQuirkPrimitiveValue.h new file mode 100644 index 0000000..56857b7 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSQuirkPrimitiveValue.h @@ -0,0 +1,50 @@ +/* + * (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 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. +// 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: + static PassRefPtr<CSSQuirkPrimitiveValue> create(double value, UnitTypes type) + { + return adoptRef(new CSSQuirkPrimitiveValue(value, type)); + } + +private: + CSSQuirkPrimitiveValue(double num, UnitTypes type) + : CSSPrimitiveValue(num, type) + { + } + + virtual bool isQuirkValue() { return true; } +}; + +} // namespace WebCore + +#endif // CSSQuirkPrimitiveValue_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSReflectValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSReflectValue.cpp new file mode 100644 index 0000000..a8ca59e --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSReflectValue.cpp @@ -0,0 +1,68 @@ +/* + * 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 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 "CSSReflectValue.h" + +#include "CSSPrimitiveValue.h" +#include "PlatformString.h" + +using namespace std; + +namespace WebCore { + +String CSSReflectValue::cssText() const +{ + String result; + switch (m_direction) { + case ReflectionBelow: + result += "below "; + break; + case ReflectionAbove: + result += "above "; + break; + case ReflectionLeft: + result += "left "; + break; + case ReflectionRight: + result += "right "; + break; + default: + break; + } + + result += m_offset->cssText() + " "; + if (m_mask) + result += m_mask->cssText(); + return result; +} + +void CSSReflectValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const CSSStyleSheet* styleSheet) +{ + if (m_mask) + m_mask->addSubresourceStyleURLs(urls, styleSheet); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSReflectValue.h b/src/3rdparty/webkit/WebCore/css/CSSReflectValue.h new file mode 100644 index 0000000..d61f8c4 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSReflectValue.h @@ -0,0 +1,70 @@ +/* + * 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 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 CSSReflectValue_h +#define CSSReflectValue_h + +#include "CSSReflectionDirection.h" +#include "CSSValue.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class CSSPrimitiveValue; + +class CSSReflectValue : public CSSValue { +public: + static PassRefPtr<CSSReflectValue> create(CSSReflectionDirection direction, + PassRefPtr<CSSPrimitiveValue> offset, PassRefPtr<CSSValue> mask) + { + return adoptRef(new CSSReflectValue(direction, offset, mask)); + } + + CSSReflectionDirection direction() const { return m_direction; } + CSSPrimitiveValue* offset() const { return m_offset.get(); } + CSSValue* mask() const { return m_mask.get(); } + + virtual String cssText() const; + + virtual void addSubresourceStyleURLs(ListHashSet<KURL>&, const CSSStyleSheet*); + +private: + CSSReflectValue(CSSReflectionDirection direction, + PassRefPtr<CSSPrimitiveValue> offset, PassRefPtr<CSSValue> mask) + : m_direction(direction) + , m_offset(offset) + , m_mask(mask) + { + } + + CSSReflectionDirection m_direction; + RefPtr<CSSPrimitiveValue> m_offset; + RefPtr<CSSValue> m_mask; +}; + +} // namespace WebCore + +#endif // CSSReflectValue_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSReflectionDirection.h b/src/3rdparty/webkit/WebCore/css/CSSReflectionDirection.h new file mode 100644 index 0000000..5a0c203 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSReflectionDirection.h @@ -0,0 +1,35 @@ +/* + * 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 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 CSSReflectionDirection_h +#define CSSReflectionDirection_h + +namespace WebCore { + +enum CSSReflectionDirection { ReflectionBelow, ReflectionAbove, ReflectionLeft, ReflectionRight }; + +} // namespace WebCore + +#endif // CSSReflectionDirection_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSRule.cpp b/src/3rdparty/webkit/WebCore/css/CSSRule.cpp new file mode 100644 index 0000000..8fe4caf --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSRule.cpp @@ -0,0 +1,48 @@ +/* + * (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" +#include "NotImplemented.h" + +namespace WebCore { + +CSSStyleSheet* CSSRule::parentStyleSheet() const +{ + StyleBase* curr = parent(); + while (curr && !curr->isCSSStyleSheet()) + curr = curr->parent(); + return curr ? static_cast<CSSStyleSheet*>(curr) : 0; +} + +CSSRule* CSSRule::parentRule() const +{ + return (parent() && parent()->isRule()) ? static_cast<CSSRule*>(parent()) : 0; +} + +void CSSRule::setCssText(const String& /*cssText*/, ExceptionCode& /*ec*/) +{ + notImplemented(); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSRule.h b/src/3rdparty/webkit/WebCore/css/CSSRule.h new file mode 100644 index 0000000..fc48dd6 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSRule.h @@ -0,0 +1,72 @@ +/* + * (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 "CSSStyleSheet.h" +#include "KURLHash.h" +#include <wtf/ListHashSet.h> + +namespace WebCore { + +typedef int ExceptionCode; + +class CSSRule : public StyleBase { +public: + // FIXME: Change name to Type. + enum CSSRuleType { + UNKNOWN_RULE, + STYLE_RULE, + CHARSET_RULE, + IMPORT_RULE, + MEDIA_RULE, + FONT_FACE_RULE, + PAGE_RULE, + VARIABLES_RULE, + WEBKIT_KEYFRAMES_RULE, + WEBKIT_KEYFRAME_RULE + }; + + // FIXME: Change to return CSSRuleType. + virtual unsigned short type() const = 0; + + CSSStyleSheet* parentStyleSheet() const; + CSSRule* parentRule() const; + + virtual String cssText() const = 0; + void setCssText(const String&, ExceptionCode&); + + virtual void addSubresourceStyleURLs(ListHashSet<KURL>&) { } + +protected: + CSSRule(CSSStyleSheet* parent) + : StyleBase(parent) + { + } + +private: + virtual bool isRule() { return true; } +}; + +} // namespace WebCore + +#endif // CSSRule_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSRule.idl b/src/3rdparty/webkit/WebCore/css/CSSRule.idl new file mode 100644 index 0000000..4d9e568 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSRule.idl @@ -0,0 +1,53 @@ +/* + * 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; + const unsigned short VARIABLES_RULE = 7; + const unsigned short WEBKIT_KEYFRAMES_RULE = 8; + const unsigned short WEBKIT_KEYFRAME_RULE = 9; + + 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/src/3rdparty/webkit/WebCore/css/CSSRuleList.cpp b/src/3rdparty/webkit/WebCore/css/CSSRuleList.cpp new file mode 100644 index 0000000..4528d40 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSRuleList.cpp @@ -0,0 +1,112 @@ +/** + * 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() +{ +} + +CSSRuleList::CSSRuleList(StyleList* list, bool omitCharsetRules) +{ + 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() +{ +} + +unsigned CSSRuleList::length() const +{ + return m_list ? m_list->length() : m_lstCSSRules.size(); +} + +CSSRule* CSSRuleList::item(unsigned index) +{ + if (m_list) { + StyleBase* rule = m_list->item(index); + ASSERT(!rule || rule->isRule()); + return static_cast<CSSRule*>(rule); + } + + if (index < m_lstCSSRules.size()) + return m_lstCSSRules[index].get(); + return 0; +} + +void CSSRuleList::deleteRule(unsigned index) +{ + ASSERT(!m_list); + + if (index >= m_lstCSSRules.size()) { + // FIXME: Should we throw an INDEX_SIZE_ERR exception here? + return; + } + + m_lstCSSRules.remove(index); +} + +void CSSRuleList::append(CSSRule* rule) +{ + ASSERT(!m_list); + if (!rule) { + // FIXME: Should we throw an exception? + return; + } + + m_lstCSSRules.append(rule); +} + +unsigned CSSRuleList::insertRule(CSSRule* rule, unsigned index) +{ + ASSERT(!m_list); + if (!rule) { + // FIXME: Should we throw an exception? + return 0; + } + + if (index > m_lstCSSRules.size()) { + // FIXME: Should we throw an INDEX_SIZE_ERR exception here? + return 0; + } + + m_lstCSSRules.insert(index, rule); + return index; +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSRuleList.h b/src/3rdparty/webkit/WebCore/css/CSSRuleList.h new file mode 100644 index 0000000..26186b3 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSRuleList.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. + * + * 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 <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class CSSRule; +class StyleList; + +class CSSRuleList : public RefCounted<CSSRuleList> { +public: + static PassRefPtr<CSSRuleList> create(StyleList* list, bool omitCharsetRules = false) + { + return adoptRef(new CSSRuleList(list, omitCharsetRules)); + } + static PassRefPtr<CSSRuleList> create() + { + return adoptRef(new CSSRuleList); + } + ~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*); + +private: + CSSRuleList(); + CSSRuleList(StyleList*, bool omitCharsetRules); + + RefPtr<StyleList> m_list; + Vector<RefPtr<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/src/3rdparty/webkit/WebCore/css/CSSRuleList.idl b/src/3rdparty/webkit/WebCore/css/CSSRuleList.idl new file mode 100644 index 0000000..224d6a1 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSSegmentedFontFace.cpp b/src/3rdparty/webkit/WebCore/css/CSSSegmentedFontFace.cpp new file mode 100644 index 0000000..c3e3fd0 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSSegmentedFontFace.cpp @@ -0,0 +1,135 @@ +/* + * 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) + : m_fontSelector(fontSelector) +{ +} + +CSSSegmentedFontFace::~CSSSegmentedFontFace() +{ + pruneTable(); + unsigned size = m_fontFaces.size(); + for (unsigned i = 0; i < size; i++) + m_fontFaces[i]->removedFromSegmentedFontFace(this); +} + +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_fontFaces.size(); + for (unsigned i = 0; i < size; i++) { + if (!m_fontFaces[i]->isLoaded()) + return false; + } + return true; +} + +bool CSSSegmentedFontFace::isValid() const +{ + unsigned size = m_fontFaces.size(); + for (unsigned i = 0; i < size; i++) { + if (!m_fontFaces[i]->isValid()) + return false; + } + return true; +} + +void CSSSegmentedFontFace::fontLoaded(CSSFontFace*) +{ + pruneTable(); +} + +void CSSSegmentedFontFace::appendFontFace(PassRefPtr<CSSFontFace> fontFace) +{ + pruneTable(); + fontFace->addedToSegmentedFontFace(this); + m_fontFaces.append(fontFace); +} + +FontData* CSSSegmentedFontFace::getFontData(const FontDescription& fontDescription) +{ + if (!isValid()) + return 0; + + FontTraitsMask desiredTraitsMask = fontDescription.traitsMask(); + unsigned hashKey = fontDescription.computedPixelSize() << FontTraitsMaskWidth | desiredTraitsMask; + + SegmentedFontData* fontData = m_fontDataTable.get(hashKey); + if (fontData) + return fontData; + + fontData = new SegmentedFontData(); + + unsigned size = m_fontFaces.size(); + for (unsigned i = 0; i < size; i++) { + FontTraitsMask traitsMask = m_fontFaces[i]->traitsMask(); + bool syntheticBold = !(traitsMask & (FontWeight600Mask | FontWeight700Mask | FontWeight800Mask | FontWeight900Mask)) && (desiredTraitsMask & (FontWeight600Mask | FontWeight700Mask | FontWeight800Mask | FontWeight900Mask)); + bool syntheticItalic = !(traitsMask & FontStyleItalicMask) && (desiredTraitsMask & FontStyleItalicMask); + if (const FontData* faceFontData = m_fontFaces[i]->getFontData(fontDescription, syntheticBold, syntheticItalic)) { + ASSERT(!faceFontData->isSegmented()); + const Vector<CSSFontFace::UnicodeRange>& ranges = m_fontFaces[i]->ranges(); + unsigned numRanges = ranges.size(); + if (!numRanges) + fontData->appendRange(FontDataRange(0, 0x7FFFFFFF, static_cast<const SimpleFontData*>(faceFontData))); + else { + for (unsigned j = 0; j < numRanges; ++j) + fontData->appendRange(FontDataRange(ranges[j].from(), ranges[j].to(), static_cast<const SimpleFontData*>(faceFontData))); + } + } + } + if (fontData->numRanges()) + m_fontDataTable.set(hashKey, fontData); + else { + delete fontData; + fontData = 0; + } + + return fontData; +} + +} diff --git a/src/3rdparty/webkit/WebCore/css/CSSSegmentedFontFace.h b/src/3rdparty/webkit/WebCore/css/CSSSegmentedFontFace.h new file mode 100644 index 0000000..57a3c58 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSSegmentedFontFace.h @@ -0,0 +1,70 @@ +/* + * 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; + +class CSSSegmentedFontFace : public RefCounted<CSSSegmentedFontFace> { +public: + static PassRefPtr<CSSSegmentedFontFace> create(CSSFontSelector* selector) { return adoptRef(new CSSSegmentedFontFace(selector)); } + ~CSSSegmentedFontFace(); + + bool isLoaded() const; + bool isValid() const; + CSSFontSelector* fontSelector() const { return m_fontSelector; } + + void fontLoaded(CSSFontFace*); + + void appendFontFace(PassRefPtr<CSSFontFace>); + + FontData* getFontData(const FontDescription&); + +private: + CSSSegmentedFontFace(CSSFontSelector*); + + void pruneTable(); + + CSSFontSelector* m_fontSelector; + HashMap<unsigned, SegmentedFontData*> m_fontDataTable; + Vector<RefPtr<CSSFontFace>, 1> m_fontFaces; +}; + +} // namespace WebCore + +#endif // CSSSegmentedFontFace_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSSelector.cpp b/src/3rdparty/webkit/WebCore/css/CSSSelector.cpp new file mode 100644 index 0000000..cc296d9 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSSelector.cpp @@ -0,0 +1,555 @@ +/* + * 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. + * Copyright (C) 2008 David Smith (catfish.man@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. + */ + +#include "config.h" +#include "CSSSelector.h" + +#include "wtf/Assertions.h" +#include "HTMLNames.h" + +#include <wtf/StdLibExtras.h> + +namespace WebCore { + +using namespace HTMLNames; + +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 (CSSSelector* tagHistory = this->tagHistory()) + s += tagHistory->specificity(); + + // make sure it doesn't overflow + return s & 0xffffff; +} + +void CSSSelector::extractPseudoType() const +{ + if (m_match != PseudoClass && m_match != PseudoElement) + return; + + DEFINE_STATIC_LOCAL(AtomicString, active, ("active")); + DEFINE_STATIC_LOCAL(AtomicString, after, ("after")); + DEFINE_STATIC_LOCAL(AtomicString, anyLink, ("-webkit-any-link")); + DEFINE_STATIC_LOCAL(AtomicString, autofill, ("-webkit-autofill")); + DEFINE_STATIC_LOCAL(AtomicString, before, ("before")); + DEFINE_STATIC_LOCAL(AtomicString, checked, ("checked")); + DEFINE_STATIC_LOCAL(AtomicString, fileUploadButton, ("-webkit-file-upload-button")); + DEFINE_STATIC_LOCAL(AtomicString, disabled, ("disabled")); + DEFINE_STATIC_LOCAL(AtomicString, readOnly, ("read-only")); + DEFINE_STATIC_LOCAL(AtomicString, readWrite, ("read-write")); + DEFINE_STATIC_LOCAL(AtomicString, drag, ("-webkit-drag")); + DEFINE_STATIC_LOCAL(AtomicString, dragAlias, ("-khtml-drag")); // was documented with this name in Apple documentation, so keep an alia + DEFINE_STATIC_LOCAL(AtomicString, empty, ("empty")); + DEFINE_STATIC_LOCAL(AtomicString, enabled, ("enabled")); + DEFINE_STATIC_LOCAL(AtomicString, firstChild, ("first-child")); + DEFINE_STATIC_LOCAL(AtomicString, firstLetter, ("first-letter")); + DEFINE_STATIC_LOCAL(AtomicString, firstLine, ("first-line")); + DEFINE_STATIC_LOCAL(AtomicString, firstOfType, ("first-of-type")); + DEFINE_STATIC_LOCAL(AtomicString, fullPageMedia, ("-webkit-full-page-media")); + DEFINE_STATIC_LOCAL(AtomicString, nthChild, ("nth-child(")); + DEFINE_STATIC_LOCAL(AtomicString, nthOfType, ("nth-of-type(")); + DEFINE_STATIC_LOCAL(AtomicString, nthLastChild, ("nth-last-child(")); + DEFINE_STATIC_LOCAL(AtomicString, nthLastOfType, ("nth-last-of-type(")); + DEFINE_STATIC_LOCAL(AtomicString, focus, ("focus")); + DEFINE_STATIC_LOCAL(AtomicString, hover, ("hover")); + DEFINE_STATIC_LOCAL(AtomicString, indeterminate, ("indeterminate")); + DEFINE_STATIC_LOCAL(AtomicString, inputPlaceholder, ("-webkit-input-placeholder")); + DEFINE_STATIC_LOCAL(AtomicString, lastChild, ("last-child")); + DEFINE_STATIC_LOCAL(AtomicString, lastOfType, ("last-of-type")); + DEFINE_STATIC_LOCAL(AtomicString, link, ("link")); + DEFINE_STATIC_LOCAL(AtomicString, lang, ("lang(")); + DEFINE_STATIC_LOCAL(AtomicString, mediaControlsPanel, ("-webkit-media-controls-panel")); + DEFINE_STATIC_LOCAL(AtomicString, mediaControlsMuteButton, ("-webkit-media-controls-mute-button")); + DEFINE_STATIC_LOCAL(AtomicString, mediaControlsPlayButton, ("-webkit-media-controls-play-button")); + DEFINE_STATIC_LOCAL(AtomicString, mediaControlsTimeDisplay, ("-webkit-media-controls-time-display")); + DEFINE_STATIC_LOCAL(AtomicString, mediaControlsTimeline, ("-webkit-media-controls-timeline")); + DEFINE_STATIC_LOCAL(AtomicString, mediaControlsSeekBackButton, ("-webkit-media-controls-seek-back-button")); + DEFINE_STATIC_LOCAL(AtomicString, mediaControlsSeekForwardButton, ("-webkit-media-controls-seek-forward-button")); + DEFINE_STATIC_LOCAL(AtomicString, mediaControlsFullscreenButton, ("-webkit-media-controls-fullscreen-button")); + DEFINE_STATIC_LOCAL(AtomicString, notStr, ("not(")); + DEFINE_STATIC_LOCAL(AtomicString, onlyChild, ("only-child")); + DEFINE_STATIC_LOCAL(AtomicString, onlyOfType, ("only-of-type")); + DEFINE_STATIC_LOCAL(AtomicString, resizer, ("-webkit-resizer")); + DEFINE_STATIC_LOCAL(AtomicString, root, ("root")); + DEFINE_STATIC_LOCAL(AtomicString, scrollbar, ("-webkit-scrollbar")); + DEFINE_STATIC_LOCAL(AtomicString, scrollbarButton, ("-webkit-scrollbar-button")); + DEFINE_STATIC_LOCAL(AtomicString, scrollbarCorner, ("-webkit-scrollbar-corner")); + DEFINE_STATIC_LOCAL(AtomicString, scrollbarThumb, ("-webkit-scrollbar-thumb")); + DEFINE_STATIC_LOCAL(AtomicString, scrollbarTrack, ("-webkit-scrollbar-track")); + DEFINE_STATIC_LOCAL(AtomicString, scrollbarTrackPiece, ("-webkit-scrollbar-track-piece")); + DEFINE_STATIC_LOCAL(AtomicString, searchCancelButton, ("-webkit-search-cancel-button")); + DEFINE_STATIC_LOCAL(AtomicString, searchDecoration, ("-webkit-search-decoration")); + DEFINE_STATIC_LOCAL(AtomicString, searchResultsDecoration, ("-webkit-search-results-decoration")); + DEFINE_STATIC_LOCAL(AtomicString, searchResultsButton, ("-webkit-search-results-button")); + DEFINE_STATIC_LOCAL(AtomicString, selection, ("selection")); + DEFINE_STATIC_LOCAL(AtomicString, sliderThumb, ("-webkit-slider-thumb")); + DEFINE_STATIC_LOCAL(AtomicString, target, ("target")); + DEFINE_STATIC_LOCAL(AtomicString, visited, ("visited")); + DEFINE_STATIC_LOCAL(AtomicString, windowInactive, ("window-inactive")); + DEFINE_STATIC_LOCAL(AtomicString, decrement, ("decrement")); + DEFINE_STATIC_LOCAL(AtomicString, increment, ("increment")); + DEFINE_STATIC_LOCAL(AtomicString, start, ("start")); + DEFINE_STATIC_LOCAL(AtomicString, end, ("end")); + DEFINE_STATIC_LOCAL(AtomicString, horizontal, ("horizontal")); + DEFINE_STATIC_LOCAL(AtomicString, vertical, ("vertical")); + DEFINE_STATIC_LOCAL(AtomicString, doubleButton, ("double-button")); + DEFINE_STATIC_LOCAL(AtomicString, singleButton, ("single-button")); + DEFINE_STATIC_LOCAL(AtomicString, noButton, ("no-button")); + DEFINE_STATIC_LOCAL(AtomicString, cornerPresent, ("corner-present")); + + 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 == readOnly) + m_pseudoType = PseudoReadOnly; + else if (m_value == readWrite) + m_pseudoType = PseudoReadWrite; + 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 == fullPageMedia) + m_pseudoType = PseudoFullPageMedia; + else if (m_value == inputPlaceholder) { + m_pseudoType = PseudoInputPlaceholder; + element = true; + } 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 == windowInactive) + m_pseudoType = PseudoWindowInactive; + else if (m_value == decrement) + m_pseudoType = PseudoDecrement; + else if (m_value == increment) + m_pseudoType = PseudoIncrement; + else if (m_value == start) + m_pseudoType = PseudoStart; + else if (m_value == end) + m_pseudoType = PseudoEnd; + else if (m_value == horizontal) + m_pseudoType = PseudoHorizontal; + else if (m_value == vertical) + m_pseudoType = PseudoVertical; + else if (m_value == doubleButton) + m_pseudoType = PseudoDoubleButton; + else if (m_value == singleButton) + m_pseudoType = PseudoSingleButton; + else if (m_value == noButton) + m_pseudoType = PseudoNoButton; + else if (m_value == scrollbarCorner) { + element = true; + m_pseudoType = PseudoScrollbarCorner; + } else if (m_value == resizer) { + element = true; + m_pseudoType = PseudoResizer; + } else if (m_value == scrollbar) { + element = true; + m_pseudoType = PseudoScrollbar; + } else if (m_value == scrollbarButton) { + element = true; + m_pseudoType = PseudoScrollbarButton; + } else if (m_value == scrollbarCorner) { + element = true; + m_pseudoType = PseudoScrollbarCorner; + } else if (m_value == scrollbarThumb) { + element = true; + m_pseudoType = PseudoScrollbarThumb; + } else if (m_value == scrollbarTrack) { + element = true; + m_pseudoType = PseudoScrollbarTrack; + } else if (m_value == scrollbarTrackPiece) { + element = true; + m_pseudoType = PseudoScrollbarTrackPiece; + } else if (m_value == cornerPresent) + m_pseudoType = PseudoCornerPresent; + 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->attribute() != sel2->attribute() || + sel1->relation() != sel2->relation() || sel1->m_match != sel2->m_match || + sel1->m_value != sel2->m_value || + sel1->pseudoType() != sel2->pseudoType() || + sel1->argument() != sel2->argument()) + return false; + sel1 = sel1->tagHistory(); + sel2 = sel2->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->simpleSelector()) + str += subSel->selectorText(); + str += ")"; + } else if (cs->pseudoType() == PseudoLang) { + str += cs->argument(); + str += ")"; + } + } else if (cs->m_match == CSSSelector::PseudoElement) { + str += "::"; + str += cs->m_value; + } else if (cs->hasAttribute()) { + str += "["; + const AtomicString& prefix = cs->attribute().prefix(); + if (!prefix.isNull()) + str += prefix + "|"; + str += cs->attribute().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->tagHistory()) + break; + cs = cs->tagHistory(); + } + + if (CSSSelector* tagHistory = cs->tagHistory()) { + String tagHistoryText = 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; +} + +void CSSSelector::setTagHistory(CSSSelector* tagHistory) +{ + if (m_hasRareData) + m_data.m_rareData->m_tagHistory.set(tagHistory); + else + m_data.m_tagHistory = tagHistory; +} + +const QualifiedName& CSSSelector::attribute() const +{ + switch (m_match) { + case Id: + return idAttr; + case Class: + return classAttr; + default: + return m_hasRareData ? m_data.m_rareData->m_attribute : anyQName(); + } +} + +void CSSSelector::setAttribute(const QualifiedName& value) +{ + createRareData(); + m_data.m_rareData->m_attribute = value; +} + +void CSSSelector::setArgument(const AtomicString& value) +{ + createRareData(); + m_data.m_rareData->m_argument = value; +} + +void CSSSelector::setSimpleSelector(CSSSelector* value) +{ + createRareData(); + m_data.m_rareData->m_simpleSelector.set(value); +} + +bool CSSSelector::parseNth() +{ + if (!m_hasRareData) + return false; + if (m_parsedNth) + return true; + m_parsedNth = m_data.m_rareData->parseNth(); + return m_parsedNth; +} + +bool CSSSelector::matchNth(int count) +{ + ASSERT(m_hasRareData); + return m_data.m_rareData->matchNth(count); +} + +// a helper function for parsing nth-arguments +bool CSSSelector::RareData::parseNth() +{ + const String& argument = m_argument; + + if (argument.isEmpty()) + return false; + + m_a = 0; + m_b = 0; + if (argument == "odd") { + m_a = 2; + m_b = 1; + } else if (argument == "even") { + m_a = 2; + m_b = 0; + } else { + int n = argument.find('n'); + if (n != -1) { + if (argument[0] == '-') { + if (n == 1) + m_a = -1; // -n == -1n + else + m_a = argument.substring(0, n).toInt(); + } else if (!n) + m_a = 1; // n == 1n + else + m_a = argument.substring(0, n).toInt(); + + int p = argument.find('+', n); + if (p != -1) + m_b = argument.substring(p + 1, argument.length() - p - 1).toInt(); + else { + p = argument.find('-', n); + m_b = -argument.substring(p + 1, argument.length() - p - 1).toInt(); + } + } else + m_b = argument.toInt(); + } + return true; +} + +// a helper function for checking nth-arguments +bool CSSSelector::RareData::matchNth(int count) +{ + if (!m_a) + return count == m_b; + else if (m_a > 0) { + if (count < m_b) + return false; + return (count - m_b) % m_a == 0; + } else { + if (count > m_b) + return false; + return (m_b - count) % (-m_a) == 0; + } +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSSelector.h b/src/3rdparty/webkit/WebCore/css/CSSSelector.h new file mode 100644 index 0000000..8da11d7 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSSelector.h @@ -0,0 +1,259 @@ +/* + * 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" +#include <wtf/Noncopyable.h> +#include <wtf/OwnPtr.h> + +namespace WebCore { + + // this class represents a selector for a StyleRule + class CSSSelector : Noncopyable { + public: + CSSSelector() + : m_tag(anyQName()) + , m_relation(Descendant) + , m_match(None) + , m_pseudoType(PseudoNotParsed) + , m_parsedNth(false) + , m_isLastInSelectorList(false) + , m_hasRareData(false) + { + } + + CSSSelector(const QualifiedName& qName) + : m_tag(qName) + , m_relation(Descendant) + , m_match(None) + , m_pseudoType(PseudoNotParsed) + , m_parsedNth(false) + , m_isLastInSelectorList(false) + , m_hasRareData(false) + { + } + + ~CSSSelector() + { + if (m_hasRareData) + delete m_data.m_rareData; + else + delete m_data.m_tagHistory; + } + + /** + * 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, + PseudoFullPageMedia, + PseudoDisabled, + PseudoInputPlaceholder, + PseudoReadOnly, + PseudoReadWrite, + PseudoIndeterminate, + PseudoTarget, + PseudoBefore, + PseudoAfter, + PseudoLang, + PseudoNot, + PseudoResizer, + PseudoRoot, + PseudoScrollbar, + PseudoScrollbarBack, + PseudoScrollbarButton, + PseudoScrollbarCorner, + PseudoScrollbarForward, + PseudoScrollbarThumb, + PseudoScrollbarTrack, + PseudoScrollbarTrackPiece, + PseudoWindowInactive, + PseudoCornerPresent, + PseudoDecrement, + PseudoIncrement, + PseudoHorizontal, + PseudoVertical, + PseudoStart, + PseudoEnd, + PseudoDoubleButton, + PseudoSingleButton, + PseudoNoButton, + 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); + } + + CSSSelector* tagHistory() const { return m_hasRareData ? m_data.m_rareData->m_tagHistory.get() : m_data.m_tagHistory; } + void setTagHistory(CSSSelector* tagHistory); + + bool hasTag() const { return m_tag != anyQName(); } + bool hasAttribute() const { return m_match == Id || m_match == Class || (m_hasRareData && m_data.m_rareData->m_attribute != anyQName()); } + + const QualifiedName& attribute() const; + const AtomicString& argument() const { return m_hasRareData ? m_data.m_rareData->m_argument : nullAtom; } + CSSSelector* simpleSelector() const { return m_hasRareData ? m_data.m_rareData->m_simpleSelector.get() : 0; } + + void setAttribute(const QualifiedName& value); + void setArgument(const AtomicString& value); + void setSimpleSelector(CSSSelector* value); + + bool parseNth(); + bool matchNth(int count); + + Relation relation() const { return static_cast<Relation>(m_relation); } + + bool isLastInSelectorList() const { return m_isLastInSelectorList; } + void setLastInSelectorList() { m_isLastInSelectorList = true; } + + mutable AtomicString m_value; + QualifiedName m_tag; + + unsigned m_relation : 3; // enum Relation + mutable unsigned m_match : 4; // enum Match + mutable unsigned m_pseudoType : 8; // PseudoType + + private: + bool m_parsedNth : 1; // Used for :nth-* + bool m_isLastInSelectorList : 1; + bool m_hasRareData : 1; + + void extractPseudoType() const; + + struct RareData { + RareData(CSSSelector* tagHistory) + : m_tagHistory(tagHistory) + , m_simpleSelector(0) + , m_attribute(anyQName()) + , m_argument(nullAtom) + , m_a(0) + , m_b(0) + { + } + + bool parseNth(); + bool matchNth(int count); + + OwnPtr<CSSSelector> m_tagHistory; + OwnPtr<CSSSelector> m_simpleSelector; // Used for :not. + QualifiedName m_attribute; // used for attribute selector + AtomicString m_argument; // Used for :contains, :lang and :nth-* + int m_a; // Used for :nth-* + int m_b; // Used for :nth-* + }; + + void createRareData() + { + if (m_hasRareData) + return; + m_data.m_rareData = new RareData(m_data.m_tagHistory); + m_hasRareData = true; + } + + union DataUnion { + DataUnion() : m_tagHistory(0) { } + CSSSelector* m_tagHistory; + RareData* m_rareData; + } m_data; + }; + +} // namespace WebCore + +#endif // CSSSelector_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSSelectorList.cpp b/src/3rdparty/webkit/WebCore/css/CSSSelectorList.cpp new file mode 100644 index 0000000..7276141 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSSelectorList.cpp @@ -0,0 +1,79 @@ +/* + * 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 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 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 "CSSSelectorList.h" + +namespace WebCore { + +CSSSelectorList::~CSSSelectorList() +{ + deleteSelectors(); +} + +void CSSSelectorList::adopt(CSSSelectorList& list) +{ + deleteSelectors(); + m_selectorArray = list.m_selectorArray; + list.m_selectorArray = 0; +} + +void CSSSelectorList::adoptSelectorVector(Vector<CSSSelector*>& selectorVector) +{ + deleteSelectors(); + const size_t size = selectorVector.size(); + ASSERT(size); + if (size == 1) { + m_selectorArray = selectorVector[0]; + m_selectorArray->setLastInSelectorList(); + selectorVector.shrink(0); + return; + } + m_selectorArray = reinterpret_cast<CSSSelector*>(fastMalloc(sizeof(CSSSelector) * selectorVector.size())); + for (size_t i = 0; i < size; ++i) { + memcpy(&m_selectorArray[i], selectorVector[i], sizeof(CSSSelector)); + fastFree(selectorVector[i]); + ASSERT(!m_selectorArray[i].isLastInSelectorList()); + } + m_selectorArray[size - 1].setLastInSelectorList(); + selectorVector.shrink(0); +} + +void CSSSelectorList::deleteSelectors() +{ + if (!m_selectorArray) + return; + CSSSelector* s = m_selectorArray; + while (1) { + bool done = s->isLastInSelectorList(); + s->~CSSSelector(); + if (done) + break; + ++s; + } + fastFree(m_selectorArray); +} + +} diff --git a/src/3rdparty/webkit/WebCore/css/CSSSelectorList.h b/src/3rdparty/webkit/WebCore/css/CSSSelectorList.h new file mode 100644 index 0000000..7a41fcf --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSSelectorList.h @@ -0,0 +1,55 @@ +/* + * 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 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 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 CSSSelectorList_h +#define CSSSelectorList_h + +#include "CSSSelector.h" +#include <wtf/Noncopyable.h> + +namespace WebCore { + + class CSSSelectorList : Noncopyable { + public: + CSSSelectorList() : m_selectorArray(0) { } + ~CSSSelectorList(); + + void adopt(CSSSelectorList& list); + void adoptSelectorVector(Vector<CSSSelector*>& selectorVector); + + CSSSelector* first() const { return m_selectorArray ? m_selectorArray : 0; } + static CSSSelector* next(CSSSelector* previous) { return previous->isLastInSelectorList() ? 0 : previous + 1; } + bool hasOneSelector() const { return m_selectorArray ? m_selectorArray->isLastInSelectorList() : false; } + + private: + void deleteSelectors(); + + // End of the array is indicated by m_isLastInSelectorList bit in the last item. + CSSSelector* m_selectorArray; + }; + +} + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/CSSStyleDeclaration.cpp b/src/3rdparty/webkit/WebCore/css/CSSStyleDeclaration.cpp new file mode 100644 index 0000000..b840e07 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSStyleDeclaration.cpp @@ -0,0 +1,158 @@ +/* + * (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 <wtf/ASCIICType.h> + +using namespace WTF; + +namespace WebCore { + +CSSStyleDeclaration::CSSStyleDeclaration(CSSRule* parent) + : StyleBase(parent) +{ +} + +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> propertiesToRemove; + { + CSSMutableStyleDeclaration::const_iterator end = style->end(); + for (CSSMutableStyleDeclaration::const_iterator it = style->begin(); it != end; ++it) { + const CSSProperty& property = *it; + RefPtr<CSSValue> value = getPropertyCSSValue(property.id()); + if (value && (value->cssText() == property.value()->cssText())) + propertiesToRemove.append(property.id()); + } + } + + // FIXME: This should use mass removal. + for (unsigned i = 0; i < propertiesToRemove.size(); i++) + style->removeProperty(propertiesToRemove[i]); +} + +PassRefPtr<CSSMutableStyleDeclaration> CSSStyleDeclaration::copyPropertiesInSet(const int* set, unsigned length) const +{ + Vector<CSSProperty> list; + list.reserveCapacity(length); + unsigned variableDependentValueCount = 0; + for (unsigned i = 0; i < length; i++) { + RefPtr<CSSValue> value = getPropertyCSSValue(set[i]); + if (value) { + if (value->isVariableDependentValue()) + variableDependentValueCount++; + list.append(CSSProperty(set[i], value.release(), false)); + } + } + return CSSMutableStyleDeclaration::create(list, variableDependentValueCount); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSStyleDeclaration.h b/src/3rdparty/webkit/WebCore/css/CSSStyleDeclaration.h new file mode 100644 index 0000000..e6fede6 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSStyleDeclaration.h @@ -0,0 +1,78 @@ +/* + * (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: + 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/src/3rdparty/webkit/WebCore/css/CSSStyleDeclaration.idl b/src/3rdparty/webkit/WebCore/css/CSSStyleDeclaration.idl new file mode 100644 index 0000000..60020d9 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSStyleRule.cpp b/src/3rdparty/webkit/WebCore/css/CSSStyleRule.cpp new file mode 100644 index 0000000..aaac254 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSStyleRule.cpp @@ -0,0 +1,85 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2002-2003 Dirk Mueller (mueller@kde.org) + * Copyright (C) 2002, 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 "CSSStyleRule.h" + +#include "CSSMutableStyleDeclaration.h" +#include "CSSSelector.h" + +namespace WebCore { + +CSSStyleRule::CSSStyleRule(CSSStyleSheet* parent) + : CSSRule(parent) +{ +} + +CSSStyleRule::~CSSStyleRule() +{ + if (m_style) + m_style->setParent(0); +} + +String CSSStyleRule::selectorText() const +{ + String str; + for (CSSSelector* s = selectorList().first(); s; s = CSSSelectorList::next(s)) { + if (s != selectorList().first()) + str += ", "; + str += s->selectorText(); + } + return str; +} + +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; +} + +void CSSStyleRule::addSubresourceStyleURLs(ListHashSet<KURL>& urls) +{ + if (m_style) + m_style->addSubresourceStyleURLs(urls); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSStyleRule.h b/src/3rdparty/webkit/WebCore/css/CSSStyleRule.h new file mode 100644 index 0000000..23d8648 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSStyleRule.h @@ -0,0 +1,75 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2002-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. + */ + +#ifndef CSSStyleRule_h +#define CSSStyleRule_h + +#include "CSSRule.h" +#include "CSSSelectorList.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class CSSMutableStyleDeclaration; +class CSSSelector; + +class CSSStyleRule : public CSSRule { +public: + static PassRefPtr<CSSStyleRule> create(CSSStyleSheet* parent) + { + return adoptRef(new CSSStyleRule(parent)); + } + virtual ~CSSStyleRule(); + + String selectorText() const; + void setSelectorText(const String&, ExceptionCode&); + + CSSMutableStyleDeclaration* style() const { return m_style.get(); } + + virtual String cssText() const; + + // Not part of the CSSOM + virtual bool parseString(const String&, bool = false); + + void adoptSelectorVector(Vector<CSSSelector*>& selectors) { m_selectorList.adoptSelectorVector(selectors); } + void setDeclaration(PassRefPtr<CSSMutableStyleDeclaration>); + + const CSSSelectorList& selectorList() const { return m_selectorList; } + CSSMutableStyleDeclaration* declaration() { return m_style.get(); } + + virtual void addSubresourceStyleURLs(ListHashSet<KURL>& urls); + +private: + CSSStyleRule(CSSStyleSheet* parent); + + virtual bool isStyleRule() { return true; } + + // Inherited from CSSRule + virtual unsigned short type() const { return STYLE_RULE; } + + RefPtr<CSSMutableStyleDeclaration> m_style; + CSSSelectorList m_selectorList; +}; + +} // namespace WebCore + +#endif // CSSStyleRule_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSStyleRule.idl b/src/3rdparty/webkit/WebCore/css/CSSStyleRule.idl new file mode 100644 index 0000000..0240dd0 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSStyleSelector.cpp b/src/3rdparty/webkit/WebCore/css/CSSStyleSelector.cpp new file mode 100644 index 0000000..3b70cf4 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSStyleSelector.cpp @@ -0,0 +1,5894 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) + * Copyright (C) 2006, 2007 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> + * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.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. + */ + +#include "config.h" +#include "CSSStyleSelector.h" + +#include "CSSBorderImageValue.h" +#include "CSSCursorImageValue.h" +#include "CSSFontFace.h" +#include "CSSFontFaceRule.h" +#include "CSSFontFaceSource.h" +#include "CSSImportRule.h" +#include "CSSMediaRule.h" +#include "CSSParser.h" +#include "CSSPrimitiveValueMappings.h" +#include "CSSProperty.h" +#include "CSSPropertyNames.h" +#include "CSSReflectValue.h" +#include "CSSRuleList.h" +#include "CSSSelector.h" +#include "CSSSelectorList.h" +#include "CSSStyleRule.h" +#include "CSSStyleSheet.h" +#include "CSSTimingFunctionValue.h" +#include "CSSValueList.h" +#include "CSSVariableDependentValue.h" +#include "CSSVariablesDeclaration.h" +#include "CSSVariablesRule.h" +#include "CachedImage.h" +#include "Counter.h" +#include "CounterContent.h" +#include "FocusController.h" +#include "FontFamilyValue.h" +#include "FontValue.h" +#include "Frame.h" +#include "FrameView.h" +#include "HTMLDocument.h" +#include "HTMLElement.h" +#include "HTMLInputElement.h" +#include "HTMLNames.h" +#include "HTMLTextAreaElement.h" +#include "LinkHash.h" +#include "MatrixTransformOperation.h" +#include "MediaList.h" +#include "MediaQueryEvaluator.h" +#include "NodeRenderStyle.h" +#include "Page.h" +#include "PageGroup.h" +#include "Pair.h" +#include "Rect.h" +#include "RenderScrollbar.h" +#include "RenderScrollbarTheme.h" +#include "RenderTheme.h" +#include "RotateTransformOperation.h" +#include "ScaleTransformOperation.h" +#include "SelectionController.h" +#include "Settings.h" +#include "ShadowValue.h" +#include "SkewTransformOperation.h" +#include "StyleCachedImage.h" +#include "StyleGeneratedImage.h" +#include "StyleSheetList.h" +#include "Text.h" +#include "TranslateTransformOperation.h" +#include "UserAgentStyleSheets.h" +#include "WebKitCSSKeyframeRule.h" +#include "WebKitCSSKeyframesRule.h" +#include "WebKitCSSTransformValue.h" +#include "XMLNames.h" +#include "loader.h" +#include <wtf/StdLibExtras.h> +#include <wtf/Vector.h> + +#if ENABLE(DASHBOARD_SUPPORT) +#include "DashboardRegion.h" +#endif + +#if ENABLE(SVG) +#include "XLinkNames.h" +#include "SVGNames.h" +#endif + +#if ENABLE(WML) +#include "WMLNames.h" +#endif + +#if PLATFORM(QT) +#include <qwebhistoryinterface.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_FILL_LAYER_INHERIT_AND_INITIAL(layerType, LayerType, prop, Prop) \ +if (isInherit) { \ + FillLayer* currChild = m_style->access##LayerType##Layers(); \ + FillLayer* prevChild = 0; \ + const FillLayer* currParent = m_parentStyle->layerType##Layers(); \ + while (currParent && currParent->is##Prop##Set()) { \ + if (!currChild) { \ + /* Need to make a new layer.*/ \ + currChild = new FillLayer(LayerType##FillLayer); \ + 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(); \ + } \ +} else if (isInitial) { \ + FillLayer* currChild = m_style->access##LayerType##Layers(); \ + currChild->set##Prop(FillLayer::initialFill##Prop(LayerType##FillLayer)); \ + for (currChild = currChild->next(); currChild; currChild = currChild->next()) \ + currChild->clear##Prop(); \ +} + +#define HANDLE_FILL_LAYER_VALUE(layerType, LayerType, prop, Prop, value) { \ +HANDLE_FILL_LAYER_INHERIT_AND_INITIAL(layerType, LayerType, prop, Prop) \ +if (isInherit || isInitial) \ + return; \ +FillLayer* currChild = m_style->access##LayerType##Layers(); \ +FillLayer* 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 FillLayer(LayerType##FillLayer); \ + prevChild->setNext(currChild); \ + } \ + mapFill##Prop(currChild, valueList->itemWithoutBoundsCheck(i)); \ + prevChild = currChild; \ + currChild = currChild->next(); \ + } \ +} else { \ + mapFill##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_FILL_LAYER_INHERIT_AND_INITIAL(background, Background, prop, Prop) + +#define HANDLE_BACKGROUND_VALUE(prop, Prop, value) \ +HANDLE_FILL_LAYER_VALUE(background, Background, prop, Prop, value) + +#define HANDLE_MASK_INHERIT_AND_INITIAL(prop, Prop) \ +HANDLE_FILL_LAYER_INHERIT_AND_INITIAL(mask, Mask, prop, Prop) + +#define HANDLE_MASK_VALUE(prop, Prop, value) \ +HANDLE_FILL_LAYER_VALUE(mask, Mask, prop, Prop, value) + +#define HANDLE_ANIMATION_INHERIT_AND_INITIAL(prop, Prop) \ +if (isInherit) { \ + AnimationList* list = m_style->accessAnimations(); \ + const AnimationList* parentList = m_parentStyle->animations(); \ + size_t i = 0, parentSize = parentList ? parentList->size() : 0; \ + for ( ; i < parentSize && parentList->animation(i)->is##Prop##Set(); ++i) { \ + if (list->size() <= i) \ + list->append(Animation::create()); \ + list->animation(i)->set##Prop(parentList->animation(i)->prop()); \ + } \ + \ + /* Reset any remaining animations to not have the property set. */ \ + for ( ; i < list->size(); ++i) \ + list->animation(i)->clear##Prop(); \ +} else if (isInitial) { \ + AnimationList* list = m_style->accessAnimations(); \ + if (list->isEmpty()) \ + list->append(Animation::create()); \ + list->animation(0)->set##Prop(Animation::initialAnimation##Prop()); \ + for (size_t i = 1; i < list->size(); ++i) \ + list->animation(0)->clear##Prop(); \ +} + +#define HANDLE_ANIMATION_VALUE(prop, Prop, value) { \ +HANDLE_ANIMATION_INHERIT_AND_INITIAL(prop, Prop) \ +if (isInherit || isInitial) \ + return; \ +AnimationList* list = m_style->accessAnimations(); \ +size_t childIndex = 0; \ +if (value->isValueList()) { \ + /* Walk each value and put it into an animation, creating new animations as needed. */ \ + CSSValueList* valueList = static_cast<CSSValueList*>(value); \ + for (unsigned int i = 0; i < valueList->length(); i++) { \ + if (childIndex <= list->size()) \ + list->append(Animation::create()); \ + mapAnimation##Prop(list->animation(childIndex), valueList->itemWithoutBoundsCheck(i)); \ + ++childIndex; \ + } \ +} else { \ + if (list->isEmpty()) \ + list->append(Animation::create()); \ + mapAnimation##Prop(list->animation(childIndex), value); \ + childIndex = 1; \ +} \ +for ( ; childIndex < list->size(); ++childIndex) { \ + /* Reset all remaining animations to not have the property set. */ \ + list->animation(childIndex)->clear##Prop(); \ +} \ +} + +#define HANDLE_TRANSITION_INHERIT_AND_INITIAL(prop, Prop) \ +if (isInherit) { \ + AnimationList* list = m_style->accessTransitions(); \ + const AnimationList* parentList = m_parentStyle->transitions(); \ + size_t i = 0, parentSize = parentList ? parentList->size() : 0; \ + for ( ; i < parentSize && parentList->animation(i)->is##Prop##Set(); ++i) { \ + if (list->size() <= i) \ + list->append(Animation::create()); \ + list->animation(i)->set##Prop(parentList->animation(i)->prop()); \ + } \ + \ + /* Reset any remaining transitions to not have the property set. */ \ + for ( ; i < list->size(); ++i) \ + list->animation(i)->clear##Prop(); \ +} else if (isInitial) { \ + AnimationList* list = m_style->accessTransitions(); \ + if (list->isEmpty()) \ + list->append(Animation::create()); \ + list->animation(0)->set##Prop(Animation::initialAnimation##Prop()); \ + for (size_t i = 1; i < list->size(); ++i) \ + list->animation(0)->clear##Prop(); \ +} + +#define HANDLE_TRANSITION_VALUE(prop, Prop, value) { \ +HANDLE_TRANSITION_INHERIT_AND_INITIAL(prop, Prop) \ +if (isInherit || isInitial) \ + return; \ +AnimationList* list = m_style->accessTransitions(); \ +size_t childIndex = 0; \ +if (value->isValueList()) { \ + /* Walk each value and put it into a transition, creating new animations as needed. */ \ + CSSValueList* valueList = static_cast<CSSValueList*>(value); \ + for (unsigned int i = 0; i < valueList->length(); i++) { \ + if (childIndex <= list->size()) \ + list->append(Animation::create()); \ + mapAnimation##Prop(list->animation(childIndex), valueList->itemWithoutBoundsCheck(i)); \ + ++childIndex; \ + } \ +} else { \ + if (list->isEmpty()) \ + list->append(Animation::create()); \ + mapAnimation##Prop(list->animation(childIndex), value); \ + childIndex = 1; \ +} \ +for ( ; childIndex < list->size(); ++childIndex) { \ + /* Reset all remaining transitions to not have the property set. */ \ + list->animation(childIndex)->clear##Prop(); \ +} \ +} + +#define HANDLE_INHERIT_COND(propID, prop, Prop) \ +if (id == propID) { \ + m_style->set##Prop(m_parentStyle->prop()); \ + return; \ +} + +#define HANDLE_INHERIT_COND_WITH_BACKUP(propID, prop, propAlt, Prop) \ +if (id == propID) { \ + if (m_parentStyle->prop().isValid()) \ + m_style->set##Prop(m_parentStyle->prop()); \ + else \ + m_style->set##Prop(m_parentStyle->propAlt()); \ + 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; +}; + +static CSSRuleSet* defaultStyle; +static CSSRuleSet* defaultQuirksStyle; +static CSSRuleSet* defaultPrintStyle; +static CSSRuleSet* defaultViewSourceStyle; +static CSSStyleSheet* simpleDefaultStyleSheet; + +RenderStyle* CSSStyleSelector::s_styleNotYetAvailable; + +static PseudoState pseudoState; + +static void loadFullDefaultStyle(); +static void loadSimpleDefaultStyle(); +// FIXME: It would be nice to use some mechanism that guarantees this is in sync with the real UA stylesheet. +static const char* simpleUserAgentStyleSheet = "html,body,div{display:block}body{margin:8px}div:focus,span:focus{outline:auto 5px -webkit-focus-ring-color}"; + +static bool elementCanUseSimpleDefaultStyle(Element* e) +{ + return e->hasTagName(htmlTag) || e->hasTagName(bodyTag) || e->hasTagName(divTag) || e->hasTagName(spanTag) || e->hasTagName(brTag); +} + +static const MediaQueryEvaluator& screenEval() +{ + DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticScreenEval, ("screen")); + return staticScreenEval; +} + +static const MediaQueryEvaluator& printEval() +{ + DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticPrintEval, ("print")); + return staticPrintEval; +} + +CSSStyleSelector::CSSStyleSelector(Document* doc, const String& userStyleSheet, StyleSheetList* styleSheets, CSSStyleSheet* mappedElementSheet, bool strictParsing, bool matchAuthorAndUserStyles) + : m_backgroundData(BackgroundFillLayer) + , m_checker(doc, strictParsing) + , m_fontSelector(CSSFontSelector::create(doc)) +{ + init(); + + m_matchAuthorAndUserStyles = matchAuthorAndUserStyles; + + Element* root = doc->documentElement(); + + if (!defaultStyle) { + if (!root || elementCanUseSimpleDefaultStyle(root)) + loadSimpleDefaultStyle(); + else + loadFullDefaultStyle(); + } + + 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 = doc->view(); + if (view) + m_medium = new MediaQueryEvaluator(view->mediaType()); + else + m_medium = new MediaQueryEvaluator("all"); + + 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.get()); + } + + // FIXME: This sucks! The user sheet is reparsed every time! + if (!userStyleSheet.isEmpty()) { + m_userSheet = CSSStyleSheet::create(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); + + unsigned length = styleSheets->length(); + for (unsigned i = 0; i < length; i++) { + StyleSheet* sheet = styleSheets->item(i); + if (sheet->isCSSStyleSheet() && !sheet->disabled()) + m_authorStyle->addRulesFromSheet(static_cast<CSSStyleSheet*>(sheet), *m_medium, this); + } +} + +// This is a simplified style setting function for keyframe styles +void CSSStyleSelector::addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule) +{ + AtomicString s(rule->name()); + m_keyframesRuleMap.add(s.impl(), rule); +} + +void CSSStyleSelector::init() +{ + m_element = 0; + m_matchedDecls.clear(); + m_ruleList = 0; + m_rootDefaultStyle = 0; + m_medium = 0; +} + +CSSStyleSelector::~CSSStyleSelector() +{ + m_fontSelector->clearDocument(); + delete m_medium; + delete m_authorStyle; + delete m_userStyle; + deleteAllValues(m_viewportDependentMediaQueryResults); + m_keyframesRuleMap.clear(); +} + +static CSSStyleSheet* parseUASheet(const String& str) +{ + CSSStyleSheet* sheet = CSSStyleSheet::create().releaseRef(); // leak the sheet on purpose + sheet->parseString(str); + return sheet; +} + +static CSSStyleSheet* parseUASheet(const char* characters, unsigned size) +{ + return parseUASheet(String(characters, size)); +} + +static void loadFullDefaultStyle() +{ + if (simpleDefaultStyleSheet) { + ASSERT(defaultStyle); + delete defaultStyle; + delete simpleDefaultStyleSheet; + defaultStyle = new CSSRuleSet; + simpleDefaultStyleSheet = 0; + } else { + ASSERT(!defaultStyle); + defaultStyle = new CSSRuleSet; + defaultPrintStyle = new CSSRuleSet; + defaultQuirksStyle = new CSSRuleSet; + } + + // Strict-mode rules. + String defaultRules = String(html4UserAgentStyleSheet, sizeof(html4UserAgentStyleSheet)) + theme()->extraDefaultStyleSheet(); + CSSStyleSheet* defaultSheet = parseUASheet(defaultRules); + defaultStyle->addRulesFromSheet(defaultSheet, screenEval()); + defaultPrintStyle->addRulesFromSheet(defaultSheet, printEval()); + + // Quirks-mode rules. + String quirksRules = String(quirksUserAgentStyleSheet, sizeof(quirksUserAgentStyleSheet)) + theme()->extraQuirksStyleSheet(); + CSSStyleSheet* quirksSheet = parseUASheet(quirksRules); + defaultQuirksStyle->addRulesFromSheet(quirksSheet, screenEval()); +} + +static void loadSimpleDefaultStyle() +{ + ASSERT(!defaultStyle); + ASSERT(!simpleDefaultStyleSheet); + + defaultStyle = new CSSRuleSet; + defaultPrintStyle = new CSSRuleSet; + defaultQuirksStyle = new CSSRuleSet; + + simpleDefaultStyleSheet = parseUASheet(simpleUserAgentStyleSheet, strlen(simpleUserAgentStyleSheet)); + defaultStyle->addRulesFromSheet(simpleDefaultStyleSheet, screenEval()); + + // No need to initialize quirks sheet yet as there are no quirk rules for elements allowed in simple default style. +} + +static void loadViewSourceStyle() +{ + ASSERT(!defaultViewSourceStyle); + defaultViewSourceStyle = new CSSRuleSet; + defaultViewSourceStyle->addRulesFromSheet(parseUASheet(sourceUserAgentStyleSheet, sizeof(sourceUserAgentStyleSheet)), screenEval()); +} + +void CSSStyleSelector::addMatchedDeclaration(CSSMutableStyleDeclaration* decl) +{ + if (!decl->hasVariableDependentValue()) { + m_matchedDecls.append(decl); + return; + } + + // See if we have already resolved the variables in this declaration. + CSSMutableStyleDeclaration* resolvedDecl = m_resolvedVariablesDeclarations.get(decl).get(); + if (resolvedDecl) { + m_matchedDecls.append(resolvedDecl); + return; + } + + // If this declaration has any variables in it, then we need to make a cloned + // declaration with as many variables resolved as possible for this style selector's media. + RefPtr<CSSMutableStyleDeclaration> newDecl = CSSMutableStyleDeclaration::create(decl->parentRule()); + m_matchedDecls.append(newDecl.get()); + m_resolvedVariablesDeclarations.set(decl, newDecl); + + HashSet<String> usedBlockVariables; + resolveVariablesForDeclaration(decl, newDecl.get(), usedBlockVariables); +} + +void CSSStyleSelector::resolveVariablesForDeclaration(CSSMutableStyleDeclaration* decl, CSSMutableStyleDeclaration* newDecl, HashSet<String>& usedBlockVariables) +{ + // Now iterate over the properties in the original declaration. As we resolve variables we'll end up + // mutating the new declaration (possibly expanding shorthands). The new declaration has no m_node + // though, so it can't mistakenly call setChanged on anything. + CSSMutableStyleDeclaration::const_iterator end = decl->end(); + for (CSSMutableStyleDeclaration::const_iterator it = decl->begin(); it != end; ++it) { + const CSSProperty& current = *it; + if (!current.value()->isVariableDependentValue()) { + // We can just add the parsed property directly. + newDecl->addParsedProperty(current); + continue; + } + CSSValueList* valueList = static_cast<CSSVariableDependentValue*>(current.value())->valueList(); + if (!valueList) + continue; + CSSParserValueList resolvedValueList; + unsigned s = valueList->length(); + bool fullyResolved = true; + for (unsigned i = 0; i < s; ++i) { + CSSValue* val = valueList->item(i); + CSSPrimitiveValue* primitiveValue = val->isPrimitiveValue() ? static_cast<CSSPrimitiveValue*>(val) : 0; + if (primitiveValue && primitiveValue->isVariable()) { + CSSVariablesRule* rule = m_variablesMap.get(primitiveValue->getStringValue()); + if (!rule || !rule->variables()) { + fullyResolved = false; + break; + } + + if (current.id() == CSSPropertyWebkitVariableDeclarationBlock && s == 1) { + fullyResolved = false; + if (!usedBlockVariables.contains(primitiveValue->getStringValue())) { + CSSMutableStyleDeclaration* declBlock = rule->variables()->getParsedVariableDeclarationBlock(primitiveValue->getStringValue()); + if (declBlock) { + usedBlockVariables.add(primitiveValue->getStringValue()); + resolveVariablesForDeclaration(declBlock, newDecl, usedBlockVariables); + } + } + } + + CSSValueList* resolvedVariable = rule->variables()->getParsedVariable(primitiveValue->getStringValue()); + if (!resolvedVariable) { + fullyResolved = false; + break; + } + unsigned valueSize = resolvedVariable->length(); + for (unsigned j = 0; j < valueSize; ++j) + resolvedValueList.addValue(resolvedVariable->item(j)->parserValue()); + } else + resolvedValueList.addValue(val->parserValue()); + } + + if (!fullyResolved) + continue; + + // We now have a fully resolved new value list. We want the parser to use this value list + // and parse our new declaration. + CSSParser(m_checker.m_strictParsing).parsePropertyWithResolvedVariables(current.id(), current.isImportant(), newDecl, &resolvedValueList); + } +} + +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()) { + ASSERT(m_styledElement); + const ClassNames& classNames = m_styledElement->classNames(); + size_t size = classNames.size(); + for (size_t i = 0; i < size; ++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_checker.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 = CSSRuleList::create(); + 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 (m_dynamicPseudo != RenderStyle::NOPSEUDO && m_checker.m_pseudoStyle == RenderStyle::NOPSEUDO) { + if (m_checker.m_collectRulesOnly) + return; + if (m_dynamicPseudo < RenderStyle::FIRST_INTERNAL_PSEUDOID) + m_style->setHasPseudoStyle(m_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; + pseudoState = PseudoUnknown; +} + +void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* parentStyle, RenderStyle::PseudoId pseudoID) +{ + m_checker.m_pseudoStyle = pseudoID; + + m_parentNode = e ? e->parentNode() : 0; + +#if ENABLE(SVG) + if (!m_parentNode && e && e->isSVGElement() && e->isShadowNode()) + m_parentNode = e->shadowParentNode(); +#endif + + if (parentStyle) + m_parentStyle = parentStyle; + else + m_parentStyle = m_parentNode ? m_parentNode->renderStyle() : 0; + + m_style = 0; + + m_matchedDecls.clear(); + + m_ruleList = 0; + + m_fontDirty = false; +} + +static inline const AtomicString* linkAttribute(Node* node) +{ + if (!node->isLink()) + return 0; + + ASSERT(node->isElementNode()); + Element* element = static_cast<Element*>(node); + if (element->isHTMLElement()) + return &element->getAttribute(hrefAttr); + +#if ENABLE(WML) + if (element->isWMLElement()) { + // <anchor> elements don't have href attributes, but we still want to + // appear as link, so linkAttribute() has to return a non-null value! + if (element->hasTagName(WMLNames::anchorTag)) + return &emptyAtom; + + return &element->getAttribute(hrefAttr); + } +#endif + +#if ENABLE(SVG) + if (element->isSVGElement()) + return &element->getAttribute(XLinkNames::hrefAttr); +#endif + + return 0; +} + +CSSStyleSelector::SelectorChecker::SelectorChecker(Document* document, bool strictParsing) + : m_document(document) + , m_strictParsing(strictParsing) + , m_collectRulesOnly(false) + , m_pseudoStyle(RenderStyle::NOPSEUDO) + , m_documentIsHTML(document->isHTMLDocument()) +{ +} + +PseudoState CSSStyleSelector::SelectorChecker::checkPseudoState(Element* element, bool checkVisited) const +{ + const AtomicString* attr = linkAttribute(element); + if (!attr || attr->isNull()) + return PseudoNone; + + if (!checkVisited) + return PseudoAnyLink; + + Frame* frame = m_document->frame(); + if (!frame) + return PseudoLink; + + Page* page = frame->page(); + if (!page) + return PseudoLink; + + Vector<UChar, 512> url; + visitedURL(m_document->baseURL(), *attr, url); + if (url.isEmpty()) + return PseudoLink; + +#if PLATFORM(QT) + // If the Qt4.4 interface for the history is used, we will have to fallback + // to the old global history. + QWebHistoryInterface* iface = QWebHistoryInterface::defaultInterface(); + if (iface) + return iface->historyContains(QString(reinterpret_cast<QChar*>(url.data()), url.size())) ? PseudoVisited : PseudoLink; +#endif + + LinkHash hash = visitedLinkHash(url.data(), url.size()); + if (!hash) + return PseudoLink; + m_linksCheckedForVisitedState.add(hash); + return page->group().isLinkVisited(hash) ? PseudoVisited : PseudoLink; +} + +bool CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* element) const +{ + pseudoState = PseudoUnknown; + RenderStyle::PseudoId dynamicPseudo = RenderStyle::NOPSEUDO; + + return checkSelector(sel, element, 0, dynamicPseudo, true, false) == SelectorMatches; +} + +#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(parent->parentElement(), 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()) || + (s->isAutofilled() != m_element->isAutofilled())) + return false; + + if (style->transitions() || style->animations()) + 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. + if (pseudoState == PseudoUnknown) { + const Color& linkColor = m_element->document()->linkColor(); + const Color& visitedColor = m_element->document()->visitedLinkColor(); + pseudoState = m_checker.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(m_element->parentElement()); + 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") + ? defaultPrintStyle : defaultStyle; + matchRules(userAgentStyleSheet, firstUARule, lastUARule); + + // In quirks mode, we match rules from the quirks user agent sheet. + if (!m_checker.m_strictParsing) + matchRules(defaultQuirksStyle, firstUARule, lastUARule); + + // If we're in view source mode, then we match rules from the view source style sheet. + if (m_checker.m_document->frame() && m_checker.m_document->frame()->inViewSourceMode()) { + if (!defaultViewSourceStyle) + loadViewSourceStyle(); + matchRules(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 + +PassRefPtr<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 (!s_styleNotYetAvailable) { + s_styleNotYetAvailable = ::new RenderStyle; + s_styleNotYetAvailable->ref(); + s_styleNotYetAvailable->setDisplay(NONE); + s_styleNotYetAvailable->font().update(m_fontSelector); + } + s_styleNotYetAvailable->ref(); + e->document()->setHasNodesWithPlaceholderStyle(); + return s_styleNotYetAvailable; + } + + initElementAndPseudoState(e); + if (allowSharing) { + RenderStyle* sharedStyle = locateSharedStyle(); + if (sharedStyle) + return sharedStyle; + } + initForStyleResolve(e, defaultParent); + + m_style = RenderStyle::create(); + + if (m_parentStyle) + m_style->inheritFrom(m_parentStyle); + else + m_parentStyle = style(); + + if (simpleDefaultStyleSheet && !elementCanUseSimpleDefaultStyle(e)) + loadFullDefaultStyle(); + +#if ENABLE(SVG) + static bool loadedSVGUserAgentSheet; + if (e->isSVGElement() && !loadedSVGUserAgentSheet) { + // SVG rules. + loadedSVGUserAgentSheet = true; + CSSStyleSheet* svgSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet)); + defaultStyle->addRulesFromSheet(svgSheet, screenEval()); + defaultPrintStyle->addRulesFromSheet(svgSheet, printEval()); + } +#endif + +#if ENABLE(WML) + static bool loadedWMLUserAgentSheet; + if (e->isWMLElement() && !loadedWMLUserAgentSheet) { + // WML rules. + loadedWMLUserAgentSheet = true; + CSSStyleSheet* wmlSheet = parseUASheet(wmlUserAgentStyleSheet, sizeof(wmlUserAgentStyleSheet)); + defaultStyle->addRulesFromSheet(wmlSheet, screenEval()); + defaultPrintStyle->addRulesFromSheet(wmlSheet, printEval()); + } +#endif + +#if ENABLE(VIDEO) + static bool loadedMediaStyleSheet; + if (!loadedMediaStyleSheet && (e->hasTagName(videoTag) || e->hasTagName(audioTag))) { + loadedMediaStyleSheet = true; + String mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + theme()->extraMediaControlsStyleSheet(); + CSSStyleSheet* mediaControlsSheet = parseUASheet(mediaRules); + defaultStyle->addRulesFromSheet(mediaControlsSheet, screenEval()); + defaultPrintStyle->addRulesFromSheet(mediaControlsSheet, 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++) { + Attribute* attr = map->attributeItem(i); + if (attr->isMappedAttribute()) { + MappedAttribute* mappedAttr = static_cast<MappedAttribute*>(attr); + if (mappedAttr->decl()) { + lastAuthorRule = m_matchedDecls.size(); + if (firstAuthorRule == -1) + firstAuthorRule = lastAuthorRule; + addMatchedDeclaration(mappedAttr->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(CSSPropertyLineHeight, 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(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.release(); +} + +void CSSStyleSelector::keyframeStylesForAnimation(Element* e, const RenderStyle* elementStyle, KeyframeList& list) +{ + list.clear(); + + // Get the keyframesRule for this name + if (!e || list.animationName().isEmpty()) + return; + + if (!m_keyframesRuleMap.contains(list.animationName().impl())) + return; + + const WebKitCSSKeyframesRule* rule = m_keyframesRuleMap.find(list.animationName().impl()).get()->second.get(); + + // Construct and populate the style for each keyframe + for (unsigned i = 0; i < rule->length(); ++i) { + // Apply the declaration to the style. This is a simplified version of the logic in styleForElement + initElementAndPseudoState(e); + initForStyleResolve(e); + + const WebKitCSSKeyframeRule* kf = rule->item(i); + addMatchedDeclaration(kf->style()); + + ASSERT(!m_style); + + // Create the style + m_style = RenderStyle::clone(elementStyle); + + m_lineHeightValue = 0; + + // We don't need to bother with !important. Since there is only ever one + // decl, there's nothing to override. So just add the first properties. + applyDeclarations(true, false, 0, m_matchedDecls.size() - 1); + + // 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(CSSPropertyLineHeight, m_lineHeightValue); + + // Now do rest of the properties. + applyDeclarations(false, false, 0, m_matchedDecls.size() - 1); + + // 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(); + + // Add all the animating properties to the list + CSSMutableStyleDeclaration::const_iterator end = kf->style()->end(); + for (CSSMutableStyleDeclaration::const_iterator it = kf->style()->begin(); it != end; ++it) + list.addProperty((*it).id()); + + // Add this keyframe style to all the indicated key times + Vector<float> keys; + kf->getKeys(keys); + for (size_t keyIndex = 0; keyIndex < keys.size(); ++keyIndex) { + float key = keys[keyIndex]; + list.insert(key, m_style); + } + m_style = 0; + } + + // Make sure there is a 0% and a 100% keyframe + float first = -1; + float last = -1; + if (list.size() >= 2) { + first = list.beginKeyframes()->key(); + last = (list.endKeyframes()-1)->key(); + } + if (first != 0 || last != 1) + list.clear(); +} + +PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(RenderStyle::PseudoId pseudo, Element* e, RenderStyle* parentStyle) +{ + if (!e) + return 0; + + initElementAndPseudoState(e); + initForStyleResolve(e, parentStyle, pseudo); + m_style = parentStyle; + + // 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 = RenderStyle::create(); + if (parentStyle) + m_style->inheritFrom(parentStyle); + + m_style->noninherited_flags._styleType = pseudo; + + 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(CSSPropertyLineHeight, 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(style(), 0); + + // Now return the style. + return m_style.release(); +} + +static void addIntrinsicMargins(RenderStyle* style) +{ + // Intrinsic margin value. + const int intrinsicMargin = 2 * style->effectiveZoom(); + + // 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 (!m_checker.m_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); + } + + if (e && (e->hasTagName(tdTag) || e->hasTagName(thTag))) { + if (style->whiteSpace() == KHTML_NOWRAP) { + // Figure out if we are really nowrapping or if we should just + // use normal instead. If the width of the cell is fixed, then + // we don't actually use NOWRAP. + if (style->width().isFixed()) + style->setWhiteSpace(NORMAL); + else + style->setWhiteSpace(NOWRAP); + } + } + + // 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 (!m_checker.m_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. + if (style->position() == StaticPosition) + 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/masks/reflections. + if (style->hasAutoZIndex() && ((e && e->document()->documentElement() == e) || style->opacity() < 1.0f || + style->hasTransform() || style->hasMask() || style->boxReflect())) + 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 ENABLE(WML) + || e->hasTagName(WMLNames::insertedLegendTag) +#endif + )) { + 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); + } + + // Menulists should have visible overflow + if (style->appearance() == MenulistPart) { + style->setOverflowX(OVISIBLE); + style->setOverflowY(OVISIBLE); + } + + // Cull out any useless layers and also repeat patterns into additional layers. + style->adjustBackgroundLayers(); + style->adjustMaskLayers(); + + // Do the same for animations and transitions. + style->adjustAnimations(); + 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(style(), m_parentStyle); + checkForZoomChange(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(); + } +} + +PassRefPtr<CSSRuleList> CSSStyleSelector::styleRulesForElement(Element* e, bool authorOnly) +{ + if (!e || !e->document()->haveStylesheetsLoaded()) + return 0; + + m_checker.m_collectRulesOnly = true; + + initElementAndPseudoState(e); + initForStyleResolve(e); + + 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_checker.m_collectRulesOnly = false; + + return m_ruleList.release(); +} + +PassRefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element*, const String&, bool) +{ + // FIXME: Implement this. + return 0; +} + +bool CSSStyleSelector::checkSelector(CSSSelector* sel) +{ + m_dynamicPseudo = RenderStyle::NOPSEUDO; + + // Check the selector + SelectorMatch match = m_checker.checkSelector(sel, m_element, &m_selectorAttrs, m_dynamicPseudo, true, false, style(), m_parentStyle); + if (match != SelectorMatches) + return false; + + if (m_checker.m_pseudoStyle != RenderStyle::NOPSEUDO && m_checker.m_pseudoStyle != m_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::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, RenderStyle::PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const +{ +#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, selectorAttrs, dynamicPseudo, isAncestor, isSubSelector, elementStyle, elementParentStyle)) + return SelectorFailsLocally; + + // The rest of the selectors has to match + CSSSelector::Relation relation = sel->relation(); + + // Prepare next sel + sel = sel->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, selectorAttrs, dynamicPseudo, 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, selectorAttrs, dynamicPseudo, true, false); + } + case CSSSelector::DirectAdjacent: + { + if (!m_collectRulesOnly && e->parentNode() && e->parentNode()->isElementNode()) { + RenderStyle* parentStyle = elementStyle ? elementParentStyle : 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, selectorAttrs, dynamicPseudo, false, false); + } + case CSSSelector::IndirectAdjacent: + if (!m_collectRulesOnly && e->parentNode() && e->parentNode()->isElementNode()) { + RenderStyle* parentStyle = elementStyle ? elementParentStyle : 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, selectorAttrs, dynamicPseudo, false, false); + if (match != SelectorFailsLocally) + return match; + }; + break; + case CSSSelector::SubSelector: + // a selector is invalid if something follows a pseudo-element + // We make an exception for scrollbar pseudo elements and allow a set of pseudo classes (but nothing else) + // to follow the pseudo elements. + if (elementStyle && dynamicPseudo != RenderStyle::NOPSEUDO && + !((RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == RenderStyle::SCROLLBAR_CORNER || dynamicPseudo == RenderStyle::RESIZER) && sel->m_match == CSSSelector::PseudoClass)) + return SelectorFailsCompletely; + return checkSelector(sel, e, selectorAttrs, dynamicPseudo, isAncestor, true, elementStyle, elementParentStyle); + } + + 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::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, RenderStyle::PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const +{ + if (!e) + return false; + + if (sel->hasTag()) { + const AtomicString& selLocalName = sel->m_tag.localName(); + if (selLocalName != starAtom && selLocalName != e->localName()) + return false; + const AtomicString& selNS = sel->m_tag.namespaceURI(); + if (selNS != starAtom && selNS != e->namespaceURI()) + return false; + } + + if (sel->hasAttribute()) { + if (sel->m_match == CSSSelector::Class) + return e->hasClass() && static_cast<StyledElement*>(e)->classNames().contains(sel->m_value); + + if (sel->m_match == CSSSelector::Id) + return e->hasID() && e->getIDAttribute() == sel->m_value; + + const QualifiedName& attr = sel->attribute(); + + // FIXME: Handle the case were elementStyle is 0. + if (elementStyle && (!e->isStyledElement() || (!static_cast<StyledElement*>(e)->isMappedAttribute(attr) && attr != typeAttr && attr != readonlyAttr))) { + elementStyle->setAffectedByAttributeSelectors(); // Special-case the "type" and "readonly" attributes so input form controls can share style. + if (selectorAttrs) + selectorAttrs->add(attr.localName().impl()); + } + + const AtomicString& value = e->getAttribute(attr); + if (value.isNull()) + return false; // attribute is not set + + bool caseSensitive = !m_documentIsHTML || !htmlAttributeHasCaseInsensitiveValue(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: + { + // Ignore empty selectors or selectors containing spaces + if (sel->m_value.contains(' ') || sel->m_value.isEmpty()) + 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) || sel->m_value.isEmpty()) + return false; + break; + case CSSSelector::Begin: + if (!value.startsWith(sel->m_value, caseSensitive) || sel->m_value.isEmpty()) + return false; + break; + case CSSSelector::End: + if (!value.endsWith(sel->m_value, caseSensitive) || sel->m_value.isEmpty()) + 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) { + // Handle :not up front. + if (sel->pseudoType() == CSSSelector::PseudoNot) { + // check the simple selector + for (CSSSelector* subSel = sel->simpleSelector(); subSel; subSel = subSel->tagHistory()) { + // :not cannot nest. I don't really know why this is a + // restriction in CSS3, but it is, so let's honor it. + if (subSel->simpleSelector()) + break; + if (!checkOneSelector(subSel, e, selectorAttrs, dynamicPseudo, isAncestor, true, elementStyle, elementParentStyle)) + return true; + } + } else if (dynamicPseudo != RenderStyle::NOPSEUDO && (RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == RenderStyle::SCROLLBAR_CORNER || dynamicPseudo == RenderStyle::RESIZER)) { + // CSS scrollbars match a specific subset of pseudo classes, and they have specialized rules for each + // (since there are no elements involved). + return checkScrollbarPseudoClass(sel, dynamicPseudo); + } + + // Normal element pseudo class checking. + switch (sel->pseudoType()) { + // Pseudo classes: + case CSSSelector::PseudoNot: + break; // Already handled up above. + 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 (elementStyle) + elementStyle->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 = elementStyle ? elementStyle : e->renderStyle(); + RenderStyle* parentStyle = elementStyle ? elementParentStyle : 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 = elementStyle ? elementParentStyle : e->parentNode()->renderStyle(); + if (parentStyle) + parentStyle->setChildrenAffectedByForwardPositionalRules(); + } + return result; + } + break; + } + case CSSSelector::PseudoLastChild: { + // last-child matches the last child that is an element + if (Element* parentElement = e->parentElement()) { + bool result = false; + if (parentElement->isFinishedParsingChildren()) { + Node* n = e->nextSibling(); + while (n && !n->isElementNode()) + n = n->nextSibling(); + if (!n) + result = true; + } + if (!m_collectRulesOnly) { + RenderStyle* childStyle = elementStyle ? elementStyle : e->renderStyle(); + RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->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 (Element* parentElement = e->parentElement()) { + if (!m_collectRulesOnly) { + RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle(); + if (parentStyle) + parentStyle->setChildrenAffectedByBackwardPositionalRules(); + } + if (!parentElement->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 (Element* parentElement = e->parentElement()) { + bool firstChild = false; + bool lastChild = false; + + Node* n = e->previousSibling(); + while (n && !n->isElementNode()) + n = n->previousSibling(); + if (!n) + firstChild = true; + if (firstChild && parentElement->isFinishedParsingChildren()) { + n = e->nextSibling(); + while (n && !n->isElementNode()) + n = n->nextSibling(); + if (!n) + lastChild = true; + } + if (!m_collectRulesOnly) { + RenderStyle* childStyle = elementStyle ? elementStyle : e->renderStyle(); + RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->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 (Element* parentElement = e->parentElement()) { + if (!m_collectRulesOnly) { + RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle(); + if (parentStyle) { + parentStyle->setChildrenAffectedByForwardPositionalRules(); + parentStyle->setChildrenAffectedByBackwardPositionalRules(); + } + } + if (!parentElement->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: { + if (!sel->parseNth()) + break; + if (Element* parentElement = e->parentElement()) { + 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 = elementStyle ? elementStyle : e->renderStyle(); + RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle(); + if (childStyle) + childStyle->setChildIndex(count); + if (parentStyle) + parentStyle->setChildrenAffectedByForwardPositionalRules(); + } + + if (sel->matchNth(count)) + return true; + } + break; + } + case CSSSelector::PseudoNthOfType: { + if (!sel->parseNth()) + break; + if (Element* parentElement = e->parentElement()) { + 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 = elementStyle ? elementParentStyle : parentElement->renderStyle(); + if (parentStyle) + parentStyle->setChildrenAffectedByForwardPositionalRules(); + } + + if (sel->matchNth(count)) + return true; + } + break; + } + case CSSSelector::PseudoNthLastChild: { + if (!sel->parseNth()) + break; + if (Element* parentElement = e->parentElement()) { + if (!m_collectRulesOnly) { + RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle(); + if (parentStyle) + parentStyle->setChildrenAffectedByBackwardPositionalRules(); + } + if (!parentElement->isFinishedParsingChildren()) + return false; + int count = 1; + Node* n = e->nextSibling(); + while (n) { + if (n->isElementNode()) + count++; + n = n->nextSibling(); + } + if (sel->matchNth(count)) + return true; + } + break; + } + case CSSSelector::PseudoNthLastOfType: { + if (!sel->parseNth()) + break; + if (Element* parentElement = e->parentElement()) { + if (!m_collectRulesOnly) { + RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle(); + if (parentStyle) + parentStyle->setChildrenAffectedByBackwardPositionalRules(); + } + if (!parentElement->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 (sel->matchNth(count)) + return true; + } + break; + } + case CSSSelector::PseudoTarget: + if (e == e->document()->getCSSTarget()) + return true; + break; + case CSSSelector::PseudoAnyLink: + if (pseudoState == PseudoUnknown) + pseudoState = checkPseudoState(e, false); + if (pseudoState == PseudoAnyLink || pseudoState == PseudoLink || pseudoState == PseudoVisited) + return true; + break; + case CSSSelector::PseudoAutofill: + if (e) + return e->isAutofilled(); + break; + case CSSSelector::PseudoLink: + if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink) + pseudoState = checkPseudoState(e); + if (pseudoState == PseudoLink) + return true; + break; + case CSSSelector::PseudoVisited: + if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink) + pseudoState = checkPseudoState(e); + if (pseudoState == PseudoVisited) + return true; + break; + case CSSSelector::PseudoDrag: { + if (elementStyle) + elementStyle->setAffectedByDragRules(true); + else if (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()->selection()->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 (m_strictParsing || isSubSelector || (sel->hasTag() && !e->hasTagName(aTag)) || e->isLink()) { + if (elementStyle) + elementStyle->setAffectedByHoverRules(true); + else if (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 (m_strictParsing || isSubSelector || (sel->hasTag() && !e->hasTagName(aTag)) || e->isLink()) { + if (elementStyle) + elementStyle->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::PseudoFullPageMedia: + return e && e->document() && e->document()->isMediaDocument(); + 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::PseudoReadOnly: + return e && e->isTextControl() && e->isReadOnlyControl(); + case CSSSelector::PseudoReadWrite: + return e && e->isTextControl() && !e->isReadOnlyControl(); + 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(); + } + const AtomicString& argument = sel->argument(); + if (value.isEmpty() || !value.startsWith(argument, false)) + break; + if (value.length() != argument.length() && value[argument.length()] != '-') + break; + return true; + } + case CSSSelector::PseudoUnknown: + case CSSSelector::PseudoNotParsed: + default: + ASSERT_NOT_REACHED(); + break; + } + return false; + } + if (sel->m_match == CSSSelector::PseudoElement) { + if (!elementStyle) + 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::PseudoInputPlaceholder: + dynamicPseudo = RenderStyle::INPUT_PLACEHOLDER; + 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::PseudoScrollbar: + dynamicPseudo = RenderStyle::SCROLLBAR; + return true; + case CSSSelector::PseudoScrollbarButton: + dynamicPseudo = RenderStyle::SCROLLBAR_BUTTON; + return true; + case CSSSelector::PseudoScrollbarCorner: + dynamicPseudo = RenderStyle::SCROLLBAR_CORNER; + return true; + case CSSSelector::PseudoScrollbarThumb: + dynamicPseudo = RenderStyle::SCROLLBAR_THUMB; + return true; + case CSSSelector::PseudoScrollbarTrack: + dynamicPseudo = RenderStyle::SCROLLBAR_TRACK; + return true; + case CSSSelector::PseudoScrollbarTrackPiece: + dynamicPseudo = RenderStyle::SCROLLBAR_TRACK_PIECE; + return true; + case CSSSelector::PseudoResizer: + dynamicPseudo = RenderStyle::RESIZER; + return true; + case CSSSelector::PseudoUnknown: + case CSSSelector::PseudoNotParsed: + default: + ASSERT_NOT_REACHED(); + break; + } + return false; + } + // ### add the rest of the checks... + return true; +} + +bool CSSStyleSelector::SelectorChecker::checkScrollbarPseudoClass(CSSSelector* sel, RenderStyle::PseudoId&) const +{ + RenderScrollbar* scrollbar = RenderScrollbar::scrollbarForStyleResolve(); + ScrollbarPart part = RenderScrollbar::partForStyleResolve(); + + // FIXME: This is a temporary hack for resizers and scrollbar corners. Eventually :window-inactive should become a real + // pseudo class and just apply to everything. + if (sel->pseudoType() == CSSSelector::PseudoWindowInactive) + return !m_document->page()->focusController()->isActive(); + + if (!scrollbar) + return false; + + ASSERT(sel->m_match == CSSSelector::PseudoClass); + switch (sel->pseudoType()) { + case CSSSelector::PseudoEnabled: + return scrollbar->enabled(); + case CSSSelector::PseudoDisabled: + return !scrollbar->enabled(); + case CSSSelector::PseudoHover: { + ScrollbarPart hoveredPart = scrollbar->hoveredPart(); + if (part == ScrollbarBGPart) + return hoveredPart != NoPart; + if (part == TrackBGPart) + return hoveredPart == BackTrackPart || hoveredPart == ForwardTrackPart || hoveredPart == ThumbPart; + return part == hoveredPart; + } + case CSSSelector::PseudoActive: { + ScrollbarPart pressedPart = scrollbar->pressedPart(); + if (part == ScrollbarBGPart) + return pressedPart != NoPart; + if (part == TrackBGPart) + return pressedPart == BackTrackPart || pressedPart == ForwardTrackPart || pressedPart == ThumbPart; + return part == pressedPart; + } + case CSSSelector::PseudoHorizontal: + return scrollbar->orientation() == HorizontalScrollbar; + case CSSSelector::PseudoVertical: + return scrollbar->orientation() == VerticalScrollbar; + case CSSSelector::PseudoDecrement: + return part == BackButtonStartPart || part == BackButtonEndPart || part == BackTrackPart; + case CSSSelector::PseudoIncrement: + return part == ForwardButtonStartPart || part == ForwardButtonEndPart || part == ForwardTrackPart; + case CSSSelector::PseudoStart: + return part == BackButtonStartPart || part == ForwardButtonStartPart || part == BackTrackPart; + case CSSSelector::PseudoEnd: + return part == BackButtonEndPart || part == ForwardButtonEndPart || part == ForwardTrackPart; + case CSSSelector::PseudoDoubleButton: { + ScrollbarButtonsPlacement buttonsPlacement = scrollbar->theme()->buttonsPlacement(); + if (part == BackButtonStartPart || part == ForwardButtonStartPart || part == BackTrackPart) + return buttonsPlacement == ScrollbarButtonsDoubleStart || buttonsPlacement == ScrollbarButtonsDoubleBoth; + if (part == BackButtonEndPart || part == ForwardButtonEndPart || part == ForwardTrackPart) + return buttonsPlacement == ScrollbarButtonsDoubleEnd || buttonsPlacement == ScrollbarButtonsDoubleBoth; + return false; + } + case CSSSelector::PseudoSingleButton: { + ScrollbarButtonsPlacement buttonsPlacement = scrollbar->theme()->buttonsPlacement(); + if (part == BackButtonStartPart || part == ForwardButtonEndPart || part == BackTrackPart || part == ForwardTrackPart) + return buttonsPlacement == ScrollbarButtonsSingle; + return false; + } + case CSSSelector::PseudoNoButton: { + ScrollbarButtonsPlacement buttonsPlacement = scrollbar->theme()->buttonsPlacement(); + if (part == BackTrackPart) + return buttonsPlacement == ScrollbarButtonsNone || buttonsPlacement == ScrollbarButtonsDoubleEnd; + if (part == ForwardTrackPart) + return buttonsPlacement == ScrollbarButtonsNone || buttonsPlacement == ScrollbarButtonsDoubleStart; + return false; + } + case CSSSelector::PseudoCornerPresent: + return scrollbar->client()->scrollbarCornerPresent(); + default: + return false; + } +} + +void CSSStyleSelector::addVariables(CSSVariablesRule* variables) +{ + CSSVariablesDeclaration* decl = variables->variables(); + if (!decl) + return; + unsigned size = decl->length(); + for (unsigned i = 0; i < size; ++i) { + String name = decl->item(i); + m_variablesMap.set(name, variables); + } +} + +CSSValue* CSSStyleSelector::resolveVariableDependentValue(CSSVariableDependentValue*) +{ + return 0; +} + +// ----------------------------------------------------------------- + +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) + 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->selectorList().first(); s; s = CSSSelectorList::next(s)) + 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->selectorList().first(); s; s = CSSSelectorList::next(s)) + addRule(rule, s); + } else if (childItem->isFontFaceRule() && styleSelector) { + // Add this font face to our set. + const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(childItem); + styleSelector->fontSelector()->addFontFaceRule(fontFaceRule); + } else if (childItem->isKeyframesRule() && styleSelector) { + // Add this keyframe rule to our set. + styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(childItem)); + } + } // 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); + } else if (item->isVariablesRule()) { + // Evaluate the media query and make sure it matches. + CSSVariablesRule* variables = static_cast<CSSVariablesRule*>(item); + if (!variables->media() || medium.eval(variables->media(), styleSelector)) + styleSelector->addVariables(variables); + } else if (item->isKeyframesRule()) + styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(item)); + } +} + +// ------------------------------------------------------------------------------------- +// 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]; + CSSMutableStyleDeclaration::const_iterator end = decl->end(); + for (CSSMutableStyleDeclaration::const_iterator it = decl->begin(); 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 CSSPropertyLineHeight: + m_lineHeightValue = current.value(); + first = !applyFirst; // we apply line-height later + break; + case CSSPropertyColor: + case CSSPropertyDirection: + case CSSPropertyDisplay: + case CSSPropertyFont: + case CSSPropertyFontSize: + case CSSPropertyFontStyle: + case CSSPropertyFontFamily: + case CSSPropertyFontWeight: + case CSSPropertyWebkitTextSizeAdjust: + case CSSPropertyFontVariant: + case CSSPropertyZoom: + // 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->itemWithoutBoundsCheck(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::applyPropertyToStyle(int id, CSSValue *value, RenderStyle* style) +{ + initElementAndPseudoState(0); + initForStyleResolve(0, style); + m_style = style; + applyProperty(id, value); +} + +void CSSStyleSelector::applyProperty(int id, CSSValue *value) +{ + CSSPrimitiveValue* primitiveValue = 0; + if (value->isPrimitiveValue()) + primitiveValue = static_cast<CSSPrimitiveValue*>(value); + + float zoomFactor = m_style->effectiveZoom(); + + 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 == CSSPropertyWebkitMarginStart) + id = m_style->direction() == LTR ? CSSPropertyMarginLeft : CSSPropertyMarginRight; + else if (id == CSSPropertyWebkitPaddingStart) + id = m_style->direction() == LTR ? CSSPropertyPaddingLeft : CSSPropertyPaddingRight; + + // 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 CSSPropertyBackgroundAttachment: + HANDLE_BACKGROUND_VALUE(attachment, Attachment, value) + return; + case CSSPropertyWebkitBackgroundClip: + HANDLE_BACKGROUND_VALUE(clip, Clip, value) + return; + case CSSPropertyWebkitBackgroundComposite: + HANDLE_BACKGROUND_VALUE(composite, Composite, value) + return; + case CSSPropertyWebkitBackgroundOrigin: + HANDLE_BACKGROUND_VALUE(origin, Origin, value) + return; + case CSSPropertyBackgroundRepeat: + HANDLE_BACKGROUND_VALUE(repeat, Repeat, value) + return; + case CSSPropertyWebkitBackgroundSize: + HANDLE_BACKGROUND_VALUE(size, Size, value) + return; + case CSSPropertyWebkitMaskAttachment: + HANDLE_MASK_VALUE(attachment, Attachment, value) + return; + case CSSPropertyWebkitMaskClip: + HANDLE_MASK_VALUE(clip, Clip, value) + return; + case CSSPropertyWebkitMaskComposite: + HANDLE_MASK_VALUE(composite, Composite, value) + return; + case CSSPropertyWebkitMaskOrigin: + HANDLE_MASK_VALUE(origin, Origin, value) + return; + case CSSPropertyWebkitMaskRepeat: + HANDLE_MASK_VALUE(repeat, Repeat, value) + return; + case CSSPropertyWebkitMaskSize: + HANDLE_MASK_VALUE(size, Size, value) + return; + case CSSPropertyBorderCollapse: + HANDLE_INHERIT_AND_INITIAL(borderCollapse, BorderCollapse) + if (!primitiveValue) + return; + switch (primitiveValue->getIdent()) { + case CSSValueCollapse: + m_style->setBorderCollapse(true); + break; + case CSSValueSeparate: + m_style->setBorderCollapse(false); + break; + default: + return; + } + return; + + case CSSPropertyBorderTopStyle: + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderTopStyle, BorderTopStyle, BorderStyle) + if (primitiveValue) + m_style->setBorderTopStyle(*primitiveValue); + return; + case CSSPropertyBorderRightStyle: + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderRightStyle, BorderRightStyle, BorderStyle) + if (primitiveValue) + m_style->setBorderRightStyle(*primitiveValue); + return; + case CSSPropertyBorderBottomStyle: + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderBottomStyle, BorderBottomStyle, BorderStyle) + if (primitiveValue) + m_style->setBorderBottomStyle(*primitiveValue); + return; + case CSSPropertyBorderLeftStyle: + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderLeftStyle, BorderLeftStyle, BorderStyle) + if (primitiveValue) + m_style->setBorderLeftStyle(*primitiveValue); + return; + case CSSPropertyOutlineStyle: + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(outlineStyle, OutlineStyle, BorderStyle) + if (primitiveValue) { + if (primitiveValue->getIdent() == CSSValueAuto) + m_style->setOutlineStyle(DOTTED, true); + else + m_style->setOutlineStyle(*primitiveValue); + } + return; + case CSSPropertyCaptionSide: + { + HANDLE_INHERIT_AND_INITIAL(captionSide, CaptionSide) + if (primitiveValue) + m_style->setCaptionSide(*primitiveValue); + return; + } + case CSSPropertyClear: + { + HANDLE_INHERIT_AND_INITIAL(clear, Clear) + if (primitiveValue) + m_style->setClear(*primitiveValue); + return; + } + case CSSPropertyDirection: + { + HANDLE_INHERIT_AND_INITIAL(direction, Direction) + if (primitiveValue) + m_style->setDirection(*primitiveValue); + return; + } + case CSSPropertyDisplay: + { + HANDLE_INHERIT_AND_INITIAL(display, Display) + if (primitiveValue) + m_style->setDisplay(*primitiveValue); + return; + } + + case CSSPropertyEmptyCells: + { + HANDLE_INHERIT_AND_INITIAL(emptyCells, EmptyCells) + if (primitiveValue) + m_style->setEmptyCells(*primitiveValue); + return; + } + case CSSPropertyFloat: + { + HANDLE_INHERIT_AND_INITIAL(floating, Floating) + if (primitiveValue) + m_style->setFloating(*primitiveValue); + return; + } + + case CSSPropertyFontStyle: + { + 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 CSSValueOblique: + // FIXME: oblique is the same as italic for the moment... + case CSSValueItalic: + fontDescription.setItalic(true); + break; + case CSSValueNormal: + fontDescription.setItalic(false); + break; + default: + return; + } + } + if (m_style->setFontDescription(fontDescription)) + m_fontDirty = true; + return; + } + + case CSSPropertyFontVariant: + { + 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 == CSSValueNormal) + fontDescription.setSmallCaps(false); + else if (id == CSSValueSmallCaps) + fontDescription.setSmallCaps(true); + else + return; + } + if (m_style->setFontDescription(fontDescription)) + m_fontDirty = true; + return; + } + + case CSSPropertyFontWeight: + { + FontDescription fontDescription = m_style->fontDescription(); + if (isInherit) + fontDescription.setWeight(m_parentStyle->fontDescription().weight()); + else if (isInitial) + fontDescription.setWeight(FontWeightNormal); + else { + if (!primitiveValue) + return; + if (primitiveValue->getIdent()) { + switch (primitiveValue->getIdent()) { + case CSSValueBolder: + fontDescription.setWeight(fontDescription.bolderWeight()); + break; + case CSSValueLighter: + fontDescription.setWeight(fontDescription.lighterWeight()); + break; + case CSSValueBold: + case CSSValue700: + fontDescription.setWeight(FontWeightBold); + break; + case CSSValueNormal: + case CSSValue400: + fontDescription.setWeight(FontWeightNormal); + break; + case CSSValue900: + fontDescription.setWeight(FontWeight900); + break; + case CSSValue800: + fontDescription.setWeight(FontWeight800); + break; + case CSSValue600: + fontDescription.setWeight(FontWeight600); + break; + case CSSValue500: + fontDescription.setWeight(FontWeight500); + break; + case CSSValue300: + fontDescription.setWeight(FontWeight300); + break; + case CSSValue200: + fontDescription.setWeight(FontWeight200); + break; + case CSSValue100: + fontDescription.setWeight(FontWeight100); + break; + default: + return; + } + } else + ASSERT_NOT_REACHED(); + } + if (m_style->setFontDescription(fontDescription)) + m_fontDirty = true; + return; + } + + case CSSPropertyListStylePosition: + { + HANDLE_INHERIT_AND_INITIAL(listStylePosition, ListStylePosition) + if (primitiveValue) + m_style->setListStylePosition(*primitiveValue); + return; + } + + case CSSPropertyListStyleType: + { + HANDLE_INHERIT_AND_INITIAL(listStyleType, ListStyleType) + if (primitiveValue) + m_style->setListStyleType(*primitiveValue); + return; + } + + case CSSPropertyOverflow: + { + 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 CSSPropertyOverflowX: + { + HANDLE_INHERIT_AND_INITIAL(overflowX, OverflowX) + m_style->setOverflowX(*primitiveValue); + return; + } + + case CSSPropertyOverflowY: + { + HANDLE_INHERIT_AND_INITIAL(overflowY, OverflowY) + m_style->setOverflowY(*primitiveValue); + return; + } + + case CSSPropertyPageBreakBefore: + { + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakBefore, PageBreakBefore, PageBreak) + if (primitiveValue) + m_style->setPageBreakBefore(*primitiveValue); + return; + } + + case CSSPropertyPageBreakAfter: + { + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakAfter, PageBreakAfter, PageBreak) + if (primitiveValue) + m_style->setPageBreakAfter(*primitiveValue); + return; + } + + case CSSPropertyPageBreakInside: { + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakInside, PageBreakInside, PageBreak) + if (!primitiveValue) + return; + EPageBreak pageBreak = *primitiveValue; + if (pageBreak != PBALWAYS) + m_style->setPageBreakInside(pageBreak); + return; + } + + case CSSPropertyPosition: + { + HANDLE_INHERIT_AND_INITIAL(position, Position) + if (primitiveValue) + m_style->setPosition(*primitiveValue); + return; + } + + case CSSPropertyTableLayout: { + HANDLE_INHERIT_AND_INITIAL(tableLayout, TableLayout) + + ETableLayout l = *primitiveValue; + if (l == TAUTO) + l = RenderStyle::initialTableLayout(); + + m_style->setTableLayout(l); + return; + } + + case CSSPropertyUnicodeBidi: { + HANDLE_INHERIT_AND_INITIAL(unicodeBidi, UnicodeBidi) + m_style->setUnicodeBidi(*primitiveValue); + return; + } + case CSSPropertyTextTransform: { + HANDLE_INHERIT_AND_INITIAL(textTransform, TextTransform) + m_style->setTextTransform(*primitiveValue); + return; + } + + case CSSPropertyVisibility: + { + HANDLE_INHERIT_AND_INITIAL(visibility, Visibility) + m_style->setVisibility(*primitiveValue); + return; + } + case CSSPropertyWhiteSpace: + HANDLE_INHERIT_AND_INITIAL(whiteSpace, WhiteSpace) + m_style->setWhiteSpace(*primitiveValue); + return; + + case CSSPropertyBackgroundPosition: + HANDLE_BACKGROUND_INHERIT_AND_INITIAL(xPosition, XPosition); + HANDLE_BACKGROUND_INHERIT_AND_INITIAL(yPosition, YPosition); + return; + case CSSPropertyBackgroundPositionX: { + HANDLE_BACKGROUND_VALUE(xPosition, XPosition, value) + return; + } + case CSSPropertyBackgroundPositionY: { + HANDLE_BACKGROUND_VALUE(yPosition, YPosition, value) + return; + } + case CSSPropertyWebkitMaskPosition: + HANDLE_MASK_INHERIT_AND_INITIAL(xPosition, XPosition); + HANDLE_MASK_INHERIT_AND_INITIAL(yPosition, YPosition); + return; + case CSSPropertyWebkitMaskPositionX: { + HANDLE_MASK_VALUE(xPosition, XPosition, value) + return; + } + case CSSPropertyWebkitMaskPositionY: { + HANDLE_MASK_VALUE(yPosition, YPosition, value) + return; + } + case CSSPropertyBorderSpacing: { + 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 CSSPropertyWebkitBorderHorizontalSpacing: { + HANDLE_INHERIT_AND_INITIAL(horizontalBorderSpacing, HorizontalBorderSpacing) + if (!primitiveValue) + return; + short spacing = primitiveValue->computeLengthShort(style(), zoomFactor); + m_style->setHorizontalBorderSpacing(spacing); + return; + } + case CSSPropertyWebkitBorderVerticalSpacing: { + HANDLE_INHERIT_AND_INITIAL(verticalBorderSpacing, VerticalBorderSpacing) + if (!primitiveValue) + return; + short spacing = primitiveValue->computeLengthShort(style(), zoomFactor); + m_style->setVerticalBorderSpacing(spacing); + return; + } + case CSSPropertyCursor: + 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->itemWithoutBoundsCheck(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(); + // FIXME: Temporary clumsiness to pass off a CachedImage to an API that will eventually convert to using + // StyleImage. + RefPtr<StyleCachedImage> styleCachedImage(image->cachedImage(m_element->document()->docLoader())); + if (styleCachedImage) + m_style->addCursor(styleCachedImage->cachedImage(), 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 CSSPropertyColor: + // If the 'currentColor' keyword is set on the 'color' property itself, + // it is treated as 'color:inherit' at parse time + if (primitiveValue && primitiveValue->getIdent() == CSSValueCurrentcolor) + isInherit = true; + case CSSPropertyBackgroundColor: + case CSSPropertyBorderTopColor: + case CSSPropertyBorderRightColor: + case CSSPropertyBorderBottomColor: + case CSSPropertyBorderLeftColor: + case CSSPropertyOutlineColor: + case CSSPropertyWebkitColumnRuleColor: + case CSSPropertyWebkitTextStrokeColor: + case CSSPropertyWebkitTextFillColor: { + Color col; + if (isInherit) { + HANDLE_INHERIT_COND(CSSPropertyBackgroundColor, backgroundColor, BackgroundColor) + HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyBorderTopColor, borderTopColor, color, BorderTopColor) + HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyBorderBottomColor, borderBottomColor, color, BorderBottomColor) + HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyBorderRightColor, borderRightColor, color, BorderRightColor) + HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyBorderLeftColor, borderLeftColor, color, BorderLeftColor) + HANDLE_INHERIT_COND(CSSPropertyColor, color, Color) + HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyOutlineColor, outlineColor, color, OutlineColor) + HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyWebkitColumnRuleColor, columnRuleColor, color, ColumnRuleColor) + HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyWebkitTextStrokeColor, textStrokeColor, color, TextStrokeColor) + HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyWebkitTextFillColor, textFillColor, color, 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 == CSSPropertyColor) + col = RenderStyle::initialColor(); + } else { + if (!primitiveValue) + return; + col = getColorFromPrimitiveValue(primitiveValue); + } + + switch (id) { + case CSSPropertyBackgroundColor: + m_style->setBackgroundColor(col); + break; + case CSSPropertyBorderTopColor: + m_style->setBorderTopColor(col); + break; + case CSSPropertyBorderRightColor: + m_style->setBorderRightColor(col); + break; + case CSSPropertyBorderBottomColor: + m_style->setBorderBottomColor(col); + break; + case CSSPropertyBorderLeftColor: + m_style->setBorderLeftColor(col); + break; + case CSSPropertyColor: + m_style->setColor(col); + break; + case CSSPropertyOutlineColor: + m_style->setOutlineColor(col); + break; + case CSSPropertyWebkitColumnRuleColor: + m_style->setColumnRuleColor(col); + break; + case CSSPropertyWebkitTextStrokeColor: + m_style->setTextStrokeColor(col); + break; + case CSSPropertyWebkitTextFillColor: + m_style->setTextFillColor(col); + break; + } + + return; + } + +// uri || inherit + case CSSPropertyBackgroundImage: + HANDLE_BACKGROUND_VALUE(image, Image, value) + return; + case CSSPropertyWebkitMaskImage: + HANDLE_MASK_VALUE(image, Image, value) + return; + case CSSPropertyListStyleImage: + { + HANDLE_INHERIT_AND_INITIAL(listStyleImage, ListStyleImage) + m_style->setListStyleImage(styleImage(value)); + return; + } + +// length + case CSSPropertyBorderTopWidth: + case CSSPropertyBorderRightWidth: + case CSSPropertyBorderBottomWidth: + case CSSPropertyBorderLeftWidth: + case CSSPropertyOutlineWidth: + case CSSPropertyWebkitColumnRuleWidth: + { + if (isInherit) { + HANDLE_INHERIT_COND(CSSPropertyBorderTopWidth, borderTopWidth, BorderTopWidth) + HANDLE_INHERIT_COND(CSSPropertyBorderRightWidth, borderRightWidth, BorderRightWidth) + HANDLE_INHERIT_COND(CSSPropertyBorderBottomWidth, borderBottomWidth, BorderBottomWidth) + HANDLE_INHERIT_COND(CSSPropertyBorderLeftWidth, borderLeftWidth, BorderLeftWidth) + HANDLE_INHERIT_COND(CSSPropertyOutlineWidth, outlineWidth, OutlineWidth) + HANDLE_INHERIT_COND(CSSPropertyWebkitColumnRuleWidth, columnRuleWidth, ColumnRuleWidth) + return; + } + else if (isInitial) { + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyBorderTopWidth, BorderTopWidth, BorderWidth) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyBorderRightWidth, BorderRightWidth, BorderWidth) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyBorderBottomWidth, BorderBottomWidth, BorderWidth) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyBorderLeftWidth, BorderLeftWidth, BorderWidth) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyOutlineWidth, OutlineWidth, BorderWidth) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyWebkitColumnRuleWidth, ColumnRuleWidth, BorderWidth) + return; + } + + if (!primitiveValue) + return; + short width = 3; + switch (primitiveValue->getIdent()) { + case CSSValueThin: + width = 1; + break; + case CSSValueMedium: + width = 3; + break; + case CSSValueThick: + width = 5; + break; + case CSSValueInvalid: + width = primitiveValue->computeLengthShort(style(), zoomFactor); + break; + default: + return; + } + + if (width < 0) return; + switch (id) { + case CSSPropertyBorderTopWidth: + m_style->setBorderTopWidth(width); + break; + case CSSPropertyBorderRightWidth: + m_style->setBorderRightWidth(width); + break; + case CSSPropertyBorderBottomWidth: + m_style->setBorderBottomWidth(width); + break; + case CSSPropertyBorderLeftWidth: + m_style->setBorderLeftWidth(width); + break; + case CSSPropertyOutlineWidth: + m_style->setOutlineWidth(width); + break; + case CSSPropertyWebkitColumnRuleWidth: + m_style->setColumnRuleWidth(width); + break; + default: + return; + } + return; + } + + case CSSPropertyLetterSpacing: + case CSSPropertyWordSpacing: + { + + if (isInherit) { + HANDLE_INHERIT_COND(CSSPropertyLetterSpacing, letterSpacing, LetterSpacing) + HANDLE_INHERIT_COND(CSSPropertyWordSpacing, wordSpacing, WordSpacing) + return; + } + else if (isInitial) { + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyLetterSpacing, LetterSpacing, LetterWordSpacing) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyWordSpacing, WordSpacing, LetterWordSpacing) + return; + } + + int width = 0; + if (primitiveValue && primitiveValue->getIdent() == CSSValueNormal){ + width = 0; + } else { + if (!primitiveValue) + return; + width = primitiveValue->computeLengthInt(style(), zoomFactor); + } + switch (id) { + case CSSPropertyLetterSpacing: + m_style->setLetterSpacing(width); + break; + case CSSPropertyWordSpacing: + m_style->setWordSpacing(width); + break; + // ### needs the definitions in renderstyle + default: break; + } + return; + } + + case CSSPropertyWordBreak: { + HANDLE_INHERIT_AND_INITIAL(wordBreak, WordBreak) + m_style->setWordBreak(*primitiveValue); + return; + } + + case CSSPropertyWordWrap: { + HANDLE_INHERIT_AND_INITIAL(wordWrap, WordWrap) + m_style->setWordWrap(*primitiveValue); + return; + } + + case CSSPropertyWebkitNbspMode: + { + HANDLE_INHERIT_AND_INITIAL(nbspMode, NBSPMode) + m_style->setNBSPMode(*primitiveValue); + return; + } + + case CSSPropertyWebkitLineBreak: + { + HANDLE_INHERIT_AND_INITIAL(khtmlLineBreak, KHTMLLineBreak) + m_style->setKHTMLLineBreak(*primitiveValue); + return; + } + + case CSSPropertyWebkitMatchNearestMailBlockquoteColor: + { + HANDLE_INHERIT_AND_INITIAL(matchNearestMailBlockquoteColor, MatchNearestMailBlockquoteColor) + m_style->setMatchNearestMailBlockquoteColor(*primitiveValue); + return; + } + + case CSSPropertyResize: + { + HANDLE_INHERIT_AND_INITIAL(resize, Resize) + + if (!primitiveValue->getIdent()) + return; + + EResize r = RESIZE_NONE; + if (primitiveValue->getIdent() == CSSValueAuto) { + if (Settings* settings = m_checker.m_document->settings()) + r = settings->textAreasAreResizable() ? RESIZE_BOTH : RESIZE_NONE; + } else + r = *primitiveValue; + + m_style->setResize(r); + return; + } + + // length, percent + case CSSPropertyMaxWidth: + // +none +inherit + if (primitiveValue && primitiveValue->getIdent() == CSSValueNone) + apply = true; + case CSSPropertyTop: + case CSSPropertyLeft: + case CSSPropertyRight: + case CSSPropertyBottom: + case CSSPropertyWidth: + case CSSPropertyMinWidth: + case CSSPropertyMarginTop: + case CSSPropertyMarginRight: + case CSSPropertyMarginBottom: + case CSSPropertyMarginLeft: + // +inherit +auto + if (id == CSSPropertyWidth || id == CSSPropertyMinWidth || id == CSSPropertyMaxWidth) { + if (primitiveValue && primitiveValue->getIdent() == CSSValueIntrinsic) { + l = Length(Intrinsic); + apply = true; + } + else if (primitiveValue && primitiveValue->getIdent() == CSSValueMinIntrinsic) { + l = Length(MinIntrinsic); + apply = true; + } + } + if (id != CSSPropertyMaxWidth && primitiveValue && primitiveValue->getIdent() == CSSValueAuto) + apply = true; + case CSSPropertyPaddingTop: + case CSSPropertyPaddingRight: + case CSSPropertyPaddingBottom: + case CSSPropertyPaddingLeft: + case CSSPropertyTextIndent: + // +inherit + { + if (isInherit) { + HANDLE_INHERIT_COND(CSSPropertyMaxWidth, maxWidth, MaxWidth) + HANDLE_INHERIT_COND(CSSPropertyBottom, bottom, Bottom) + HANDLE_INHERIT_COND(CSSPropertyTop, top, Top) + HANDLE_INHERIT_COND(CSSPropertyLeft, left, Left) + HANDLE_INHERIT_COND(CSSPropertyRight, right, Right) + HANDLE_INHERIT_COND(CSSPropertyWidth, width, Width) + HANDLE_INHERIT_COND(CSSPropertyMinWidth, minWidth, MinWidth) + HANDLE_INHERIT_COND(CSSPropertyPaddingTop, paddingTop, PaddingTop) + HANDLE_INHERIT_COND(CSSPropertyPaddingRight, paddingRight, PaddingRight) + HANDLE_INHERIT_COND(CSSPropertyPaddingBottom, paddingBottom, PaddingBottom) + HANDLE_INHERIT_COND(CSSPropertyPaddingLeft, paddingLeft, PaddingLeft) + HANDLE_INHERIT_COND(CSSPropertyMarginTop, marginTop, MarginTop) + HANDLE_INHERIT_COND(CSSPropertyMarginRight, marginRight, MarginRight) + HANDLE_INHERIT_COND(CSSPropertyMarginBottom, marginBottom, MarginBottom) + HANDLE_INHERIT_COND(CSSPropertyMarginLeft, marginLeft, MarginLeft) + HANDLE_INHERIT_COND(CSSPropertyTextIndent, textIndent, TextIndent) + return; + } + else if (isInitial) { + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMaxWidth, MaxWidth, MaxSize) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyBottom, Bottom, Offset) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyTop, Top, Offset) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyLeft, Left, Offset) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyRight, Right, Offset) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyWidth, Width, Size) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMinWidth, MinWidth, MinSize) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyPaddingTop, PaddingTop, Padding) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyPaddingRight, PaddingRight, Padding) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyPaddingBottom, PaddingBottom, Padding) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyPaddingLeft, PaddingLeft, Padding) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMarginTop, MarginTop, Margin) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMarginRight, MarginRight, Margin) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMarginBottom, MarginBottom, Margin) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMarginLeft, MarginLeft, Margin) + HANDLE_INITIAL_COND(CSSPropertyTextIndent, 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(style(), zoomFactor), Fixed, + primitiveValue->isQuirkValue()); + else if (type == CSSPrimitiveValue::CSS_PERCENTAGE) + l = Length(primitiveValue->getDoubleValue(), Percent); + else + return; + if (id == CSSPropertyPaddingLeft || id == CSSPropertyPaddingRight || + id == CSSPropertyPaddingTop || id == CSSPropertyPaddingBottom) + // Padding can't be negative + apply = !((l.isFixed() || l.isPercent()) && l.calcValue(100) < 0); + else + apply = true; + } + if (!apply) return; + switch (id) { + case CSSPropertyMaxWidth: + m_style->setMaxWidth(l); + break; + case CSSPropertyBottom: + m_style->setBottom(l); + break; + case CSSPropertyTop: + m_style->setTop(l); + break; + case CSSPropertyLeft: + m_style->setLeft(l); + break; + case CSSPropertyRight: + m_style->setRight(l); + break; + case CSSPropertyWidth: + m_style->setWidth(l); + break; + case CSSPropertyMinWidth: + m_style->setMinWidth(l); + break; + case CSSPropertyPaddingTop: + m_style->setPaddingTop(l); + break; + case CSSPropertyPaddingRight: + m_style->setPaddingRight(l); + break; + case CSSPropertyPaddingBottom: + m_style->setPaddingBottom(l); + break; + case CSSPropertyPaddingLeft: + m_style->setPaddingLeft(l); + break; + case CSSPropertyMarginTop: + m_style->setMarginTop(l); + break; + case CSSPropertyMarginRight: + m_style->setMarginRight(l); + break; + case CSSPropertyMarginBottom: + m_style->setMarginBottom(l); + break; + case CSSPropertyMarginLeft: + m_style->setMarginLeft(l); + break; + case CSSPropertyTextIndent: + m_style->setTextIndent(l); + break; + default: + break; + } + return; + } + + case CSSPropertyMaxHeight: + if (primitiveValue && primitiveValue->getIdent() == CSSValueNone) { + l = Length(undefinedLength, Fixed); + apply = true; + } + case CSSPropertyHeight: + case CSSPropertyMinHeight: + if (primitiveValue && primitiveValue->getIdent() == CSSValueIntrinsic) { + l = Length(Intrinsic); + apply = true; + } else if (primitiveValue && primitiveValue->getIdent() == CSSValueMinIntrinsic) { + l = Length(MinIntrinsic); + apply = true; + } else if (id != CSSPropertyMaxHeight && primitiveValue && primitiveValue->getIdent() == CSSValueAuto) + apply = true; + if (isInherit) { + HANDLE_INHERIT_COND(CSSPropertyMaxHeight, maxHeight, MaxHeight) + HANDLE_INHERIT_COND(CSSPropertyHeight, height, Height) + HANDLE_INHERIT_COND(CSSPropertyMinHeight, minHeight, MinHeight) + return; + } + if (isInitial) { + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMaxHeight, MaxHeight, MaxSize) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyHeight, Height, Size) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMinHeight, MinHeight, MinSize) + return; + } + + if (primitiveValue && !apply) { + unsigned short type = primitiveValue->primitiveType(); + if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) + l = Length(primitiveValue->computeLengthIntForLength(style(), zoomFactor), Fixed); + else if (type == CSSPrimitiveValue::CSS_PERCENTAGE) + l = Length(primitiveValue->getDoubleValue(), Percent); + else + return; + apply = true; + } + if (apply) + switch (id) { + case CSSPropertyMaxHeight: + m_style->setMaxHeight(l); + break; + case CSSPropertyHeight: + m_style->setHeight(l); + break; + case CSSPropertyMinHeight: + m_style->setMinHeight(l); + break; + } + return; + + case CSSPropertyVerticalAlign: + HANDLE_INHERIT_AND_INITIAL(verticalAlign, VerticalAlign) + if (!primitiveValue) + return; + if (primitiveValue->getIdent()) { + EVerticalAlign align; + + switch (primitiveValue->getIdent()) { + case CSSValueTop: + align = TOP; break; + case CSSValueBottom: + align = BOTTOM; break; + case CSSValueMiddle: + align = MIDDLE; break; + case CSSValueBaseline: + align = BASELINE; break; + case CSSValueTextBottom: + align = TEXT_BOTTOM; break; + case CSSValueTextTop: + align = TEXT_TOP; break; + case CSSValueSub: + align = SUB; break; + case CSSValueSuper: + align = SUPER; break; + case CSSValueWebkitBaselineMiddle: + 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(style(), zoomFactor), Fixed); + else if (type == CSSPrimitiveValue::CSS_PERCENTAGE) + l = Length(primitiveValue->getDoubleValue(), Percent); + + m_style->setVerticalAlign(LENGTH); + m_style->setVerticalAlignLength(l); + } + return; + + case CSSPropertyFontSize: + { + 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(CSSValueMedium, m_style->htmlHacks(), familyIsFixed); + fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1); + } else if (primitiveValue->getIdent()) { + // Keywords are being used. + switch (primitiveValue->getIdent()) { + case CSSValueXxSmall: + case CSSValueXSmall: + case CSSValueSmall: + case CSSValueMedium: + case CSSValueLarge: + case CSSValueXLarge: + case CSSValueXxLarge: + case CSSValueWebkitXxxLarge: + size = fontSizeForKeyword(primitiveValue->getIdent(), m_style->htmlHacks(), familyIsFixed); + fontDescription.setKeywordSize(primitiveValue->getIdent() - CSSValueXxSmall + 1); + break; + case CSSValueLarger: + size = largerFontSize(oldSize, m_style->htmlHacks()); + break; + case CSSValueSmaller: + size = smallerFontSize(oldSize, m_style->htmlHacks()); + break; + default: + return; + } + + fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize && + (primitiveValue->getIdent() == CSSValueLarger || + primitiveValue->getIdent() == CSSValueSmaller)); + } 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, true); + 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 CSSPropertyZIndex: { + if (isInherit) { + if (m_parentStyle->hasAutoZIndex()) + m_style->setHasAutoZIndex(); + else + m_style->setZIndex(m_parentStyle->zIndex()); + return; + } else if (isInitial || primitiveValue->getIdent() == CSSValueAuto) { + 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 CSSPropertyWidows: + { + HANDLE_INHERIT_AND_INITIAL(widows, Widows) + if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER) + return; + m_style->setWidows(primitiveValue->getIntValue()); + return; + } + + case CSSPropertyOrphans: + { + HANDLE_INHERIT_AND_INITIAL(orphans, Orphans) + if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER) + return; + m_style->setOrphans(primitiveValue->getIntValue()); + return; + } + +// length, percent, number + case CSSPropertyLineHeight: + { + HANDLE_INHERIT_AND_INITIAL(lineHeight, LineHeight) + if (!primitiveValue) + return; + Length lineHeight; + int type = primitiveValue->primitiveType(); + if (primitiveValue->getIdent() == CSSValueNormal) + lineHeight = Length(-100.0, Percent); + else if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) { + double multiplier = m_style->effectiveZoom(); + if (m_style->textSizeAdjust() && m_checker.m_document->frame() && m_checker.m_document->frame()->shouldApplyTextZoom()) + multiplier *= m_checker.m_document->frame()->textZoomFactor(); + lineHeight = Length(primitiveValue->computeLengthIntForLength(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 CSSPropertyTextAlign: + { + HANDLE_INHERIT_AND_INITIAL(textAlign, TextAlign) + if (!primitiveValue) + return; + int id = primitiveValue->getIdent(); + if (id == CSSValueStart) + m_style->setTextAlign(m_style->direction() == LTR ? LEFT : RIGHT); + else if (id == CSSValueEnd) + m_style->setTextAlign(m_style->direction() == LTR ? RIGHT : LEFT); + else + m_style->setTextAlign(*primitiveValue); + return; + } + +// rect + case CSSPropertyClip: + { + Length top; + Length right; + Length bottom; + Length left; + bool hasClip = true; + if (isInherit) { + if (m_parentStyle->hasClip()) { + top = m_parentStyle->clipTop(); + right = m_parentStyle->clipRight(); + bottom = m_parentStyle->clipBottom(); + left = m_parentStyle->clipLeft(); + } + else { + hasClip = false; + top = right = bottom = left = Length(); + } + } else if (isInitial) { + hasClip = false; + top = right = bottom = left = Length(); + } else if (!primitiveValue) { + return; + } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RECT) { + Rect* rect = primitiveValue->getRectValue(); + if (!rect) + return; + top = convertToLength(rect->top(), style()); + right = convertToLength(rect->right(), style()); + bottom = convertToLength(rect->bottom(), style()); + left = convertToLength(rect->left(), style()); + + } else if (primitiveValue->getIdent() != CSSValueAuto) { + return; + } + m_style->setClip(top, right, bottom, left); + m_style->setHasClip(hasClip); + + // rect, ident + return; + } + +// lists + case CSSPropertyContent: + // 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->itemWithoutBoundsCheck(i); + if (item->isImageGeneratorValue()) { + m_style->setContent(static_cast<CSSImageGeneratorValue*>(item)->generatedImage(), didSet); + didSet = true; + } + + 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->cachedImage(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 CSSPropertyCounterIncrement: + applyCounterList(style(), value->isValueList() ? static_cast<CSSValueList*>(value) : 0, false); + return; + case CSSPropertyCounterReset: + applyCounterList(style(), value->isValueList() ? static_cast<CSSValueList*>(value) : 0, true); + return; + + case CSSPropertyFontFamily: { + // 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(CSSValueXxSmall + fontDescription.keywordSize() - 1, m_style->htmlHacks(), false)); + fontDescription.setGenericFamily(initialDesc.genericFamily()); + if (!initialDesc.firstFamily().familyIsEmpty()) + 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->itemWithoutBoundsCheck(i); + if (!item->isPrimitiveValue()) continue; + CSSPrimitiveValue *val = static_cast<CSSPrimitiveValue*>(item); + AtomicString face; + Settings* settings = m_checker.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 CSSValueWebkitBody: + face = settings->standardFontFamily(); + break; + case CSSValueSerif: + face = "-webkit-serif"; + fontDescription.setGenericFamily(FontDescription::SerifFamily); + break; + case CSSValueSansSerif: + face = "-webkit-sans-serif"; + fontDescription.setGenericFamily(FontDescription::SansSerifFamily); + break; + case CSSValueCursive: + face = "-webkit-cursive"; + fontDescription.setGenericFamily(FontDescription::CursiveFamily); + break; + case CSSValueFantasy: + face = "-webkit-fantasy"; + fontDescription.setGenericFamily(FontDescription::FantasyFamily); + break; + case CSSValueMonospace: + face = "-webkit-monospace"; + fontDescription.setGenericFamily(FontDescription::MonospaceFamily); + break; + } + } + + if (!face.isEmpty()) { + if (!currFamily) { + // Filling in the first family. + firstFamily.setFamily(face); + currFamily = &firstFamily; + } + else { + RefPtr<SharedFontFamily> newFamily = SharedFontFamily::create(); + newFamily->setFamily(face); + currFamily->appendFamily(newFamily); + currFamily = newFamily.get(); + } + + if (fontDescription.keywordSize() && (fontDescription.genericFamily() == FontDescription::MonospaceFamily) != oldFamilyIsMonospace) + setFontSize(fontDescription, fontSizeForKeyword(CSSValueXxSmall + fontDescription.keywordSize() - 1, m_style->htmlHacks(), !oldFamilyIsMonospace)); + + if (m_style->setFontDescription(fontDescription)) + m_fontDirty = true; + } + } + return; + } + case CSSPropertyTextDecoration: { + // list of ident + HANDLE_INHERIT_AND_INITIAL(textDecoration, TextDecoration) + int t = RenderStyle::initialTextDecoration(); + if (primitiveValue && primitiveValue->getIdent() == CSSValueNone) { + // 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->itemWithoutBoundsCheck(i); + if (!item->isPrimitiveValue()) continue; + primitiveValue = static_cast<CSSPrimitiveValue*>(item); + switch (primitiveValue->getIdent()) { + case CSSValueNone: + t = TDNONE; break; + case CSSValueUnderline: + t |= UNDERLINE; break; + case CSSValueOverline: + t |= OVERLINE; break; + case CSSValueLineThrough: + t |= LINE_THROUGH; break; + case CSSValueBlink: + t |= BLINK; break; + default: + return; + } + } + } + + m_style->setTextDecoration(t); + return; + } + + case CSSPropertyZoom: + { + // Reset the zoom in effect before we do anything. This allows the setZoom method to accurately compute a new + // zoom in effect. + m_style->setEffectiveZoom(m_parentStyle ? m_parentStyle->effectiveZoom() : RenderStyle::initialZoom()); + + // Now we can handle inherit and initial. + HANDLE_INHERIT_AND_INITIAL(zoom, Zoom) + + // Handle normal/reset, numbers and percentages. + int type = primitiveValue->primitiveType(); + if (primitiveValue->getIdent() == CSSValueNormal) + m_style->setZoom(RenderStyle::initialZoom()); + else if (primitiveValue->getIdent() == CSSValueReset) { + m_style->setEffectiveZoom(RenderStyle::initialZoom()); + m_style->setZoom(RenderStyle::initialZoom()); + } else if (primitiveValue->getIdent() == CSSValueDocument) { + float docZoom = m_checker.m_document->renderer()->style()->zoom(); + m_style->setEffectiveZoom(docZoom); + m_style->setZoom(docZoom); + } else if (type == CSSPrimitiveValue::CSS_PERCENTAGE) { + if (primitiveValue->getFloatValue()) + m_style->setZoom(primitiveValue->getFloatValue() / 100.0f); + } else if (type == CSSPrimitiveValue::CSS_NUMBER) { + if (primitiveValue->getFloatValue()) + m_style->setZoom(primitiveValue->getFloatValue()); + } + + m_fontDirty = true; + return; + } +// shorthand properties + case CSSPropertyBackground: + if (isInitial) { + m_style->clearBackgroundLayers(); + m_style->setBackgroundColor(Color()); + } + else if (isInherit) { + m_style->inheritBackgroundLayers(*m_parentStyle->backgroundLayers()); + m_style->setBackgroundColor(m_parentStyle->backgroundColor()); + } + return; + case CSSPropertyWebkitMask: + if (isInitial) + m_style->clearMaskLayers(); + else if (isInherit) + m_style->inheritMaskLayers(*m_parentStyle->maskLayers()); + return; + + case CSSPropertyBorder: + case CSSPropertyBorderStyle: + case CSSPropertyBorderWidth: + case CSSPropertyBorderColor: + if (id == CSSPropertyBorder || id == CSSPropertyBorderColor) + { + if (isInherit) { + m_style->setBorderTopColor(m_parentStyle->borderTopColor().isValid() ? m_parentStyle->borderTopColor() : m_parentStyle->color()); + m_style->setBorderBottomColor(m_parentStyle->borderBottomColor().isValid() ? m_parentStyle->borderBottomColor() : m_parentStyle->color()); + m_style->setBorderLeftColor(m_parentStyle->borderLeftColor().isValid() ? m_parentStyle->borderLeftColor() : m_parentStyle->color()); + m_style->setBorderRightColor(m_parentStyle->borderRightColor().isValid() ? m_parentStyle->borderRightColor(): m_parentStyle->color()); + } + 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 == CSSPropertyBorder || id == CSSPropertyBorderStyle) + { + 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 == CSSPropertyBorder || id == CSSPropertyBorderWidth) + { + 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 CSSPropertyBorderTop: + if (isInherit) { + m_style->setBorderTopColor(m_parentStyle->borderTopColor().isValid() ? m_parentStyle->borderTopColor() : m_parentStyle->color()); + m_style->setBorderTopStyle(m_parentStyle->borderTopStyle()); + m_style->setBorderTopWidth(m_parentStyle->borderTopWidth()); + } + else if (isInitial) + m_style->resetBorderTop(); + return; + case CSSPropertyBorderRight: + if (isInherit) { + m_style->setBorderRightColor(m_parentStyle->borderRightColor().isValid() ? m_parentStyle->borderRightColor() : m_parentStyle->color()); + m_style->setBorderRightStyle(m_parentStyle->borderRightStyle()); + m_style->setBorderRightWidth(m_parentStyle->borderRightWidth()); + } + else if (isInitial) + m_style->resetBorderRight(); + return; + case CSSPropertyBorderBottom: + if (isInherit) { + m_style->setBorderBottomColor(m_parentStyle->borderBottomColor().isValid() ? m_parentStyle->borderBottomColor() : m_parentStyle->color()); + m_style->setBorderBottomStyle(m_parentStyle->borderBottomStyle()); + m_style->setBorderBottomWidth(m_parentStyle->borderBottomWidth()); + } + else if (isInitial) + m_style->resetBorderBottom(); + return; + case CSSPropertyBorderLeft: + if (isInherit) { + m_style->setBorderLeftColor(m_parentStyle->borderLeftColor().isValid() ? m_parentStyle->borderLeftColor() : m_parentStyle->color()); + m_style->setBorderLeftStyle(m_parentStyle->borderLeftStyle()); + m_style->setBorderLeftWidth(m_parentStyle->borderLeftWidth()); + } + else if (isInitial) + m_style->resetBorderLeft(); + return; + case CSSPropertyMargin: + 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 CSSPropertyPadding: + 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 CSSPropertyFont: + 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_checker.m_document->settings(); + FontDescription fontDescription; + fontDescription.setGenericFamily(FontDescription::StandardFamily); + fontDescription.setRenderingMode(settings->fontRenderingMode()); + fontDescription.setUsePrinterFont(m_checker.m_document->printing()); + const AtomicString& standardFontFamily = m_checker.m_document->settings()->standardFontFamily(); + if (!standardFontFamily.isEmpty()) { + fontDescription.firstFamily().setFamily(standardFontFamily); + fontDescription.firstFamily().appendFamily(0); + } + fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1); + setFontSize(fontDescription, fontSizeForKeyword(CSSValueMedium, 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()) { + // Make sure the rendering mode and printer font settings are updated. + Settings* settings = m_checker.m_document->settings(); + fontDescription.setRenderingMode(settings->fontRenderingMode()); + fontDescription.setUsePrinterFont(m_checker.m_document->printing()); + + // 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(CSSPropertyFontStyle, font->style.get()); + applyProperty(CSSPropertyFontVariant, font->variant.get()); + applyProperty(CSSPropertyFontWeight, font->weight.get()); + applyProperty(CSSPropertyFontSize, font->size.get()); + + m_lineHeightValue = font->lineHeight.get(); + + applyProperty(CSSPropertyFontFamily, font->family.get()); + } + return; + + case CSSPropertyListStyle: + 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 CSSPropertyOutline: + if (isInherit) { + m_style->setOutlineWidth(m_parentStyle->outlineWidth()); + m_style->setOutlineColor(m_parentStyle->outlineColor().isValid() ? m_parentStyle->outlineColor() : m_parentStyle->color()); + m_style->setOutlineStyle(m_parentStyle->outlineStyle()); + } + else if (isInitial) + m_style->resetOutline(); + return; + + // CSS3 Properties + case CSSPropertyWebkitAppearance: { + HANDLE_INHERIT_AND_INITIAL(appearance, Appearance) + if (!primitiveValue) + return; + m_style->setAppearance(*primitiveValue); + return; + } + case CSSPropertyWebkitBinding: { +#if ENABLE(XBL) + if (isInitial || (primitiveValue && primitiveValue->getIdent() == CSSValueNone)) { + 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->itemWithoutBoundsCheck(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 CSSPropertyWebkitBorderImage: + case CSSPropertyWebkitMaskBoxImage: { + if (isInherit) { + HANDLE_INHERIT_COND(CSSPropertyWebkitBorderImage, borderImage, BorderImage) + HANDLE_INHERIT_COND(CSSPropertyWebkitMaskBoxImage, maskBoxImage, MaskBoxImage) + return; + } else if (isInitial) { + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyWebkitBorderImage, BorderImage, NinePieceImage) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyWebkitMaskBoxImage, MaskBoxImage, NinePieceImage) + return; + } + + NinePieceImage image; + mapNinePieceImage(value, image); + + if (id == CSSPropertyWebkitBorderImage) + m_style->setBorderImage(image); + else + m_style->setMaskBoxImage(image); + return; + } + + case CSSPropertyWebkitBorderRadius: + 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 CSSPropertyWebkitBorderTopLeftRadius: + case CSSPropertyWebkitBorderTopRightRadius: + case CSSPropertyWebkitBorderBottomLeftRadius: + case CSSPropertyWebkitBorderBottomRightRadius: { + if (isInherit) { + HANDLE_INHERIT_COND(CSSPropertyWebkitBorderTopLeftRadius, borderTopLeftRadius, BorderTopLeftRadius) + HANDLE_INHERIT_COND(CSSPropertyWebkitBorderTopRightRadius, borderTopRightRadius, BorderTopRightRadius) + HANDLE_INHERIT_COND(CSSPropertyWebkitBorderBottomLeftRadius, borderBottomLeftRadius, BorderBottomLeftRadius) + HANDLE_INHERIT_COND(CSSPropertyWebkitBorderBottomRightRadius, borderBottomRightRadius, BorderBottomRightRadius) + return; + } + + if (isInitial) { + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyWebkitBorderTopLeftRadius, BorderTopLeftRadius, BorderRadius) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyWebkitBorderTopRightRadius, BorderTopRightRadius, BorderRadius) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyWebkitBorderBottomLeftRadius, BorderBottomLeftRadius, BorderRadius) + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyWebkitBorderBottomRightRadius, BorderBottomRightRadius, BorderRadius) + return; + } + + if (!primitiveValue) + return; + + Pair* pair = primitiveValue->getPairValue(); + if (!pair) + return; + + int width = pair->first()->computeLengthInt(style(), zoomFactor); + int height = pair->second()->computeLengthInt(style(), zoomFactor); + 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 CSSPropertyWebkitBorderTopLeftRadius: + m_style->setBorderTopLeftRadius(size); + break; + case CSSPropertyWebkitBorderTopRightRadius: + m_style->setBorderTopRightRadius(size); + break; + case CSSPropertyWebkitBorderBottomLeftRadius: + m_style->setBorderBottomLeftRadius(size); + break; + case CSSPropertyWebkitBorderBottomRightRadius: + m_style->setBorderBottomRightRadius(size); + break; + default: + m_style->setBorderRadius(size); + break; + } + return; + } + + case CSSPropertyOutlineOffset: + HANDLE_INHERIT_AND_INITIAL(outlineOffset, OutlineOffset) + m_style->setOutlineOffset(primitiveValue->computeLengthInt(style(), zoomFactor)); + return; + + case CSSPropertyTextShadow: + case CSSPropertyWebkitBoxShadow: { + if (isInherit) { + if (id == CSSPropertyTextShadow) + 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 == CSSPropertyTextShadow ? 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->itemWithoutBoundsCheck(i)); + int x = item->x->computeLengthInt(style(), zoomFactor); + int y = item->y->computeLengthInt(style(), zoomFactor); + int blur = item->blur ? item->blur->computeLengthInt(style(), zoomFactor) : 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 == CSSPropertyTextShadow) + m_style->setTextShadow(shadowData, i != 0); + else + m_style->setBoxShadow(shadowData, i != 0); + } + return; + } + case CSSPropertyWebkitBoxReflect: { + HANDLE_INHERIT_AND_INITIAL(boxReflect, BoxReflect) + if (primitiveValue) { + m_style->setBoxReflect(RenderStyle::initialBoxReflect()); + return; + } + CSSReflectValue* reflectValue = static_cast<CSSReflectValue*>(value); + RefPtr<StyleReflection> reflection = StyleReflection::create(); + reflection->setDirection(reflectValue->direction()); + if (reflectValue->offset()) { + int type = reflectValue->offset()->primitiveType(); + if (type == CSSPrimitiveValue::CSS_PERCENTAGE) + reflection->setOffset(Length(reflectValue->offset()->getDoubleValue(), Percent)); + else + reflection->setOffset(Length(reflectValue->offset()->computeLengthIntForLength(style(), zoomFactor), Fixed)); + } + NinePieceImage mask; + mapNinePieceImage(reflectValue->mask(), mask); + reflection->setMask(mask); + + m_style->setBoxReflect(reflection.release()); + return; + } + case CSSPropertyOpacity: + 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 CSSPropertyWebkitBoxAlign: + { + HANDLE_INHERIT_AND_INITIAL(boxAlign, BoxAlign) + if (!primitiveValue) + return; + EBoxAlignment boxAlignment = *primitiveValue; + if (boxAlignment != BJUSTIFY) + m_style->setBoxAlign(boxAlignment); + return; + } + case CSSPropertySrc: // Only used in @font-face rules. + return; + case CSSPropertyUnicodeRange: // Only used in @font-face rules. + return; + case CSSPropertyWebkitBoxDirection: + HANDLE_INHERIT_AND_INITIAL(boxDirection, BoxDirection) + if (primitiveValue) + m_style->setBoxDirection(*primitiveValue); + return; + case CSSPropertyWebkitBoxLines: + HANDLE_INHERIT_AND_INITIAL(boxLines, BoxLines) + if (primitiveValue) + m_style->setBoxLines(*primitiveValue); + return; + case CSSPropertyWebkitBoxOrient: + HANDLE_INHERIT_AND_INITIAL(boxOrient, BoxOrient) + if (primitiveValue) + m_style->setBoxOrient(*primitiveValue); + return; + case CSSPropertyWebkitBoxPack: + { + HANDLE_INHERIT_AND_INITIAL(boxPack, BoxPack) + if (!primitiveValue) + return; + EBoxAlignment boxPack = *primitiveValue; + if (boxPack != BSTRETCH && boxPack != BBASELINE) + m_style->setBoxPack(boxPack); + return; + } + case CSSPropertyWebkitBoxFlex: + HANDLE_INHERIT_AND_INITIAL(boxFlex, BoxFlex) + if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER) + return; // Error case. + m_style->setBoxFlex(primitiveValue->getFloatValue()); + return; + case CSSPropertyWebkitBoxFlexGroup: + 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 CSSPropertyWebkitBoxOrdinalGroup: + 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 CSSPropertyWebkitBoxSizing: + HANDLE_INHERIT_AND_INITIAL(boxSizing, BoxSizing) + if (!primitiveValue) + return; + if (primitiveValue->getIdent() == CSSValueContentBox) + m_style->setBoxSizing(CONTENT_BOX); + else + m_style->setBoxSizing(BORDER_BOX); + return; + case CSSPropertyWebkitColumnCount: { + if (isInherit) { + if (m_parentStyle->hasAutoColumnCount()) + m_style->setHasAutoColumnCount(); + else + m_style->setColumnCount(m_parentStyle->columnCount()); + return; + } else if (isInitial || primitiveValue->getIdent() == CSSValueAuto) { + m_style->setHasAutoColumnCount(); + return; + } + m_style->setColumnCount(static_cast<unsigned short>(primitiveValue->getDoubleValue())); + return; + } + case CSSPropertyWebkitColumnGap: { + if (isInherit) { + if (m_parentStyle->hasNormalColumnGap()) + m_style->setHasNormalColumnGap(); + else + m_style->setColumnGap(m_parentStyle->columnGap()); + return; + } else if (isInitial || primitiveValue->getIdent() == CSSValueNormal) { + m_style->setHasNormalColumnGap(); + return; + } + m_style->setColumnGap(primitiveValue->computeLengthFloat(style(), zoomFactor)); + return; + } + case CSSPropertyWebkitColumnWidth: { + if (isInherit) { + if (m_parentStyle->hasAutoColumnWidth()) + m_style->setHasAutoColumnWidth(); + else + m_style->setColumnWidth(m_parentStyle->columnWidth()); + return; + } else if (isInitial || primitiveValue->getIdent() == CSSValueAuto) { + m_style->setHasAutoColumnWidth(); + return; + } + m_style->setColumnWidth(primitiveValue->computeLengthFloat(style(), zoomFactor)); + return; + } + case CSSPropertyWebkitColumnRuleStyle: + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(columnRuleStyle, ColumnRuleStyle, BorderStyle) + m_style->setColumnRuleStyle(*primitiveValue); + return; + case CSSPropertyWebkitColumnBreakBefore: { + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(columnBreakBefore, ColumnBreakBefore, PageBreak) + m_style->setColumnBreakBefore(*primitiveValue); + return; + } + case CSSPropertyWebkitColumnBreakAfter: { + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(columnBreakAfter, ColumnBreakAfter, PageBreak) + m_style->setColumnBreakAfter(*primitiveValue); + return; + } + case CSSPropertyWebkitColumnBreakInside: { + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(columnBreakInside, ColumnBreakInside, PageBreak) + EPageBreak pb = *primitiveValue; + if (pb != PBALWAYS) + m_style->setColumnBreakInside(pb); + return; + } + case CSSPropertyWebkitColumnRule: + if (isInherit) { + m_style->setColumnRuleColor(m_parentStyle->columnRuleColor().isValid() ? m_parentStyle->columnRuleColor() : m_parentStyle->color()); + m_style->setColumnRuleStyle(m_parentStyle->columnRuleStyle()); + m_style->setColumnRuleWidth(m_parentStyle->columnRuleWidth()); + } + else if (isInitial) + m_style->resetColumnRule(); + return; + case CSSPropertyWebkitColumns: + 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 CSSPropertyWebkitMarquee: + 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 CSSPropertyWebkitMarqueeRepetition: { + HANDLE_INHERIT_AND_INITIAL(marqueeLoopCount, MarqueeLoopCount) + if (!primitiveValue) + return; + if (primitiveValue->getIdent() == CSSValueInfinite) + m_style->setMarqueeLoopCount(-1); // -1 means repeat forever. + else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) + m_style->setMarqueeLoopCount(primitiveValue->getIntValue()); + return; + } + case CSSPropertyWebkitMarqueeSpeed: { + HANDLE_INHERIT_AND_INITIAL(marqueeSpeed, MarqueeSpeed) + if (!primitiveValue) + return; + if (primitiveValue->getIdent()) { + switch (primitiveValue->getIdent()) { + case CSSValueSlow: + m_style->setMarqueeSpeed(500); // 500 msec. + break; + case CSSValueNormal: + m_style->setMarqueeSpeed(85); // 85msec. The WinIE default. + break; + case CSSValueFast: + 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 CSSPropertyWebkitMarqueeIncrement: { + HANDLE_INHERIT_AND_INITIAL(marqueeIncrement, MarqueeIncrement) + if (!primitiveValue) + return; + if (primitiveValue->getIdent()) { + switch (primitiveValue->getIdent()) { + case CSSValueSmall: + m_style->setMarqueeIncrement(Length(1, Fixed)); // 1px. + break; + case CSSValueNormal: + m_style->setMarqueeIncrement(Length(6, Fixed)); // 6px. The WinIE default. + break; + case CSSValueLarge: + m_style->setMarqueeIncrement(Length(36, Fixed)); // 36px. + break; + } + } + else { + bool ok = true; + Length l = convertToLength(primitiveValue, style(), &ok); + if (ok) + m_style->setMarqueeIncrement(l); + } + return; + } + case CSSPropertyWebkitMarqueeStyle: { + HANDLE_INHERIT_AND_INITIAL(marqueeBehavior, MarqueeBehavior) + if (primitiveValue) + m_style->setMarqueeBehavior(*primitiveValue); + return; + } + case CSSPropertyWebkitMarqueeDirection: { + HANDLE_INHERIT_AND_INITIAL(marqueeDirection, MarqueeDirection) + if (primitiveValue) + m_style->setMarqueeDirection(*primitiveValue); + return; + } + case CSSPropertyWebkitUserDrag: { + HANDLE_INHERIT_AND_INITIAL(userDrag, UserDrag) + if (primitiveValue) + m_style->setUserDrag(*primitiveValue); + return; + } + case CSSPropertyWebkitUserModify: { + HANDLE_INHERIT_AND_INITIAL(userModify, UserModify) + if (primitiveValue) + m_style->setUserModify(*primitiveValue); + return; + } + case CSSPropertyWebkitUserSelect: { + HANDLE_INHERIT_AND_INITIAL(userSelect, UserSelect) + if (primitiveValue) + m_style->setUserSelect(*primitiveValue); + return; + } + case CSSPropertyTextOverflow: { + // 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() == CSSValueEllipsis); + return; + } + case CSSPropertyWebkitMarginCollapse: { + 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 CSSPropertyWebkitMarginTopCollapse: { + HANDLE_INHERIT_AND_INITIAL(marginTopCollapse, MarginTopCollapse) + if (primitiveValue) + m_style->setMarginTopCollapse(*primitiveValue); + return; + } + case CSSPropertyWebkitMarginBottomCollapse: { + HANDLE_INHERIT_AND_INITIAL(marginBottomCollapse, MarginBottomCollapse) + if (primitiveValue) + m_style->setMarginBottomCollapse(*primitiveValue); + return; + } + + // Apple-specific changes. Do not merge these properties into KHTML. + case CSSPropertyWebkitLineClamp: { + HANDLE_INHERIT_AND_INITIAL(lineClamp, LineClamp) + if (!primitiveValue) + return; + m_style->setLineClamp(primitiveValue->getIntValue(CSSPrimitiveValue::CSS_PERCENTAGE)); + return; + } + case CSSPropertyWebkitHighlight: { + HANDLE_INHERIT_AND_INITIAL(highlight, Highlight); + if (primitiveValue->getIdent() == CSSValueNone) + m_style->setHighlight(nullAtom); + else + m_style->setHighlight(primitiveValue->getStringValue()); + return; + } + case CSSPropertyWebkitBorderFit: { + HANDLE_INHERIT_AND_INITIAL(borderFit, BorderFit); + if (primitiveValue->getIdent() == CSSValueBorder) + m_style->setBorderFit(BorderFitBorder); + else + m_style->setBorderFit(BorderFitLines); + return; + } + case CSSPropertyWebkitTextSizeAdjust: { + HANDLE_INHERIT_AND_INITIAL(textSizeAdjust, TextSizeAdjust) + if (!primitiveValue || !primitiveValue->getIdent()) return; + m_style->setTextSizeAdjust(primitiveValue->getIdent() == CSSValueAuto); + m_fontDirty = true; + return; + } + case CSSPropertyWebkitTextSecurity: { + HANDLE_INHERIT_AND_INITIAL(textSecurity, TextSecurity) + if (primitiveValue) + m_style->setTextSecurity(*primitiveValue); + return; + } +#if ENABLE(DASHBOARD_SUPPORT) + case CSSPropertyWebkitDashboardRegion: { + HANDLE_INHERIT_AND_INITIAL(dashboardRegions, DashboardRegions) + if (!primitiveValue) + return; + + if (primitiveValue->getIdent() == CSSValueNone) { + m_style->setDashboardRegions(RenderStyle::noneDashboardRegions()); + return; + } + + DashboardRegion *region = primitiveValue->getDashboardRegionValue(); + if (!region) + return; + + DashboardRegion *first = region; + while (region) { + Length top = convertToLength(region->top(), style()); + Length right = convertToLength(region->right(), style()); + Length bottom = convertToLength(region->bottom(), style()); + Length left = convertToLength(region->left(), 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; + } +#endif + case CSSPropertyWebkitRtlOrdering: + HANDLE_INHERIT_AND_INITIAL(visuallyOrdered, VisuallyOrdered) + if (!primitiveValue || !primitiveValue->getIdent()) + return; + m_style->setVisuallyOrdered(primitiveValue->getIdent() == CSSValueVisual); + return; + case CSSPropertyWebkitTextStrokeWidth: { + HANDLE_INHERIT_AND_INITIAL(textStrokeWidth, TextStrokeWidth) + float width = 0; + switch (primitiveValue->getIdent()) { + case CSSValueThin: + case CSSValueMedium: + case CSSValueThick: { + double result = 1.0 / 48; + if (primitiveValue->getIdent() == CSSValueMedium) + result *= 3; + else if (primitiveValue->getIdent() == CSSValueThick) + result *= 5; + width = CSSPrimitiveValue::create(result, CSSPrimitiveValue::CSS_EMS)->computeLengthFloat(style(), zoomFactor); + break; + } + default: + width = primitiveValue->computeLengthFloat(style(), zoomFactor); + break; + } + m_style->setTextStrokeWidth(width); + return; + } + case CSSPropertyWebkitTransform: { + HANDLE_INHERIT_AND_INITIAL(transform, Transform); + TransformOperations operations; + createTransformOperations(value, style(), operations); + m_style->setTransform(operations); + return; + } + case CSSPropertyWebkitTransformOrigin: + HANDLE_INHERIT_AND_INITIAL(transformOriginX, TransformOriginX) + HANDLE_INHERIT_AND_INITIAL(transformOriginY, TransformOriginY) + return; + case CSSPropertyWebkitTransformOriginX: { + 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(style(), zoomFactor), Fixed); + else if (type == CSSPrimitiveValue::CSS_PERCENTAGE) + l = Length(primitiveValue->getDoubleValue(), Percent); + else + return; + m_style->setTransformOriginX(l); + break; + } + case CSSPropertyWebkitTransformOriginY: { + 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(style(), zoomFactor), Fixed); + else if(type == CSSPrimitiveValue::CSS_PERCENTAGE) + l = Length(primitiveValue->getDoubleValue(), Percent); + else + return; + m_style->setTransformOriginY(l); + break; + } + case CSSPropertyWebkitAnimation: + if (isInitial) + m_style->clearAnimations(); + else if (isInherit) + m_style->inheritAnimations(m_parentStyle->animations()); + return; + case CSSPropertyWebkitAnimationDelay: + HANDLE_ANIMATION_VALUE(delay, Delay, value) + return; + case CSSPropertyWebkitAnimationDirection: + HANDLE_ANIMATION_VALUE(direction, Direction, value) + return; + case CSSPropertyWebkitAnimationDuration: + HANDLE_ANIMATION_VALUE(duration, Duration, value) + return; + case CSSPropertyWebkitAnimationIterationCount: + HANDLE_ANIMATION_VALUE(iterationCount, IterationCount, value) + return; + case CSSPropertyWebkitAnimationName: + HANDLE_ANIMATION_VALUE(name, Name, value) + return; + case CSSPropertyWebkitAnimationPlayState: + HANDLE_ANIMATION_VALUE(playState, PlayState, value) + return; + case CSSPropertyWebkitAnimationTimingFunction: + HANDLE_ANIMATION_VALUE(timingFunction, TimingFunction, value) + return; + case CSSPropertyWebkitTransition: + if (isInitial) + m_style->clearTransitions(); + else if (isInherit) + m_style->inheritTransitions(m_parentStyle->transitions()); + return; + case CSSPropertyWebkitTransitionDelay: + HANDLE_TRANSITION_VALUE(delay, Delay, value) + return; + case CSSPropertyWebkitTransitionDuration: + HANDLE_TRANSITION_VALUE(duration, Duration, value) + return; + case CSSPropertyWebkitTransitionProperty: + HANDLE_TRANSITION_VALUE(property, Property, value) + return; + case CSSPropertyWebkitTransitionTimingFunction: + HANDLE_TRANSITION_VALUE(timingFunction, TimingFunction, value) + return; + case CSSPropertyPointerEvents: + { + HANDLE_INHERIT_AND_INITIAL(pointerEvents, PointerEvents) + if (!primitiveValue) + return; + m_style->setPointerEvents(*primitiveValue); + return; + } + case CSSPropertyInvalid: + return; + case CSSPropertyFontStretch: + case CSSPropertyPage: + case CSSPropertyQuotes: + case CSSPropertyScrollbar3dlightColor: + case CSSPropertyScrollbarArrowColor: + case CSSPropertyScrollbarDarkshadowColor: + case CSSPropertyScrollbarFaceColor: + case CSSPropertyScrollbarHighlightColor: + case CSSPropertyScrollbarShadowColor: + case CSSPropertyScrollbarTrackColor: + case CSSPropertySize: + case CSSPropertyTextLineThrough: + case CSSPropertyTextLineThroughColor: + case CSSPropertyTextLineThroughMode: + case CSSPropertyTextLineThroughStyle: + case CSSPropertyTextLineThroughWidth: + case CSSPropertyTextOverline: + case CSSPropertyTextOverlineColor: + case CSSPropertyTextOverlineMode: + case CSSPropertyTextOverlineStyle: + case CSSPropertyTextOverlineWidth: + case CSSPropertyTextUnderline: + case CSSPropertyTextUnderlineColor: + case CSSPropertyTextUnderlineMode: + case CSSPropertyTextUnderlineStyle: + case CSSPropertyTextUnderlineWidth: + case CSSPropertyWebkitFontSizeDelta: + case CSSPropertyWebkitMarginStart: + case CSSPropertyWebkitPaddingStart: + case CSSPropertyWebkitTextDecorationsInEffect: + case CSSPropertyWebkitTextStroke: + return; +#if ENABLE(SVG) + default: + // Try the SVG properties + applySVGProperty(id, value); +#endif + } +} + +void CSSStyleSelector::mapFillAttachment(FillLayer* layer, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setAttachment(FillLayer::initialFillAttachment(layer->type())); + return; + } + + if (!value->isPrimitiveValue()) + return; + + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + switch (primitiveValue->getIdent()) { + case CSSValueFixed: + layer->setAttachment(false); + break; + case CSSValueScroll: + layer->setAttachment(true); + break; + default: + return; + } +} + +void CSSStyleSelector::mapFillClip(FillLayer* layer, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setClip(FillLayer::initialFillClip(layer->type())); + return; + } + + if (!value->isPrimitiveValue()) + return; + + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + layer->setClip(*primitiveValue); +} + +void CSSStyleSelector::mapFillComposite(FillLayer* layer, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setComposite(FillLayer::initialFillComposite(layer->type())); + return; + } + + if (!value->isPrimitiveValue()) + return; + + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + layer->setComposite(*primitiveValue); +} + +void CSSStyleSelector::mapFillOrigin(FillLayer* layer, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setOrigin(FillLayer::initialFillOrigin(layer->type())); + return; + } + + if (!value->isPrimitiveValue()) + return; + + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + layer->setOrigin(*primitiveValue); +} + +StyleImage* CSSStyleSelector::styleImage(CSSValue* value) +{ + if (value->isImageValue()) + return static_cast<CSSImageValue*>(value)->cachedImage(m_element->document()->docLoader()); + if (value->isImageGeneratorValue()) + return static_cast<CSSImageGeneratorValue*>(value)->generatedImage(); + return 0; +} + +void CSSStyleSelector::mapFillImage(FillLayer* layer, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setImage(FillLayer::initialFillImage(layer->type())); + return; + } + + layer->setImage(styleImage(value)); +} + +void CSSStyleSelector::mapFillRepeat(FillLayer* layer, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setRepeat(FillLayer::initialFillRepeat(layer->type())); + return; + } + + if (!value->isPrimitiveValue()) + return; + + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + layer->setRepeat(*primitiveValue); +} + +void CSSStyleSelector::mapFillSize(FillLayer* layer, CSSValue* value) +{ + LengthSize b = FillLayer::initialFillSize(layer->type()); + + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setSize(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(); + + float zoomFactor = m_style->effectiveZoom(); + + if (firstType == CSSPrimitiveValue::CSS_UNKNOWN) + firstLength = Length(Auto); + else if (firstType > CSSPrimitiveValue::CSS_PERCENTAGE && firstType < CSSPrimitiveValue::CSS_DEG) + firstLength = Length(first->computeLengthIntForLength(style(), zoomFactor), 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(style(), zoomFactor), Fixed); + else if (secondType == CSSPrimitiveValue::CSS_PERCENTAGE) + secondLength = Length(second->getDoubleValue(), Percent); + else + return; + + b.setWidth(firstLength); + b.setHeight(secondLength); + layer->setSize(b); +} + +void CSSStyleSelector::mapFillXPosition(FillLayer* layer, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setXPosition(FillLayer::initialFillXPosition(layer->type())); + return; + } + + if (!value->isPrimitiveValue()) + return; + + float zoomFactor = m_style->effectiveZoom(); + + 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(style(), zoomFactor), Fixed); + else if (type == CSSPrimitiveValue::CSS_PERCENTAGE) + l = Length(primitiveValue->getDoubleValue(), Percent); + else + return; + layer->setXPosition(l); +} + +void CSSStyleSelector::mapFillYPosition(FillLayer* layer, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setYPosition(FillLayer::initialFillYPosition(layer->type())); + return; + } + + if (!value->isPrimitiveValue()) + return; + + float zoomFactor = m_style->effectiveZoom(); + + 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(style(), zoomFactor), Fixed); + else if (type == CSSPrimitiveValue::CSS_PERCENTAGE) + l = Length(primitiveValue->getDoubleValue(), Percent); + else + return; + layer->setYPosition(l); +} + +void CSSStyleSelector::mapAnimationDelay(Animation* animation, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + animation->setDelay(Animation::initialAnimationDelay()); + return; + } + + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S) + animation->setDelay(primitiveValue->getFloatValue()); + else + animation->setDelay(primitiveValue->getFloatValue()/1000.0f); +} + +void CSSStyleSelector::mapAnimationDirection(Animation* layer, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setDirection(Animation::initialAnimationDirection()); + return; + } + + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + layer->setDirection(primitiveValue->getIdent() == CSSValueAlternate); +} + +void CSSStyleSelector::mapAnimationDuration(Animation* animation, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + animation->setDuration(Animation::initialAnimationDuration()); + return; + } + + if (!value->isPrimitiveValue()) + return; + + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S) + animation->setDuration(primitiveValue->getFloatValue()); + else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_MS) + animation->setDuration(primitiveValue->getFloatValue()/1000.0f); +} + +void CSSStyleSelector::mapAnimationIterationCount(Animation* animation, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + animation->setIterationCount(Animation::initialAnimationIterationCount()); + return; + } + + if (!value->isPrimitiveValue()) + return; + + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + if (primitiveValue->getIdent() == CSSValueInfinite) + animation->setIterationCount(-1); + else + animation->setIterationCount(int(primitiveValue->getFloatValue())); +} + +void CSSStyleSelector::mapAnimationName(Animation* layer, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setName(Animation::initialAnimationName()); + return; + } + + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + + if (primitiveValue->getIdent() == CSSValueNone) + layer->setIsNoneAnimation(true); + else + layer->setName(primitiveValue->getStringValue()); +} + +void CSSStyleSelector::mapAnimationPlayState(Animation* layer, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setPlayState(Animation::initialAnimationPlayState()); + return; + } + + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + layer->setPlayState((primitiveValue->getIdent() == CSSValuePaused) ? AnimPlayStatePaused : AnimPlayStatePlaying); +} + +void CSSStyleSelector::mapAnimationProperty(Animation* animation, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + animation->setProperty(Animation::initialAnimationProperty()); + return; + } + + if (!value->isPrimitiveValue()) + return; + + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + if (primitiveValue->getIdent() == CSSValueAll) + animation->setProperty(cAnimateAll); + else if (primitiveValue->getIdent() == CSSValueNone) + animation->setProperty(cAnimateNone); + else + animation->setProperty(static_cast<CSSPropertyID>(primitiveValue->getIdent())); +} + +void CSSStyleSelector::mapAnimationTimingFunction(Animation* animation, CSSValue* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + animation->setTimingFunction(Animation::initialAnimationTimingFunction()); + return; + } + + if (value->isPrimitiveValue()) { + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + switch (primitiveValue->getIdent()) { + case CSSValueLinear: + animation->setTimingFunction(TimingFunction(LinearTimingFunction, 0.0, 0.0, 1.0, 1.0)); + break; + case CSSValueEase: + animation->setTimingFunction(TimingFunction()); + break; + case CSSValueEaseIn: + animation->setTimingFunction(TimingFunction(CubicBezierTimingFunction, 0.42, 0.0, 1.0, 1.0)); + break; + case CSSValueEaseOut: + animation->setTimingFunction(TimingFunction(CubicBezierTimingFunction, 0.0, 0.0, 0.58, 1.0)); + break; + case CSSValueEaseInOut: + animation->setTimingFunction(TimingFunction(CubicBezierTimingFunction, 0.42, 0.0, 0.58, 1.0)); + break; + } + return; + } + + if (value->isTimingFunctionValue()) { + CSSTimingFunctionValue* timingFunction = static_cast<CSSTimingFunctionValue*>(value); + animation->setTimingFunction(TimingFunction(CubicBezierTimingFunction, timingFunction->x1(), timingFunction->y1(), timingFunction->x2(), timingFunction->y2())); + } +} + +void CSSStyleSelector::mapNinePieceImage(CSSValue* value, NinePieceImage& image) +{ + // If we're a primitive value, then we are "none" and don't need to alter the empty image at all. + if (!value || value->isPrimitiveValue()) + return; + + // Retrieve the border image value. + CSSBorderImageValue* borderImage = static_cast<CSSBorderImageValue*>(value); + + // Set the image (this kicks off the load). + image.m_image = styleImage(borderImage->imageValue()); + + // 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.m_top = Length(r->top()->getDoubleValue(), Percent); + else + l.m_top = Length(r->top()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed); + if (r->bottom()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE) + l.m_bottom = Length(r->bottom()->getDoubleValue(), Percent); + else + l.m_bottom = Length((int)r->bottom()->getFloatValue(CSSPrimitiveValue::CSS_NUMBER), Fixed); + if (r->left()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE) + l.m_left = Length(r->left()->getDoubleValue(), Percent); + else + l.m_left = Length(r->left()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed); + if (r->right()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE) + l.m_right = Length(r->right()->getDoubleValue(), Percent); + else + l.m_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 CSSValueStretch: + image.m_horizontalRule = StretchImageRule; + break; + case CSSValueRound: + image.m_horizontalRule = RoundImageRule; + break; + default: // CSSValueRepeat + image.m_horizontalRule = RepeatImageRule; + break; + } + + switch (borderImage->m_verticalSizeRule) { + case CSSValueStretch: + image.m_verticalRule = StretchImageRule; + break; + case CSSValueRound: + image.m_verticalRule = RoundImageRule; + break; + default: // CSSValueRepeat + image.m_verticalRule = RepeatImageRule; + break; + } +} + +void CSSStyleSelector::checkForTextSizeAdjust() +{ + if (m_style->textSizeAdjust()) + return; + + FontDescription newFontDescription(m_style->fontDescription()); + newFontDescription.setComputedSize(newFontDescription.specifiedSize()); + m_style->setFontDescription(newFontDescription); +} + +void CSSStyleSelector::checkForZoomChange(RenderStyle* style, RenderStyle* parentStyle) +{ + if (style->effectiveZoom() == parentStyle->effectiveZoom()) + return; + + const FontDescription& childFont = style->fontDescription(); + FontDescription newFontDescription(childFont); + setFontSize(newFontDescription, childFont.specifiedSize()); + 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(CSSValueXxSmall + childFont.keywordSize() - 1, style->htmlHacks(), + childFont.genericFamily() == FontDescription::MonospaceFamily); + } else { + Settings* settings = m_checker.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_checker.m_document->settings(); + if (!settings) + return 1.0f; + + int minSize = settings->minimumFontSize(); + int minLogicalSize = settings->minimumLogicalFontSize(); + + float zoomFactor = m_style->effectiveZoom(); + if (m_checker.m_document->frame() && m_checker.m_document->frame()->shouldApplyTextZoom()) + zoomFactor *= m_checker.m_document->frame()->textZoomFactor(); + + float zoomedSize = specifiedSize * zoomFactor; + + // 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_checker.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 - CSSValueXxSmall); + 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 - CSSValueXxSmall]*mediumSize, minLogicalSize); +} + +float CSSStyleSelector::largerFontSize(float size, bool) 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) 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; +} + +static Color colorForCSSValue(int cssValueId) +{ + struct ColorValue { + int cssValueId; + RGBA32 color; + }; + + static const ColorValue colorValues[] = { + { CSSValueAqua, 0xFF00FFFF }, + { CSSValueBlack, 0xFF000000 }, + { CSSValueBlue, 0xFF0000FF }, + { CSSValueFuchsia, 0xFFFF00FF }, + { CSSValueGray, 0xFF808080 }, + { CSSValueGreen, 0xFF008000 }, + { CSSValueGrey, 0xFF808080 }, + { CSSValueLime, 0xFF00FF00 }, + { CSSValueMaroon, 0xFF800000 }, + { CSSValueNavy, 0xFF000080 }, + { CSSValueOlive, 0xFF808000 }, + { CSSValueOrange, 0xFFFFA500 }, + { CSSValuePurple, 0xFF800080 }, + { CSSValueRed, 0xFFFF0000 }, + { CSSValueSilver, 0xFFC0C0C0 }, + { CSSValueTeal, 0xFF008080 }, + { CSSValueTransparent, 0x00000000 }, + { CSSValueWhite, 0xFFFFFFFF }, + { CSSValueYellow, 0xFFFFFF00 }, + { 0, 0 } + }; + + 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 == CSSValueWebkitText) + col = m_element->document()->textColor(); + else if (ident == CSSValueWebkitLink) { + const Color& linkColor = m_element->document()->linkColor(); + const Color& visitedColor = m_element->document()->visitedLinkColor(); + if (linkColor == visitedColor) + col = linkColor; + else { + if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink) + pseudoState = m_checker.checkPseudoState(m_element); + col = (pseudoState == PseudoLink) ? linkColor : visitedColor; + } + } else if (ident == CSSValueWebkitActivelink) + col = m_element->document()->activeLinkColor(); + else if (ident == CSSValueWebkitFocusRingColor) + col = focusRingColor(); + else if (ident == CSSValueCurrentcolor) + col = m_style->color(); + 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; +} + +void CSSStyleSelector::SelectorChecker::allVisitedStateChanged() +{ + if (m_linksCheckedForVisitedState.isEmpty()) + return; + for (Node* node = m_document; node; node = node->traverseNextNode()) { + if (node->isLink()) + node->setChanged(); + } +} + +void CSSStyleSelector::SelectorChecker::visitedStateChanged(LinkHash visitedHash) +{ + if (!m_linksCheckedForVisitedState.contains(visitedHash)) + return; + for (Node* node = m_document; node; node = node->traverseNextNode()) { + const AtomicString* attr = linkAttribute(node); + if (attr && visitedLinkHash(m_document->baseURL(), *attr) == visitedHash) + node->setChanged(); + } +} + +TransformOperation::OperationType getTransformOperationType(WebKitCSSTransformValue::TransformOperationType type) +{ + switch (type) { + case WebKitCSSTransformValue::ScaleTransformOperation: return TransformOperation::SCALE; + case WebKitCSSTransformValue::ScaleXTransformOperation: return TransformOperation::SCALE_X; + case WebKitCSSTransformValue::ScaleYTransformOperation: return TransformOperation::SCALE_Y; + case WebKitCSSTransformValue::TranslateTransformOperation: return TransformOperation::TRANSLATE; + case WebKitCSSTransformValue::TranslateXTransformOperation: return TransformOperation::TRANSLATE_X; + case WebKitCSSTransformValue::TranslateYTransformOperation: return TransformOperation::TRANSLATE_Y; + case WebKitCSSTransformValue::RotateTransformOperation: return TransformOperation::ROTATE; + case WebKitCSSTransformValue::SkewTransformOperation: return TransformOperation::SKEW; + case WebKitCSSTransformValue::SkewXTransformOperation: return TransformOperation::SKEW_X; + case WebKitCSSTransformValue::SkewYTransformOperation: return TransformOperation::SKEW_Y; + case WebKitCSSTransformValue::MatrixTransformOperation: return TransformOperation::MATRIX; + case WebKitCSSTransformValue::UnknownTransformOperation: return TransformOperation::NONE; + } + return TransformOperation::NONE; +} + +bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, TransformOperations& outOperations) +{ + TransformOperations operations; + if (inValue && !inValue->isPrimitiveValue()) { + CSSValueList* list = static_cast<CSSValueList*>(inValue); + unsigned size = list->length(); + for (unsigned i = 0; i < size; i++) { + WebKitCSSTransformValue* val = static_cast<WebKitCSSTransformValue*>(list->itemWithoutBoundsCheck(i)); + + CSSPrimitiveValue* firstValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(0)); + + switch (val->operationType()) { + case WebKitCSSTransformValue::ScaleTransformOperation: + case WebKitCSSTransformValue::ScaleXTransformOperation: + case WebKitCSSTransformValue::ScaleYTransformOperation: { + double sx = 1.0; + double sy = 1.0; + if (val->operationType() == WebKitCSSTransformValue::ScaleYTransformOperation) + sy = firstValue->getDoubleValue(); + else { + sx = firstValue->getDoubleValue(); + if (val->operationType() != WebKitCSSTransformValue::ScaleXTransformOperation) { + if (val->length() > 1) { + CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1)); + sy = secondValue->getDoubleValue(); + } else + sy = sx; + } + } + operations.operations().append(ScaleTransformOperation::create(sx, sy, getTransformOperationType(val->operationType()))); + break; + } + case WebKitCSSTransformValue::TranslateTransformOperation: + case WebKitCSSTransformValue::TranslateXTransformOperation: + case WebKitCSSTransformValue::TranslateYTransformOperation: { + bool ok = true; + Length tx = Length(0, Fixed); + Length ty = Length(0, Fixed); + if (val->operationType() == WebKitCSSTransformValue::TranslateYTransformOperation) + ty = convertToLength(firstValue, inStyle, &ok); + else { + tx = convertToLength(firstValue, inStyle, &ok); + if (val->operationType() != WebKitCSSTransformValue::TranslateXTransformOperation) { + if (val->length() > 1) { + CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1)); + ty = convertToLength(secondValue, inStyle, &ok); + } + } + } + + if (!ok) + return false; + + operations.operations().append(TranslateTransformOperation::create(tx, ty, getTransformOperationType(val->operationType()))); + break; + } + case WebKitCSSTransformValue::RotateTransformOperation: { + double angle = firstValue->getDoubleValue(); + if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_RAD) + angle = rad2deg(angle); + else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD) + angle = grad2deg(angle); + else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_TURN) + angle = turn2deg(angle); + + operations.operations().append(RotateTransformOperation::create(angle, getTransformOperationType(val->operationType()))); + break; + } + case WebKitCSSTransformValue::SkewTransformOperation: + case WebKitCSSTransformValue::SkewXTransformOperation: + case WebKitCSSTransformValue::SkewYTransformOperation: { + double angleX = 0; + double angleY = 0; + double angle = firstValue->getDoubleValue(); + if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_RAD) + angle = rad2deg(angle); + else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD) + angle = grad2deg(angle); + else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_TURN) + angle = turn2deg(angle); + if (val->operationType() == WebKitCSSTransformValue::SkewYTransformOperation) + angleY = angle; + else { + angleX = angle; + if (val->operationType() == WebKitCSSTransformValue::SkewTransformOperation) { + if (val->length() > 1) { + CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1)); + angleY = secondValue->getDoubleValue(); + if (secondValue->primitiveType() == CSSPrimitiveValue::CSS_RAD) + angleY = rad2deg(angleY); + else if (secondValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD) + angleY = grad2deg(angleY); + else if (secondValue->primitiveType() == CSSPrimitiveValue::CSS_TURN) + angleY = turn2deg(angleY); + } + } + } + operations.operations().append(SkewTransformOperation::create(angleX, angleY, getTransformOperationType(val->operationType()))); + break; + } + case WebKitCSSTransformValue::MatrixTransformOperation: { + float a = firstValue->getFloatValue(); + float b = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1))->getFloatValue(); + float c = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(2))->getFloatValue(); + float d = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(3))->getFloatValue(); + float e = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(4))->getFloatValue(); + float f = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(5))->getFloatValue(); + operations.operations().append(MatrixTransformOperation::create(a, b, c, d, e, f)); + break; + } + case WebKitCSSTransformValue::UnknownTransformOperation: + ASSERT_NOT_REACHED(); + break; + } + } + } + outOperations = operations; + return true; +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSStyleSelector.h b/src/3rdparty/webkit/WebCore/css/CSSStyleSelector.h new file mode 100644 index 0000000..74f9dd7 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSStyleSelector.h @@ -0,0 +1,327 @@ +/* + * 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 "KeyframeList.h" +#include "LinkHash.h" +#include "MediaQueryExp.h" +#include "RenderStyle.h" +#include "StringHash.h" +#include <wtf/HashMap.h> +#include <wtf/HashSet.h> +#include <wtf/RefPtr.h> +#include <wtf/Vector.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 CSSVariableDependentValue; +class CSSVariablesRule; +class Document; +class Element; +class Frame; +class FrameView; +class KURL; +class MediaQueryEvaluator; +class Node; +class Settings; +class StyleImage; +class StyleSheet; +class StyleSheetList; +class StyledElement; +class WebKitCSSKeyframesRule; + +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 a collection of stylesheets. + class CSSStyleSelector : Noncopyable { + public: + CSSStyleSelector(Document*, const String& userStyleSheet, StyleSheetList*, CSSStyleSheet*, bool strictParsing, bool matchAuthorAndUserStyles); + ~CSSStyleSelector(); + + void initElementAndPseudoState(Element*); + void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, RenderStyle::PseudoId = RenderStyle::NOPSEUDO); + PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false); + void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList& list); + + PassRefPtr<RenderStyle> pseudoStyleForElement(RenderStyle::PseudoId, Element*, RenderStyle* parentStyle = 0); + + private: + RenderStyle* locateSharedStyle(); + Node* locateCousinList(Element* parent, unsigned depth = 1); + bool canShareStyleWithElement(Node*); + + RenderStyle* style() const { return m_style.get(); } + + public: + // These methods will give back the set of rules that matched for a given element (or a pseudo-element). + PassRefPtr<CSSRuleList> styleRulesForElement(Element*, bool authorOnly); + PassRefPtr<CSSRuleList> pseudoStyleRulesForElement(Element*, const String& pseudoStyle, bool authorOnly); + + // 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; + + private: + // 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; + + public: + void setStyle(PassRefPtr<RenderStyle> s) { m_style = s; } // Used by the document when setting up its root style. + void setFontSize(FontDescription&, float size); + + void applyPropertyToStyle(int id, CSSValue*, RenderStyle*); + + private: + float getComputedSizeFromSpecifiedSize(bool isAbsoluteSize, float specifiedSize); + + public: + 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 current element. + bool checkSelector(CSSSelector*); + + void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result); + + bool affectedByViewportChange() const; + + void allVisitedStateChanged() { m_checker.allVisitedStateChanged(); } + void visitedStateChanged(LinkHash visitedHash) { m_checker.visitedStateChanged(visitedHash); } + + void addVariables(CSSVariablesRule* variables); + CSSValue* resolveVariableDependentValue(CSSVariableDependentValue*); + void resolveVariablesForDeclaration(CSSMutableStyleDeclaration* decl, CSSMutableStyleDeclaration* newDecl, HashSet<String>& usedBlockVariables); + + void addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule); + + static bool createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, TransformOperations& outOperations); + + private: + enum SelectorMatch { SelectorMatches, SelectorFailsLocally, SelectorFailsCompletely }; + + // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh + void checkForGenericFamilyChange(RenderStyle*, RenderStyle* parentStyle); + void checkForZoomChange(RenderStyle*, RenderStyle* parentStyle); + void checkForTextSizeAdjust(); + + void adjustRenderStyle(RenderStyle*, Element*); + + void addMatchedRule(CSSRuleData* rule) { m_matchedRules.append(rule); } + void addMatchedDeclaration(CSSMutableStyleDeclaration* decl); + + void matchRules(CSSRuleSet*, int& firstRuleIndex, int& lastRuleIndex); + void matchRulesForList(CSSRuleDataList*, int& firstRuleIndex, int& lastRuleIndex); + void sortMatchedRules(unsigned start, unsigned end); + + void applyDeclarations(bool firstPass, bool important, int startIndex, int endIndex); + + CSSRuleSet* m_authorStyle; + CSSRuleSet* m_userStyle; + RefPtr<CSSStyleSheet> m_userSheet; + + bool m_hasUAAppearance; + BorderData m_borderData; + FillLayer m_backgroundData; + Color m_backgroundColor; + + typedef HashMap<AtomicStringImpl*, RefPtr<WebKitCSSKeyframesRule> > KeyframesRuleMap; + KeyframesRuleMap m_keyframesRuleMap; + + public: + static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; } + + class SelectorChecker : public Noncopyable { + public: + SelectorChecker(Document*, bool strictParsing); + + bool checkSelector(CSSSelector*, Element*) const; + SelectorMatch checkSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, RenderStyle::PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const; + bool checkOneSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, RenderStyle::PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle*, RenderStyle* elementParentStyle) const; + PseudoState checkPseudoState(Element*, bool checkVisited = true) const; + bool checkScrollbarPseudoClass(CSSSelector*, RenderStyle::PseudoId& dynamicPseudo) const; + + void allVisitedStateChanged(); + void visitedStateChanged(LinkHash visitedHash); + + Document* m_document; + bool m_strictParsing; + bool m_collectRulesOnly; + RenderStyle::PseudoId m_pseudoStyle; + bool m_documentIsHTML; + mutable HashSet<LinkHash, LinkHashHash> m_linksCheckedForVisitedState; + }; + + private: + static RenderStyle* s_styleNotYetAvailable; + + void init(); + + void matchUARules(int& firstUARule, int& lastUARule); + void updateFont(); + void cacheBorderAndBackground(); + + void mapFillAttachment(FillLayer*, CSSValue*); + void mapFillClip(FillLayer*, CSSValue*); + void mapFillComposite(FillLayer*, CSSValue*); + void mapFillOrigin(FillLayer*, CSSValue*); + void mapFillImage(FillLayer*, CSSValue*); + void mapFillRepeat(FillLayer*, CSSValue*); + void mapFillSize(FillLayer*, CSSValue*); + void mapFillXPosition(FillLayer*, CSSValue*); + void mapFillYPosition(FillLayer*, CSSValue*); + + void mapAnimationDelay(Animation*, CSSValue*); + void mapAnimationDirection(Animation*, CSSValue*); + void mapAnimationDuration(Animation*, CSSValue*); + void mapAnimationIterationCount(Animation*, CSSValue*); + void mapAnimationName(Animation*, CSSValue*); + void mapAnimationPlayState(Animation*, CSSValue*); + void mapAnimationProperty(Animation*, CSSValue*); + void mapAnimationTimingFunction(Animation*, CSSValue*); + + void mapNinePieceImage(CSSValue*, NinePieceImage&); + + void applyProperty(int id, CSSValue*); +#if ENABLE(SVG) + void applySVGProperty(int id, CSSValue*); +#endif + + StyleImage* styleImage(CSSValue* value); + + // 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; + + RefPtr<CSSRuleList> m_ruleList; + + MediaQueryEvaluator* m_medium; + RefPtr<RenderStyle> m_rootDefaultStyle; + + RenderStyle::PseudoId m_dynamicPseudo; + + SelectorChecker m_checker; + + RefPtr<RenderStyle> m_style; + RenderStyle* m_parentStyle; + Element* m_element; + StyledElement* m_styledElement; + Node* m_parentNode; + CSSValue* m_lineHeightValue; + bool m_fontDirty; + bool m_matchAuthorAndUserStyles; + + RefPtr<CSSFontSelector> m_fontSelector; + HashSet<AtomicStringImpl*> m_selectorAttrs; + Vector<CSSMutableStyleDeclaration*> m_additionalAttributeStyleDecls; + Vector<MediaQueryResult*> m_viewportDependentMediaQueryResults; + + HashMap<String, CSSVariablesRule*> m_variablesMap; + HashMap<CSSMutableStyleDeclaration*, RefPtr<CSSMutableStyleDeclaration> > m_resolvedVariablesDeclarations; + }; + + 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/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.cpp b/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.cpp new file mode 100644 index 0000000..47b2c81 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.cpp @@ -0,0 +1,236 @@ +/* + * (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" +#include "TextEncoding.h" +#include <wtf/Deque.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) + , m_strictParsing(!parentSheet || parentSheet->useStrictParsing()) +{ +} + +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) + , m_strictParsing(false) +{ +} + +CSSStyleSheet::CSSStyleSheet(CSSRule *ownerRule, const String& href, const String& charset) + : StyleSheet(ownerRule, href) + , m_namespaces(0) + , m_charset(charset) + , m_loadCompleted(false) + , m_strictParsing(!ownerRule || ownerRule->useStrictParsing()) +{ + CSSStyleSheet* parentSheet = ownerRule ? ownerRule->parentStyleSheet() : 0; + m_doc = parentSheet ? parentSheet->doc() : 0; +} + +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); +} + + +PassRefPtr<CSSRuleList> CSSStyleSheet::cssRules(bool omitCharsetRules) +{ + return CSSRuleList::create(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->m_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 = ownerNode() ? ownerNode()->sheetLoaded() : true; +} + +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(); +} + +KURL CSSStyleSheet::completeURL(const String& url) const +{ + // Always return a null URL when passed a null string. + // FIXME: Should we change the KURL constructor to have this behavior? + // See also Document::completeURL(const String&) + if (url.isNull() || m_charset.isEmpty()) + return StyleSheet::completeURL(url); + const TextEncoding encoding = TextEncoding(m_charset); + return KURL(baseURL(), url, encoding); +} + +void CSSStyleSheet::addSubresourceStyleURLs(ListHashSet<KURL>& urls) +{ + Deque<CSSStyleSheet*> styleSheetQueue; + styleSheetQueue.append(this); + + while (!styleSheetQueue.isEmpty()) { + CSSStyleSheet* styleSheet = styleSheetQueue.first(); + styleSheetQueue.removeFirst(); + + RefPtr<CSSRuleList> ruleList = styleSheet->cssRules(); + + for (unsigned i = 0; i < ruleList->length(); ++i) { + CSSRule* rule = ruleList->item(i); + if (rule->isImportRule()) { + if (CSSStyleSheet* ruleStyleSheet = static_cast<CSSImportRule*>(rule)->styleSheet()) + styleSheetQueue.append(ruleStyleSheet); + } + rule->addSubresourceStyleURLs(urls); + } + } +} + +} diff --git a/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.h b/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.h new file mode 100644 index 0000000..8646ee9 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.h @@ -0,0 +1,113 @@ +/* + * (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 "CSSRuleList.h" +#include "StyleSheet.h" + +namespace WebCore { + +class CSSNamespace; +class CSSParser; +class CSSRule; +class DocLoader; +class Document; + +typedef int ExceptionCode; + +class CSSStyleSheet : public StyleSheet { +public: + static PassRefPtr<CSSStyleSheet> create() + { + return adoptRef(new CSSStyleSheet(static_cast<CSSStyleSheet*>(0), String(), String())); + } + static PassRefPtr<CSSStyleSheet> create(Node* ownerNode) + { + return adoptRef(new CSSStyleSheet(ownerNode, String(), String())); + } + static PassRefPtr<CSSStyleSheet> create(Node* ownerNode, const String& href) + { + return adoptRef(new CSSStyleSheet(ownerNode, href, String())); + } + static PassRefPtr<CSSStyleSheet> create(Node* ownerNode, const String& href, const String& charset) + { + return adoptRef(new CSSStyleSheet(ownerNode, href, charset)); + } + static PassRefPtr<CSSStyleSheet> create(CSSRule* ownerRule, const String& href, const String& charset) + { + return adoptRef(new CSSStyleSheet(ownerRule, href, charset)); + } + + virtual ~CSSStyleSheet(); + + CSSRule* ownerRule() const; + PassRefPtr<CSSRuleList> cssRules(bool omitCharsetRules = false); + unsigned insertRule(const String& rule, unsigned index, ExceptionCode&); + void deleteRule(unsigned index, ExceptionCode&); + + // IE Extensions + PassRefPtr<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(); + + Document* doc() { return m_doc; } + + const String& charset() const { return m_charset; } + + bool loadCompleted() const { return m_loadCompleted; } + + virtual KURL completeURL(const String& url) const; + virtual void addSubresourceStyleURLs(ListHashSet<KURL>&); + + void setStrictParsing(bool b) { m_strictParsing = b; } + bool useStrictParsing() const { return m_strictParsing; } + +private: + CSSStyleSheet(Node* ownerNode, const String& href, const String& charset); + CSSStyleSheet(CSSStyleSheet* parentSheet, const String& href, const String& charset); + CSSStyleSheet(CSSRule* ownerRule, const String& href, const String& charset); + + virtual bool isCSSStyleSheet() const { return true; } + virtual String type() const { return "text/css"; } + + Document* m_doc; + CSSNamespace* m_namespaces; + String m_charset; + bool m_loadCompleted : 1; + bool m_strictParsing : 1; +}; + +} // namespace + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.idl b/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.idl new file mode 100644 index 0000000..d10844c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSStyleSheet.idl @@ -0,0 +1,49 @@ +/* + * 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 [ + GenerateConstructor, + 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/src/3rdparty/webkit/WebCore/css/CSSTimingFunctionValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSTimingFunctionValue.cpp new file mode 100644 index 0000000..e576d36 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSTimingFunctionValue.h b/src/3rdparty/webkit/WebCore/css/CSSTimingFunctionValue.h new file mode 100644 index 0000000..e465993 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSTimingFunctionValue.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 CSSTimingFunctionValue_h +#define CSSTimingFunctionValue_h + +#include "CSSValue.h" +#include <wtf/PassRefPtr.h> + +namespace WebCore { + +class CSSTimingFunctionValue : public CSSValue { +public: + static PassRefPtr<CSSTimingFunctionValue> create(double x1, double y1, double x2, double y2) + { + return adoptRef(new CSSTimingFunctionValue(x1, y1, x2, y2)); + } + + virtual String cssText() const; + + 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: + CSSTimingFunctionValue(double x1, double y1, double x2, double y2) + : m_x1(x1) + , m_y1(y1) + , m_x2(x2) + , m_y2(y2) + { + } + + virtual bool isTimingFunctionValue() const { return true; } + + double m_x1; + double m_y1; + double m_x2; + double m_y2; +}; + +} // namespace + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/CSSUnicodeRangeValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSUnicodeRangeValue.cpp new file mode 100644 index 0000000..599c078 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSUnicodeRangeValue.h b/src/3rdparty/webkit/WebCore/css/CSSUnicodeRangeValue.h new file mode 100644 index 0000000..0ba1980 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSUnicodeRangeValue.h @@ -0,0 +1,62 @@ +/* + * 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/PassRefPtr.h> +#include <wtf/unicode/Unicode.h> + +namespace WebCore { + +class CSSUnicodeRangeValue : public CSSValue { +public: + static PassRefPtr<CSSUnicodeRangeValue> create(UChar32 from, UChar32 to) + { + return adoptRef(new CSSUnicodeRangeValue(from, to)); + } + + virtual ~CSSUnicodeRangeValue(); + + UChar32 from() const { return m_from; } + UChar32 to() const { return m_to; } + + virtual String cssText() const; + +private: + CSSUnicodeRangeValue(UChar32 from, UChar32 to) + : m_from(from) + , m_to(to) + { + } + + UChar32 m_from; + UChar32 m_to; +}; + +} // namespace WebCore + +#endif // CSSUnicodeRangeValue_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSUnknownRule.h b/src/3rdparty/webkit/WebCore/css/CSSUnknownRule.h new file mode 100644 index 0000000..b2448dd --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSUnknownRule.h @@ -0,0 +1,36 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2002-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. + */ + +#ifndef CSSUnknownRule_h +#define CSSUnknownRule_h + +#include "CSSRule.h" + +namespace WebCore { + +class CSSUnknownRule : public CSSRule { +private: + virtual unsigned short type() const { return UNKNOWN_RULE; } +}; + +} // namespace WebCore + +#endif // CSSUnknownRule_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSUnknownRule.idl b/src/3rdparty/webkit/WebCore/css/CSSUnknownRule.idl new file mode 100644 index 0000000..2365cd2 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSValue.h b/src/3rdparty/webkit/WebCore/css/CSSValue.h new file mode 100644 index 0000000..0bd6496 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSValue.h @@ -0,0 +1,78 @@ +/* + * (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. + */ + +#ifndef CSSValue_h +#define CSSValue_h + +#include "StyleBase.h" + +#include "CSSParserValues.h" +#include "KURLHash.h" +#include <wtf/ListHashSet.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class CSSStyleSheet; + +typedef int ExceptionCode; + +class CSSValue : public RefCounted<CSSValue> { +public: + // FIXME: Change name to Type. + enum UnitTypes { + CSS_INHERIT = 0, + CSS_PRIMITIVE_VALUE = 1, + CSS_VALUE_LIST = 2, + CSS_CUSTOM = 3, + CSS_INITIAL = 4 + }; + + virtual ~CSSValue() { } + + // FIXME: Change this to return UnitTypes. + virtual unsigned short cssValueType() const { return CSS_CUSTOM; } + + virtual String cssText() const = 0; + void setCssText(const String&, ExceptionCode&) { } // FIXME: Not implemented. + + virtual bool isFontValue() const { return false; } + virtual bool isImageGeneratorValue() const { return false; } + virtual bool isImageValue() const { return false; } + virtual bool isImplicitInitialValue() const { return false; } + virtual bool isPrimitiveValue() const { return false; } + virtual bool isTimingFunctionValue() const { return false; } + virtual bool isValueList() const { return false; } + virtual bool isWebKitCSSTransformValue() const { return false; } + +#if ENABLE(SVG) + virtual bool isSVGColor() const { return false; } + virtual bool isSVGPaint() const { return false; } +#endif + + virtual bool isVariableDependentValue() const { return false; } + virtual CSSParserValue parserValue() const { ASSERT_NOT_REACHED(); return CSSParserValue(); } + + virtual void addSubresourceStyleURLs(ListHashSet<KURL>&, const CSSStyleSheet*) { } +}; + +} // namespace WebCore + +#endif // CSSValue_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSValue.idl b/src/3rdparty/webkit/WebCore/css/CSSValue.idl new file mode 100644 index 0000000..8979b61 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSValueKeywords.in b/src/3rdparty/webkit/WebCore/css/CSSValueKeywords.in new file mode 100644 index 0000000..3271166 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSValueKeywords.in @@ -0,0 +1,601 @@ +# 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 +# The following is only allowed in @font-face: +all +# +# 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 +currentcolor +# +# 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 +-webkit-grab +-webkit-grabbing +# 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 +default-button +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 +slider-horizontal +slider-vertical +sliderthumb-horizontal +sliderthumb-vertical +caret +searchfield +searchfield-decoration +searchfield-results-decoration +searchfield-results-button +searchfield-cancel-button +textfield +textarea +caps-lock-indicator + +# +# 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_ANIMATION_DIRECTION +# +# alternate + +# +# CSS_PROP__WEBKIT_ANIMATION_ITERATION_COUNT +# +# infinite + +# +# CSS_PROP__WEBKIT_ANIMATION_PLAY_STATE +# +running +paused + +# +# CSS_PROP__WEBKIT_TRANSITION_TIMING_FUNCTION +# CSS_PROP__WEBKIT_ANIMATION_TIMING_FUNCTION +# +ease +linear +ease-in +ease-out +ease-in-out + +# +# CSS_PROP_ZOOM +# +document +reset + +# +# CSS_PROP_POINTER_EVENTS +# +visiblePainted +visibleFill +visibleStroke +#visible +painted +fill +stroke +#all +#none
\ No newline at end of file diff --git a/src/3rdparty/webkit/WebCore/css/CSSValueList.cpp b/src/3rdparty/webkit/WebCore/css/CSSValueList.cpp new file mode 100644 index 0000000..b547768 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSValueList.cpp @@ -0,0 +1,109 @@ +/** + * 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 "CSSParserValues.h" +#include "PlatformString.h" + +namespace WebCore { + +CSSValueList::CSSValueList(bool isSpaceSeparated) + : m_isSpaceSeparated(isSpaceSeparated) +{ +} + +CSSValueList::CSSValueList(CSSParserValueList* list) + : m_isSpaceSeparated(true) +{ + if (list) { + unsigned s = list->size(); + for (unsigned i = 0; i < s; ++i) { + CSSParserValue* v = list->valueAt(i); + append(v->createCSSValue()); + } + } +} + +CSSValueList::~CSSValueList() +{ +} + +CSSValue* CSSValueList::item(unsigned index) +{ + if (index >= m_values.size()) + return 0; + return m_values[index].get(); +} + +unsigned short CSSValueList::cssValueType() const +{ + return CSS_VALUE_LIST; +} + +void CSSValueList::append(PassRefPtr<CSSValue> val) +{ + m_values.append(val); +} + +void CSSValueList::prepend(PassRefPtr<CSSValue> val) +{ + m_values.prepend(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; +} + +CSSParserValueList* CSSValueList::createParserValueList() const +{ + unsigned s = m_values.size(); + if (!s) + return 0; + CSSParserValueList* result = new CSSParserValueList; + for (unsigned i = 0; i < s; ++i) + result->addValue(m_values[i]->parserValue()); + return result; +} + +void CSSValueList::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const CSSStyleSheet* styleSheet) +{ + size_t size = m_values.size(); + for (size_t i = 0; i < size; ++i) + m_values[i]->addSubresourceStyleURLs(urls, styleSheet); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/CSSValueList.h b/src/3rdparty/webkit/WebCore/css/CSSValueList.h new file mode 100644 index 0000000..d34f445 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSValueList.h @@ -0,0 +1,77 @@ +/* + * (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. + */ + +#ifndef CSSValueList_h +#define CSSValueList_h + +#include "CSSValue.h" +#include <wtf/PassRefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class CSSParserValueList; + +class CSSValueList : public CSSValue { +public: + static PassRefPtr<CSSValueList> createCommaSeparated() + { + return adoptRef(new CSSValueList(false)); + } + static PassRefPtr<CSSValueList> createSpaceSeparated() + { + return adoptRef(new CSSValueList(true)); + } + static PassRefPtr<CSSValueList> createFromParserValueList(CSSParserValueList* list) + { + return adoptRef(new CSSValueList(list)); + } + + virtual ~CSSValueList(); + + size_t length() const { return m_values.size(); } + CSSValue* item(unsigned); + CSSValue* itemWithoutBoundsCheck(unsigned index) { return m_values[index].get(); } + + void append(PassRefPtr<CSSValue>); + void prepend(PassRefPtr<CSSValue>); + + virtual String cssText() const; + + CSSParserValueList* createParserValueList() const; + + virtual void addSubresourceStyleURLs(ListHashSet<KURL>&, const CSSStyleSheet*); + +protected: + CSSValueList(bool isSpaceSeparated); + CSSValueList(CSSParserValueList*); + +private: + virtual bool isValueList() const { return true; } + + virtual unsigned short cssValueType() const; + + Vector<RefPtr<CSSValue> > m_values; + bool m_isSpaceSeparated; +}; + +} // namespace WebCore + +#endif // CSSValueList_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSValueList.idl b/src/3rdparty/webkit/WebCore/css/CSSValueList.idl new file mode 100644 index 0000000..8ddfaae --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/CSSVariableDependentValue.cpp b/src/3rdparty/webkit/WebCore/css/CSSVariableDependentValue.cpp new file mode 100644 index 0000000..2eadc1c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSVariableDependentValue.cpp @@ -0,0 +1,49 @@ +/* + * 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 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 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 "CSSVariableDependentValue.h" + +#include "CSSValueList.h" + +namespace WebCore { + +CSSVariableDependentValue::CSSVariableDependentValue(PassRefPtr<CSSValueList> list) +: m_list(list) +{ +} + +CSSVariableDependentValue::~CSSVariableDependentValue() +{ +} + +String CSSVariableDependentValue::cssText() const +{ + if (m_list) + return m_list->cssText(); + return ""; +} + +} diff --git a/src/3rdparty/webkit/WebCore/css/CSSVariableDependentValue.h b/src/3rdparty/webkit/WebCore/css/CSSVariableDependentValue.h new file mode 100644 index 0000000..e8dce2e --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSVariableDependentValue.h @@ -0,0 +1,57 @@ +/* + * 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 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 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 CSSVariableDependentValue_h +#define CSSVariableDependentValue_h + +#include "CSSValue.h" + +namespace WebCore { + +class CSSValueList; + +class CSSVariableDependentValue : public CSSValue { +public: + static PassRefPtr<CSSVariableDependentValue> create(PassRefPtr<CSSValueList> valueList) + { + return adoptRef(new CSSVariableDependentValue(valueList)); + } + virtual ~CSSVariableDependentValue(); + + virtual String cssText() const; + + bool isVariableDependentValue() const { return true; } + + CSSValueList* valueList() const { return m_list.get(); } + +private: + CSSVariableDependentValue(PassRefPtr<CSSValueList>); + + RefPtr<CSSValueList> m_list; +}; + +} +#endif + diff --git a/src/3rdparty/webkit/WebCore/css/CSSVariablesDeclaration.cpp b/src/3rdparty/webkit/WebCore/css/CSSVariablesDeclaration.cpp new file mode 100644 index 0000000..5f8d601 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSVariablesDeclaration.cpp @@ -0,0 +1,175 @@ +/* + * 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 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 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 "CSSVariablesDeclaration.h" + +#include "CSSParser.h" +#include "CSSRule.h" +#include "CSSValueList.h" +#include "Document.h" +#include "ExceptionCode.h" + +namespace WebCore { + +CSSVariablesDeclaration::CSSVariablesDeclaration(StyleBase* parent, const Vector<String>& names, const Vector<RefPtr<CSSValue> >& values) + : StyleBase(parent) +{ + m_variableNames = names; + ASSERT(names.size() == values.size()); + unsigned s = names.size(); + for (unsigned i = 0; i < s; ++i) + addParsedVariable(names[i], values[i], false); +} + +CSSVariablesDeclaration::~CSSVariablesDeclaration() +{ +} + +String CSSVariablesDeclaration::getVariableValue(const String& variableName) +{ + CSSValue* val = m_variablesMap.get(variableName).get(); + if (val) + return val->cssText(); + return ""; +} + +String CSSVariablesDeclaration::removeVariable(const String& variableName, ExceptionCode&) +{ + // FIXME: The spec has this method taking an exception code but no exceptions are + // specified as being thrown. + RefPtr<CSSValue> val = m_variablesMap.take(variableName); + String result = val ? val->cssText() : ""; + if (val) { + int s = m_variableNames.size(); + for (int i = 0; i < s; ++i) { + if (m_variableNames[i] == variableName) { + m_variableNames.remove(i); + i--; + s--; + } + } + + setChanged(); + } + + // FIXME: Communicate this change so that the document will update. + return result; +} + +void CSSVariablesDeclaration::setVariable(const String& variableName, const String& variableValue, ExceptionCode& excCode) +{ + // Try to parse the variable value into a Value*. If it fails we throw an exception. + CSSParser parser(useStrictParsing()); + if (!parser.parseVariable(this, variableName, variableValue)) // If the parse succeeds, it will call addParsedVariable (our internal method for doing the add) with the parsed Value*. + excCode = SYNTAX_ERR; + else + setChanged(); +} + +void CSSVariablesDeclaration::addParsedVariable(const String& variableName, PassRefPtr<CSSValue> variableValue, bool updateNamesList) +{ +// FIXME: Disabling declarations as variable values for now since they no longer have a common base class with CSSValues. +#if 0 + variableValue->setParent(this); // Needed to connect variables that are CSSMutableStyleDeclarations, since the parent couldn't be set until now. +#endif + + // Don't leak duplicates. For multiple variables with the same name, the last one + // declared will win. + CSSValue* current = m_variablesMap.take(variableName).get(); + if (!current && updateNamesList) + m_variableNames.append(variableName); + m_variablesMap.set(variableName, variableValue); + + // FIXME: Communicate this change so the document will update. +} + +CSSValueList* CSSVariablesDeclaration::getParsedVariable(const String& variableName) +{ + CSSValue* result = m_variablesMap.get(variableName).get(); + if (result->isValueList()) + return static_cast<CSSValueList*>(result); + return 0; +} + +CSSMutableStyleDeclaration* CSSVariablesDeclaration::getParsedVariableDeclarationBlock(const String&) +{ +// FIXME: Disabling declarations as variable values for now since they no longer have a common base class with CSSValues. +#if 0 + StyleBase* result = m_variablesMap.get(variableName).get(); + + if (result->isMutableStyleDeclaration()) + return static_cast<CSSMutableStyleDeclaration*>(result); +#endif + return 0; +} + +unsigned CSSVariablesDeclaration::length() const +{ + return m_variableNames.size(); +} + +String CSSVariablesDeclaration::item(unsigned index) +{ + if (index >= m_variableNames.size()) + return ""; + return m_variableNames[index]; +} + +CSSRule* CSSVariablesDeclaration::parentRule() +{ + return (parent() && parent()->isRule()) ? static_cast<CSSRule*>(parent()) : 0; +} + +String CSSVariablesDeclaration::cssText() const +{ + String result = "{ "; + unsigned s = m_variableNames.size(); + for (unsigned i = 0; i < s; ++i) { + result += m_variableNames[i] + ": "; + result += m_variablesMap.get(m_variableNames[i])->cssText(); + if (i < s - 1) + result += "; "; + } + result += " }"; + return result; +} + +void CSSVariablesDeclaration::setCssText(const String&) +{ + // FIXME: It's not clear if this is actually settable. +} + +void CSSVariablesDeclaration::setChanged() +{ + // FIXME: Make this much better (it has the same problem CSSMutableStyleDeclaration does). + StyleBase* root = this; + while (StyleBase* parent = root->parent()) + root = parent; + if (root->isCSSStyleSheet()) + static_cast<CSSStyleSheet*>(root)->doc()->updateStyleSelector(); +} + +} diff --git a/src/3rdparty/webkit/WebCore/css/CSSVariablesDeclaration.h b/src/3rdparty/webkit/WebCore/css/CSSVariablesDeclaration.h new file mode 100644 index 0000000..aa98158 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSVariablesDeclaration.h @@ -0,0 +1,82 @@ +/* + * 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 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 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 CSSVariablesDeclaration_h +#define CSSVariablesDeclaration_h + +#include "PlatformString.h" +#include "StringHash.h" +#include "StyleBase.h" +#include <wtf/HashMap.h> +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +typedef int ExceptionCode; + +class CSSMutableStyleDeclaration; +class CSSRule; +class CSSValue; +class CSSValueList; + +class CSSVariablesDeclaration : public StyleBase { +public: + static PassRefPtr<CSSVariablesDeclaration> create(StyleBase* owningRule, const Vector<String>& names, const Vector<RefPtr<CSSValue> >& values) + { + return adoptRef(new CSSVariablesDeclaration(owningRule, names, values)); + } + virtual ~CSSVariablesDeclaration(); + + String getVariableValue(const String&); + String removeVariable(const String&, ExceptionCode&); + void setVariable(const String&, const String&, ExceptionCode&); + + unsigned length() const; + String item(unsigned index); + + CSSRule* parentRule(); + + String cssText() const; + void setCssText(const String&); // FIXME: The spec contradicts itself regarding whether or not cssText is settable. + + void addParsedVariable(const String& variableName, PassRefPtr<CSSValue> variableValue, bool updateNamesList = true); + + CSSValueList* getParsedVariable(const String& variableName); + CSSMutableStyleDeclaration* getParsedVariableDeclarationBlock(const String& variableName); + +private: + CSSVariablesDeclaration(StyleBase* owningRule, const Vector<String>& names, const Vector<RefPtr<CSSValue> >& values); + + void setChanged(); + +protected: + Vector<String> m_variableNames; + HashMap<String, RefPtr<CSSValue> > m_variablesMap; +}; + +} // namespace WebCore + +#endif // CSSVariablesDeclaration_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSVariablesDeclaration.idl b/src/3rdparty/webkit/WebCore/css/CSSVariablesDeclaration.idl new file mode 100644 index 0000000..82d2e9c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSVariablesDeclaration.idl @@ -0,0 +1,45 @@ +/* + * 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 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 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 { + + interface [ + GenerateConstructor, + HasIndexGetter + ] CSSVariablesDeclaration { + attribute DOMString cssText; + + DOMString getVariableValue(in DOMString variableName); + DOMString removeVariable(in DOMString variableName) + raises(DOMException); + void setVariable(in DOMString variableName, + in DOMString value) + raises(DOMException); + readonly attribute unsigned long length; + DOMString item(in unsigned long index); + readonly attribute CSSRule parentRule; + }; + +} diff --git a/src/3rdparty/webkit/WebCore/css/CSSVariablesRule.cpp b/src/3rdparty/webkit/WebCore/css/CSSVariablesRule.cpp new file mode 100644 index 0000000..0771952 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSVariablesRule.cpp @@ -0,0 +1,61 @@ +/* + * 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 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 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 "CSSVariablesRule.h" + +#include "MediaList.h" +#include "PlatformString.h" +#include <wtf/HashMap.h> + +namespace WebCore { + +CSSVariablesRule::CSSVariablesRule(CSSStyleSheet* parent, MediaList* mediaList, bool variablesKeyword) + : CSSRule(parent) + , m_lstMedia(mediaList) + , m_variablesKeyword(variablesKeyword) +{ +} + +CSSVariablesRule::~CSSVariablesRule() +{ +} + +String CSSVariablesRule::cssText() const +{ + String result = m_variablesKeyword ? "@-webkit-variables " : "@-webkit-define "; + if (m_lstMedia) { + if (!m_variablesKeyword) + result += "for "; + result += m_lstMedia->mediaText(); + result += " "; + } + if (m_variables) + result += m_variables->cssText(); + result += ";"; + return result; +} + +} diff --git a/src/3rdparty/webkit/WebCore/css/CSSVariablesRule.h b/src/3rdparty/webkit/WebCore/css/CSSVariablesRule.h new file mode 100644 index 0000000..d2cea39 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSVariablesRule.h @@ -0,0 +1,70 @@ +/* + * 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 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 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 CSSVariablesRule_h +#define CSSVariablesRule_h + +#include "CSSRule.h" +#include "CSSVariablesDeclaration.h" +#include <wtf/RefPtr.h> + +namespace WebCore { + +class CSSStyleSheet; +class MediaList; + +class CSSVariablesRule : public CSSRule { +public: + static PassRefPtr<CSSVariablesRule> create(CSSStyleSheet* parent, MediaList* mediaList, bool variablesKeyword) + { + return adoptRef(new CSSVariablesRule(parent, mediaList, variablesKeyword)); + } + + virtual ~CSSVariablesRule(); + + // CSSVariablesRule interface + MediaList* media() const { return m_lstMedia.get(); } + CSSVariablesDeclaration* variables() { return m_variables.get(); } + + // Inherited from CSSRule + virtual unsigned short type() const { return VARIABLES_RULE; } + virtual String cssText() const; + virtual bool isVariablesRule() { return true; } + + // Used internally. Does not notify the document of the change. Only intended + // for use on initial parse. + void setDeclaration(PassRefPtr<CSSVariablesDeclaration> decl) { m_variables = decl; } + +private: + CSSVariablesRule(CSSStyleSheet* parent, MediaList*, bool variablesKeyword); + + RefPtr<MediaList> m_lstMedia; + RefPtr<CSSVariablesDeclaration> m_variables; + bool m_variablesKeyword; +}; + +} // namespace WebCore + +#endif // CSSVariablesRule_h diff --git a/src/3rdparty/webkit/WebCore/css/CSSVariablesRule.idl b/src/3rdparty/webkit/WebCore/css/CSSVariablesRule.idl new file mode 100644 index 0000000..ec49282 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/CSSVariablesRule.idl @@ -0,0 +1,35 @@ +/* + * 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 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 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 { + + interface [ + GenerateConstructor + ] CSSVariablesRule : CSSRule { + readonly attribute stylesheets::MediaList media; + readonly attribute CSSVariablesDeclaration variables; + }; + +} diff --git a/src/3rdparty/webkit/WebCore/css/Counter.h b/src/3rdparty/webkit/WebCore/css/Counter.h new file mode 100644 index 0000000..0a45009 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/Counter.h @@ -0,0 +1,61 @@ +/* + * (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 Counter_h +#define Counter_h + +#include "CSSPrimitiveValue.h" +#include "PlatformString.h" + +namespace WebCore { + +class Counter : public RefCounted<Counter> { +public: + static PassRefPtr<Counter> create(PassRefPtr<CSSPrimitiveValue> identifier, PassRefPtr<CSSPrimitiveValue> listStyle, PassRefPtr<CSSPrimitiveValue> separator) + { + return adoptRef(new Counter(identifier, listStyle, 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; } + +private: + Counter(PassRefPtr<CSSPrimitiveValue> identifier, PassRefPtr<CSSPrimitiveValue> listStyle, PassRefPtr<CSSPrimitiveValue> separator) + : m_identifier(identifier) + , m_listStyle(listStyle) + , m_separator(separator) + { + } + + RefPtr<CSSPrimitiveValue> m_identifier; // string + RefPtr<CSSPrimitiveValue> m_listStyle; // int + RefPtr<CSSPrimitiveValue> m_separator; // string +}; + +} // namespace WebCore + +#endif // Counter_h diff --git a/src/3rdparty/webkit/WebCore/css/Counter.idl b/src/3rdparty/webkit/WebCore/css/Counter.idl new file mode 100644 index 0000000..5be8f0d --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/DashboardRegion.h b/src/3rdparty/webkit/WebCore/css/DashboardRegion.h new file mode 100644 index 0000000..91e5d7a --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/DashboardRegion.h @@ -0,0 +1,48 @@ +/* + * (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 DashboardRegion_h +#define DashboardRegion_h + +#include "Rect.h" + +#if ENABLE(DASHBOARD_SUPPORT) + +namespace WebCore { + +class DashboardRegion : public RectBase, public RefCounted<DashboardRegion> { +public: + static PassRefPtr<DashboardRegion> create() { return adoptRef(new DashboardRegion); } + + RefPtr<DashboardRegion> m_next; + String m_label; + String m_geometryType; + bool m_isCircle : 1; + bool m_isRectangle : 1; + +private: + DashboardRegion() : m_isCircle(false), m_isRectangle(false) { } +}; + +} // namespace + +#endif + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/DashboardSupportCSSPropertyNames.in b/src/3rdparty/webkit/WebCore/css/DashboardSupportCSSPropertyNames.in new file mode 100644 index 0000000..615bd6c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/DashboardSupportCSSPropertyNames.in @@ -0,0 +1 @@ +-webkit-dashboard-region diff --git a/src/3rdparty/webkit/WebCore/css/FontFamilyValue.cpp b/src/3rdparty/webkit/WebCore/css/FontFamilyValue.cpp new file mode 100644 index 0000000..90a8c9d --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/FontFamilyValue.cpp @@ -0,0 +1,107 @@ +/* + * (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 { + +// FIXME: This appears identical to isCSSTokenizerIdentifier from CSSPrimitiveValue.cpp, we should use a single function. +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 == '-' || 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 " 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/src/3rdparty/webkit/WebCore/css/FontFamilyValue.h b/src/3rdparty/webkit/WebCore/css/FontFamilyValue.h new file mode 100644 index 0000000..087d22a --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/FontFamilyValue.h @@ -0,0 +1,50 @@ +/* + * (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: + static PassRefPtr<FontFamilyValue> create(const String& familyName) + { + return adoptRef(new FontFamilyValue(familyName)); + } + + void appendSpaceSeparated(const UChar* characters, unsigned length); + + const String& familyName() const { return m_familyName; } + + virtual String cssText() const; + +private: + FontFamilyValue(const String& familyName); + + String m_familyName; +}; + +} // namespace + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/FontValue.cpp b/src/3rdparty/webkit/WebCore/css/FontValue.cpp new file mode 100644 index 0000000..231ac64 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/FontValue.h b/src/3rdparty/webkit/WebCore/css/FontValue.h new file mode 100644 index 0000000..5c7406c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/FontValue.h @@ -0,0 +1,57 @@ +/* + * (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 FontValue_h +#define FontValue_h + +#include "CSSValue.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class CSSPrimitiveValue; +class CSSValueList; + +class FontValue : public CSSValue { +public: + static PassRefPtr<FontValue> create() + { + return adoptRef(new FontValue); + } + + virtual String cssText() const; + + RefPtr<CSSPrimitiveValue> style; + RefPtr<CSSPrimitiveValue> variant; + RefPtr<CSSPrimitiveValue> weight; + RefPtr<CSSPrimitiveValue> size; + RefPtr<CSSPrimitiveValue> lineHeight; + RefPtr<CSSValueList> family; + +private: + FontValue() { } + + virtual bool isFontValue() const { return true; } +}; + +} // namespace + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/MediaFeatureNames.cpp b/src/3rdparty/webkit/WebCore/css/MediaFeatureNames.cpp new file mode 100644 index 0000000..fcee5de --- /dev/null +++ b/src/3rdparty/webkit/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 SKIP_STATIC_CONSTRUCTORS_ON_GCC +#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/src/3rdparty/webkit/WebCore/css/MediaFeatureNames.h b/src/3rdparty/webkit/WebCore/css/MediaFeatureNames.h new file mode 100644 index 0000000..bea2b8a --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/MediaFeatureNames.h @@ -0,0 +1,73 @@ +/* + * 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") \ + macro(transform_2d, "-webkit-transform-2d") \ + macro(transform_3d, "-webkit-transform-3d") \ + macro(transition, "-webkit-transition") \ + macro(animation, "-webkit-animation") \ +// 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/src/3rdparty/webkit/WebCore/css/MediaList.cpp b/src/3rdparty/webkit/WebCore/css/MediaList.cpp new file mode 100644 index 0000000..452345f --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/MediaList.cpp @@ -0,0 +1,258 @@ +/* + * (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 "CSSImportRule.h" +#include "CSSParser.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(CSSImportRule* parentRule, const String& media) + : StyleBase(parentRule) + , m_fallback(false) +{ + ExceptionCode ec = 0; + setMediaText(media, ec); + if (ec) + setMediaText("invalid", ec); +} + +MediaList::~MediaList() +{ + deleteAllValues(m_queries); +} + +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) +{ + RefPtr<MediaList> tempMediaList = MediaList::create(); + CSSParser p(true); + + MediaQuery* oldQuery = 0; + bool deleteOldQuery = false; + + if (p.parseMediaQuery(tempMediaList.get(), 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) +{ + RefPtr<MediaList> tempMediaList = MediaList::create(); + 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.get(), 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/src/3rdparty/webkit/WebCore/css/MediaList.h b/src/3rdparty/webkit/WebCore/css/MediaList.h new file mode 100644 index 0000000..f1eb0c0 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/MediaList.h @@ -0,0 +1,92 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * 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 MediaList_h +#define MediaList_h + +#include "StyleBase.h" +#include <wtf/PassRefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class CSSImportRule; +class CSSStyleSheet; +class MediaQuery; +class String; + +typedef int ExceptionCode; + +class MediaList : public StyleBase { +public: + static PassRefPtr<MediaList> create() + { + return adoptRef(new MediaList(0, false)); + } + static PassRefPtr<MediaList> create(CSSImportRule* parentRule, const String& media) + { + return adoptRef(new MediaList(parentRule, media)); + } + static PassRefPtr<MediaList> create(CSSStyleSheet* parentSheet, const String& media) + { + return adoptRef(new MediaList(parentSheet, media, false)); + } + + static PassRefPtr<MediaList> createAllowingDescriptionSyntax(const String& mediaQueryOrDescription) + { + return adoptRef(new MediaList(0, mediaQueryOrDescription, true)); + } + static PassRefPtr<MediaList> createAllowingDescriptionSyntax(CSSStyleSheet* parentSheet, const String& mediaQueryOrDescription) + { + return adoptRef(new MediaList(parentSheet, mediaQueryOrDescription, true)); + } + + static PassRefPtr<MediaList> create(const String& media, bool allowDescriptionSyntax) + { + return adoptRef(new MediaList(0, media, allowDescriptionSyntax)); + } + + virtual ~MediaList(); + + unsigned length() const { return 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*); + const Vector<MediaQuery*>& mediaQueries() const { return m_queries; } + +private: + MediaList(CSSStyleSheet* parentSheet, bool fallbackToDescription); + MediaList(CSSStyleSheet* parentSheet, const String& media, bool fallbackToDescription); + MediaList(CSSImportRule* parentRule, const String& media); + + void notifyChanged(); + + Vector<MediaQuery*> m_queries; + bool m_fallback; // true if failed media query parsing should fallback to media description parsing +}; + +} // namespace + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/MediaList.idl b/src/3rdparty/webkit/WebCore/css/MediaList.idl new file mode 100644 index 0000000..dc10e63 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/MediaQuery.cpp b/src/3rdparty/webkit/WebCore/css/MediaQuery.cpp new file mode 100644 index 0000000..ff57372 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/MediaQuery.h b/src/3rdparty/webkit/WebCore/css/MediaQuery.h new file mode 100644 index 0000000..0aa0da1 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/MediaQueryEvaluator.cpp b/src/3rdparty/webkit/WebCore/css/MediaQueryEvaluator.cpp new file mode 100644 index 0000000..211178c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/MediaQueryEvaluator.cpp @@ -0,0 +1,455 @@ +/* + * 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) + , 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->itemWithoutBoundsCheck(0); + CSSValue* i1 = valueList->itemWithoutBoundsCheck(1); + CSSValue* i2 = valueList->itemWithoutBoundsCheck(2); + if (i0->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i0)->primitiveType() == CSSPrimitiveValue::CSS_NUMBER + && i1->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i1)->primitiveType() == CSSPrimitiveValue::CSS_STRING + && i2->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i2)->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) { + 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*, 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())) { + if (value) { + float number; + return numberValue(value, number) && compareValue(0, static_cast<int>(number), op); + } + return false; + } + + return colorMediaFeatureEval(value, style, frame, op); +} + +static bool device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle*, 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*, 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*, 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->layoutHeight(), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style), op); + + return view->layoutHeight() != 0; +} + +static bool widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op) +{ + FrameView* view = frame->view(); + + if (value) + return value->isPrimitiveValue() && compareValue(view->layoutWidth(), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style), op); + + return view->layoutWidth() != 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) +{ + return colorMediaFeatureEval(value, style, frame, MinPrefix); +} + +static bool max_colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return colorMediaFeatureEval(value, style, frame, MaxPrefix); +} + +static bool min_monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return monochromeMediaFeatureEval(value, style, frame, MinPrefix); +} + +static bool max_monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return monochromeMediaFeatureEval(value, style, frame, MaxPrefix); +} + +static bool min_device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return device_aspect_ratioMediaFeatureEval(value, style, frame, MinPrefix); +} + +static bool max_device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return device_aspect_ratioMediaFeatureEval(value, style, frame, MaxPrefix); +} + +static bool min_device_pixel_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return device_pixel_ratioMediaFeatureEval(value, style, frame, MinPrefix); +} + +static bool max_device_pixel_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return device_pixel_ratioMediaFeatureEval(value, style, frame, MaxPrefix); +} + +static bool min_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return heightMediaFeatureEval(value, style, frame, MinPrefix); +} + +static bool max_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return heightMediaFeatureEval(value, style, frame, MaxPrefix); +} + +static bool min_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return widthMediaFeatureEval(value, style, frame, MinPrefix); +} + +static bool max_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return widthMediaFeatureEval(value, style, frame, MaxPrefix); +} + +static bool min_device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return device_heightMediaFeatureEval(value, style, frame, MinPrefix); +} + +static bool max_device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return device_heightMediaFeatureEval(value, style, frame, MaxPrefix); +} + +static bool min_device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return device_widthMediaFeatureEval(value, style, frame, MinPrefix); +} + +static bool max_device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) +{ + return device_widthMediaFeatureEval(value, style, frame, MaxPrefix); +} + +static bool animationMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op) +{ + if (value) { + float number; + return numberValue(value, number) && compareValue(1, static_cast<int>(number), op); + } + return true; +} + +static bool transitionMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op) +{ + if (value) { + float number; + return numberValue(value, number) && compareValue(1, static_cast<int>(number), op); + } + return true; +} + +static bool transform_2dMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op) +{ + if (value) { + float number; + return numberValue(value, number) && compareValue(1, static_cast<int>(number), op); + } + return true; +} + +static bool transform_3dMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op) +{ + if (value) { + float number; + return numberValue(value, number) && compareValue(0, static_cast<int>(number), op); + } + return false; +} + +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/src/3rdparty/webkit/WebCore/css/MediaQueryEvaluator.h b/src/3rdparty/webkit/WebCore/css/MediaQueryEvaluator.h new file mode 100644 index 0000000..5ae8fec --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/MediaQueryExp.cpp b/src/3rdparty/webkit/WebCore/css/MediaQueryExp.cpp new file mode 100644 index 0000000..7ba6d84 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/MediaQueryExp.cpp @@ -0,0 +1,83 @@ +/* + * 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, CSSParserValueList* valueList) + : m_mediaFeature(mediaFeature) + , m_value(0) +{ + if (valueList) { + if (valueList->size() == 1) { + CSSParserValue* value = valueList->current(); + + if (value->id != 0) + m_value = CSSPrimitiveValue::createIdentifier(value->id); + else if (value->unit == CSSPrimitiveValue::CSS_STRING) + m_value = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit); + else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && + value->unit <= CSSPrimitiveValue::CSS_KHZ) + m_value = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit); + + valueList->next(); + } else if (valueList->size() > 1) { + // create list of values + // currently accepts only <integer>/<integer> + + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + CSSParserValue* value = 0; + bool isValid = true; + + while ((value = valueList->current()) && isValid) { + if (value->unit == CSSParserValue::Operator && value->iValue == '/') + list->append(CSSPrimitiveValue::create("/", CSSPrimitiveValue::CSS_STRING)); + else if (value->unit == CSSPrimitiveValue::CSS_NUMBER) + list->append(CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER)); + else + isValid = false; + + value = valueList->next(); + } + + if (isValid) + m_value = list.release(); + } + } +} + +MediaQueryExp::~MediaQueryExp() +{ +} + +} // namespace diff --git a/src/3rdparty/webkit/WebCore/css/MediaQueryExp.h b/src/3rdparty/webkit/WebCore/css/MediaQueryExp.h new file mode 100644 index 0000000..daae232 --- /dev/null +++ b/src/3rdparty/webkit/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 CSSParserValueList; + +class MediaQueryExp +{ +public: + MediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* 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/src/3rdparty/webkit/WebCore/css/Pair.h b/src/3rdparty/webkit/WebCore/css/Pair.h new file mode 100644 index 0000000..a2b127e --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/Pair.h @@ -0,0 +1,65 @@ +/* + * 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: + static PassRefPtr<Pair> create() + { + return adoptRef(new Pair); + } + static PassRefPtr<Pair> create(PassRefPtr<CSSPrimitiveValue> first, PassRefPtr<CSSPrimitiveValue> second) + { + return adoptRef(new Pair(first, 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; } + +private: + Pair() : m_first(0), m_second(0) { } + Pair(PassRefPtr<CSSPrimitiveValue> first, PassRefPtr<CSSPrimitiveValue> second) + : m_first(first), m_second(second) { } + + RefPtr<CSSPrimitiveValue> m_first; + RefPtr<CSSPrimitiveValue> m_second; +}; + +} // namespace + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/RGBColor.idl b/src/3rdparty/webkit/WebCore/css/RGBColor.idl new file mode 100644 index 0000000..cb14319 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/RGBColor.idl @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2006, 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 [ + ObjCCustomImplementation, + GenerateConstructor, + PODType=RGBA32, + 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/src/3rdparty/webkit/WebCore/css/Rect.h b/src/3rdparty/webkit/WebCore/css/Rect.h new file mode 100644 index 0000000..ca6dd25 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/Rect.h @@ -0,0 +1,62 @@ +/* + * Copyright (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. + */ + +#ifndef Rect_h +#define Rect_h + +#include "CSSPrimitiveValue.h" +#include <wtf/RefPtr.h> + +namespace WebCore { + + class RectBase { + public: + 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; } + + protected: + RectBase() { } + ~RectBase() { } + + private: + RefPtr<CSSPrimitiveValue> m_top; + RefPtr<CSSPrimitiveValue> m_right; + RefPtr<CSSPrimitiveValue> m_bottom; + RefPtr<CSSPrimitiveValue> m_left; + }; + + class Rect : public RectBase, public RefCounted<Rect> { + public: + static PassRefPtr<Rect> create() { return adoptRef(new Rect); } + + private: + Rect() { } + }; + +} // namespace WebCore + +#endif // Rect_h diff --git a/src/3rdparty/webkit/WebCore/css/Rect.idl b/src/3rdparty/webkit/WebCore/css/Rect.idl new file mode 100644 index 0000000..3c31dc6 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/SVGCSSComputedStyleDeclaration.cpp b/src/3rdparty/webkit/WebCore/css/SVGCSSComputedStyleDeclaration.cpp new file mode 100644 index 0000000..1375fc2 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/SVGCSSComputedStyleDeclaration.cpp @@ -0,0 +1,188 @@ +/* + 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 PassRefPtr<CSSPrimitiveValue> glyphOrientationToCSSPrimitiveValue(EGlyphOrientation orientation) +{ + switch (orientation) { + case GO_0DEG: + return CSSPrimitiveValue::create(0.0f, CSSPrimitiveValue::CSS_DEG); + case GO_90DEG: + return CSSPrimitiveValue::create(90.0f, CSSPrimitiveValue::CSS_DEG); + case GO_180DEG: + return CSSPrimitiveValue::create(180.0f, CSSPrimitiveValue::CSS_DEG); + case GO_270DEG: + return CSSPrimitiveValue::create(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 CSSPropertyClipRule: + return CSSPrimitiveValue::create(svgStyle->clipRule()); + case CSSPropertyFloodOpacity: + return CSSPrimitiveValue::create(svgStyle->floodOpacity(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyStopOpacity: + return CSSPrimitiveValue::create(svgStyle->stopOpacity(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyColorInterpolation: + return CSSPrimitiveValue::create(svgStyle->colorInterpolation()); + case CSSPropertyColorInterpolationFilters: + return CSSPrimitiveValue::create(svgStyle->colorInterpolationFilters()); + case CSSPropertyFillOpacity: + return CSSPrimitiveValue::create(svgStyle->fillOpacity(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyFillRule: + return CSSPrimitiveValue::create(svgStyle->fillRule()); + case CSSPropertyColorRendering: + return CSSPrimitiveValue::create(svgStyle->colorRendering()); + case CSSPropertyImageRendering: + return CSSPrimitiveValue::create(svgStyle->imageRendering()); + case CSSPropertyShapeRendering: + return CSSPrimitiveValue::create(svgStyle->shapeRendering()); + case CSSPropertyStrokeLinecap: + return CSSPrimitiveValue::create(svgStyle->capStyle()); + case CSSPropertyStrokeLinejoin: + return CSSPrimitiveValue::create(svgStyle->joinStyle()); + case CSSPropertyStrokeMiterlimit: + return CSSPrimitiveValue::create(svgStyle->strokeMiterLimit(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyStrokeOpacity: + return CSSPrimitiveValue::create(svgStyle->strokeOpacity(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyTextRendering: + return CSSPrimitiveValue::create(svgStyle->textRendering()); + case CSSPropertyAlignmentBaseline: + return CSSPrimitiveValue::create(svgStyle->alignmentBaseline()); + case CSSPropertyDominantBaseline: + return CSSPrimitiveValue::create(svgStyle->dominantBaseline()); + case CSSPropertyTextAnchor: + return CSSPrimitiveValue::create(svgStyle->textAnchor()); + case CSSPropertyWritingMode: + return CSSPrimitiveValue::create(svgStyle->writingMode()); + case CSSPropertyClipPath: + if (!svgStyle->clipPath().isEmpty()) + return CSSPrimitiveValue::create(svgStyle->clipPath(), CSSPrimitiveValue::CSS_URI); + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + case CSSPropertyMask: + if (!svgStyle->maskElement().isEmpty()) + return CSSPrimitiveValue::create(svgStyle->maskElement(), CSSPrimitiveValue::CSS_URI); + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + case CSSPropertyFilter: + if (!svgStyle->filter().isEmpty()) + return CSSPrimitiveValue::create(svgStyle->filter(), CSSPrimitiveValue::CSS_URI); + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + case CSSPropertyFloodColor: + return CSSPrimitiveValue::createColor(svgStyle->floodColor().rgb()); + case CSSPropertyLightingColor: + return CSSPrimitiveValue::createColor(svgStyle->lightingColor().rgb()); + case CSSPropertyStopColor: + return CSSPrimitiveValue::createColor(svgStyle->stopColor().rgb()); + case CSSPropertyFill: + return svgStyle->fillPaint(); + case CSSPropertyKerning: + return svgStyle->kerning(); + case CSSPropertyMarkerEnd: + if (!svgStyle->endMarker().isEmpty()) + return CSSPrimitiveValue::create(svgStyle->endMarker(), CSSPrimitiveValue::CSS_URI); + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + case CSSPropertyMarkerMid: + if (!svgStyle->midMarker().isEmpty()) + return CSSPrimitiveValue::create(svgStyle->midMarker(), CSSPrimitiveValue::CSS_URI); + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + case CSSPropertyMarkerStart: + if (!svgStyle->startMarker().isEmpty()) + return CSSPrimitiveValue::create(svgStyle->startMarker(), CSSPrimitiveValue::CSS_URI); + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + case CSSPropertyStroke: + return svgStyle->strokePaint(); + case CSSPropertyStrokeDasharray: + return svgStyle->strokeDashArray(); + case CSSPropertyStrokeDashoffset: + return svgStyle->strokeDashOffset(); + case CSSPropertyStrokeWidth: + return svgStyle->strokeWidth(); + case CSSPropertyBaselineShift: { + switch (svgStyle->baselineShift()) { + case BS_BASELINE: + return CSSPrimitiveValue::createIdentifier(CSSValueBaseline); + case BS_SUPER: + return CSSPrimitiveValue::createIdentifier(CSSValueSuper); + case BS_SUB: + return CSSPrimitiveValue::createIdentifier(CSSValueSub); + case BS_LENGTH: + return svgStyle->baselineShiftValue(); + } + } + case CSSPropertyGlyphOrientationHorizontal: + return glyphOrientationToCSSPrimitiveValue(svgStyle->glyphOrientationHorizontal()); + case CSSPropertyGlyphOrientationVertical: { + if (RefPtr<CSSPrimitiveValue> value = glyphOrientationToCSSPrimitiveValue(svgStyle->glyphOrientationVertical())) + return value.release(); + + if (svgStyle->glyphOrientationVertical() == GO_AUTO) + return CSSPrimitiveValue::createIdentifier(CSSValueAuto); + + return 0; + } + case CSSPropertyMarker: + case CSSPropertyEnableBackground: + case CSSPropertyColorProfile: + // 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/src/3rdparty/webkit/WebCore/css/SVGCSSParser.cpp b/src/3rdparty/webkit/WebCore/css/SVGCSSParser.cpp new file mode 100644 index 0000000..a6d7fbc --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/SVGCSSParser.cpp @@ -0,0 +1,359 @@ +/* + Copyright (C) 2008 Eric Seidel <eric@webkit.org> + 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 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) +{ + CSSParserValue* value = m_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 CSSPropertyAlignmentBaseline: + // auto | baseline | before-edge | text-before-edge | middle | + // central | after-edge | text-after-edge | ideographic | alphabetic | + // hanging | mathematical | inherit + if (id == CSSValueAuto || id == CSSValueBaseline || id == CSSValueMiddle || + (id >= CSSValueBeforeEdge && id <= CSSValueMathematical)) + valid_primitive = true; + break; + + case CSSPropertyBaselineShift: + // baseline | super | sub | <percentage> | <length> | inherit + if (id == CSSValueBaseline || id == CSSValueSub || + id >= CSSValueSuper) + valid_primitive = true; + else + valid_primitive = validUnit(value, FLength|FPercent, false); + break; + + case CSSPropertyDominantBaseline: + // auto | use-script | no-change | reset-size | ideographic | + // alphabetic | hanging | mathematical | central | middle | + // text-after-edge | text-before-edge | inherit + if (id == CSSValueAuto || id == CSSValueMiddle || + (id >= CSSValueUseScript && id <= CSSValueResetSize) || + (id >= CSSValueCentral && id <= CSSValueMathematical)) + valid_primitive = true; + break; + + case CSSPropertyEnableBackground: + // accumulate | new [x] [y] [width] [height] | inherit + if (id == CSSValueAccumulate) // TODO : new + valid_primitive = true; + break; + + case CSSPropertyMarkerStart: + case CSSPropertyMarkerMid: + case CSSPropertyMarkerEnd: + case CSSPropertyMask: + if (id == CSSValueNone) + valid_primitive = true; + else if (value->unit == CSSPrimitiveValue::CSS_URI) { + parsedValue = CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_URI); + if (parsedValue) + m_valueList->next(); + } + break; + + case CSSPropertyClipRule: // nonzero | evenodd | inherit + case CSSPropertyFillRule: + if (id == CSSValueNonzero || id == CSSValueEvenodd) + valid_primitive = true; + break; + + case CSSPropertyStrokeMiterlimit: // <miterlimit> | inherit + valid_primitive = validUnit(value, FNumber|FNonNeg, false); + break; + + case CSSPropertyStrokeLinejoin: // miter | round | bevel | inherit + if (id == CSSValueMiter || id == CSSValueRound || id == CSSValueBevel) + valid_primitive = true; + break; + + case CSSPropertyStrokeLinecap: // butt | round | square | inherit + if (id == CSSValueButt || id == CSSValueRound || id == CSSValueSquare) + valid_primitive = true; + break; + + case CSSPropertyStrokeOpacity: // <opacity-value> | inherit + case CSSPropertyFillOpacity: + case CSSPropertyStopOpacity: + case CSSPropertyFloodOpacity: + valid_primitive = (!id && validUnit(value, FNumber|FPercent, false)); + break; + + case CSSPropertyShapeRendering: + // auto | optimizeSpeed | crispEdges | geometricPrecision | inherit + if (id == CSSValueAuto || id == CSSValueOptimizespeed || + id == CSSValueCrispedges || id == CSSValueGeometricprecision) + valid_primitive = true; + break; + + case CSSPropertyTextRendering: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision | inherit + if (id == CSSValueAuto || id == CSSValueOptimizespeed || id == CSSValueOptimizelegibility || + id == CSSValueGeometricprecision) + valid_primitive = true; + break; + + case CSSPropertyImageRendering: // auto | optimizeSpeed | + case CSSPropertyColorRendering: // optimizeQuality | inherit + if (id == CSSValueAuto || id == CSSValueOptimizespeed || + id == CSSValueOptimizequality) + valid_primitive = true; + break; + + case CSSPropertyColorProfile: // auto | sRGB | <name> | <uri> inherit + if (id == CSSValueAuto || id == CSSValueSrgb) + valid_primitive = true; + break; + + case CSSPropertyColorInterpolation: // auto | sRGB | linearRGB | inherit + case CSSPropertyColorInterpolationFilters: + if (id == CSSValueAuto || id == CSSValueSrgb || id == CSSValueLinearrgb) + 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 CSSPropertyPointerEvents: + // none | visiblePainted | visibleFill | visibleStroke | visible | + // painted | fill | stroke | none | all | inherit + if (id == CSSValueVisible || id == CSSValueNone || id == CSSValueAll || + (id >= CSSValueVisiblepainted && id <= CSSValueStroke)) + valid_primitive = true; + break; + + case CSSPropertyTextAnchor: // start | middle | end | inherit + if (id == CSSValueStart || id == CSSValueMiddle || id == CSSValueEnd) + valid_primitive = true; + break; + + case CSSPropertyGlyphOrientationVertical: // auto | <angle> | inherit + if (id == CSSValueAuto) { + valid_primitive = true; + break; + } + /* fallthrough intentional */ + case CSSPropertyGlyphOrientationHorizontal: // <angle> (restricted to _deg_ per SVG 1.1 spec) | inherit + if (value->unit == CSSPrimitiveValue::CSS_DEG || value->unit == CSSPrimitiveValue::CSS_NUMBER) { + parsedValue = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_DEG); + + if (parsedValue) + m_valueList->next(); + } + break; + + case CSSPropertyFill: // <paint> | inherit + case CSSPropertyStroke: // <paint> | inherit + { + if (id == CSSValueNone) + parsedValue = SVGPaint::create(SVGPaint::SVG_PAINTTYPE_NONE); + else if (id == CSSValueCurrentcolor) + parsedValue = SVGPaint::create(SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR); + else if (value->unit == CSSPrimitiveValue::CSS_URI) { + RGBA32 c = Color::transparent; + if (m_valueList->next() && parseColorFromValue(m_valueList->current(), c, true)) { + parsedValue = SVGPaint::create(value->string, c); + } else + parsedValue = SVGPaint::create(SVGPaint::SVG_PAINTTYPE_URI, value->string); + } else + parsedValue = parseSVGPaint(); + + if (parsedValue) + m_valueList->next(); + } + break; + + case CSSPropertyColor: // <color> | inherit + if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || + (id >= CSSValueAliceblue && id <= CSSValueYellowgreen)) + parsedValue = SVGColor::create(value->string); + else + parsedValue = parseSVGColor(); + + if (parsedValue) + m_valueList->next(); + break; + + case CSSPropertyStopColor: // TODO : icccolor + case CSSPropertyFloodColor: + case CSSPropertyLightingColor: + if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || + (id >= CSSValueAliceblue && id <= CSSValueYellowgreen)) + parsedValue = SVGColor::create(value->string); + else if (id == CSSValueCurrentcolor) + parsedValue = SVGColor::createCurrentColor(); + else // TODO : svgcolor (iccColor) + parsedValue = parseSVGColor(); + + if (parsedValue) + m_valueList->next(); + + break; + + case CSSPropertyWritingMode: + // lr-tb | rl_tb | tb-rl | lr | rl | tb | inherit + if (id >= CSSValueLrTb && id <= CSSValueTb) + valid_primitive = true; + break; + + case CSSPropertyStrokeWidth: // <length> | inherit + case CSSPropertyStrokeDashoffset: + valid_primitive = validUnit(value, FLength | FPercent, false); + break; + case CSSPropertyStrokeDasharray: // none | <dasharray> | inherit + if (id == CSSValueNone) + valid_primitive = true; + else + parsedValue = parseSVGStrokeDasharray(); + + break; + + case CSSPropertyKerning: // auto | normal | <length> | inherit + if (id == CSSValueAuto || id == CSSValueNormal) + valid_primitive = true; + else + valid_primitive = validUnit(value, FLength, false); + break; + + case CSSPropertyClipPath: // <uri> | none | inherit + case CSSPropertyFilter: + if (id == CSSValueNone) + valid_primitive = true; + else if (value->unit == CSSPrimitiveValue::CSS_URI) { + parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit); + if (parsedValue) + m_valueList->next(); + } + break; + + /* shorthand properties */ + case CSSPropertyMarker: + { + ShorthandScope scope(this, propId); + m_implicitShorthand = true; + if (!parseValue(CSSPropertyMarkerStart, important)) + return false; + if (m_valueList->current()) { + rollbackLastProperties(1); + return false; + } + CSSValue* value = m_parsedProperties[m_numParsedProperties - 1]->value(); + addProperty(CSSPropertyMarkerMid, value, important); + addProperty(CSSPropertyMarkerEnd, 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 = CSSPrimitiveValue::createIdentifier(id); + else if (value->unit == CSSPrimitiveValue::CSS_STRING) + parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit); + else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ) + parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit); + else if (value->unit >= CSSParserValue::Q_EMS) + parsedValue = CSSQuirkPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_EMS); + m_valueList->next(); + } + if (!parsedValue || (m_valueList->current() && !inShorthand())) + return false; + + addProperty(propId, parsedValue.release(), important); + return true; +} + +PassRefPtr<CSSValue> CSSParser::parseSVGStrokeDasharray() +{ + RefPtr<CSSValueList> ret = CSSValueList::createCommaSeparated(); + CSSParserValue* value = m_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(CSSPrimitiveValue::createIdentifier(value->id)); + else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ) + ret->append(CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit)); + value = m_valueList->next(); + if (value && value->unit == CSSParserValue::Operator && value->iValue == ',') + value = m_valueList->next(); + } + if (!valid_primitive) + return 0; + return ret.release(); +} + +PassRefPtr<CSSValue> CSSParser::parseSVGPaint() +{ + RGBA32 c = Color::transparent; + if (!parseColorFromValue(m_valueList->current(), c, true)) + return SVGPaint::create(); + return SVGPaint::create(Color(c)); +} + +PassRefPtr<CSSValue> CSSParser::parseSVGColor() +{ + RGBA32 c = Color::transparent; + if (!parseColorFromValue(m_valueList->current(), c, true)) + return 0; + return SVGColor::create(Color(c)); +} + +} + +#endif // ENABLE(SVG) + +// vim:ts=4:noet diff --git a/src/3rdparty/webkit/WebCore/css/SVGCSSPropertyNames.in b/src/3rdparty/webkit/WebCore/css/SVGCSSPropertyNames.in new file mode 100644 index 0000000..965fbbf --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/SVGCSSStyleSelector.cpp b/src/3rdparty/webkit/WebCore/css/SVGCSSStyleSelector.cpp new file mode 100644 index 0000000..34d981c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/SVGCSSStyleSelector.cpp @@ -0,0 +1,608 @@ +/* + Copyright (C) 2005 Apple Computer, Inc. + Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> + 2004, 2005, 2008 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 "Document.h" +#include "SVGColor.h" +#include "SVGNames.h" +#include "SVGPaint.h" +#include "SVGRenderStyle.h" +#include "SVGRenderStyleDefs.h" +#include "SVGStyledElement.h" +#include "SVGURIReference.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 CSSPropertyAlignmentBaseline: + { + HANDLE_INHERIT_AND_INITIAL(alignmentBaseline, AlignmentBaseline) + if (!primitiveValue) + break; + + svgstyle->setAlignmentBaseline(*primitiveValue); + break; + } + case CSSPropertyBaselineShift: + { + HANDLE_INHERIT_AND_INITIAL(baselineShift, BaselineShift); + if (!primitiveValue) + break; + + if (primitiveValue->getIdent()) { + switch (primitiveValue->getIdent()) { + case CSSValueBaseline: + svgstyle->setBaselineShift(BS_BASELINE); + break; + case CSSValueSub: + svgstyle->setBaselineShift(BS_SUB); + break; + case CSSValueSuper: + svgstyle->setBaselineShift(BS_SUPER); + break; + default: + break; + } + } else { + svgstyle->setBaselineShift(BS_LENGTH); + svgstyle->setBaselineShiftValue(primitiveValue); + } + + break; + } + case CSSPropertyKerning: + { + if (isInherit) { + HANDLE_INHERIT_COND(CSSPropertyKerning, kerning, Kerning) + return; + } + else if (isInitial) { + HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyKerning, Kerning, Kerning) + return; + } + + svgstyle->setKerning(primitiveValue); + break; + } + case CSSPropertyDominantBaseline: + { + HANDLE_INHERIT_AND_INITIAL(dominantBaseline, DominantBaseline) + if (primitiveValue) + svgstyle->setDominantBaseline(*primitiveValue); + break; + } + case CSSPropertyColorInterpolation: + { + HANDLE_INHERIT_AND_INITIAL(colorInterpolation, ColorInterpolation) + if (primitiveValue) + svgstyle->setColorInterpolation(*primitiveValue); + break; + } + case CSSPropertyColorInterpolationFilters: + { + HANDLE_INHERIT_AND_INITIAL(colorInterpolationFilters, ColorInterpolationFilters) + if (primitiveValue) + svgstyle->setColorInterpolationFilters(*primitiveValue); + break; + } + case CSSPropertyColorRendering: + { + HANDLE_INHERIT_AND_INITIAL(colorRendering, ColorRendering) + if (primitiveValue) + svgstyle->setColorRendering(*primitiveValue); + break; + } + case CSSPropertyClipRule: + { + HANDLE_INHERIT_AND_INITIAL(clipRule, ClipRule) + if (primitiveValue) + svgstyle->setClipRule(*primitiveValue); + break; + } + case CSSPropertyFillRule: + { + HANDLE_INHERIT_AND_INITIAL(fillRule, FillRule) + if (primitiveValue) + svgstyle->setFillRule(*primitiveValue); + break; + } + case CSSPropertyStrokeLinejoin: + { + HANDLE_INHERIT_AND_INITIAL(joinStyle, JoinStyle) + if (primitiveValue) + svgstyle->setJoinStyle(*primitiveValue); + break; + } + case CSSPropertyImageRendering: + { + HANDLE_INHERIT_AND_INITIAL(imageRendering, ImageRendering) + if (primitiveValue) + svgstyle->setImageRendering(*primitiveValue); + break; + } + case CSSPropertyShapeRendering: + { + HANDLE_INHERIT_AND_INITIAL(shapeRendering, ShapeRendering) + if (primitiveValue) + svgstyle->setShapeRendering(*primitiveValue); + break; + } + case CSSPropertyTextRendering: + { + HANDLE_INHERIT_AND_INITIAL(textRendering, TextRendering) + if (primitiveValue) + svgstyle->setTextRendering(*primitiveValue); + break; + } + // end of ident only properties + case CSSPropertyFill: + { + HANDLE_INHERIT_AND_INITIAL(fillPaint, FillPaint) + if (!primitiveValue && value) { + SVGPaint *paint = static_cast<SVGPaint*>(value); + if (paint) + svgstyle->setFillPaint(paint); + } + + break; + } + case CSSPropertyStroke: + { + HANDLE_INHERIT_AND_INITIAL(strokePaint, StrokePaint) + if (!primitiveValue && value) { + SVGPaint *paint = static_cast<SVGPaint*>(value); + if (paint) + svgstyle->setStrokePaint(paint); + } + + break; + } + case CSSPropertyStrokeWidth: + { + HANDLE_INHERIT_AND_INITIAL(strokeWidth, StrokeWidth) + if (!primitiveValue) + return; + + svgstyle->setStrokeWidth(primitiveValue); + break; + } + case CSSPropertyStrokeDasharray: + { + HANDLE_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray) + if (!primitiveValue && value) { + CSSValueList* dashes = static_cast<CSSValueList*>(value); + if (dashes) + svgstyle->setStrokeDashArray(dashes); + } + + break; + } + case CSSPropertyStrokeDashoffset: + { + HANDLE_INHERIT_AND_INITIAL(strokeDashOffset, StrokeDashOffset) + if (!primitiveValue) + return; + + svgstyle->setStrokeDashOffset(primitiveValue); + break; + } + case CSSPropertyFillOpacity: + { + 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 CSSPropertyStrokeOpacity: + { + 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 CSSPropertyStopOpacity: + { + 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 CSSPropertyMarkerStart: + { + 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(SVGURIReference::getTarget(s)); + break; + } + case CSSPropertyMarkerMid: + { + 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(SVGURIReference::getTarget(s)); + break; + } + case CSSPropertyMarkerEnd: + { + 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(SVGURIReference::getTarget(s)); + break; + } + case CSSPropertyStrokeLinecap: + { + HANDLE_INHERIT_AND_INITIAL(capStyle, CapStyle) + if (primitiveValue) + svgstyle->setCapStyle(*primitiveValue); + break; + } + case CSSPropertyStrokeMiterlimit: + { + 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 CSSPropertyFilter: + { + 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(SVGURIReference::getTarget(s)); + break; + } + case CSSPropertyMask: + { + 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(SVGURIReference::getTarget(s)); + break; + } + case CSSPropertyClipPath: + { + 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(SVGURIReference::getTarget(s)); + break; + } + case CSSPropertyTextAnchor: + { + HANDLE_INHERIT_AND_INITIAL(textAnchor, TextAnchor) + if (primitiveValue) + svgstyle->setTextAnchor(*primitiveValue); + break; + } + case CSSPropertyWritingMode: + { + HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode) + if (primitiveValue) + svgstyle->setWritingMode(*primitiveValue); + break; + } + case CSSPropertyStopColor: + { + 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 CSSPropertyLightingColor: + { + 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 CSSPropertyFloodOpacity: + { + 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 CSSPropertyFloodColor: + { + 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 CSSPropertyGlyphOrientationHorizontal: + { + 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 CSSPropertyGlyphOrientationVertical: + { + 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() == CSSValueAuto) + svgstyle->setGlyphOrientationVertical(GO_AUTO); + + break; + } + case CSSPropertyEnableBackground: + // 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/src/3rdparty/webkit/WebCore/css/SVGCSSValueKeywords.in b/src/3rdparty/webkit/WebCore/css/SVGCSSValueKeywords.in new file mode 100644 index 0000000..c866a17 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/SVGCSSValueKeywords.in @@ -0,0 +1,287 @@ +# 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_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/src/3rdparty/webkit/WebCore/css/ShadowValue.cpp b/src/3rdparty/webkit/WebCore/css/ShadowValue.cpp new file mode 100644 index 0000000..5794405 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/ShadowValue.h b/src/3rdparty/webkit/WebCore/css/ShadowValue.h new file mode 100644 index 0000000..179531e --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/ShadowValue.h @@ -0,0 +1,59 @@ +/* + * (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 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: + static PassRefPtr<ShadowValue> create(PassRefPtr<CSSPrimitiveValue> x, + PassRefPtr<CSSPrimitiveValue> y, + PassRefPtr<CSSPrimitiveValue> blur, + PassRefPtr<CSSPrimitiveValue> color) + { + return adoptRef(new ShadowValue(x, y, blur, color)); + } + + virtual String cssText() const; + + RefPtr<CSSPrimitiveValue> x; + RefPtr<CSSPrimitiveValue> y; + RefPtr<CSSPrimitiveValue> blur; + RefPtr<CSSPrimitiveValue> color; + +private: + ShadowValue(PassRefPtr<CSSPrimitiveValue> x, + PassRefPtr<CSSPrimitiveValue> y, + PassRefPtr<CSSPrimitiveValue> blur, + PassRefPtr<CSSPrimitiveValue> color); +}; + +} // namespace + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/StyleBase.cpp b/src/3rdparty/webkit/WebCore/css/StyleBase.cpp new file mode 100644 index 0000000..17b51bb --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/StyleBase.cpp @@ -0,0 +1,68 @@ +/* + * 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 { + +String StyleBase::cssText() const +{ + return ""; +} + +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/src/3rdparty/webkit/WebCore/css/StyleBase.h b/src/3rdparty/webkit/WebCore/css/StyleBase.h new file mode 100644 index 0000000..a2f1002 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/StyleBase.h @@ -0,0 +1,86 @@ +/* + * 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; + + // Base class for most CSS DOM objects. + + // FIXME: We don't need these to all share one base class. + // Refactor so they don't any more. + + class StyleBase : public RefCounted<StyleBase> { + public: + 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 isCSSStyleSheet() const { return false; } + virtual bool isCharsetRule() { return false; } + virtual bool isFontFaceRule() { return false; } + virtual bool isImportRule() { return false; } + virtual bool isKeyframeRule() { return false; } + virtual bool isKeyframesRule() { return false; } + virtual bool isMediaRule() { return false; } + virtual bool isVariablesRule() { return false; } + + virtual bool isRule() { return false; } + virtual bool isStyleRule() { return false; } + virtual bool isStyleSheet() const { return false; } + virtual bool isXSLStyleSheet() const { return false; } + + virtual bool isMutableStyleDeclaration() const { return false; } + + virtual String cssText() const; + + virtual void checkLoaded(); + + bool useStrictParsing() const { return !m_parent || m_parent->useStrictParsing(); } + + virtual void insertedIntoParent() { } + + StyleSheet* stylesheet(); + + protected: + StyleBase(StyleBase* parent) + : m_parent(parent) + { + } + + private: + StyleBase* m_parent; + }; +} + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/StyleList.cpp b/src/3rdparty/webkit/WebCore/css/StyleList.cpp new file mode 100644 index 0000000..2510470 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/StyleList.cpp @@ -0,0 +1,55 @@ +/* + * 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 "StyleList.h" + +#include <wtf/PassRefPtr.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/src/3rdparty/webkit/WebCore/css/StyleList.h b/src/3rdparty/webkit/WebCore/css/StyleList.h new file mode 100644 index 0000000..ceca28a --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/StyleList.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) + * 1999 Waldo Bastian (bastian@kde.org) + * 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 StyleList_h +#define StyleList_h + +#include "StyleBase.h" +#include <wtf/Forward.h> +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + + // a style class which has a list of children (StyleSheets for example) + class StyleList : public StyleBase { + public: + 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: + StyleList(StyleBase* parent) : StyleBase(parent) { } + + Vector<RefPtr<StyleBase> > m_children; + }; +} + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/StyleSheet.cpp b/src/3rdparty/webkit/WebCore/css/StyleSheet.cpp new file mode 100644 index 0000000..16e6278 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/StyleSheet.cpp @@ -0,0 +1,84 @@ +/** + * 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(PassRefPtr<MediaList> media) +{ + if (m_media) + m_media->setParent(0); + + m_media = media; + m_media->setParent(this); +} + +KURL StyleSheet::completeURL(const String& url) const +{ + // Always return a null URL when passed a null string. + // FIXME: Should we change the KURL constructor to have this behavior? + // See also Document::completeURL(const String&) + if (url.isNull()) + return KURL(); + return KURL(baseURL(), url); +} + +} diff --git a/src/3rdparty/webkit/WebCore/css/StyleSheet.h b/src/3rdparty/webkit/WebCore/css/StyleSheet.h new file mode 100644 index 0000000..016d50a --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/StyleSheet.h @@ -0,0 +1,77 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * 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 StyleSheet_h +#define StyleSheet_h + +#include "KURLHash.h" +#include "PlatformString.h" +#include "StyleList.h" +#include <wtf/ListHashSet.h> + +namespace WebCore { + +class CachedCSSStyleSheet; +class MediaList; +class Node; + +class StyleSheet : public StyleList { +public: + virtual ~StyleSheet(); + + bool disabled() const { return m_disabled; } + void setDisabled(bool disabled) { m_disabled = disabled; styleSheetChanged(); } + + Node* ownerNode() const { return m_parentNode; } + StyleSheet *parentStyleSheet() const; + const String& href() const { return m_strHref; } + void setHref(const String& href) { m_strHref = href; } + const String& title() const { return m_strTitle; } + void setTitle(const String& s) { m_strTitle = s; } + MediaList* media() const { return m_media.get(); } + void setMedia(PassRefPtr<MediaList>); + + virtual String type() const = 0; + virtual bool isLoading() = 0; + virtual void styleSheetChanged() { } + + virtual KURL completeURL(const String& url) const; + virtual void addSubresourceStyleURLs(ListHashSet<KURL>&) { } + + virtual bool parseString(const String&, bool strict = true) = 0; + +protected: + StyleSheet(Node* ownerNode, const String& href); + StyleSheet(StyleSheet* parentSheet, const String& href); + StyleSheet(StyleBase* owner, const String& href); + +private: + virtual bool isStyleSheet() const { return true; } + + Node* m_parentNode; + String m_strHref; + String m_strTitle; + RefPtr<MediaList> m_media; + bool m_disabled; +}; + +} // namespace + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/StyleSheet.idl b/src/3rdparty/webkit/WebCore/css/StyleSheet.idl new file mode 100644 index 0000000..81bbe34 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/StyleSheet.idl @@ -0,0 +1,40 @@ +/* + * 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 stylesheets { + + // Introduced in DOM Level 2: + interface [ + CustomMarkFunction, + 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/src/3rdparty/webkit/WebCore/css/StyleSheetList.cpp b/src/3rdparty/webkit/WebCore/css/StyleSheetList.cpp new file mode 100644 index 0000000..b9df810 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/StyleSheetList.cpp @@ -0,0 +1,77 @@ +/** + * 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) + : m_doc(doc) +{ +} + +StyleSheetList::~StyleSheetList() +{ +} + +void StyleSheetList::documentDestroyed() +{ + m_doc = 0; +} + +unsigned StyleSheetList::length() const +{ + return m_sheets.size(); +} + +StyleSheet* StyleSheetList::item(unsigned index) +{ + return index < length() ? m_sheets[index].get() : 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/src/3rdparty/webkit/WebCore/css/StyleSheetList.h b/src/3rdparty/webkit/WebCore/css/StyleSheetList.h new file mode 100644 index 0000000..ecdc1cf --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/StyleSheetList.h @@ -0,0 +1,63 @@ +/* + * (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 <wtf/PassRefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class Document; +class HTMLStyleElement; +class StyleSheet; +class String; + +typedef Vector<RefPtr<StyleSheet> > StyleSheetVector; + +class StyleSheetList : public RefCounted<StyleSheetList> { +public: + static PassRefPtr<StyleSheetList> create(Document* doc) { return adoptRef(new StyleSheetList(doc)); } + ~StyleSheetList(); + + void documentDestroyed(); + + unsigned length() const; + StyleSheet* item(unsigned index); + + HTMLStyleElement* getNamedItem(const String&) const; + + void swap(StyleSheetVector& sheets) + { + m_sheets.swap(sheets); + } + +private: + StyleSheetList(Document*); + + Document* m_doc; + StyleSheetVector m_sheets; +}; + +} // namespace WebCore + +#endif // StyleSheetList_h diff --git a/src/3rdparty/webkit/WebCore/css/StyleSheetList.idl b/src/3rdparty/webkit/WebCore/css/StyleSheetList.idl new file mode 100644 index 0000000..2abd22f --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframeRule.cpp b/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframeRule.cpp new file mode 100644 index 0000000..8f3d676 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframeRule.cpp @@ -0,0 +1,98 @@ +/* + * 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 "WebKitCSSKeyframeRule.h" + +#include "CSSMutableStyleDeclaration.h" + +namespace WebCore { + +WebKitCSSKeyframeRule::WebKitCSSKeyframeRule(CSSStyleSheet* parent) + : CSSRule(parent) +{ +} + +WebKitCSSKeyframeRule::~WebKitCSSKeyframeRule() +{ + if (m_style) + m_style->setParent(0); +} + +String WebKitCSSKeyframeRule::cssText() const +{ + String result = m_key; + + result += " { "; + result += m_style->cssText(); + result += "}"; + + return result; +} + +bool WebKitCSSKeyframeRule::parseString(const String& /*string*/, bool /*strict*/) +{ + // FIXME + return false; +} + +void WebKitCSSKeyframeRule::setDeclaration(PassRefPtr<CSSMutableStyleDeclaration> style) +{ + m_style = style; + m_style->setParent(parent()); +} + +/* static */ +void WebKitCSSKeyframeRule::parseKeyString(const String& s, Vector<float>& keys) +{ + keys.clear(); + Vector<String> strings; + s.split(',', strings); + + for (size_t i = 0; i < strings.size(); ++i) { + float key = -1; + String cur = strings[i].stripWhiteSpace(); + + // For now the syntax MUST be 'xxx%' or 'from' or 'to', where xxx is a legal floating point number + if (cur == "from") + key = 0; + else if (cur == "to") + key = 1; + else if (cur.endsWith("%")) { + float k = cur.substring(0, cur.length() - 1).toFloat(); + if (k >= 0 && k <= 100) + key = k/100; + } + + if (key < 0) { + keys.clear(); + return; + } + else + keys.append(key); + } +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframeRule.h b/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframeRule.h new file mode 100644 index 0000000..e41510a --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframeRule.h @@ -0,0 +1,85 @@ +/* + * 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 WebKitCSSKeyframeRule_h +#define WebKitCSSKeyframeRule_h + +#include "CSSRule.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class CSSMutableStyleDeclaration; + +typedef int ExceptionCode; + +class WebKitCSSKeyframeRule : public CSSRule { +public: + static PassRefPtr<WebKitCSSKeyframeRule> create() + { + return adoptRef(new WebKitCSSKeyframeRule(0)); + } + static PassRefPtr<WebKitCSSKeyframeRule> create(CSSStyleSheet* parent) + { + return adoptRef(new WebKitCSSKeyframeRule(parent)); + } + + virtual ~WebKitCSSKeyframeRule(); + + virtual bool isKeyframeRule() { return true; } + + // Inherited from CSSRule + virtual unsigned short type() const { return WEBKIT_KEYFRAME_RULE; } + + String keyText() const { return m_key; } + void setKeyText(const String& s) { m_key = s; } + + void getKeys(Vector<float>& keys) const { parseKeyString(m_key, keys); } + + CSSMutableStyleDeclaration* style() const { return m_style.get(); } + + virtual String cssText() const; + + // Not part of the CSSOM + virtual bool parseString(const String&, bool = false); + + void setDeclaration(PassRefPtr<CSSMutableStyleDeclaration>); + + CSSMutableStyleDeclaration* declaration() { return m_style.get(); } + const CSSMutableStyleDeclaration* declaration() const { return m_style.get(); } + +private: + static void parseKeyString(const String& s, Vector<float>& keys); + + WebKitCSSKeyframeRule(CSSStyleSheet* parent); + + RefPtr<CSSMutableStyleDeclaration> m_style; + String m_key; // comma separated list of keys +}; + +} // namespace WebCore + +#endif // WebKitCSSKeyframeRule_h diff --git a/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframeRule.idl b/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframeRule.idl new file mode 100644 index 0000000..a8dd9c3 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframeRule.idl @@ -0,0 +1,43 @@ +/* + * 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module css { + + // Introduced in DOM Level ?: + interface [ + GenerateConstructor, + InterfaceUUID=87b7cde8-5818-4f68-b554-5382e6d9428c, + ImplementationUUID=b000d468-bb7a-4866-8946-5dea8b6a3c13 + ] WebKitCSSKeyframeRule : CSSRule { + + attribute DOMString keyText; + readonly attribute CSSStyleDeclaration style; + + }; + +} diff --git a/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframesRule.cpp b/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframesRule.cpp new file mode 100644 index 0000000..440d7a2 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframesRule.cpp @@ -0,0 +1,138 @@ +/* + * 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 "CSSParser.h" +#include "WebKitCSSKeyframesRule.h" +#include "WebKitCSSKeyframeRule.h" +#include "CSSRuleList.h" +#include "StyleSheet.h" + +namespace WebCore { + +WebKitCSSKeyframesRule::WebKitCSSKeyframesRule(CSSStyleSheet* parent) + : CSSRule(parent) + , m_lstCSSRules(CSSRuleList::create()) +{ +} + +WebKitCSSKeyframesRule::~WebKitCSSKeyframesRule() +{ + int length = m_lstCSSRules->length(); + if (length == 0) + return; + + for (int i = 0; i < length; i++) + m_lstCSSRules->item(i)->setParent(0); +} + +String WebKitCSSKeyframesRule::name() const +{ + return m_name; +} + +void WebKitCSSKeyframesRule::setName(const String& name) +{ + m_name = name; + + // Since the name is used in the keyframe map list in CSSStyleSelector, we need + // to recompute the style sheet to get the updated name. + stylesheet()->styleSheetChanged(); +} + +unsigned WebKitCSSKeyframesRule::length() const +{ + return m_lstCSSRules.get()->length(); +} + +WebKitCSSKeyframeRule* WebKitCSSKeyframesRule::item(unsigned index) +{ + CSSRule* rule = m_lstCSSRules.get()->item(index); + return (rule && rule->isKeyframeRule()) ? static_cast<WebKitCSSKeyframeRule*>(rule) : 0; +} + +const WebKitCSSKeyframeRule* WebKitCSSKeyframesRule::item(unsigned index) const +{ + CSSRule* rule = m_lstCSSRules.get()->item(index); + return (rule && rule->isKeyframeRule()) ? static_cast<const WebKitCSSKeyframeRule*>(rule) : 0; +} + +void WebKitCSSKeyframesRule::append(WebKitCSSKeyframeRule* rule) +{ + m_lstCSSRules.get()->append(rule); +} + +void WebKitCSSKeyframesRule::insertRule(const String& rule) +{ + CSSParser p(useStrictParsing()); + RefPtr<CSSRule> newRule = p.parseKeyframeRule(parentStyleSheet(), rule); + if (newRule.get() && newRule.get()->isKeyframeRule()) + append(static_cast<WebKitCSSKeyframeRule*>(newRule.get())); +} + +void WebKitCSSKeyframesRule::deleteRule(const String& s) +{ + int i = findRuleIndex(s); + if (i >= 0) + m_lstCSSRules.get()->deleteRule(i); +} + +WebKitCSSKeyframeRule* WebKitCSSKeyframesRule::findRule(const String& s) +{ + int i = findRuleIndex(s); + return (i >= 0) ? item(i) : 0; +} + +int WebKitCSSKeyframesRule::findRuleIndex(const String& key) const +{ + for (unsigned i = 0; i < length(); ++i) { + if (item(i)->keyText() == key) + return i; + } + + return -1; +} + +String WebKitCSSKeyframesRule::cssText() const +{ + String result = "@-webkit-keyframes "; + result += m_name; + 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/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframesRule.h b/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframesRule.h new file mode 100644 index 0000000..8c76b61 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframesRule.h @@ -0,0 +1,95 @@ +/* + * 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 WebKitCSSKeyframesRule_h +#define WebKitCSSKeyframesRule_h + +#include "CSSRule.h" +#include <wtf/RefPtr.h> +#include "AtomicString.h" + +namespace WebCore { + +class CSSRuleList; +class WebKitCSSKeyframeRule; +class String; + +typedef int ExceptionCode; + +class WebKitCSSKeyframesRule : public CSSRule { +public: + static PassRefPtr<WebKitCSSKeyframesRule> create() + { + return adoptRef(new WebKitCSSKeyframesRule(0)); + } + static PassRefPtr<WebKitCSSKeyframesRule> create(CSSStyleSheet* parent) + { + return adoptRef(new WebKitCSSKeyframesRule(parent)); + } + + ~WebKitCSSKeyframesRule(); + + virtual bool isKeyframesRule() { return true; } + + // Inherited from CSSRule + virtual unsigned short type() const { return WEBKIT_KEYFRAMES_RULE; } + + String name() const; + void setName(const String&); + + // This version of setName does not call styleSheetChanged to avoid + // unnecessary work. It assumes callers will either make that call + // themselves, or know that it will get called later. + void setNameInternal(const String& name) + { + m_name = name; + } + + CSSRuleList* cssRules() { return m_lstCSSRules.get(); } + + void insertRule(const String& rule); + void deleteRule(const String& key); + WebKitCSSKeyframeRule* findRule(const String& key); + + virtual String cssText() const; + + /* not part of the DOM */ + unsigned length() const; + WebKitCSSKeyframeRule* item(unsigned index); + const WebKitCSSKeyframeRule* item(unsigned index) const; + void append(WebKitCSSKeyframeRule* rule); + +private: + WebKitCSSKeyframesRule(CSSStyleSheet* parent); + + int findRuleIndex(const String& key) const; + + RefPtr<CSSRuleList> m_lstCSSRules; + AtomicString m_name; +}; + +} // namespace WebCore + +#endif // WebKitCSSKeyframesRule_h diff --git a/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframesRule.idl b/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframesRule.idl new file mode 100644 index 0000000..2b64be1 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/WebKitCSSKeyframesRule.idl @@ -0,0 +1,47 @@ +/* + * 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module css { + + // Introduced in DOM Level ?: + interface [ + GenerateConstructor, + HasIndexGetter, + InterfaceUUID=49f5644a-5dbb-4e31-ac6b-9446ae3895c9, + ImplementationUUID=a7c78aaa-5883-4ef2-a8bd-f2f1a1fd025a + ] WebKitCSSKeyframesRule : CSSRule { + + attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString name; + readonly attribute CSSRuleList cssRules; + + void insertRule(in DOMString rule); + void deleteRule(in DOMString key); + WebKitCSSKeyframeRule findRule(in DOMString key); + }; + +} diff --git a/src/3rdparty/webkit/WebCore/css/WebKitCSSTransformValue.cpp b/src/3rdparty/webkit/WebCore/css/WebKitCSSTransformValue.cpp new file mode 100644 index 0000000..e6af840 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/WebKitCSSTransformValue.cpp @@ -0,0 +1,92 @@ +/* + * 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 "WebKitCSSTransformValue.h" + +#include "CSSValueList.h" +#include "PlatformString.h" +#include <wtf/PassRefPtr.h> + +namespace WebCore { + +WebKitCSSTransformValue::WebKitCSSTransformValue(TransformOperationType op) + : CSSValueList(false) + , m_type(op) +{ +} + +WebKitCSSTransformValue::~WebKitCSSTransformValue() +{ +} + +String WebKitCSSTransformValue::cssText() const +{ + String result; + switch (m_type) { + case TranslateTransformOperation: + result += "translate("; + break; + case TranslateXTransformOperation: + result += "translateX("; + break; + case TranslateYTransformOperation: + result += "translateY("; + break; + case RotateTransformOperation: + result += "rotate("; + break; + case ScaleTransformOperation: + result += "scale("; + break; + case ScaleXTransformOperation: + result += "scaleX("; + break; + case ScaleYTransformOperation: + result += "scaleY("; + break; + case SkewTransformOperation: + result += "skew("; + break; + case SkewXTransformOperation: + result += "skewX("; + break; + case SkewYTransformOperation: + result += "skewY("; + break; + case MatrixTransformOperation: + result += "matrix("; + break; + default: + break; + } + + result += CSSValueList::cssText(); + + result += ")"; + return result; +} + +} diff --git a/src/3rdparty/webkit/WebCore/css/WebKitCSSTransformValue.h b/src/3rdparty/webkit/WebCore/css/WebKitCSSTransformValue.h new file mode 100644 index 0000000..2bb2631 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/WebKitCSSTransformValue.h @@ -0,0 +1,74 @@ +/* + * 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 WebKitCSSTransformValue_h +#define WebKitCSSTransformValue_h + +#include "CSSValueList.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class WebKitCSSTransformValue : public CSSValueList { +public: + // NOTE: these have to match the values in the IDL + enum TransformOperationType { + UnknownTransformOperation, + TranslateTransformOperation, + TranslateXTransformOperation, + TranslateYTransformOperation, + RotateTransformOperation, + ScaleTransformOperation, + ScaleXTransformOperation, + ScaleYTransformOperation, + SkewTransformOperation, + SkewXTransformOperation, + SkewYTransformOperation, + MatrixTransformOperation + }; + + static PassRefPtr<WebKitCSSTransformValue> create(TransformOperationType type) + { + return adoptRef(new WebKitCSSTransformValue(type)); + } + + virtual ~WebKitCSSTransformValue(); + + virtual String cssText() const; + + TransformOperationType operationType() const { return m_type; } + +private: + WebKitCSSTransformValue(TransformOperationType); + + virtual bool isWebKitCSSTransformValue() const { return true; } + + TransformOperationType m_type; +}; + +} + +#endif diff --git a/src/3rdparty/webkit/WebCore/css/WebKitCSSTransformValue.idl b/src/3rdparty/webkit/WebCore/css/WebKitCSSTransformValue.idl new file mode 100644 index 0000000..39e97a3 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/WebKitCSSTransformValue.idl @@ -0,0 +1,55 @@ +/* + * 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module css { + + interface [ + GenerateConstructor, + HasIndexGetter + InterfaceUUID=303fe632-5dcf-4472-b977-33a5481e1d12, + ImplementationUUID=eb49e5c6-6075-45b8-b5c4-7e775c01e7c4 + ] WebKitCSSTransformValue : CSSValueList { + + // OperationTypes + + const unsigned short CSS_TRANSLATE = 1; + const unsigned short CSS_TRANSLATEX = 2; + const unsigned short CSS_TRANSLATEY = 3; + const unsigned short CSS_ROTATE = 4; + const unsigned short CSS_SCALE = 5; + const unsigned short CSS_SCALEX = 6; + const unsigned short CSS_SCALEY = 7; + const unsigned short CSS_SKEW = 8; + const unsigned short CSS_SKEWX = 9; + const unsigned short CSS_SKEWY = 10; + const unsigned short CSS_MATRIX = 11; + + readonly attribute unsigned short operationType; + }; + +} diff --git a/src/3rdparty/webkit/WebCore/css/html4.css b/src/3rdparty/webkit/WebCore/css/html4.css new file mode 100644 index 0000000..4709a37 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/html4.css @@ -0,0 +1,596 @@ +/* + * 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-top: 0__qem +} + +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; + display: inline-block; +} + +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: searchfield-decoration; + display: inline-block; +} + +input[type="search"]::-webkit-search-results-decoration { + -webkit-appearance: searchfield-results-decoration; + display: inline-block; +} + +input[type="search"]::-webkit-search-results-button { + -webkit-appearance: searchfield-results-button; + display: inline-block; +} + +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::-webkit-input-placeholder { + color: darkGray; +} + +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; + text-align: start !important; +} + +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 +} + +/* noscript is handled internally, as it depends on settings */ diff --git a/src/3rdparty/webkit/WebCore/css/make-css-file-arrays.pl b/src/3rdparty/webkit/WebCore/css/make-css-file-arrays.pl new file mode 100755 index 0000000..05c8fd1 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/makegrammar.pl b/src/3rdparty/webkit/WebCore/css/makegrammar.pl new file mode 100644 index 0000000..06faaa9 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/makegrammar.pl @@ -0,0 +1,55 @@ +#! /usr/bin/perl +# +# This file is part of the WebKit project +# +# Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; see the file COPYING.LIB. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +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/src/3rdparty/webkit/WebCore/css/makeprop.pl b/src/3rdparty/webkit/WebCore/css/makeprop.pl new file mode 100644 index 0000000..bc979f9 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/makeprop.pl @@ -0,0 +1,119 @@ +#! /usr/bin/perl +# +# This file is part of the WebKit project +# +# Copyright (C) 1999 Waldo Bastian (bastian@kde.org) +# Copyright (C) 2007, 2008 Apple Inc. All rights reserved. +# Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; see the file COPYING.LIB. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +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/(^[^-])|-(.)/uc($1||$2)/ge; + print GPERF $name . ", CSSProperty" . $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 { + CSSPropertyInvalid = 0, +EOF + +my $first = 1001; +my $i = 1001; +my $maxLen = 0; +foreach my $name (@names) { + my $id = $name; + $id =~ s/(^[^-])|-(.)/uc($1||$2)/ge; + print HEADER " CSSProperty" . $id . " = " . $i . ",\n"; + $i = $i + 1; + if (length($name) > $maxLen) { + $maxLen = length($name); + } +} +my $num = $i - $first; + +print HEADER "};\n\n"; +print HEADER "const int firstCSSProperty = $first;\n"; +print HEADER "const int numCSSProperties = $num;\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.cpp") == 0 || die "calling gperf failed: $?"; + +open C, ">>CSSPropertyNames.cpp" || die "Could not open CSSPropertyNames.cpp for writing"; +print C "static const char * const propertyNameStrings[$num] = {\n"; + +foreach my $name (@names) { + print C "\"$name\",\n"; +} + +print C << "EOF"; +}; +const char* getPropertyName(CSSPropertyID id) +{ + if (id < firstCSSProperty) + return 0; + int index = id - firstCSSProperty; + if (index >= numCSSProperties) + return 0; + return propertyNameStrings[index]; +} +EOF + +close C; + diff --git a/src/3rdparty/webkit/WebCore/css/maketokenizer b/src/3rdparty/webkit/WebCore/css/maketokenizer new file mode 100644 index 0000000..4f65d17 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/maketokenizer @@ -0,0 +1,128 @@ +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 +#define forkeyword 2 + +/* 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/src/3rdparty/webkit/WebCore/css/makevalues.pl b/src/3rdparty/webkit/WebCore/css/makevalues.pl new file mode 100644 index 0000000..5d4e8ac --- /dev/null +++ b/src/3rdparty/webkit/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) 2008 Nokia Corporation and/or its subsidiary(-ies) +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; see the file COPYING.LIB. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +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/(^[^-])|-(.)/uc($1||$2)/ge; + print GPERF $name . ", CSSValue" . $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 CSSValueInvalid = 0; +EOF + +my $i = 1; +my $maxLen = 0; +foreach my $name (@names) { + my $id = $name; + $id =~ s/(^[^-])|-(.)/uc($1||$2)/ge; + print HEADER "const int CSSValue" . $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/src/3rdparty/webkit/WebCore/css/mediaControls.css b/src/3rdparty/webkit/WebCore/css/mediaControls.css new file mode 100644 index 0000000..1dbb2c3 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/mediaControls.css @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2009 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, + * 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. + */ + +/* media controls */ + +audio { + width: 200px; + height: 16px; +} + +audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel { + position: absolute; + bottom: 0; + width: 100%; + height: 100%; + -webkit-user-select: none; +} + +video:-webkit-full-page-media::-webkit-media-controls-panel { + bottom: -16px; +} + +audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-button { + -webkit-appearance: media-mute-button; + position: absolute; + top: auto; + bottom: 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: auto; + bottom: 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: auto; + bottom: 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: auto; + bottom: 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: auto; + bottom: 0; + right: 0; + width: 17px; + height: 16px; +} + +audio::-webkit-media-controls-fullscreen-button, video::-webkit-media-controls-fullscreen-button { + display: none; +} diff --git a/src/3rdparty/webkit/WebCore/css/qt/mediaControls-extras.css b/src/3rdparty/webkit/WebCore/css/qt/mediaControls-extras.css new file mode 100644 index 0000000..d85deae --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/qt/mediaControls-extras.css @@ -0,0 +1,101 @@ +/* + * QtWebKit specific overrides for HTML5 media elements. + * + * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + * + * 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. + */ + +audio { + height: 34px; + width: 400px; +} + +audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-button { + left: auto; + right: 5px; + width: 12px; + height: 12px; + padding: 6px; + margin: 5px 0px; +} + +audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button { + left: 5px; + width: 9px; + height: 12px; + padding: 6px 12px 6px 11px; + margin: 5px 0px; +} + +audio::-webkit-media-controls-time-display, video::-webkit-media-controls-time-display { + /* Since MediaControlElements are always created with a renderer we have to hide + the controls we don't use, so they don't mess up activation and event handling */ + left: 0px; + top: 0px; + width: 0px; + height: 0px; + + display: none; +} + +audio::-webkit-media-controls-timeline, video::-webkit-media-controls-timeline { + left: 42px; + right: 34px; + height: 12px; + padding: 6px 8px; + margin: 5px 0px; +} + +audio::-webkit-media-controls-seek-back-button, video::-webkit-media-controls-seek-back-button { + /* Since MediaControlElements are always created with a renderer we have to hide + the controls we don't use, so they don't mess up activation and event handling */ + left: 0px; + top: 0px; + width: 0px; + height: 0px; + + display: none; +} + +audio::-webkit-media-controls-seek-forward-button, video::-webkit-media-controls-seek-forward-button { + /* Since MediaControlElements are always created with a renderer we have to hide + the controls we don't use, so they don't mess up activation and event handling */ + left: 0px; + top: 0px; + width: 0px; + height: 0px; + + display: none; +} + +audio::-webkit-media-controls-fullscreen-button, video::-webkit-media-controls-fullscreen-button { + /* Since MediaControlElements are always created with a renderer we have to hide + the controls we don't use, so they don't mess up activation and event handling */ + left: 0px; + top: 0px; + width: 0px; + height: 0px; + + display: none; +} + diff --git a/src/3rdparty/webkit/WebCore/css/quirks.css b/src/3rdparty/webkit/WebCore/css/quirks.css new file mode 100644 index 0000000..4477708 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/quirks.css @@ -0,0 +1,54 @@ +/* + * 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; +} + +/* Set margin-bottom for form element in quirks mode. */ +/* Compatible with Gecko. (Doing this only for quirks mode is a fix for bug 17696.) */ +form { + margin-bottom: 1em +} diff --git a/src/3rdparty/webkit/WebCore/css/svg.css b/src/3rdparty/webkit/WebCore/css/svg.css new file mode 100644 index 0000000..322eda8 --- /dev/null +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/css/themeWin.css b/src/3rdparty/webkit/WebCore/css/themeWin.css new file mode 100644 index 0000000..42962c4 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/themeWin.css @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2008, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* These styles override the default styling for HTML elements as defined in + WebCore/css/html4.css. So far we have used this file exclusively for + making our form elements match Firefox's. */ + +input:not([type]), +input[type="text"], +input[type="password"], +input[type="search"] { + margin:0; + padding:1px 0; +} + +input[type="checkbox"] { + margin:3px 3px 3px 4px; +} + +input[type="radio"] { + margin:3px 3px 0 5px; +} + +/* Not sure this is the right color. #EBEBE4 is what Firefox uses. + FIXME: Figure out how to support legacy input rendering. + FIXME: Add input[type="file"] once we figure out our file inputs. + FIXME: Add input[type="image"] once we figure out our image inputs. + FIXME: We probably do the wrong thing if you put an invalid input type. + do we care? +*/ +textarea:disabled, +input:not([type]):disabled, +input[type="text"]:disabled, +input[type="password"]:disabled, +input[type="search"]:disabled { + background-color: #EBEBE4; +} + +/* Windows should render input[type="search"] the same as input with no type. + This search thing is an Apple-ism to get mac style search inputs. */ +input[type="search"] { + -webkit-appearance: textfield; + -webkit-box-sizing: content-box; +} + +input[type="button"], input[type="submit"], input[type="reset"], input[type="file"]::-webkit-file-upload-button, button { + /* Matches Firefox */ + padding: 0 6px; + margin: 0; +} + +/* Windows selects are not rounded. Custom borders for them shouldn't be either. */ +keygen, +select, +select[size="0"], +select[size="1"] { + -webkit-border-radius: 0; + margin: 0; +} + +textarea { + font-family: monospace; + margin: 1px 0; + + /* Matches IE */ + padding: 2px; +} diff --git a/src/3rdparty/webkit/WebCore/css/themeWinQuirks.css b/src/3rdparty/webkit/WebCore/css/themeWinQuirks.css new file mode 100644 index 0000000..688eabc --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/themeWinQuirks.css @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2008, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* These styles override the default styling for HTML elements in quirks-mode + as defined in WebCore/css/quirks.css. So far we have used this file exclusively for + making our form elements match Firefox's. */ + +textarea { + /* Matches IE's text offsets in quirksmode (causes text to wrap the same as IE). */ + padding: 2px 0 0 2px; +} diff --git a/src/3rdparty/webkit/WebCore/css/tokenizer.flex b/src/3rdparty/webkit/WebCore/css/tokenizer.flex new file mode 100644 index 0000000..e800bae --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/tokenizer.flex @@ -0,0 +1,110 @@ +%option case-insensitive +%option noyywrap +%option 8bit +%option stack +%s mediaquery +%s forkeyword + +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;} +<forkeyword>"for" {BEGIN(mediaquery); yyTok = VARIABLES_FOR; 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; } +"@-webkit-selector" {yyTok = WEBKIT_SELECTOR_SYM; return yyTok; } +"@-webkit-variables" {BEGIN(mediaquery); yyTok = WEBKIT_VARIABLES_SYM; return yyTok; } +"@-webkit-define" {BEGIN(forkeyword); yyTok = WEBKIT_DEFINE_SYM; return yyTok; } +"@-webkit-variables-decls" { yyTok = WEBKIT_VARIABLES_DECLS_SYM; return yyTok; } +"@-webkit-keyframes" {yyTok = WEBKIT_KEYFRAMES_SYM; return yyTok; } +"@-webkit-keyframe-rule" {yyTok = WEBKIT_KEYFRAME_RULE_SYM; return yyTok; } + +"@"{ident} {yyTok = ATKEYWORD; 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}turn {yyTok = TURNS; 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;} +"-webkit-var("{w}{ident}{w}")" { yyTok = VARCALL; 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/src/3rdparty/webkit/WebCore/css/view-source.css b/src/3rdparty/webkit/WebCore/css/view-source.css new file mode 100644 index 0000000..20722ee --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/view-source.css @@ -0,0 +1,158 @@ +/* + * 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 { + width: 100%; + border-spacing: 0; + counter-reset: lines; + white-space: pre-wrap !important; + margin: 0; + word-break: break-word; + font-size: 10px; + font-family: Monaco, Lucida Console, monospace; +} + +td { + padding: 0 !important; + vertical-align: baseline +} + +.webkit-line-gutter-backdrop, .webkit-line-number { + /* Keep this in sync with inspector.css (.webkit-line-gutter-backdrop) */ + -webkit-box-sizing: border-box; + padding: 0 4px !important; + width: 31px; + background-color: rgb(240, 240, 240); + border-right: 1px solid rgb(187, 187, 187) !important; + -webkit-user-select: none; +} + +.webkit-line-gutter-backdrop { + /* Keep this in sync with inspector.css (.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 (.webkit-html-comment) */ + color: rgb(35, 110, 37); +} + +.webkit-html-doctype { + /* Keep this in sync with inspector.css (.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; + min-height: 13px; + 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; +} diff --git a/src/3rdparty/webkit/WebCore/css/wml.css b/src/3rdparty/webkit/WebCore/css/wml.css new file mode 100644 index 0000000..9c938dd --- /dev/null +++ b/src/3rdparty/webkit/WebCore/css/wml.css @@ -0,0 +1,249 @@ +/* + * The default style sheet used to render WML. + * + * Copyright (C) 2000 Lars Knoll (knoll@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.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. + * + */ + +@namespace "http://www.wapforum.org/DTD/wml_1.1.xml" + +wml { + display: block +} + +/* children of the <head> element all have display:none */ +head { + display: none +} + +meta { + display: none +} + +access { + display: none +} + +/* generic block-level elements */ + +card { + display: block; + margin: 8px +} + +p { + display: block; + margin: 1.0__qem 0px +} + +/* tables */ + +table { + display: table; + border-collapse: separate; + border-spacing: 2px; + border-color: gray +} + +/* for tables without table section elements (can happen with XHTML or dynamically created tables) */ +table > tr { + vertical-align: middle; +} + +tr { + display: table-row; + vertical-align: inherit; + border-color: inherit +} + +td { + display: table-cell; + vertical-align: inherit +} + +/* form elements */ + +go { + display: block; + margin-top: 0__qem +} + +insertedLegend { + 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 +} + +do { + -webkit-appearance: 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, select, do { + 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, input[type="password"] { + -webkit-appearance: textfield; + padding: 1px; + background-color: white; + border: 2px inset; + -webkit-rtl-ordering: logical; + -webkit-user-select: text; + cursor: auto; +} + +input::-webkit-input-placeholder { + color: darkGray; +} + +input[type="password"] { + -webkit-text-security: disc !important; +} + +input:-webkit-autofill { + background-color: #FAFFBD !important; + background-image:none !important; +} + +do:disabled, select:disabled, optgroup:disabled, option:disabled { + color: GrayText +} + +do:active { + border-style: inset +} + +do:active:disabled { + border-style: outset +} + +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 { + text-decoration: underline +} + +strong, b { + font-weight: bolder +} + +i, em { + font-style: italic +} + +big { + font-size: larger +} + +small { + font-size: smaller +} + +/* states */ + +:focus { + outline: auto 5px -webkit-focus-ring-color +} + +/* Read-only text fields do not show a focus ring but do still receive focus */ +wml:focus, card:focus { + outline: none +} + +input:focus, select:focus { + outline-offset: -2px +} + +a:-webkit-any-link, anchor:-webkit-any-link { + color: -webkit-link; + text-decoration: underline; + cursor: auto; +} + +a:-webkit-any-link:active, anchor:-webkit-any-link:active { + color: -webkit-activelink +} |