summaryrefslogtreecommitdiffstats
path: root/WebCore/css/CSSPrimitiveValue.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-06 11:45:16 +0100
committerSteve Block <steveblock@google.com>2011-05-12 13:44:10 +0100
commitcad810f21b803229eb11403f9209855525a25d57 (patch)
tree29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /WebCore/css/CSSPrimitiveValue.cpp
parent121b0cf4517156d0ac5111caf9830c51b69bae8f (diff)
downloadexternal_webkit-cad810f21b803229eb11403f9209855525a25d57.zip
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'WebCore/css/CSSPrimitiveValue.cpp')
-rw-r--r--WebCore/css/CSSPrimitiveValue.cpp998
1 files changed, 0 insertions, 998 deletions
diff --git a/WebCore/css/CSSPrimitiveValue.cpp b/WebCore/css/CSSPrimitiveValue.cpp
deleted file mode 100644
index ce1b87b..0000000
--- a/WebCore/css/CSSPrimitiveValue.cpp
+++ /dev/null
@@ -1,998 +0,0 @@
-/*
- * (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 "CSSParser.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 "RGBColor.h"
-#include "Rect.h"
-#include "RenderStyle.h"
-#include <wtf/ASCIICType.h>
-#include <wtf/DecimalNumber.h>
-#include <wtf/MathExtras.h>
-#include <wtf/StdLibExtras.h>
-#include <wtf/text/StringBuffer.h>
-
-#if ENABLE(DASHBOARD_SUPPORT)
-#include "DashboardRegion.h"
-#endif
-
-using namespace WTF;
-
-namespace WebCore {
-
-static CSSPrimitiveValue::UnitCategory unitCategory(CSSPrimitiveValue::UnitTypes type)
-{
- // Here we violate the spec (http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSPrimitiveValue) and allow conversions
- // between CSS_PX and relative lengths (see cssPixelsPerInch comment in CSSHelper.h for the topic treatment).
- switch (type) {
- case CSSPrimitiveValue::CSS_NUMBER:
- return CSSPrimitiveValue::UNumber;
- case CSSPrimitiveValue::CSS_PERCENTAGE:
- return CSSPrimitiveValue::UPercent;
- case CSSPrimitiveValue::CSS_PX:
- case CSSPrimitiveValue::CSS_CM:
- case CSSPrimitiveValue::CSS_MM:
- case CSSPrimitiveValue::CSS_IN:
- case CSSPrimitiveValue::CSS_PT:
- case CSSPrimitiveValue::CSS_PC:
- return CSSPrimitiveValue::ULength;
- case CSSPrimitiveValue::CSS_MS:
- case CSSPrimitiveValue::CSS_S:
- return CSSPrimitiveValue::UTime;
- case CSSPrimitiveValue::CSS_DEG:
- case CSSPrimitiveValue::CSS_RAD:
- case CSSPrimitiveValue::CSS_GRAD:
- case CSSPrimitiveValue::CSS_TURN:
- return CSSPrimitiveValue::UAngle;
- case CSSPrimitiveValue::CSS_HZ:
- case CSSPrimitiveValue::CSS_KHZ:
- return CSSPrimitiveValue::UFrequency;
- default:
- return CSSPrimitiveValue::UOther;
- }
-}
-
-typedef HashMap<const CSSPrimitiveValue*, String> CSSTextCache;
-static CSSTextCache& cssTextCache()
-{
- DEFINE_STATIC_LOCAL(CSSTextCache, cache, ());
- return cache;
-}
-
-// 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.
-
-inline PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createUncachedIdentifier(int identifier)
-{
- return adoptRef(new CSSPrimitiveValue(identifier));
-}
-
-inline PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createUncachedColor(unsigned rgbValue)
-{
- return adoptRef(new CSSPrimitiveValue(rgbValue));
-}
-
-inline PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createUncached(double value, UnitTypes type)
-{
- return adoptRef(new CSSPrimitiveValue(value, type));
-}
-
-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 = createUncachedIdentifier(ident);
- identValueCache[ident] = primitiveValue;
- }
- return primitiveValue.release();
- }
- return createUncachedIdentifier(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 = createUncachedColor(Color::transparent).releaseRef();
- return colorTransparent;
- }
- if (rgbValue == Color::white) {
- static CSSPrimitiveValue* colorWhite = createUncachedColor(Color::white).releaseRef();
- return colorWhite;
- }
- RefPtr<CSSPrimitiveValue> primitiveValue = colorValueCache->get(rgbValue);
- if (primitiveValue)
- return primitiveValue.release();
- primitiveValue = createUncachedColor(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 = createUncached(value, type);
- integerValueCache[intValue][type] = primitiveValue;
- }
- return primitiveValue.release();
- }
- }
-
- return createUncached(value, type);
-}
-
-PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::create(const String& value, UnitTypes type)
-{
- return adoptRef(new CSSPrimitiveValue(value, type));
-}
-
-static const AtomicString& valueOrPropertyName(int valueOrPropertyID)
-{
- ASSERT_ARG(valueOrPropertyID, valueOrPropertyID >= 0);
- ASSERT_ARG(valueOrPropertyID, valueOrPropertyID < numCSSValueKeywords || (valueOrPropertyID >= firstCSSProperty && valueOrPropertyID < firstCSSProperty + numCSSProperties));
-
- if (valueOrPropertyID < 0)
- return nullAtom;
-
- if (valueOrPropertyID < numCSSValueKeywords) {
- static AtomicString* cssValueKeywordStrings[numCSSValueKeywords];
- if (!cssValueKeywordStrings[valueOrPropertyID])
- cssValueKeywordStrings[valueOrPropertyID] = new AtomicString(getValueName(valueOrPropertyID));
- return *cssValueKeywordStrings[valueOrPropertyID];
- }
-
- if (valueOrPropertyID >= firstCSSProperty && valueOrPropertyID < firstCSSProperty + numCSSProperties) {
- static AtomicString* cssPropertyStrings[numCSSProperties];
- int propertyIndex = valueOrPropertyID - firstCSSProperty;
- if (!cssPropertyStrings[propertyIndex])
- cssPropertyStrings[propertyIndex] = new AtomicString(getPropertyName(static_cast<CSSPropertyID>(valueOrPropertyID)));
- return *cssPropertyStrings[propertyIndex];
- }
-
- return nullAtom;
-}
-
-CSSPrimitiveValue::CSSPrimitiveValue()
- : m_type(0)
- , m_hasCachedCSSText(false)
-{
-}
-
-CSSPrimitiveValue::CSSPrimitiveValue(int ident)
- : m_type(CSS_IDENT)
- , m_hasCachedCSSText(false)
-{
- m_value.ident = ident;
-}
-
-CSSPrimitiveValue::CSSPrimitiveValue(double num, UnitTypes type)
- : m_type(type)
- , m_hasCachedCSSText(false)
-{
- m_value.num = num;
-}
-
-CSSPrimitiveValue::CSSPrimitiveValue(const String& str, UnitTypes type)
- : m_type(type)
- , m_hasCachedCSSText(false)
-{
- if ((m_value.string = str.impl()))
- m_value.string->ref();
-}
-
-CSSPrimitiveValue::CSSPrimitiveValue(RGBA32 color)
- : m_type(CSS_RGBCOLOR)
- , m_hasCachedCSSText(false)
-{
- m_value.rgbcolor = color;
-}
-
-CSSPrimitiveValue::CSSPrimitiveValue(const Length& length)
- : m_hasCachedCSSText(false)
-{
- 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_hasCachedCSSText = false;
- m_value.counter = c.releaseRef();
-}
-
-void CSSPrimitiveValue::init(PassRefPtr<Rect> r)
-{
- m_type = CSS_RECT;
- m_hasCachedCSSText = false;
- m_value.rect = r.releaseRef();
-}
-
-#if ENABLE(DASHBOARD_SUPPORT)
-void CSSPrimitiveValue::init(PassRefPtr<DashboardRegion> r)
-{
- m_type = CSS_DASHBOARD_REGION;
- m_hasCachedCSSText = false;
- m_value.region = r.releaseRef();
-}
-#endif
-
-void CSSPrimitiveValue::init(PassRefPtr<Pair> p)
-{
- m_type = CSS_PAIR;
- m_hasCachedCSSText = false;
- 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_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;
- if (m_hasCachedCSSText) {
- cssTextCache().remove(this);
- m_hasCachedCSSText = false;
- }
-}
-
-int CSSPrimitiveValue::computeLengthInt(RenderStyle* style, RenderStyle* rootStyle)
-{
- return roundForImpreciseConversion<int, INT_MAX, INT_MIN>(computeLengthDouble(style, rootStyle));
-}
-
-int CSSPrimitiveValue::computeLengthInt(RenderStyle* style, RenderStyle* rootStyle, double multiplier)
-{
- return roundForImpreciseConversion<int, INT_MAX, INT_MIN>(computeLengthDouble(style, rootStyle, multiplier));
-}
-
-// Lengths expect an int that is only 28-bits, so we have to check for a
-// different overflow.
-int CSSPrimitiveValue::computeLengthIntForLength(RenderStyle* style, RenderStyle* rootStyle)
-{
- return roundForImpreciseConversion<int, intMaxForLength, intMinForLength>(computeLengthDouble(style, rootStyle));
-}
-
-int CSSPrimitiveValue::computeLengthIntForLength(RenderStyle* style, RenderStyle* rootStyle, double multiplier)
-{
- return roundForImpreciseConversion<int, intMaxForLength, intMinForLength>(computeLengthDouble(style, rootStyle, multiplier));
-}
-
-short CSSPrimitiveValue::computeLengthShort(RenderStyle* style, RenderStyle* rootStyle)
-{
- return roundForImpreciseConversion<short, SHRT_MAX, SHRT_MIN>(computeLengthDouble(style, rootStyle));
-}
-
-short CSSPrimitiveValue::computeLengthShort(RenderStyle* style, RenderStyle* rootStyle, double multiplier)
-{
- return roundForImpreciseConversion<short, SHRT_MAX, SHRT_MIN>(computeLengthDouble(style, rootStyle, multiplier));
-}
-
-float CSSPrimitiveValue::computeLengthFloat(RenderStyle* style, RenderStyle* rootStyle, bool computingFontSize)
-{
- return static_cast<float>(computeLengthDouble(style, rootStyle, 1.0, computingFontSize));
-}
-
-float CSSPrimitiveValue::computeLengthFloat(RenderStyle* style, RenderStyle* rootStyle, double multiplier, bool computingFontSize)
-{
- return static_cast<float>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize));
-}
-
-double CSSPrimitiveValue::computeLengthDouble(RenderStyle* style, RenderStyle* rootStyle, 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_REMS:
- applyZoomMultiplier = false;
- factor = computingFontSize ? rootStyle->fontDescription().specifiedSize() : rootStyle->fontDescription().computedSize();
- 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, double, ExceptionCode& ec)
-{
- // Keeping values immutable makes optimizations easier and allows sharing of the primitive value objects.
- // No other engine supports mutating style through this API. Computed style is always read-only anyway.
- // Supporting setter would require making primitive value copy-on-write and taking care of style invalidation.
- ec = NO_MODIFICATION_ALLOWED_ERR;
-}
-
-static double conversionToCanonicalUnitsScaleFactor(unsigned short unitType)
-{
- double factor = 1.0;
- // FIXME: the switch can be replaced by an array of scale factors.
- switch (unitType) {
- // These are "canonical" units in their respective categories.
- case CSSPrimitiveValue::CSS_PX:
- case CSSPrimitiveValue::CSS_DEG:
- case CSSPrimitiveValue::CSS_MS:
- case CSSPrimitiveValue::CSS_HZ:
- 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;
- case CSSPrimitiveValue::CSS_RAD:
- factor = 180 / piDouble;
- break;
- case CSSPrimitiveValue::CSS_GRAD:
- factor = 0.9;
- break;
- case CSSPrimitiveValue::CSS_TURN:
- factor = 360;
- break;
- case CSSPrimitiveValue::CSS_S:
- case CSSPrimitiveValue::CSS_KHZ:
- factor = 1000;
- break;
- default:
- break;
- }
-
- return factor;
-}
-
-double CSSPrimitiveValue::getDoubleValue(unsigned short unitType, ExceptionCode& ec) const
-{
- double result = 0;
- bool success = getDoubleValueInternal(static_cast<UnitTypes>(unitType), &result);
- if (!success) {
- ec = INVALID_ACCESS_ERR;
- return 0.0;
- }
-
- ec = 0;
- return result;
-}
-
-double CSSPrimitiveValue::getDoubleValue(unsigned short unitType) const
-{
- double result = 0;
- getDoubleValueInternal(static_cast<UnitTypes>(unitType), &result);
- return result;
-}
-
-CSSPrimitiveValue::UnitTypes CSSPrimitiveValue::canonicalUnitTypeForCategory(UnitCategory category)
-{
- // The canonical unit type is chosen according to the way CSSParser::validUnit() chooses the default unit
- // in each category (based on unitflags).
- switch (category) {
- case UNumber:
- return CSS_NUMBER;
- case ULength:
- return CSS_PX;
- case UPercent:
- return CSS_UNKNOWN; // Cannot convert between numbers and percent.
- case UTime:
- return CSS_MS;
- case UAngle:
- return CSS_DEG;
- case UFrequency:
- return CSS_HZ;
- default:
- return CSS_UNKNOWN;
- }
-}
-
-bool CSSPrimitiveValue::getDoubleValueInternal(UnitTypes requestedUnitType, double* result) const
-{
- if (m_type < CSS_NUMBER || (m_type > CSS_DIMENSION && m_type < CSS_TURN) || requestedUnitType < CSS_NUMBER || (requestedUnitType > CSS_DIMENSION && requestedUnitType < CSS_TURN))
- return false;
- if (requestedUnitType == m_type || requestedUnitType == CSS_DIMENSION) {
- *result = m_value.num;
- return true;
- }
-
- UnitTypes sourceUnitType = static_cast<UnitTypes>(m_type);
- UnitCategory sourceCategory = unitCategory(sourceUnitType);
- ASSERT(sourceCategory != UOther);
-
- UnitTypes targetUnitType = requestedUnitType;
- UnitCategory targetCategory = unitCategory(targetUnitType);
- ASSERT(targetCategory != UOther);
-
- // Cannot convert between unrelated unit categories if one of them is not UNumber.
- if (sourceCategory != targetCategory && sourceCategory != UNumber && targetCategory != UNumber)
- return false;
-
- if (targetCategory == UNumber) {
- // We interpret conversion to CSS_NUMBER as conversion to a canonical unit in this value's category.
- targetUnitType = canonicalUnitTypeForCategory(sourceCategory);
- if (targetUnitType == CSS_UNKNOWN)
- return false;
- }
-
- if (sourceUnitType == CSS_NUMBER) {
- // We interpret conversion from CSS_NUMBER in the same way as CSSParser::validUnit() while using non-strict mode.
- sourceUnitType = canonicalUnitTypeForCategory(targetCategory);
- if (sourceUnitType == CSS_UNKNOWN)
- return false;
- }
-
- double convertedValue = m_value.num;
-
- // First convert the value from m_type to canonical type.
- double factor = conversionToCanonicalUnitsScaleFactor(sourceUnitType);
- convertedValue *= factor;
-
- // Now convert from canonical type to the target unitType.
- factor = conversionToCanonicalUnitsScaleFactor(targetUnitType);
- convertedValue /= factor;
-
- *result = convertedValue;
- return true;
-}
-
-void CSSPrimitiveValue::setStringValue(unsigned short, const String&, ExceptionCode& ec)
-{
- // Keeping values immutable makes optimizations easier and allows sharing of the primitive value objects.
- // No other engine supports mutating style through this API. Computed style is always read-only anyway.
- // Supporting setter would require making primitive value copy-on-write and taking care of style invalidation.
- ec = NO_MODIFICATION_ALLOWED_ERR;
-}
-
-String CSSPrimitiveValue::getStringValue(ExceptionCode& ec) const
-{
- ec = 0;
- switch (m_type) {
- case CSS_STRING:
- case CSS_ATTR:
- case CSS_URI:
- return m_value.string;
- case CSS_IDENT:
- return 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:
- 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;
-}
-
-PassRefPtr<RGBColor> CSSPrimitiveValue::getRGBColorValue(ExceptionCode& ec) const
-{
- ec = 0;
- if (m_type != CSS_RGBCOLOR) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
-
- // FIMXE: This should not return a new object for each invocation.
- return RGBColor::create(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() const
-{
- if (m_type != CSS_IDENT)
- return 0;
- return m_value.ident;
-}
-
-static String formatNumber(double number)
-{
- DecimalNumber decimal(number);
-
- StringBuffer buffer(decimal.bufferLengthForStringDecimal());
- unsigned length = decimal.toStringDecimal(buffer.characters(), buffer.length());
- ASSERT_UNUSED(length, length == buffer.length());
-
- return String::adopt(buffer);
-}
-
-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
-
- if (m_hasCachedCSSText) {
- ASSERT(cssTextCache().contains(this));
- return cssTextCache().get(this);
- }
-
- String text;
- switch (m_type) {
- case CSS_UNKNOWN:
- // FIXME
- break;
- case CSS_NUMBER:
- case CSS_PARSER_INTEGER:
- text = formatNumber(m_value.num);
- break;
- case CSS_PERCENTAGE:
- text = formatNumber(m_value.num) + "%";
- break;
- case CSS_EMS:
- text = formatNumber(m_value.num) + "em";
- break;
- case CSS_EXS:
- text = formatNumber(m_value.num) + "ex";
- break;
- case CSS_REMS:
- text = formatNumber(m_value.num) + "rem";
- break;
- case CSS_PX:
- text = formatNumber(m_value.num) + "px";
- break;
- case CSS_CM:
- text = formatNumber(m_value.num) + "cm";
- break;
- case CSS_MM:
- text = formatNumber(m_value.num) + "mm";
- break;
- case CSS_IN:
- text = formatNumber(m_value.num) + "in";
- break;
- case CSS_PT:
- text = formatNumber(m_value.num) + "pt";
- break;
- case CSS_PC:
- text = formatNumber(m_value.num) + "pc";
- break;
- case CSS_DEG:
- text = formatNumber(m_value.num) + "deg";
- break;
- case CSS_RAD:
- text = formatNumber(m_value.num) + "rad";
- break;
- case CSS_GRAD:
- text = formatNumber(m_value.num) + "grad";
- break;
- case CSS_MS:
- text = formatNumber(m_value.num) + "ms";
- break;
- case CSS_S:
- text = formatNumber(m_value.num) + "s";
- break;
- case CSS_HZ:
- text = formatNumber(m_value.num) + "hz";
- break;
- case CSS_KHZ:
- text = formatNumber(m_value.num) + "khz";
- break;
- case CSS_TURN:
- text = formatNumber(m_value.num) + "turn";
- break;
- case CSS_DIMENSION:
- // FIXME
- break;
- case CSS_STRING:
- text = quoteCSSStringIfNeeded(m_value.string);
- break;
- case CSS_URI:
- text = "url(" + quoteCSSURLIfNeeded(m_value.string) + ")";
- break;
- case CSS_IDENT:
- text = valueOrPropertyName(m_value.ident);
- break;
- case CSS_ATTR: {
- DEFINE_STATIC_LOCAL(const String, attrParen, ("attr("));
-
- Vector<UChar> result;
- result.reserveInitialCapacity(6 + m_value.string->length());
-
- append(result, attrParen);
- append(result, m_value.string);
- result.uncheckedAppend(')');
-
- text = String::adopt(result);
- 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.reserveInitialCapacity(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(')');
-
- text = String::adopt(result);
- break;
- }
- 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.reserveInitialCapacity(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(color.alpha() / 256.0f));
- }
-
- result.append(')');
- text = String::adopt(result);
- break;
- }
- 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_OPERATOR: {
- char c = static_cast<char>(m_value.ident);
- text = String(&c, 1U);
- break;
- }
- case CSS_PARSER_IDENTIFIER:
- text = quoteCSSStringIfNeeded(m_value.string);
- break;
- }
-
- ASSERT(!cssTextCache().contains(this));
- cssTextCache().set(this, text);
- m_hasCachedCSSText = true;
- 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_REMS:
- 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_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;
- const AtomicString& 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