diff options
author | Steve Block <steveblock@google.com> | 2011-05-06 11:45:16 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-05-12 13:44:10 +0100 |
commit | cad810f21b803229eb11403f9209855525a25d57 (patch) | |
tree | 29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /WebCore/css/CSSPrimitiveValue.cpp | |
parent | 121b0cf4517156d0ac5111caf9830c51b69bae8f (diff) | |
download | external_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.cpp | 998 |
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 |