summaryrefslogtreecommitdiff
path: root/Source/WebCore/css/CSSPrimitiveValue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/css/CSSPrimitiveValue.cpp')
-rw-r--r--Source/WebCore/css/CSSPrimitiveValue.cpp1046
1 files changed, 437 insertions, 609 deletions
diff --git a/Source/WebCore/css/CSSPrimitiveValue.cpp b/Source/WebCore/css/CSSPrimitiveValue.cpp
index 1492d25a3..482fd3da8 100644
--- a/Source/WebCore/css/CSSPrimitiveValue.cpp
+++ b/Source/WebCore/css/CSSPrimitiveValue.cpp
@@ -23,15 +23,20 @@
#include "CSSBasicShapes.h"
#include "CSSCalculationValue.h"
+#include "CSSFontFamily.h"
#include "CSSHelper.h"
-#include "CSSParser.h"
+#include "CSSMarkup.h"
+#include "CSSParserSelector.h"
+#include "CSSPrimitiveValueMappings.h"
#include "CSSPropertyNames.h"
+#include "CSSToLengthConversionData.h"
#include "CSSValueKeywords.h"
#include "CalculationValue.h"
#include "Color.h"
#include "Counter.h"
+#include "DeprecatedCSSOMPrimitiveValue.h"
#include "ExceptionCode.h"
-#include "Font.h"
+#include "FontCascade.h"
#include "Node.h"
#include "Pair.h"
#include "RGBColor.h"
@@ -40,6 +45,7 @@
#include "StyleSheetContents.h"
#include <wtf/ASCIICType.h>
#include <wtf/DecimalNumber.h>
+#include <wtf/NeverDestroyed.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/StringBuffer.h>
#include <wtf/text/StringBuilder.h>
@@ -52,22 +58,20 @@ using namespace WTF;
namespace WebCore {
-static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::UnitTypes unitType)
+static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::UnitType unitType)
{
switch (unitType) {
case CSSPrimitiveValue::CSS_CALC:
- case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_NUMBER:
case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_LENGTH:
+ case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_NUMBER:
+ case CSSPrimitiveValue::CSS_CHS:
case CSSPrimitiveValue::CSS_CM:
case CSSPrimitiveValue::CSS_DEG:
case CSSPrimitiveValue::CSS_DIMENSION:
-#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
- case CSSPrimitiveValue::CSS_DPPX:
- case CSSPrimitiveValue::CSS_DPI:
- case CSSPrimitiveValue::CSS_DPCM:
-#endif
case CSSPrimitiveValue::CSS_EMS:
+ case CSSPrimitiveValue::CSS_QUIRKY_EMS:
case CSSPrimitiveValue::CSS_EXS:
+ case CSSPrimitiveValue::CSS_FR:
case CSSPrimitiveValue::CSS_GRAD:
case CSSPrimitiveValue::CSS_HZ:
case CSSPrimitiveValue::CSS_IN:
@@ -75,48 +79,111 @@ static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::Unit
case CSSPrimitiveValue::CSS_MM:
case CSSPrimitiveValue::CSS_MS:
case CSSPrimitiveValue::CSS_NUMBER:
- case CSSPrimitiveValue::CSS_PERCENTAGE:
case CSSPrimitiveValue::CSS_PC:
+ case CSSPrimitiveValue::CSS_PERCENTAGE:
case CSSPrimitiveValue::CSS_PT:
case CSSPrimitiveValue::CSS_PX:
case CSSPrimitiveValue::CSS_RAD:
case CSSPrimitiveValue::CSS_REMS:
- case CSSPrimitiveValue::CSS_CHS:
case CSSPrimitiveValue::CSS_S:
case CSSPrimitiveValue::CSS_TURN:
- case CSSPrimitiveValue::CSS_VW:
case CSSPrimitiveValue::CSS_VH:
- case CSSPrimitiveValue::CSS_VMIN:
case CSSPrimitiveValue::CSS_VMAX:
- case CSSPrimitiveValue::CSS_FR:
+ case CSSPrimitiveValue::CSS_VMIN:
+ case CSSPrimitiveValue::CSS_VW:
return true;
+ case CSSPrimitiveValue::CSS_DPCM:
+ case CSSPrimitiveValue::CSS_DPI:
+ case CSSPrimitiveValue::CSS_DPPX:
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
+ return true;
+#else
+ return false;
+#endif
case CSSPrimitiveValue::CSS_ATTR:
case CSSPrimitiveValue::CSS_COUNTER:
case CSSPrimitiveValue::CSS_COUNTER_NAME:
+ case CSSPrimitiveValue::CSS_FONT_FAMILY:
+ case CSSPrimitiveValue::CSS_IDENT:
+ case CSSPrimitiveValue::CSS_PAIR:
+ case CSSPrimitiveValue::CSS_PROPERTY_ID:
+ case CSSPrimitiveValue::CSS_QUAD:
+ case CSSPrimitiveValue::CSS_RECT:
+ case CSSPrimitiveValue::CSS_RGBCOLOR:
+ case CSSPrimitiveValue::CSS_SHAPE:
+ case CSSPrimitiveValue::CSS_STRING:
+ case CSSPrimitiveValue::CSS_UNICODE_RANGE:
+ case CSSPrimitiveValue::CSS_UNKNOWN:
+ case CSSPrimitiveValue::CSS_URI:
+ case CSSPrimitiveValue::CSS_VALUE_ID:
#if ENABLE(DASHBOARD_SUPPORT)
case CSSPrimitiveValue::CSS_DASHBOARD_REGION:
#endif
-#if !ENABLE(CSS_IMAGE_RESOLUTION) && !ENABLE(RESOLUTION_MEDIA_QUERY)
- case CSSPrimitiveValue::CSS_DPPX:
- case CSSPrimitiveValue::CSS_DPI:
+ return false;
+ }
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+#if !ASSERT_DISABLED
+
+static inline bool isStringType(CSSPrimitiveValue::UnitType type)
+{
+ switch (type) {
+ case CSSPrimitiveValue::CSS_STRING:
+ case CSSPrimitiveValue::CSS_URI:
+ case CSSPrimitiveValue::CSS_ATTR:
+ case CSSPrimitiveValue::CSS_COUNTER_NAME:
+ case CSSPrimitiveValue::CSS_DIMENSION:
+ return true;
+ case CSSPrimitiveValue::CSS_CALC:
+ case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_LENGTH:
+ case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_NUMBER:
+ case CSSPrimitiveValue::CSS_CHS:
+ case CSSPrimitiveValue::CSS_CM:
+ case CSSPrimitiveValue::CSS_COUNTER:
+ case CSSPrimitiveValue::CSS_DEG:
case CSSPrimitiveValue::CSS_DPCM:
-#endif
+ case CSSPrimitiveValue::CSS_DPI:
+ case CSSPrimitiveValue::CSS_DPPX:
+ case CSSPrimitiveValue::CSS_EMS:
+ case CSSPrimitiveValue::CSS_QUIRKY_EMS:
+ case CSSPrimitiveValue::CSS_EXS:
+ case CSSPrimitiveValue::CSS_FONT_FAMILY:
+ case CSSPrimitiveValue::CSS_FR:
+ case CSSPrimitiveValue::CSS_GRAD:
+ case CSSPrimitiveValue::CSS_HZ:
case CSSPrimitiveValue::CSS_IDENT:
- case CSSPrimitiveValue::CSS_PROPERTY_ID:
- case CSSPrimitiveValue::CSS_VALUE_ID:
+ case CSSPrimitiveValue::CSS_IN:
+ case CSSPrimitiveValue::CSS_KHZ:
+ case CSSPrimitiveValue::CSS_MM:
+ case CSSPrimitiveValue::CSS_MS:
+ case CSSPrimitiveValue::CSS_NUMBER:
case CSSPrimitiveValue::CSS_PAIR:
- case CSSPrimitiveValue::CSS_PARSER_HEXCOLOR:
- case CSSPrimitiveValue::CSS_PARSER_IDENTIFIER:
- case CSSPrimitiveValue::CSS_PARSER_INTEGER:
- case CSSPrimitiveValue::CSS_PARSER_OPERATOR:
- case CSSPrimitiveValue::CSS_RECT:
+ case CSSPrimitiveValue::CSS_PC:
+ case CSSPrimitiveValue::CSS_PERCENTAGE:
+ case CSSPrimitiveValue::CSS_PROPERTY_ID:
+ case CSSPrimitiveValue::CSS_PT:
+ case CSSPrimitiveValue::CSS_PX:
case CSSPrimitiveValue::CSS_QUAD:
+ case CSSPrimitiveValue::CSS_RAD:
+ case CSSPrimitiveValue::CSS_RECT:
+ case CSSPrimitiveValue::CSS_REMS:
case CSSPrimitiveValue::CSS_RGBCOLOR:
+ case CSSPrimitiveValue::CSS_S:
case CSSPrimitiveValue::CSS_SHAPE:
- case CSSPrimitiveValue::CSS_STRING:
+ case CSSPrimitiveValue::CSS_TURN:
case CSSPrimitiveValue::CSS_UNICODE_RANGE:
case CSSPrimitiveValue::CSS_UNKNOWN:
- case CSSPrimitiveValue::CSS_URI:
+ case CSSPrimitiveValue::CSS_VALUE_ID:
+ case CSSPrimitiveValue::CSS_VH:
+ case CSSPrimitiveValue::CSS_VMAX:
+ case CSSPrimitiveValue::CSS_VMIN:
+ case CSSPrimitiveValue::CSS_VW:
+#if ENABLE(DASHBOARD_SUPPORT)
+ case CSSPrimitiveValue::CSS_DASHBOARD_REGION:
+#endif
return false;
}
@@ -124,7 +191,9 @@ static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::Unit
return false;
}
-CSSPrimitiveValue::UnitCategory CSSPrimitiveValue::unitCategory(CSSPrimitiveValue::UnitTypes type)
+#endif // !ASSERT_DISABLED
+
+CSSPrimitiveValue::UnitCategory CSSPrimitiveValue::unitCategory(CSSPrimitiveValue::UnitType 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).
@@ -151,11 +220,6 @@ CSSPrimitiveValue::UnitCategory CSSPrimitiveValue::unitCategory(CSSPrimitiveValu
case CSS_HZ:
case CSS_KHZ:
return UFrequency;
- case CSS_VW:
- case CSS_VH:
- case CSS_VMIN:
- case CSS_VMAX:
- return UViewportPercentageLength;
#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
case CSS_DPPX:
case CSS_DPI:
@@ -170,7 +234,7 @@ CSSPrimitiveValue::UnitCategory CSSPrimitiveValue::unitCategory(CSSPrimitiveValu
typedef HashMap<const CSSPrimitiveValue*, String> CSSTextCache;
static CSSTextCache& cssTextCache()
{
- DEFINE_STATIC_LOCAL(CSSTextCache, cache, ());
+ static NeverDestroyed<CSSTextCache> cache;
return cache;
}
@@ -179,20 +243,29 @@ unsigned short CSSPrimitiveValue::primitiveType() const
if (m_primitiveUnitType == CSS_PROPERTY_ID || m_primitiveUnitType == CSS_VALUE_ID)
return CSS_IDENT;
+ // Web-exposed content expects font family values to have CSS_STRING primitive type
+ // so we need to map our internal CSS_FONT_FAMILY type here.
+ if (m_primitiveUnitType == CSS_FONT_FAMILY)
+ return CSS_STRING;
+
if (m_primitiveUnitType != CSSPrimitiveValue::CSS_CALC)
return m_primitiveUnitType;
switch (m_value.calc->category()) {
case CalcNumber:
return CSSPrimitiveValue::CSS_NUMBER;
- case CalcPercent:
- return CSSPrimitiveValue::CSS_PERCENTAGE;
case CalcLength:
return CSSPrimitiveValue::CSS_PX;
+ case CalcPercent:
+ return CSSPrimitiveValue::CSS_PERCENTAGE;
case CalcPercentNumber:
return CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_NUMBER;
case CalcPercentLength:
return CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_LENGTH;
+ case CalcAngle:
+ case CalcTime:
+ case CalcFrequency:
+ return m_value.calc->primitiveType();
case CalcOther:
return CSSPrimitiveValue::CSS_UNKNOWN;
}
@@ -201,12 +274,8 @@ unsigned short CSSPrimitiveValue::primitiveType() const
static const AtomicString& propertyName(CSSPropertyID propertyID)
{
- ASSERT_ARG(propertyID, propertyID >= 0);
ASSERT_ARG(propertyID, (propertyID >= firstCSSProperty && propertyID < firstCSSProperty + numCSSProperties));
- if (propertyID < 0)
- return nullAtom;
-
return getPropertyNameAtomicString(propertyID);
}
@@ -239,14 +308,7 @@ CSSPrimitiveValue::CSSPrimitiveValue(CSSPropertyID propertyID)
m_value.propertyID = propertyID;
}
-CSSPrimitiveValue::CSSPrimitiveValue(int parserOperator)
- : CSSValue(PrimitiveClass)
-{
- m_primitiveUnitType = CSS_PARSER_OPERATOR;
- m_value.parserOperator = parserOperator;
-}
-
-CSSPrimitiveValue::CSSPrimitiveValue(double num, UnitTypes type)
+CSSPrimitiveValue::CSSPrimitiveValue(double num, UnitType type)
: CSSValue(PrimitiveClass)
{
m_primitiveUnitType = type;
@@ -254,19 +316,20 @@ CSSPrimitiveValue::CSSPrimitiveValue(double num, UnitTypes type)
m_value.num = num;
}
-CSSPrimitiveValue::CSSPrimitiveValue(const String& str, UnitTypes type)
+CSSPrimitiveValue::CSSPrimitiveValue(const String& string, UnitType type)
: CSSValue(PrimitiveClass)
{
+ ASSERT(isStringType(type));
m_primitiveUnitType = type;
- if ((m_value.string = str.impl()))
+ if ((m_value.string = string.impl()))
m_value.string->ref();
}
-CSSPrimitiveValue::CSSPrimitiveValue(RGBA32 color)
+CSSPrimitiveValue::CSSPrimitiveValue(const Color& color)
: CSSValue(PrimitiveClass)
{
m_primitiveUnitType = CSS_RGBCOLOR;
- m_value.rgbcolor = color;
+ m_value.color = new Color(color);
}
CSSPrimitiveValue::CSSPrimitiveValue(const Length& length)
@@ -275,7 +338,7 @@ CSSPrimitiveValue::CSSPrimitiveValue(const Length& length)
init(length);
}
-CSSPrimitiveValue::CSSPrimitiveValue(const Length& length, const RenderStyle* style)
+CSSPrimitiveValue::CSSPrimitiveValue(const Length& length, const RenderStyle& style)
: CSSValue(PrimitiveClass)
{
switch (length.type()) {
@@ -287,10 +350,6 @@ CSSPrimitiveValue::CSSPrimitiveValue(const Length& length, const RenderStyle* st
case FillAvailable:
case FitContent:
case Percent:
- case ViewportPercentageWidth:
- case ViewportPercentageHeight:
- case ViewportPercentageMin:
- case ViewportPercentageMax:
init(length);
return;
case Fixed:
@@ -298,21 +357,21 @@ CSSPrimitiveValue::CSSPrimitiveValue(const Length& length, const RenderStyle* st
m_value.num = adjustFloatForAbsoluteZoom(length.value(), style);
return;
case Calculated: {
- RefPtr<CSSCalcValue> calcValue = CSSCalcValue::create(length.calculationValue().get(), style);
- init(calcValue.release());
+ init(CSSCalcValue::create(length.calculationValue(), style));
return;
}
case Relative:
case Undefined:
ASSERT_NOT_REACHED();
- break;
+ return;
}
+ ASSERT_NOT_REACHED();
}
-CSSPrimitiveValue::CSSPrimitiveValue(const LengthSize& lengthSize)
+CSSPrimitiveValue::CSSPrimitiveValue(const LengthSize& lengthSize, const RenderStyle& style)
: CSSValue(PrimitiveClass)
{
- init(lengthSize);
+ init(lengthSize, style);
}
void CSSPrimitiveValue::init(const Length& length)
@@ -321,94 +380,79 @@ void CSSPrimitiveValue::init(const Length& length)
case Auto:
m_primitiveUnitType = CSS_VALUE_ID;
m_value.valueID = CSSValueAuto;
- break;
+ return;
case WebCore::Fixed:
m_primitiveUnitType = CSS_PX;
m_value.num = length.value();
- break;
+ return;
case Intrinsic:
m_primitiveUnitType = CSS_VALUE_ID;
m_value.valueID = CSSValueIntrinsic;
- break;
+ return;
case MinIntrinsic:
m_primitiveUnitType = CSS_VALUE_ID;
m_value.valueID = CSSValueMinIntrinsic;
- break;
+ return;
case MinContent:
m_primitiveUnitType = CSS_VALUE_ID;
m_value.valueID = CSSValueWebkitMinContent;
- break;
+ return;
case MaxContent:
m_primitiveUnitType = CSS_VALUE_ID;
m_value.valueID = CSSValueWebkitMaxContent;
- break;
+ return;
case FillAvailable:
m_primitiveUnitType = CSS_VALUE_ID;
m_value.valueID = CSSValueWebkitFillAvailable;
- break;
+ return;
case FitContent:
m_primitiveUnitType = CSS_VALUE_ID;
m_value.valueID = CSSValueWebkitFitContent;
- break;
+ return;
case Percent:
m_primitiveUnitType = CSS_PERCENTAGE;
ASSERT(std::isfinite(length.percent()));
m_value.num = length.percent();
- break;
- case ViewportPercentageWidth:
- m_primitiveUnitType = CSS_VW;
- m_value.num = length.viewportPercentageLength();
- break;
- case ViewportPercentageHeight:
- m_primitiveUnitType = CSS_VH;
- m_value.num = length.viewportPercentageLength();
- break;
- case ViewportPercentageMin:
- m_primitiveUnitType = CSS_VMIN;
- m_value.num = length.viewportPercentageLength();
- break;
- case ViewportPercentageMax:
- m_primitiveUnitType = CSS_VMAX;
- m_value.num = length.viewportPercentageLength();
- break;
+ return;
case Calculated:
case Relative:
case Undefined:
ASSERT_NOT_REACHED();
- break;
+ return;
}
+ ASSERT_NOT_REACHED();
}
-void CSSPrimitiveValue::init(const LengthSize& lengthSize)
+void CSSPrimitiveValue::init(const LengthSize& lengthSize, const RenderStyle& style)
{
m_primitiveUnitType = CSS_PAIR;
m_hasCachedCSSText = false;
- m_value.pair = Pair::create(create(lengthSize.width()), create(lengthSize.height())).leakRef();
+ m_value.pair = &Pair::create(create(lengthSize.width, style), create(lengthSize.height, style)).leakRef();
}
-void CSSPrimitiveValue::init(PassRefPtr<Counter> c)
+void CSSPrimitiveValue::init(Ref<Counter>&& counter)
{
m_primitiveUnitType = CSS_COUNTER;
m_hasCachedCSSText = false;
- m_value.counter = c.leakRef();
+ m_value.counter = &counter.leakRef();
}
-void CSSPrimitiveValue::init(PassRefPtr<Rect> r)
+void CSSPrimitiveValue::init(Ref<Rect>&& r)
{
m_primitiveUnitType = CSS_RECT;
m_hasCachedCSSText = false;
- m_value.rect = r.leakRef();
+ m_value.rect = &r.leakRef();
}
-void CSSPrimitiveValue::init(PassRefPtr<Quad> quad)
+void CSSPrimitiveValue::init(Ref<Quad>&& quad)
{
m_primitiveUnitType = CSS_QUAD;
m_hasCachedCSSText = false;
- m_value.quad = quad.leakRef();
+ m_value.quad = &quad.leakRef();
}
#if ENABLE(DASHBOARD_SUPPORT)
-void CSSPrimitiveValue::init(PassRefPtr<DashboardRegion> r)
+void CSSPrimitiveValue::init(RefPtr<DashboardRegion>&& r)
{
m_primitiveUnitType = CSS_DASHBOARD_REGION;
m_hasCachedCSSText = false;
@@ -416,25 +460,25 @@ void CSSPrimitiveValue::init(PassRefPtr<DashboardRegion> r)
}
#endif
-void CSSPrimitiveValue::init(PassRefPtr<Pair> p)
+void CSSPrimitiveValue::init(Ref<Pair>&& p)
{
m_primitiveUnitType = CSS_PAIR;
m_hasCachedCSSText = false;
- m_value.pair = p.leakRef();
+ m_value.pair = &p.leakRef();
}
-void CSSPrimitiveValue::init(PassRefPtr<CSSCalcValue> c)
+void CSSPrimitiveValue::init(Ref<CSSBasicShape>&& shape)
{
- m_primitiveUnitType = CSS_CALC;
+ m_primitiveUnitType = CSS_SHAPE;
m_hasCachedCSSText = false;
- m_value.calc = c.leakRef();
+ m_value.shape = &shape.leakRef();
}
-void CSSPrimitiveValue::init(PassRefPtr<CSSBasicShape> shape)
+void CSSPrimitiveValue::init(RefPtr<CSSCalcValue>&& c)
{
- m_primitiveUnitType = CSS_SHAPE;
+ m_primitiveUnitType = CSS_CALC;
m_hasCachedCSSText = false;
- m_value.shape = shape.leakRef();
+ m_value.calc = c.leakRef();
}
CSSPrimitiveValue::~CSSPrimitiveValue()
@@ -444,15 +488,16 @@ CSSPrimitiveValue::~CSSPrimitiveValue()
void CSSPrimitiveValue::cleanup()
{
- switch (static_cast<UnitTypes>(m_primitiveUnitType)) {
+ auto type = static_cast<UnitType>(m_primitiveUnitType);
+ switch (type) {
case CSS_STRING:
case CSS_URI:
case CSS_ATTR:
case CSS_COUNTER_NAME:
- case CSS_PARSER_HEXCOLOR:
if (m_value.string)
m_value.string->deref();
break;
+ case CSS_DIMENSION:
case CSS_COUNTER:
m_value.counter->deref();
break;
@@ -481,10 +526,20 @@ void CSSPrimitiveValue::cleanup()
case CSS_SHAPE:
m_value.shape->deref();
break;
+ case CSS_FONT_FAMILY:
+ ASSERT(m_value.fontFamily);
+ delete m_value.fontFamily;
+ m_value.fontFamily = nullptr;
+ break;
+ case CSS_RGBCOLOR:
+ ASSERT(m_value.color);
+ delete m_value.color;
+ m_value.color = nullptr;
+ break;
case CSS_NUMBER:
- case CSS_PARSER_INTEGER:
case CSS_PERCENTAGE:
case CSS_EMS:
+ case CSS_QUIRKY_EMS:
case CSS_EXS:
case CSS_REMS:
case CSS_CHS:
@@ -511,14 +566,11 @@ void CSSPrimitiveValue::cleanup()
case CSS_DPCM:
case CSS_FR:
case CSS_IDENT:
- case CSS_RGBCOLOR:
- case CSS_DIMENSION:
case CSS_UNKNOWN:
case CSS_UNICODE_RANGE:
- case CSS_PARSER_OPERATOR:
- case CSS_PARSER_IDENTIFIER:
case CSS_PROPERTY_ID:
case CSS_VALUE_ID:
+ ASSERT(!isStringType(type));
break;
}
m_primitiveUnitType = 0;
@@ -528,91 +580,96 @@ void CSSPrimitiveValue::cleanup()
}
}
-double CSSPrimitiveValue::computeDegrees()
+double CSSPrimitiveValue::computeDegrees() const
{
- switch (m_primitiveUnitType) {
+ switch (primitiveType()) {
case CSS_DEG:
- return getDoubleValue();
+ return doubleValue();
case CSS_RAD:
- return rad2deg(getDoubleValue());
+ return rad2deg(doubleValue());
case CSS_GRAD:
- return grad2deg(getDoubleValue());
+ return grad2deg(doubleValue());
case CSS_TURN:
- return turn2deg(getDoubleValue());
+ return turn2deg(doubleValue());
default:
ASSERT_NOT_REACHED();
return 0;
}
}
-template<> int CSSPrimitiveValue::computeLength(const RenderStyle* style, const RenderStyle* rootStyle, float multiplier, bool computingFontSize) const
+template<> int CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
{
- return roundForImpreciseConversion<int>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize));
+ return roundForImpreciseConversion<int>(computeLengthDouble(conversionData));
}
-template<> unsigned CSSPrimitiveValue::computeLength(const RenderStyle* style, const RenderStyle* rootStyle, float multiplier, bool computingFontSize) const
+template<> unsigned CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
{
- return roundForImpreciseConversion<unsigned>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize));
+ return roundForImpreciseConversion<unsigned>(computeLengthDouble(conversionData));
}
-template<> Length CSSPrimitiveValue::computeLength(const RenderStyle* style, const RenderStyle* rootStyle, float multiplier, bool computingFontSize) const
+template<> Length CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
{
-#if ENABLE(SUBPIXEL_LAYOUT)
- return Length(clampTo<float>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize), minValueForCssLength, maxValueForCssLength), Fixed);
-#else
- return Length(clampTo<float>(roundForImpreciseConversion<float>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)), minValueForCssLength, maxValueForCssLength), Fixed);
-#endif
+ return Length(clampTo<float>(computeLengthDouble(conversionData), minValueForCssLength, maxValueForCssLength), Fixed);
}
-template<> short CSSPrimitiveValue::computeLength(const RenderStyle* style, const RenderStyle* rootStyle, float multiplier, bool computingFontSize) const
+template<> short CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
{
- return roundForImpreciseConversion<short>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize));
+ return roundForImpreciseConversion<short>(computeLengthDouble(conversionData));
}
-template<> unsigned short CSSPrimitiveValue::computeLength(const RenderStyle* style, const RenderStyle* rootStyle, float multiplier, bool computingFontSize) const
+template<> unsigned short CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
{
- return roundForImpreciseConversion<unsigned short>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize));
+ return roundForImpreciseConversion<unsigned short>(computeLengthDouble(conversionData));
}
-template<> float CSSPrimitiveValue::computeLength(const RenderStyle* style, const RenderStyle* rootStyle, float multiplier, bool computingFontSize) const
+template<> float CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
{
- return static_cast<float>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize));
+ return static_cast<float>(computeLengthDouble(conversionData));
}
-template<> double CSSPrimitiveValue::computeLength(const RenderStyle* style, const RenderStyle* rootStyle, float multiplier, bool computingFontSize) const
+template<> double CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
{
- return computeLengthDouble(style, rootStyle, multiplier, computingFontSize);
+ return computeLengthDouble(conversionData);
}
-double CSSPrimitiveValue::computeLengthDouble(const RenderStyle* style, const RenderStyle* rootStyle, float multiplier, bool computingFontSize) const
+double CSSPrimitiveValue::computeLengthDouble(const CSSToLengthConversionData& conversionData) const
{
if (m_primitiveUnitType == CSS_CALC)
// The multiplier and factor is applied to each value in the calc expression individually
- return m_value.calc->computeLengthPx(style, rootStyle, multiplier, computingFontSize);
+ return m_value.calc->computeLengthPx(conversionData);
+
+ return computeNonCalcLengthDouble(conversionData, static_cast<UnitType>(primitiveType()), m_value.num);
+}
+double CSSPrimitiveValue::computeNonCalcLengthDouble(const CSSToLengthConversionData& conversionData, UnitType primitiveType, double value)
+{
double factor;
- switch (primitiveType()) {
+ switch (primitiveType) {
case CSS_EMS:
- factor = computingFontSize ? style->fontDescription().specifiedSize() : style->fontDescription().computedSize();
+ case CSS_QUIRKY_EMS:
+ ASSERT(conversionData.style());
+ factor = conversionData.computingFontSize() ? conversionData.style()->fontDescription().specifiedSize() : conversionData.style()->fontDescription().computedSize();
break;
case CSS_EXS:
+ ASSERT(conversionData.style());
// 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.
- if (style->fontMetrics().hasXHeight())
- factor = style->fontMetrics().xHeight();
+ if (conversionData.style()->fontMetrics().hasXHeight())
+ factor = conversionData.style()->fontMetrics().xHeight();
else
- factor = (computingFontSize ? style->fontDescription().specifiedSize() : style->fontDescription().computedSize()) / 2.0;
+ factor = (conversionData.computingFontSize() ? conversionData.style()->fontDescription().specifiedSize() : conversionData.style()->fontDescription().computedSize()) / 2.0;
break;
case CSS_REMS:
- if (rootStyle)
- factor = computingFontSize ? rootStyle->fontDescription().specifiedSize() : rootStyle->fontDescription().computedSize();
+ if (conversionData.rootStyle())
+ factor = conversionData.computingFontSize() ? conversionData.rootStyle()->fontDescription().specifiedSize() : conversionData.rootStyle()->fontDescription().computedSize();
else
factor = 1.0;
break;
case CSS_CHS:
- factor = style->fontMetrics().zeroWidth();
+ ASSERT(conversionData.style());
+ factor = conversionData.style()->fontMetrics().zeroWidth();
break;
case CSS_PX:
factor = 1.0;
@@ -638,10 +695,16 @@ double CSSPrimitiveValue::computeLengthDouble(const RenderStyle* style, const Re
ASSERT_NOT_REACHED();
return -1.0;
case CSS_VH:
+ factor = conversionData.viewportHeightFactor();
+ break;
case CSS_VW:
+ factor = conversionData.viewportWidthFactor();
+ break;
case CSS_VMAX:
+ factor = conversionData.viewportMaxFactor();
+ break;
case CSS_VMIN:
- factor = 1.0;
+ factor = conversionData.viewportMinFactor();
break;
default:
ASSERT_NOT_REACHED();
@@ -651,22 +714,22 @@ double CSSPrimitiveValue::computeLengthDouble(const RenderStyle* style, const Re
// 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."
- double result = getDoubleValue() * factor;
- if (computingFontSize || isFontRelativeLength())
+ double result = value * factor;
+ if (conversionData.computingFontSize() || isFontRelativeLength(primitiveType))
return result;
- return result * multiplier;
+ return result * conversionData.zoom();
}
-void CSSPrimitiveValue::setFloatValue(unsigned short, double, ExceptionCode& ec)
+ExceptionOr<void> CSSPrimitiveValue::setFloatValue(unsigned short, double)
{
// 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;
+ return Exception { NO_MODIFICATION_ALLOWED_ERR };
}
-double CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(unsigned short unitType)
+double CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(UnitType unitType)
{
double factor = 1.0;
// FIXME: the switch can be replaced by an array of scale factors.
@@ -718,32 +781,26 @@ double CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(unsigned short u
return factor;
}
-double CSSPrimitiveValue::getDoubleValue(unsigned short unitType, ExceptionCode& ec) const
+ExceptionOr<float> CSSPrimitiveValue::getFloatValue(unsigned short unitType) 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;
+ auto result = doubleValueInternal(static_cast<UnitType>(unitType));
+ if (!result)
+ return Exception { INVALID_ACCESS_ERR };
+ return clampTo<float>(result.value());
}
-double CSSPrimitiveValue::getDoubleValue(unsigned short unitType) const
+double CSSPrimitiveValue::doubleValue(UnitType unitType) const
{
- double result = 0;
- getDoubleValueInternal(static_cast<UnitTypes>(unitType), &result);
- return result;
+ return doubleValueInternal(unitType).value_or(0);
}
-double CSSPrimitiveValue::getDoubleValue() const
+double CSSPrimitiveValue::doubleValue() const
{
return m_primitiveUnitType != CSS_CALC ? m_value.num : m_value.calc->doubleValue();
}
-CSSPrimitiveValue::UnitTypes CSSPrimitiveValue::canonicalUnitTypeForCategory(UnitCategory category)
+
+CSSPrimitiveValue::UnitType 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).
@@ -760,8 +817,6 @@ CSSPrimitiveValue::UnitTypes CSSPrimitiveValue::canonicalUnitTypeForCategory(Uni
return CSS_DEG;
case UFrequency:
return CSS_HZ;
- case UViewportPercentageLength:
- return CSS_UNKNOWN; // Cannot convert between numbers and relative lengths.
#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
case UResolution:
return CSS_DPPX;
@@ -771,43 +826,41 @@ CSSPrimitiveValue::UnitTypes CSSPrimitiveValue::canonicalUnitTypeForCategory(Uni
}
}
-bool CSSPrimitiveValue::getDoubleValueInternal(UnitTypes requestedUnitType, double* result) const
+std::optional<double> CSSPrimitiveValue::doubleValueInternal(UnitType requestedUnitType) const
{
- if (!isValidCSSUnitTypeForDoubleConversion(static_cast<UnitTypes>(m_primitiveUnitType)) || !isValidCSSUnitTypeForDoubleConversion(requestedUnitType))
- return false;
+ if (!isValidCSSUnitTypeForDoubleConversion(static_cast<UnitType>(m_primitiveUnitType)) || !isValidCSSUnitTypeForDoubleConversion(requestedUnitType))
+ return std::nullopt;
- UnitTypes sourceUnitType = static_cast<UnitTypes>(primitiveType());
- if (requestedUnitType == sourceUnitType || requestedUnitType == CSS_DIMENSION) {
- *result = getDoubleValue();
- return true;
- }
+ UnitType sourceUnitType = static_cast<UnitType>(primitiveType());
+ if (requestedUnitType == sourceUnitType || requestedUnitType == CSS_DIMENSION)
+ return doubleValue();
UnitCategory sourceCategory = unitCategory(sourceUnitType);
ASSERT(sourceCategory != UOther);
- UnitTypes targetUnitType = requestedUnitType;
+ UnitType 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;
+ return std::nullopt;
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;
+ return std::nullopt;
}
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;
+ return std::nullopt;
}
- double convertedValue = getDoubleValue();
+ double convertedValue = doubleValue();
// First convert the value from m_primitiveUnitType to canonical type.
double factor = conversionToCanonicalUnitsScaleFactor(sourceUnitType);
@@ -817,509 +870,281 @@ bool CSSPrimitiveValue::getDoubleValueInternal(UnitTypes requestedUnitType, doub
factor = conversionToCanonicalUnitsScaleFactor(targetUnitType);
convertedValue /= factor;
- *result = convertedValue;
- return true;
+ return convertedValue;
}
-void CSSPrimitiveValue::setStringValue(unsigned short, const String&, ExceptionCode& ec)
+ExceptionOr<void> CSSPrimitiveValue::setStringValue(unsigned short, const String&)
{
// 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;
+ return Exception { NO_MODIFICATION_ALLOWED_ERR };
}
-String CSSPrimitiveValue::getStringValue(ExceptionCode& ec) const
+ExceptionOr<String> CSSPrimitiveValue::getStringValue() const
{
- ec = 0;
switch (m_primitiveUnitType) {
case CSS_STRING:
case CSS_ATTR:
case CSS_URI:
return m_value.string;
+ case CSS_FONT_FAMILY:
+ return String { m_value.fontFamily->familyName };
case CSS_VALUE_ID:
- return valueName(m_value.valueID);
+ return String { valueName(m_value.valueID).string() };
case CSS_PROPERTY_ID:
- return propertyName(m_value.propertyID);
+ return String { propertyName(m_value.propertyID).string() };
default:
- ec = INVALID_ACCESS_ERR;
- break;
+ return Exception { INVALID_ACCESS_ERR };
}
-
- return String();
}
-String CSSPrimitiveValue::getStringValue() const
+String CSSPrimitiveValue::stringValue() const
{
switch (m_primitiveUnitType) {
case CSS_STRING:
case CSS_ATTR:
case CSS_URI:
return m_value.string;
+ case CSS_FONT_FAMILY:
+ return m_value.fontFamily->familyName;
case CSS_VALUE_ID:
return valueName(m_value.valueID);
case CSS_PROPERTY_ID:
return propertyName(m_value.propertyID);
default:
- break;
+ return String();
}
-
- return String();
-}
-
-Counter* CSSPrimitiveValue::getCounterValue(ExceptionCode& ec) const
-{
- ec = 0;
- if (m_primitiveUnitType != CSS_COUNTER) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
-
- return m_value.counter;
}
-Rect* CSSPrimitiveValue::getRectValue(ExceptionCode& ec) const
+ExceptionOr<Counter&> CSSPrimitiveValue::getCounterValue() const
{
- ec = 0;
- if (m_primitiveUnitType != CSS_RECT) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
-
- return m_value.rect;
+ if (m_primitiveUnitType != CSS_COUNTER)
+ return Exception { INVALID_ACCESS_ERR };
+ return *m_value.counter;
}
-Quad* CSSPrimitiveValue::getQuadValue(ExceptionCode& ec) const
+ExceptionOr<Rect&> CSSPrimitiveValue::getRectValue() const
{
- ec = 0;
- if (m_primitiveUnitType != CSS_QUAD) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
-
- return m_value.quad;
+ if (m_primitiveUnitType != CSS_RECT)
+ return Exception { INVALID_ACCESS_ERR };
+ return *m_value.rect;
}
-PassRefPtr<RGBColor> CSSPrimitiveValue::getRGBColorValue(ExceptionCode& ec) const
+ExceptionOr<Ref<RGBColor>> CSSPrimitiveValue::getRGBColorValue() const
{
- ec = 0;
- if (m_primitiveUnitType != CSS_RGBCOLOR) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
+ if (m_primitiveUnitType != CSS_RGBCOLOR)
+ return Exception { INVALID_ACCESS_ERR };
- // FIMXE: This should not return a new object for each invocation.
- return RGBColor::create(m_value.rgbcolor);
+ // FIXME: This should not return a new object for each invocation.
+ return RGBColor::create(m_value.color->rgb());
}
-Pair* CSSPrimitiveValue::getPairValue(ExceptionCode& ec) const
+NEVER_INLINE Ref<StringImpl> CSSPrimitiveValue::formatNumberValue(const char* suffix, unsigned suffixLength) const
{
- ec = 0;
- if (m_primitiveUnitType != CSS_PAIR) {
- ec = INVALID_ACCESS_ERR;
- return 0;
- }
-
- return m_value.pair;
-}
+ DecimalNumber decimal(m_value.num);
-static String formatNumber(double number, const char* suffix, unsigned suffixLength)
-{
- DecimalNumber decimal(number);
+ unsigned bufferLength = decimal.bufferLengthForStringDecimal() + suffixLength;
+ LChar* buffer;
+ auto string = StringImpl::createUninitialized(bufferLength, buffer);
- StringBuffer<LChar> buffer(decimal.bufferLengthForStringDecimal() + suffixLength);
- unsigned length = decimal.toStringDecimal(buffer.characters(), buffer.length());
- ASSERT(length + suffixLength == buffer.length());
+ unsigned length = decimal.toStringDecimal(buffer, bufferLength);
for (unsigned i = 0; i < suffixLength; ++i)
buffer[length + i] = static_cast<LChar>(suffix[i]);
- return String::adopt(buffer);
+ return string;
}
template <unsigned characterCount>
-ALWAYS_INLINE static String formatNumber(double number, const char (&characters)[characterCount])
-{
- return formatNumber(number, characters, characterCount - 1);
-}
-
-String CSSPrimitiveValue::customCSSText() 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_primitiveUnitType) {
- 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_CHS:
- text = formatNumber(m_value.num, "ch");
- break;
- case CSS_PX:
- text = formatNumber(m_value.num, "px");
- break;
- case CSS_CM:
- text = formatNumber(m_value.num, "cm");
- break;
-#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
- case CSS_DPPX:
- text = formatNumber(m_value.num, "dppx");
- break;
- case CSS_DPI:
- text = formatNumber(m_value.num, "dpi");
- break;
- case CSS_DPCM:
- text = formatNumber(m_value.num, "dpcm");
- break;
-#endif
- 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_FR:
- text = formatNumber(m_value.num, "fr");
- break;
- case CSS_DIMENSION:
- // FIXME: We currently don't handle CSS_DIMENSION properly as we don't store
- // the actual dimension, just the numeric value as a string.
- break;
- case CSS_STRING:
- text = quoteCSSStringIfNeeded(m_value.string);
- break;
- case CSS_URI:
- text = "url(" + quoteCSSURLIfNeeded(m_value.string) + ')';
- break;
- case CSS_VALUE_ID:
- text = valueName(m_value.valueID);
- break;
- case CSS_PROPERTY_ID:
- text = propertyName(m_value.propertyID);
- break;
- case CSS_ATTR: {
- StringBuilder result;
- result.reserveCapacity(6 + m_value.string->length());
- result.appendLiteral("attr(");
- result.append(m_value.string);
- result.append(')');
-
- text = result.toString();
- break;
- }
- case CSS_COUNTER_NAME:
- text = "counter(" + String(m_value.string) + ')';
- break;
- case CSS_COUNTER: {
- StringBuilder result;
- String separator = m_value.counter->separator();
- if (separator.isEmpty())
- result.appendLiteral("counter(");
- else
- result.appendLiteral("counters(");
-
- result.append(m_value.counter->identifier());
- if (!separator.isEmpty()) {
- result.appendLiteral(", ");
- result.append(quoteCSSStringIfNeeded(separator));
- }
- String listStyle = m_value.counter->listStyle();
- if (!listStyle.isEmpty()) {
- result.appendLiteral(", ");
- result.append(listStyle);
- }
- result.append(')');
-
- text = result.toString();
- break;
- }
- case CSS_RECT:
- text = getRectValue()->cssText();
- break;
- case CSS_QUAD:
- text = getQuadValue()->cssText();
- break;
- case CSS_RGBCOLOR:
- case CSS_PARSER_HEXCOLOR: {
- RGBA32 rgbColor = m_value.rgbcolor;
- if (m_primitiveUnitType == CSS_PARSER_HEXCOLOR)
- Color::parseHexColor(m_value.string, rgbColor);
- Color color(rgbColor);
-
- Vector<LChar> result;
- result.reserveInitialCapacity(32);
- bool colorHasAlpha = color.hasAlpha();
- if (colorHasAlpha)
- result.append("rgba(", 5);
- else
- result.append("rgb(", 4);
-
- appendNumber(result, static_cast<unsigned char>(color.red()));
- result.append(", ", 2);
-
- appendNumber(result, static_cast<unsigned char>(color.green()));
- result.append(", ", 2);
-
- appendNumber(result, static_cast<unsigned char>(color.blue()));
- if (colorHasAlpha) {
- result.append(", ", 2);
-
- NumberToStringBuffer buffer;
- const char* alphaString = numberToFixedPrecisionString(color.alpha() / 255.0f, 6, buffer, true);
- result.append(alphaString, strlen(alphaString));
- }
-
- result.append(')');
- text = String::adopt(result);
- break;
- }
- case CSS_PAIR:
- text = getPairValue()->cssText();
- break;
-#if ENABLE(DASHBOARD_SUPPORT)
- case CSS_DASHBOARD_REGION: {
- StringBuilder result;
- for (DashboardRegion* region = getDashboardRegionValue(); region; region = region->m_next.get()) {
- if (!result.isEmpty())
- result.append(' ');
- result.appendLiteral("dashboard-region(");
- result.append(region->m_label);
- if (region->m_isCircle)
- result.appendLiteral(" circle");
- else if (region->m_isRectangle)
- result.appendLiteral(" rectangle");
- else
- break;
- if (region->top()->m_primitiveUnitType == CSS_VALUE_ID && region->top()->getValueID() == CSSValueInvalid) {
- ASSERT(region->right()->m_primitiveUnitType == CSS_VALUE_ID);
- ASSERT(region->bottom()->m_primitiveUnitType == CSS_VALUE_ID);
- ASSERT(region->left()->m_primitiveUnitType == CSS_VALUE_ID);
- ASSERT(region->right()->getValueID() == CSSValueInvalid);
- ASSERT(region->bottom()->getValueID() == CSSValueInvalid);
- ASSERT(region->left()->getValueID() == CSSValueInvalid);
- } else {
- result.append(' ');
- result.append(region->top()->cssText());
- result.append(' ');
- result.append(region->right()->cssText());
- result.append(' ');
- result.append(region->bottom()->cssText());
- result.append(' ');
- result.append(region->left()->cssText());
- }
- result.append(')');
- }
- text = result.toString();
- break;
- }
-#endif
- case CSS_PARSER_OPERATOR: {
- char c = static_cast<char>(m_value.parserOperator);
- text = String(&c, 1U);
- break;
- }
- case CSS_PARSER_IDENTIFIER:
- text = quoteCSSStringIfNeeded(m_value.string);
- break;
- case CSS_CALC:
- text = m_value.calc->cssText();
- break;
- case CSS_SHAPE:
- text = m_value.shape->cssText();
- break;
- case CSS_VW:
- text = formatNumber(m_value.num, "vw");
- break;
- case CSS_VH:
- text = formatNumber(m_value.num, "vh");
- break;
- case CSS_VMIN:
- text = formatNumber(m_value.num, "vmin");
- break;
- case CSS_VMAX:
- text = formatNumber(m_value.num, "vmax");
- break;
- }
-
- ASSERT(!cssTextCache().contains(this));
- cssTextCache().set(this, text);
- m_hasCachedCSSText = true;
- return text;
-}
-
-void CSSPrimitiveValue::addSubresourceStyleURLs(ListHashSet<URL>& urls, const StyleSheetContents* styleSheet) const
-{
- if (m_primitiveUnitType == CSS_URI)
- addSubresourceURL(urls, styleSheet->completeURL(m_value.string));
-}
-
-Length CSSPrimitiveValue::viewportPercentageLength() const
+ALWAYS_INLINE Ref<StringImpl> CSSPrimitiveValue::formatNumberValue(const char (&characters)[characterCount]) const
{
- ASSERT(isViewportPercentageLength());
- Length viewportLength;
- switch (m_primitiveUnitType) {
- case CSS_VW:
- viewportLength = Length(getDoubleValue(), ViewportPercentageWidth);
- break;
- case CSS_VH:
- viewportLength = Length(getDoubleValue(), ViewportPercentageHeight);
- break;
- case CSS_VMIN:
- viewportLength = Length(getDoubleValue(), ViewportPercentageMin);
- break;
- case CSS_VMAX:
- viewportLength = Length(getDoubleValue(), ViewportPercentageMax);
- break;
- default:
- break;
- }
- return viewportLength;
+ return formatNumberValue(characters, characterCount - 1);
}
-PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::cloneForCSSOM() const
+ALWAYS_INLINE String CSSPrimitiveValue::formatNumberForCustomCSSText() const
{
- RefPtr<CSSPrimitiveValue> result;
-
switch (m_primitiveUnitType) {
- case CSS_STRING:
- case CSS_URI:
- case CSS_ATTR:
- case CSS_COUNTER_NAME:
- result = CSSPrimitiveValue::create(m_value.string, static_cast<UnitTypes>(m_primitiveUnitType));
- break;
- case CSS_COUNTER:
- result = CSSPrimitiveValue::create(m_value.counter->cloneForCSSOM());
- break;
- case CSS_RECT:
- result = CSSPrimitiveValue::create(m_value.rect->cloneForCSSOM());
- break;
- case CSS_QUAD:
- result = CSSPrimitiveValue::create(m_value.quad->cloneForCSSOM());
- break;
- case CSS_PAIR:
- // Pair is not exposed to the CSSOM, no need for a deep clone.
- result = CSSPrimitiveValue::create(m_value.pair);
- break;
-#if ENABLE(DASHBOARD_SUPPORT)
- case CSS_DASHBOARD_REGION:
- // DashboardRegion is not exposed to the CSSOM, no need for a deep clone.
- result = CSSPrimitiveValue::create(m_value.region);
- break;
-#endif
- case CSS_CALC:
- // CSSCalcValue is not exposed to the CSSOM, no need for a deep clone.
- result = CSSPrimitiveValue::create(m_value.calc);
- break;
- case CSS_SHAPE:
- // CSSShapeValue is not exposed to the CSSOM, no need for a deep clone.
- result = CSSPrimitiveValue::create(m_value.shape);
- break;
+ case CSS_UNKNOWN:
+ return String();
case CSS_NUMBER:
- case CSS_PARSER_INTEGER:
+ return formatNumberValue("");
case CSS_PERCENTAGE:
+ return formatNumberValue("%");
case CSS_EMS:
+ case CSS_QUIRKY_EMS:
+ return formatNumberValue("em");
case CSS_EXS:
+ return formatNumberValue("ex");
case CSS_REMS:
+ return formatNumberValue("rem");
case CSS_CHS:
+ return formatNumberValue("ch");
case CSS_PX:
+ return formatNumberValue("px");
case CSS_CM:
+ return formatNumberValue("cm");
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
+ case CSS_DPPX:
+ return formatNumberValue("dppx");
+ case CSS_DPI:
+ return formatNumberValue("dpi");
+ case CSS_DPCM:
+ return formatNumberValue("dpcm");
+#endif
case CSS_MM:
+ return formatNumberValue("mm");
case CSS_IN:
+ return formatNumberValue("in");
case CSS_PT:
+ return formatNumberValue("pt");
case CSS_PC:
+ return formatNumberValue("pc");
case CSS_DEG:
+ return formatNumberValue("deg");
case CSS_RAD:
+ return formatNumberValue("rad");
case CSS_GRAD:
+ return formatNumberValue("grad");
case CSS_MS:
+ return formatNumberValue("ms");
case CSS_S:
+ return formatNumberValue("s");
case CSS_HZ:
+ return formatNumberValue("hz");
case CSS_KHZ:
+ return formatNumberValue("khz");
case CSS_TURN:
+ return formatNumberValue("turn");
+ case CSS_FR:
+ return formatNumberValue("fr");
+ case CSS_DIMENSION:
+ // FIXME: We currently don't handle CSS_DIMENSION properly as we don't store
+ // the actual dimension, just the numeric value as a string.
+ case CSS_STRING:
+ // FIME-NEWPARSER: Once we have CSSCustomIdentValue hooked up, this can just be
+ // serializeString, since custom identifiers won't be the same value as strings
+ // any longer.
+ return serializeAsStringOrCustomIdent(m_value.string);
+ case CSS_FONT_FAMILY:
+ return serializeFontFamily(m_value.fontFamily->familyName);
+ case CSS_URI:
+ return serializeURL(m_value.string);
+ case CSS_VALUE_ID:
+ return valueName(m_value.valueID);
+ case CSS_PROPERTY_ID:
+ return propertyName(m_value.propertyID);
+ case CSS_ATTR: {
+ StringBuilder result;
+ result.reserveCapacity(6 + m_value.string->length());
+ result.appendLiteral("attr(");
+ result.append(String(m_value.string));
+ result.append(')');
+
+ return result.toString();
+ }
+ case CSS_COUNTER_NAME:
+ return "counter(" + String(m_value.string) + ')';
+ case CSS_COUNTER: {
+ StringBuilder result;
+ String separator = m_value.counter->separator();
+ if (separator.isEmpty())
+ result.appendLiteral("counter(");
+ else
+ result.appendLiteral("counters(");
+
+ result.append(m_value.counter->identifier());
+ if (!separator.isEmpty()) {
+ result.appendLiteral(", ");
+ serializeString(separator, result);
+ }
+ String listStyle = m_value.counter->listStyle();
+ if (!listStyle.isEmpty()) {
+ result.appendLiteral(", ");
+ result.append(listStyle);
+ }
+ result.append(')');
+
+ return result.toString();
+ }
+ case CSS_RECT:
+ return rectValue()->cssText();
+ case CSS_QUAD:
+ return quadValue()->cssText();
+ case CSS_RGBCOLOR:
+ return color().cssText();
+ case CSS_PAIR:
+ return pairValue()->cssText();
+#if ENABLE(DASHBOARD_SUPPORT)
+ case CSS_DASHBOARD_REGION: {
+ StringBuilder result;
+ for (DashboardRegion* region = dashboardRegionValue(); region; region = region->m_next.get()) {
+ if (!result.isEmpty())
+ result.append(' ');
+ result.appendLiteral("dashboard-region(");
+ result.append(region->m_label);
+ if (region->m_isCircle)
+ result.appendLiteral(" circle");
+ else if (region->m_isRectangle)
+ result.appendLiteral(" rectangle");
+ else
+ break;
+ if (region->top()->m_primitiveUnitType == CSS_VALUE_ID && region->top()->valueID() == CSSValueInvalid) {
+ ASSERT(region->right()->m_primitiveUnitType == CSS_VALUE_ID);
+ ASSERT(region->bottom()->m_primitiveUnitType == CSS_VALUE_ID);
+ ASSERT(region->left()->m_primitiveUnitType == CSS_VALUE_ID);
+ ASSERT(region->right()->valueID() == CSSValueInvalid);
+ ASSERT(region->bottom()->valueID() == CSSValueInvalid);
+ ASSERT(region->left()->valueID() == CSSValueInvalid);
+ } else {
+ result.append(' ');
+ result.append(region->top()->cssText());
+ result.append(' ');
+ result.append(region->right()->cssText());
+ result.append(' ');
+ result.append(region->bottom()->cssText());
+ result.append(' ');
+ result.append(region->left()->cssText());
+ }
+ result.append(')');
+ }
+ return result.toString();
+ }
+#endif
+ case CSS_CALC:
+ return m_value.calc->cssText();
+ case CSS_SHAPE:
+ return m_value.shape->cssText();
case CSS_VW:
+ return formatNumberValue("vw");
case CSS_VH:
+ return formatNumberValue("vh");
case CSS_VMIN:
+ return formatNumberValue("vmin");
case CSS_VMAX:
-#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
- case CSS_DPPX:
- case CSS_DPI:
- case CSS_DPCM:
-#endif
- case CSS_FR:
- result = CSSPrimitiveValue::create(m_value.num, static_cast<UnitTypes>(m_primitiveUnitType));
- break;
- case CSS_PROPERTY_ID:
- result = CSSPrimitiveValue::createIdentifier(m_value.propertyID);
- break;
- case CSS_VALUE_ID:
- result = CSSPrimitiveValue::createIdentifier(m_value.valueID);
- break;
- case CSS_RGBCOLOR:
- result = CSSPrimitiveValue::createColor(m_value.rgbcolor);
- break;
- case CSS_DIMENSION:
- case CSS_UNKNOWN:
- case CSS_PARSER_OPERATOR:
- case CSS_PARSER_IDENTIFIER:
- case CSS_PARSER_HEXCOLOR:
- ASSERT_NOT_REACHED();
- break;
+ return formatNumberValue("vmax");
+ }
+ return String();
+}
+
+String CSSPrimitiveValue::customCSSText() 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
+
+ CSSTextCache& cssTextCache = WebCore::cssTextCache();
+
+ if (m_hasCachedCSSText) {
+ ASSERT(cssTextCache.contains(this));
+ return cssTextCache.get(this);
}
- if (result)
- result->setCSSOMSafe();
- return result;
+ String text = formatNumberForCustomCSSText();
+
+ ASSERT(!cssTextCache.contains(this));
+ m_hasCachedCSSText = true;
+ cssTextCache.set(this, text);
+ return text;
}
bool CSSPrimitiveValue::equals(const CSSPrimitiveValue& other) const
@@ -1331,9 +1156,9 @@ bool CSSPrimitiveValue::equals(const CSSPrimitiveValue& other) const
case CSS_UNKNOWN:
return false;
case CSS_NUMBER:
- case CSS_PARSER_INTEGER:
case CSS_PERCENTAGE:
case CSS_EMS:
+ case CSS_QUIRKY_EMS:
case CSS_EXS:
case CSS_REMS:
case CSS_PX:
@@ -1358,19 +1183,17 @@ bool CSSPrimitiveValue::equals(const CSSPrimitiveValue& other) const
case CSS_VW:
case CSS_VH:
case CSS_VMIN:
- case CSS_DIMENSION:
case CSS_FR:
return m_value.num == other.m_value.num;
case CSS_PROPERTY_ID:
return propertyName(m_value.propertyID) == propertyName(other.m_value.propertyID);
case CSS_VALUE_ID:
return valueName(m_value.valueID) == valueName(other.m_value.valueID);
+ case CSS_DIMENSION:
case CSS_STRING:
case CSS_URI:
case CSS_ATTR:
case CSS_COUNTER_NAME:
- case CSS_PARSER_IDENTIFIER:
- case CSS_PARSER_HEXCOLOR:
return equal(m_value.string, other.m_value.string);
case CSS_COUNTER:
return m_value.counter && other.m_value.counter && m_value.counter->equals(*other.m_value.counter);
@@ -1379,21 +1202,26 @@ bool CSSPrimitiveValue::equals(const CSSPrimitiveValue& other) const
case CSS_QUAD:
return m_value.quad && other.m_value.quad && m_value.quad->equals(*other.m_value.quad);
case CSS_RGBCOLOR:
- return m_value.rgbcolor == other.m_value.rgbcolor;
+ return color() == other.color();
case CSS_PAIR:
return m_value.pair && other.m_value.pair && m_value.pair->equals(*other.m_value.pair);
#if ENABLE(DASHBOARD_SUPPORT)
case CSS_DASHBOARD_REGION:
return m_value.region && other.m_value.region && m_value.region->equals(*other.m_value.region);
#endif
- case CSS_PARSER_OPERATOR:
- return m_value.parserOperator == other.m_value.parserOperator;
case CSS_CALC:
return m_value.calc && other.m_value.calc && m_value.calc->equals(*other.m_value.calc);
case CSS_SHAPE:
return m_value.shape && other.m_value.shape && m_value.shape->equals(*other.m_value.shape);
+ case CSS_FONT_FAMILY:
+ return fontFamily() == other.fontFamily();
}
return false;
}
+Ref<DeprecatedCSSOMPrimitiveValue> CSSPrimitiveValue::createDeprecatedCSSOMPrimitiveWrapper() const
+{
+ return DeprecatedCSSOMPrimitiveValue::create(*this);
+}
+
} // namespace WebCore