Chromium Code Reviews| Index: Source/core/css/CSSValue.cpp |
| diff --git a/Source/core/css/CSSValue.cpp b/Source/core/css/CSSValue.cpp |
| index a18425ece021ee015879c473b291f80669d1ef4f..1ab5e400fd4dc4cf0488638c432382308f29f425 100644 |
| --- a/Source/core/css/CSSValue.cpp |
| +++ b/Source/core/css/CSSValue.cpp |
| @@ -30,6 +30,7 @@ |
| #include "core/css/CSSBorderImageSliceValue.h" |
| #include "core/css/CSSCanvasValue.h" |
| #include "core/css/CSSContentDistributionValue.h" |
| +#include "core/css/CSSCounterValue.h" |
| #include "core/css/CSSCrossfadeValue.h" |
| #include "core/css/CSSCursorImageValue.h" |
| #include "core/css/CSSFontFaceSrcValue.h" |
| @@ -61,6 +62,13 @@ struct SameSizeAsCSSValue : public RefCountedWillBeGarbageCollectedFinalized<Sam |
| static_assert(sizeof(CSSValue) <= sizeof(SameSizeAsCSSValue), "CSSValue should stay small"); |
| +typedef HashMap<const CSSValue*, String> CSSTextCache; |
| +static CSSTextCache& cssTextCache() |
| +{ |
| + AtomicallyInitializedStaticReference(ThreadSpecific<CSSTextCache>, cache, new ThreadSpecific<CSSTextCache>()); |
| + return *cache; |
| +} |
| + |
| bool CSSValue::isImplicitInitialValue() const |
| { |
| return m_classType == InitialClass && toCSSInitialValue(this)->isImplicit(); |
| @@ -96,6 +104,8 @@ bool CSSValue::equals(const CSSValue& other) const |
| return compareCSSValues<CSSBorderImageSliceValue>(*this, other); |
| case CanvasClass: |
| return compareCSSValues<CSSCanvasValue>(*this, other); |
| + case CounterClass: |
| + return compareCSSValues<CSSCounterValue>(*this, other); |
| case CursorImageClass: |
| return compareCSSValues<CSSCursorImageValue>(*this, other); |
| case FontFaceSrcClass: |
| @@ -156,68 +166,112 @@ bool CSSValue::equals(const CSSValue& other) const |
| String CSSValue::cssText() const |
| { |
| + if (m_hasCachedCSSText) { |
| + ASSERT(cssTextCache().contains(this)); |
| + return cssTextCache().get(this); |
| + } |
| + |
| + String text; |
|
Timothy Loh
2015/08/21 07:33:12
String CSSValue::uncachedCSSText() const { .. }?
sashab
2015/08/24 01:36:11
Should I do this in CSSPrimitiveValue? Not sure ho
|
| switch (classType()) { |
| case BorderImageSliceClass: |
| - return toCSSBorderImageSliceValue(this)->customCSSText(); |
| + text = toCSSBorderImageSliceValue(this)->customCSSText(); |
| + break; |
| case CanvasClass: |
| - return toCSSCanvasValue(this)->customCSSText(); |
| + text = toCSSCanvasValue(this)->customCSSText(); |
| + break; |
| + case CounterClass: |
| + text = toCSSCounterValue(this)->customCSSText(); |
| + break; |
| case CursorImageClass: |
| - return toCSSCursorImageValue(this)->customCSSText(); |
| + text = toCSSCursorImageValue(this)->customCSSText(); |
| + break; |
| case FontFaceSrcClass: |
| - return toCSSFontFaceSrcValue(this)->customCSSText(); |
| + text = toCSSFontFaceSrcValue(this)->customCSSText(); |
| + break; |
| case FontFeatureClass: |
| - return toCSSFontFeatureValue(this)->customCSSText(); |
| + text = toCSSFontFeatureValue(this)->customCSSText(); |
| + break; |
| case FunctionClass: |
| - return toCSSFunctionValue(this)->customCSSText(); |
| + text = toCSSFunctionValue(this)->customCSSText(); |
| + break; |
| case LinearGradientClass: |
| - return toCSSLinearGradientValue(this)->customCSSText(); |
| + text = toCSSLinearGradientValue(this)->customCSSText(); |
| + break; |
| case RadialGradientClass: |
| - return toCSSRadialGradientValue(this)->customCSSText(); |
| + text = toCSSRadialGradientValue(this)->customCSSText(); |
| + break; |
| case CrossfadeClass: |
| - return toCSSCrossfadeValue(this)->customCSSText(); |
| + text = toCSSCrossfadeValue(this)->customCSSText(); |
| + break; |
| case ImageClass: |
| - return toCSSImageValue(this)->customCSSText(); |
| + text = toCSSImageValue(this)->customCSSText(); |
| + break; |
| case InheritedClass: |
| - return toCSSInheritedValue(this)->customCSSText(); |
| + text = toCSSInheritedValue(this)->customCSSText(); |
| + break; |
| case UnsetClass: |
| - return toCSSUnsetValue(this)->customCSSText(); |
| + text = toCSSUnsetValue(this)->customCSSText(); |
| + break; |
| case InitialClass: |
| - return toCSSInitialValue(this)->customCSSText(); |
| + text = toCSSInitialValue(this)->customCSSText(); |
| + break; |
| case GridLineNamesClass: |
| - return toCSSGridLineNamesValue(this)->customCSSText(); |
| + text = toCSSGridLineNamesValue(this)->customCSSText(); |
| + break; |
| case GridTemplateAreasClass: |
| - return toCSSGridTemplateAreasValue(this)->customCSSText(); |
| + text = toCSSGridTemplateAreasValue(this)->customCSSText(); |
| + break; |
| case PathClass: |
| - return toCSSPathValue(this)->customCSSText(); |
| + text = toCSSPathValue(this)->customCSSText(); |
| + break; |
| case PrimitiveClass: |
| - return toCSSPrimitiveValue(this)->customCSSText(); |
| + text = toCSSPrimitiveValue(this)->customCSSText(); |
| + break; |
| case ReflectClass: |
| - return toCSSReflectValue(this)->customCSSText(); |
| + text = toCSSReflectValue(this)->customCSSText(); |
| + break; |
| case ShadowClass: |
| - return toCSSShadowValue(this)->customCSSText(); |
| + text = toCSSShadowValue(this)->customCSSText(); |
| + break; |
| case CubicBezierTimingFunctionClass: |
| - return toCSSCubicBezierTimingFunctionValue(this)->customCSSText(); |
| + text = toCSSCubicBezierTimingFunctionValue(this)->customCSSText(); |
| + break; |
| case StepsTimingFunctionClass: |
| - return toCSSStepsTimingFunctionValue(this)->customCSSText(); |
| + text = toCSSStepsTimingFunctionValue(this)->customCSSText(); |
| + break; |
| case UnicodeRangeClass: |
| - return toCSSUnicodeRangeValue(this)->customCSSText(); |
| + text = toCSSUnicodeRangeValue(this)->customCSSText(); |
| + break; |
| case ValueListClass: |
| - return toCSSValueList(this)->customCSSText(); |
| + text = toCSSValueList(this)->customCSSText(); |
| + break; |
| case LineBoxContainClass: |
| - return toCSSLineBoxContainValue(this)->customCSSText(); |
| + text = toCSSLineBoxContainValue(this)->customCSSText(); |
| + break; |
| case ImageSetClass: |
| - return toCSSImageSetValue(this)->customCSSText(); |
| + text = toCSSImageSetValue(this)->customCSSText(); |
| + break; |
| case CSSSVGDocumentClass: |
| - return toCSSSVGDocumentValue(this)->customCSSText(); |
| + text = toCSSSVGDocumentValue(this)->customCSSText(); |
| + break; |
| case CSSContentDistributionClass: |
| - return toCSSContentDistributionValue(this)->customCSSText(); |
| + text = toCSSContentDistributionValue(this)->customCSSText(); |
| + break; |
| } |
| - ASSERT_NOT_REACHED(); |
| - return String(); |
| + |
| + ASSERT(!cssTextCache().contains(this)); |
| + cssTextCache().set(this, text); |
| + m_hasCachedCSSText = true; |
| + return text; |
| } |
| void CSSValue::destroy() |
| { |
| + if (m_hasCachedCSSText) { |
| + cssTextCache().remove(this); |
| + m_hasCachedCSSText = false; |
| + } |
| + |
| switch (classType()) { |
| case BorderImageSliceClass: |
| delete toCSSBorderImageSliceValue(this); |
| @@ -225,6 +279,9 @@ void CSSValue::destroy() |
| case CanvasClass: |
| delete toCSSCanvasValue(this); |
| return; |
| + case CounterClass: |
| + delete toCSSCounterValue(this); |
| + return; |
| case CursorImageClass: |
| delete toCSSCursorImageValue(this); |
| return; |
| @@ -313,6 +370,9 @@ void CSSValue::finalizeGarbageCollectedObject() |
| case CanvasClass: |
| toCSSCanvasValue(this)->~CSSCanvasValue(); |
| return; |
| + case CounterClass: |
| + toCSSCounterValue(this)->~CSSCounterValue(); |
| + return; |
| case CursorImageClass: |
| toCSSCursorImageValue(this)->~CSSCursorImageValue(); |
| return; |
| @@ -401,6 +461,9 @@ DEFINE_TRACE(CSSValue) |
| case CanvasClass: |
| toCSSCanvasValue(this)->traceAfterDispatch(visitor); |
| return; |
| + case CounterClass: |
| + toCSSCounterValue(this)->traceAfterDispatch(visitor); |
| + return; |
| case CursorImageClass: |
| toCSSCursorImageValue(this)->traceAfterDispatch(visitor); |
| return; |