Implement CSSValue::equals(const CSSValue&) to optimise CSSValue comparison
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 11 Feb 2013 11:00:54 +0000 (11:00 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 11 Feb 2013 11:00:54 +0000 (11:00 +0000)
https://bugs.webkit.org/show_bug.cgi?id=102901

Patch by Alexander Shalamov <alexander.shalamov@intel.com> on 2013-02-11
Reviewed by Antti Koivisto.

Source/WebCore:

Added comparison method to CSSValue and its children, so that the
css values could be compared efficiently. Before this patch, CSSValue
objects were compared using strings that were generated by the cssText() method.

Test: cssom/cssvalue-comparison.html

* css/CSSAspectRatioValue.cpp:
(WebCore::CSSAspectRatioValue::equals):
(WebCore):
* css/CSSAspectRatioValue.h:
(CSSAspectRatioValue):
* css/CSSBasicShapes.cpp:
(WebCore::CSSBasicShapeRectangle::equals):
(WebCore):
(WebCore::CSSBasicShapeCircle::equals):
(WebCore::CSSBasicShapeEllipse::equals):
(WebCore::CSSBasicShapePolygon::equals):
* css/CSSBasicShapes.h:
(CSSBasicShapeRectangle):
(CSSBasicShapeCircle):
(CSSBasicShapeEllipse):
(CSSBasicShapePolygon):
* css/CSSBorderImageSliceValue.cpp:
(WebCore::CSSBorderImageSliceValue::equals):
(WebCore):
* css/CSSBorderImageSliceValue.h:
(CSSBorderImageSliceValue):
* css/CSSCalculationValue.cpp:
(WebCore::CSSCalcValue::equals):
(WebCore):
(WebCore::CSSCalcPrimitiveValue::equals):
(CSSCalcPrimitiveValue):
(WebCore::CSSCalcPrimitiveValue::type):
(WebCore::CSSCalcBinaryOperation::equals):
(CSSCalcBinaryOperation):
(WebCore::CSSCalcBinaryOperation::type):
* css/CSSCalculationValue.h:
(WebCore::CSSCalcExpressionNode::equals):
(CSSCalcExpressionNode):
(CSSCalcValue):
* css/CSSCanvasValue.cpp:
(WebCore::CSSCanvasValue::equals):
(WebCore):
* css/CSSCanvasValue.h:
(CSSCanvasValue):
* css/CSSComputedStyleDeclaration.cpp:
(WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
(WebCore::CSSComputedStyleDeclaration::cssPropertyMatches):
(WebCore::CSSComputedStyleDeclaration::getCSSPropertyValuesForSidesShorthand):
* css/CSSCrossfadeValue.cpp:
(WebCore::CSSCrossfadeValue::equals):
(WebCore):
* css/CSSCrossfadeValue.h:
(CSSCrossfadeValue):
* css/CSSCursorImageValue.cpp:
(WebCore::CSSCursorImageValue::equals):
(WebCore):
* css/CSSCursorImageValue.h:
(CSSCursorImageValue):
* css/CSSFontFaceSrcValue.cpp:
(WebCore::CSSFontFaceSrcValue::equals):
(WebCore):
* css/CSSFontFaceSrcValue.h:
(CSSFontFaceSrcValue):
* css/CSSFunctionValue.cpp:
(WebCore::CSSFunctionValue::equals):
(WebCore):
* css/CSSFunctionValue.h:
(CSSFunctionValue):
* css/CSSGradientValue.cpp:
(WebCore::CSSLinearGradientValue::equals):
(WebCore):
(WebCore::CSSRadialGradientValue::equals):
* css/CSSGradientValue.h:
(WebCore::CSSGradientColorStop::operator==):
(CSSLinearGradientValue):
(CSSRadialGradientValue):
* css/CSSImageValue.cpp:
(WebCore::CSSImageValue::equals):
(WebCore):
* css/CSSImageValue.h:
(CSSImageValue):
* css/CSSInheritedValue.h:
(WebCore::CSSInheritedValue::equals):
(CSSInheritedValue):
* css/CSSInitialValue.h:
(WebCore::CSSInitialValue::equals):
(CSSInitialValue):
* css/CSSLineBoxContainValue.h:
(WebCore::CSSLineBoxContainValue::equals):
* css/CSSPrimitiveValue.cpp:
(WebCore::CSSPrimitiveValue::equals):
(WebCore):
* css/CSSPrimitiveValue.h:
(CSSPrimitiveValue):
* css/CSSReflectValue.cpp:
(WebCore::CSSReflectValue::equals):
(WebCore):
* css/CSSReflectValue.h:
(CSSReflectValue):
* css/CSSTimingFunctionValue.cpp:
(WebCore::CSSCubicBezierTimingFunctionValue::equals):
(WebCore):
(WebCore::CSSStepsTimingFunctionValue::equals):
* css/CSSTimingFunctionValue.h:
(WebCore::CSSLinearTimingFunctionValue::equals):
(CSSLinearTimingFunctionValue):
(CSSCubicBezierTimingFunctionValue):
(CSSStepsTimingFunctionValue):
* css/CSSUnicodeRangeValue.cpp:
(WebCore::CSSUnicodeRangeValue::equals):
(WebCore):
* css/CSSUnicodeRangeValue.h:
(CSSUnicodeRangeValue):
* css/CSSValue.cpp:
(WebCore):
(WebCore::compareCSSValues):
(WebCore::CSSValue::equals):
* css/CSSValue.h:
(CSSValue):
(WebCore):
(WebCore::compareCSSValueVector):
(WebCore::compareCSSValuePtr):
* css/CSSValueList.cpp:
(WebCore::CSSValueList::removeAll):
(WebCore::CSSValueList::hasValue):
(WebCore::CSSValueList::equals):
(WebCore):
* css/CSSValueList.h:
(CSSValueList):
* css/CSSVariableValue.h:
(WebCore::CSSVariableValue::equals):
(CSSVariableValue):
* css/Counter.h:
(Counter):
(WebCore::Counter::equals):
* css/DashboardRegion.h:
(WebCore::DashboardRegion::equals):
* css/FontFeatureValue.cpp:
(WebCore::FontFeatureValue::equals):
(WebCore):
* css/FontFeatureValue.h:
(FontFeatureValue):
* css/FontValue.cpp:
(WebCore::FontValue::equals):
(WebCore):
* css/FontValue.h:
(FontValue):
* css/MediaQueryExp.h:
(WebCore::MediaQueryExp::operator==):
* css/Pair.h:
(WebCore::Pair::equals):
(Pair):
* css/Rect.h:
(WebCore::RectBase::equals):
(RectBase):
* css/ShadowValue.cpp:
(WebCore::ShadowValue::equals):
(WebCore):
* css/ShadowValue.h:
(ShadowValue):
* css/StylePropertySet.cpp:
(WebCore::StylePropertySet::get4Values):
(WebCore::StylePropertySet::propertyMatches):
* css/WebKitCSSArrayFunctionValue.cpp:
(WebCore::WebKitCSSArrayFunctionValue::equals):
(WebCore):
* css/WebKitCSSArrayFunctionValue.h:
(WebKitCSSArrayFunctionValue):
* css/WebKitCSSFilterValue.cpp:
(WebCore::WebKitCSSFilterValue::equals):
(WebCore):
* css/WebKitCSSFilterValue.h:
(WebKitCSSFilterValue):
* css/WebKitCSSMixFunctionValue.cpp:
(WebCore::WebKitCSSMixFunctionValue::equals):
(WebCore):
* css/WebKitCSSMixFunctionValue.h:
(WebKitCSSMixFunctionValue):
* css/WebKitCSSSVGDocumentValue.cpp:
(WebCore::WebKitCSSSVGDocumentValue::equals):
(WebCore):
* css/WebKitCSSSVGDocumentValue.h:
(WebKitCSSSVGDocumentValue):
* css/WebKitCSSShaderValue.cpp:
(WebCore::WebKitCSSShaderValue::equals):
(WebCore):
* css/WebKitCSSShaderValue.h:
(WebKitCSSShaderValue):
* css/WebKitCSSTransformValue.h:
(WebCore::WebKitCSSTransformValue::equals):
* editing/EditingStyle.cpp:
(WebCore::HTMLAttributeEquivalent::valueIsPresentInStyle):
* svg/SVGColor.cpp:
(WebCore::SVGColor::equals):
(WebCore):
* svg/SVGColor.h:
(SVGColor):
* svg/SVGPaint.cpp:
(WebCore::SVGPaint::equals):
(WebCore):
* svg/SVGPaint.h:
(SVGPaint):

LayoutTests:

New layout test to verify that CSSValue objects comparison works properly.

* cssom/cssvalue-comparison-expected.txt: Added.
* cssom/cssvalue-comparison.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@142444 268f45cc-cd09-0410-ab3c-d52691b4dbfc

71 files changed:
LayoutTests/ChangeLog
LayoutTests/cssom/cssvalue-comparison-expected.txt [new file with mode: 0644]
LayoutTests/cssom/cssvalue-comparison.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/CSSAspectRatioValue.cpp
Source/WebCore/css/CSSAspectRatioValue.h
Source/WebCore/css/CSSBasicShapes.cpp
Source/WebCore/css/CSSBasicShapes.h
Source/WebCore/css/CSSBorderImageSliceValue.cpp
Source/WebCore/css/CSSBorderImageSliceValue.h
Source/WebCore/css/CSSCalculationValue.cpp
Source/WebCore/css/CSSCalculationValue.h
Source/WebCore/css/CSSCanvasValue.cpp
Source/WebCore/css/CSSCanvasValue.h
Source/WebCore/css/CSSComputedStyleDeclaration.cpp
Source/WebCore/css/CSSCrossfadeValue.cpp
Source/WebCore/css/CSSCrossfadeValue.h
Source/WebCore/css/CSSCursorImageValue.cpp
Source/WebCore/css/CSSCursorImageValue.h
Source/WebCore/css/CSSFontFaceSrcValue.cpp
Source/WebCore/css/CSSFontFaceSrcValue.h
Source/WebCore/css/CSSFunctionValue.cpp
Source/WebCore/css/CSSFunctionValue.h
Source/WebCore/css/CSSGradientValue.cpp
Source/WebCore/css/CSSGradientValue.h
Source/WebCore/css/CSSImageValue.cpp
Source/WebCore/css/CSSImageValue.h
Source/WebCore/css/CSSInheritedValue.h
Source/WebCore/css/CSSInitialValue.h
Source/WebCore/css/CSSLineBoxContainValue.h
Source/WebCore/css/CSSPrimitiveValue.cpp
Source/WebCore/css/CSSPrimitiveValue.h
Source/WebCore/css/CSSReflectValue.cpp
Source/WebCore/css/CSSReflectValue.h
Source/WebCore/css/CSSTimingFunctionValue.cpp
Source/WebCore/css/CSSTimingFunctionValue.h
Source/WebCore/css/CSSUnicodeRangeValue.cpp
Source/WebCore/css/CSSUnicodeRangeValue.h
Source/WebCore/css/CSSValue.cpp
Source/WebCore/css/CSSValue.h
Source/WebCore/css/CSSValueList.cpp
Source/WebCore/css/CSSValueList.h
Source/WebCore/css/CSSVariableValue.h
Source/WebCore/css/Counter.h
Source/WebCore/css/DashboardRegion.h
Source/WebCore/css/FontFeatureValue.cpp
Source/WebCore/css/FontFeatureValue.h
Source/WebCore/css/FontValue.cpp
Source/WebCore/css/FontValue.h
Source/WebCore/css/MediaQueryExp.h
Source/WebCore/css/Pair.h
Source/WebCore/css/Rect.h
Source/WebCore/css/ShadowValue.cpp
Source/WebCore/css/ShadowValue.h
Source/WebCore/css/StylePropertySet.cpp
Source/WebCore/css/WebKitCSSArrayFunctionValue.cpp
Source/WebCore/css/WebKitCSSArrayFunctionValue.h
Source/WebCore/css/WebKitCSSFilterValue.cpp
Source/WebCore/css/WebKitCSSFilterValue.h
Source/WebCore/css/WebKitCSSMixFunctionValue.cpp
Source/WebCore/css/WebKitCSSMixFunctionValue.h
Source/WebCore/css/WebKitCSSSVGDocumentValue.cpp
Source/WebCore/css/WebKitCSSSVGDocumentValue.h
Source/WebCore/css/WebKitCSSShaderValue.cpp
Source/WebCore/css/WebKitCSSShaderValue.h
Source/WebCore/css/WebKitCSSTransformValue.h
Source/WebCore/editing/EditingStyle.cpp
Source/WebCore/svg/SVGColor.cpp
Source/WebCore/svg/SVGColor.h
Source/WebCore/svg/SVGPaint.cpp
Source/WebCore/svg/SVGPaint.h

index 9dc8535327a3b348e9f32a35bc1f4659addd24d2..7f0fb60d930ef6f8b9fac8f0450cc5c2aa33e238 100644 (file)
@@ -1,3 +1,15 @@
+2013-02-11  Alexander Shalamov  <alexander.shalamov@intel.com>
+
+        Implement CSSValue::equals(const CSSValue&) to optimise CSSValue comparison
+        https://bugs.webkit.org/show_bug.cgi?id=102901
+
+        Reviewed by Antti Koivisto.
+
+        New layout test to verify that CSSValue objects comparison works properly.
+
+        * cssom/cssvalue-comparison-expected.txt: Added.
+        * cssom/cssvalue-comparison.html: Added.
+
 2013-02-11  Kentaro Hara  <haraken@chromium.org>
 
         Unreviewed gardening. Mark svg/custom/foreign-object-skew.svg
diff --git a/LayoutTests/cssom/cssvalue-comparison-expected.txt b/LayoutTests/cssom/cssvalue-comparison-expected.txt
new file mode 100644 (file)
index 0000000..187839d
--- /dev/null
@@ -0,0 +1,103 @@
+This test verifies that CSSValue objects comparison works correctly.
+
+
+PASS Two CSSValues "20%" for property "width" are equal. 
+PASS Two CSSValues "2em" for property "width" are equal. 
+PASS Two CSSValues "2rem" for property "width" are equal. 
+PASS Two CSSValues "20px" for property "width" are equal. 
+PASS Two CSSValues "2cm" for property "width" are equal. 
+PASS Two CSSValues "20mm" for property "width" are equal. 
+PASS Two CSSValues "4in" for property "width" are equal. 
+PASS Two CSSValues "20pt" for property "width" are equal. 
+PASS Two CSSValues "10pc" for property "width" are equal. 
+PASS Two CSSValues "6vw" for property "width" are equal. 
+PASS Two CSSValues "6vh" for property "width" are equal. 
+PASS Two CSSValues "4vmin" for property "width" are equal. 
+PASS Two CSSValues "-webkit-calc(-100px + 100%)" for property "width" are equal. 
+PASS Two CSSValues "20%" and "2em" for property "width" are not equal. 
+PASS Two CSSValues "rotate(15deg)" for property "-webkit-transform" are equal. 
+PASS Two CSSValues "rotate(1.55rad)" for property "-webkit-transform" are equal. 
+PASS Two CSSValues "rotate(200grad)" for property "-webkit-transform" are equal. 
+PASS Two CSSValues "rotate(0.5turn)" for property "-webkit-transform" are equal. 
+PASS Two CSSValues "rotate(15deg)" and "rotate(1.55rad)" for property "-webkit-transform" are not equal. 
+PASS Two CSSValues "url(dummy://test.png)" for property "background" are equal. 
+PASS Two CSSValues "url(dummy://green.png)" for property "background" are equal. 
+PASS Two CSSValues "url(dummy://test.png)" and "url(dummy://green.png)" for property "background" are not equal. 
+PASS Two CSSValues "bold" for property "font-weight" are equal. 
+PASS Two CSSValues "inherit" for property "font-weight" are equal. 
+PASS Two CSSValues "bold" and "inherit" for property "font-weight" are not equal. 
+PASS Two CSSValues "counter(a)" for property "content" are equal. 
+PASS Two CSSValues "counters(a, '.')" for property "content" are equal. 
+PASS Two CSSValues "counter(a)" and "counters(a, '.')" for property "content" are not equal. 
+PASS Two CSSValues "attr(a)" for property "content" are equal. 
+PASS Two CSSValues "attr(p)" for property "content" are equal. 
+PASS Two CSSValues "attr(a)" and "attr(p)" for property "content" are not equal. 
+PASS Two CSSValues "rect(40px, 0, 45px, -5px)" for property "clip" are equal. 
+PASS Two CSSValues "rect(10px, 5px, 15px, -10px)" for property "clip" are equal. 
+PASS Two CSSValues "rect(40px, 0, 45px, -5px)" and "rect(10px, 5px, 15px, -10px)" for property "clip" are not equal. 
+PASS Two CSSValues "30px 75px 15px 15px" for property "border-radius" are equal. 
+PASS Two CSSValues "164px / 82px" for property "border-radius" are equal. 
+PASS Two CSSValues "40px" for property "border-radius" are equal. 
+PASS Two CSSValues "30px 75px 15px 15px" and "164px / 82px" for property "border-radius" are not equal. 
+PASS Two CSSValues "rgb(255,0,0)" for property "stop-color" are equal. 
+PASS Two CSSValues "#FF5566" for property "stop-color" are equal. 
+PASS Two CSSValues "rgb(255,0,0)" and "#FF5566" for property "stop-color" are not equal. 
+PASS Two CSSValues "polygon(evenodd, 10px 75px, 180px 180px, 100px 10px, 10px 180px, 180px 75px, 10px 75px)" for property "-webkit-clip-path" are equal. 
+PASS Two CSSValues "polygon(nonzero, 20% 20%, 80% 20%, 80% 80%, 20% 80%)" for property "-webkit-clip-path" are equal. 
+PASS Two CSSValues "polygon(evenodd, 10px 75px, 180px 180px, 100px 10px, 10px 180px, 180px 75px, 10px 75px)" and "polygon(nonzero, 20% 20%, 80% 20%, 80% 80%, 20% 80%)" for property "-webkit-clip-path" are not equal. 
+PASS Two CSSValues "10s" for property "-webkit-animation-duration" are equal. 
+PASS Two CSSValues "100ms" for property "-webkit-animation-duration" are equal. 
+PASS Two CSSValues "10s" and "100ms" for property "-webkit-animation-duration" are not equal. 
+PASS Two CSSValues "red" for property "color" are equal. 
+PASS Two CSSValues "blue" for property "color" are equal. 
+PASS Two CSSValues "red" and "blue" for property "color" are not equal. 
+PASS Two CSSValues "url(resources/greenbox.png)" for property "border-image-source" are equal. 
+PASS Two CSSValues "url(resources/redbox.png)" for property "border-image-source" are equal. 
+PASS Two CSSValues "url(resources/greenbox.png)" and "url(resources/redbox.png)" for property "border-image-source" are not equal. 
+PASS Two CSSValues "1 2 3 4" for property "border-image-slice" are equal. 
+PASS Two CSSValues "2 3 4 5" for property "border-image-slice" are equal. 
+PASS Two CSSValues "1 2 3 4" and "2 3 4 5" for property "border-image-slice" are not equal. 
+PASS Two CSSValues "url(resources/greenbox.png) 0 0, pointer" for property "cursor" are equal. 
+PASS Two CSSValues "url(resources/cursor.png) 1 1, wait" for property "cursor" are equal. 
+PASS Two CSSValues "url(resources/greenbox.png) 0 0, pointer" and "url(resources/cursor.png) 1 1, wait" for property "cursor" are not equal. 
+PASS Two CSSValues "italic bold 12px/30px arial" for property "font" are equal. 
+PASS Two CSSValues "italic bold 8px/16px helvetica" for property "font" are equal. 
+PASS Two CSSValues "italic bold 12px/30px arial" and "italic bold 8px/16px helvetica" for property "font" are not equal. 
+PASS Two CSSValues "-webkit-gradient(linear, left top, left bottom, from(#ccc), to(#000))" for property "background" are equal. 
+PASS Two CSSValues "-webkit-gradient(radial, 45 45, 0, 52 50, 0, from(#A7D30C), to(rgba(1,159,98,0)), color-stop(90%, #019F62))" for property "background" are equal. 
+PASS Two CSSValues "-webkit-gradient(linear, left top, left bottom, from(#ccc), to(#000))" and "-webkit-gradient(radial, 45 45, 0, 52 50, 0, from(#A7D30C), to(rgba(1,159,98,0)), color-stop(90%, #019F62))" for property "background" are not equal. 
+PASS Two CSSValues "-webkit-cross-fade(url(dummy://example.png), url(dummy://example.png), 50%)" for property "background-image" are equal. 
+PASS Two CSSValues "-webkit-cross-fade(url(dummy://background.png), url(dummy://foreground.png), 80%)" for property "background-image" are equal. 
+PASS Two CSSValues "-webkit-cross-fade(url(dummy://example.png), url(dummy://example.png), 50%)" and "-webkit-cross-fade(url(dummy://background.png), url(dummy://foreground.png), 80%)" for property "background-image" are not equal. 
+PASS Two CSSValues "below 10px" for property "-webkit-box-reflect" are equal. 
+PASS Two CSSValues "below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), to(rgba(10, 55, 234, 1)))" for property "-webkit-box-reflect" are equal. 
+PASS Two CSSValues "below 10px" and "below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), to(rgba(10, 55, 234, 1)))" for property "-webkit-box-reflect" are not equal. 
+PASS Two CSSValues "0 -20px 10px red, 0 20px 10px blue" for property "-webkit-box-shadow" are equal. 
+PASS Two CSSValues "0 20px 10px blue" for property "-webkit-box-shadow" are equal. 
+PASS Two CSSValues "5px 5px 5px rgba(0, 0, 0, 0.3)" for property "-webkit-box-shadow" are equal. 
+PASS Two CSSValues "0 -20px 10px red, 0 20px 10px blue" and "0 20px 10px blue" for property "-webkit-box-shadow" are not equal. 
+PASS Two CSSValues "cubic-bezier(0.25, 0.1, 0.25, 1)" for property "-webkit-transition-timing-function" are equal. 
+PASS Two CSSValues "linear" for property "-webkit-transition-timing-function" are equal. 
+PASS Two CSSValues "steps(3, end)" for property "-webkit-transition-timing-function" are equal. 
+PASS Two CSSValues "cubic-bezier(0.25, 0.1, 0.25, 1)" and "linear" for property "-webkit-transition-timing-function" are not equal. 
+PASS Two CSSValues "rotate(30deg)" for property "-webkit-transform" are equal. 
+PASS Two CSSValues "translate(50px,50px)" for property "-webkit-transform" are equal. 
+PASS Two CSSValues "scale(2,4)" for property "-webkit-transform" are equal. 
+PASS Two CSSValues "skew(30deg,20deg)" for property "-webkit-transform" are equal. 
+PASS Two CSSValues "matrix(0.4,0.5,-0.5,0.4,0,0)" for property "-webkit-transform" are equal. 
+PASS Two CSSValues "rotate(30deg)" and "translate(50px,50px)" for property "-webkit-transform" are not equal. 
+PASS Two CSSValues "inline-box" for property "-webkit-line-box-contain" are equal. 
+PASS Two CSSValues "font" for property "-webkit-line-box-contain" are equal. 
+PASS Two CSSValues "glyphs" for property "-webkit-line-box-contain" are equal. 
+PASS Two CSSValues "replaced" for property "-webkit-line-box-contain" are equal. 
+PASS Two CSSValues "inline-box" and "font" for property "-webkit-line-box-contain" are not equal. 
+PASS Two CSSValues "-webkit-image-set(url(dummy://test.png) 1x, url(dummy://test.png) 2x)" for property "background-image" are equal. 
+PASS Two CSSValues "-webkit-image-set(url(dummy://small.png) 2x, url(dummy://big.png) 3x)" for property "background-image" are equal. 
+PASS Two CSSValues "-webkit-image-set(url(dummy://test.png) 1x, url(dummy://test.png) 2x)" and "-webkit-image-set(url(dummy://small.png) 2x, url(dummy://big.png) 3x)" for property "background-image" are not equal. 
+PASS Two CSSValues "grayscale(100%) sepia(100%)" for property "-webkit-filter" are equal. 
+PASS Two CSSValues "sepia(10%) grayscale(50%)" for property "-webkit-filter" are equal. 
+PASS Two CSSValues "grayscale(100%) sepia(100%)" and "sepia(10%) grayscale(50%)" for property "-webkit-filter" are not equal. 
+PASS Two CSSValues "dashboard-region(label circle)" for property "-webkit-dashboard-region" are equal. 
+PASS Two CSSValues "dashboard-region(label circle 1px 2px 3px 4px) dashboard-region(label rectangle 5px 6px 7px 8px)" for property "-webkit-dashboard-region" are equal. 
+PASS Two CSSValues "dashboard-region(label circle)" and "dashboard-region(label circle 1px 2px 3px 4px) dashboard-region(label rectangle 5px 6px 7px 8px)" for property "-webkit-dashboard-region" are not equal. 
+
diff --git a/LayoutTests/cssom/cssvalue-comparison.html b/LayoutTests/cssom/cssvalue-comparison.html
new file mode 100644 (file)
index 0000000..1a73128
--- /dev/null
@@ -0,0 +1,84 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>CSSValue comparison test</title>
+  <script type="text/javascript" src="../resources/testharness.js"></script>
+  <script type="text/javascript" src="../resources/testharnessreport.js"></script>
+</head>
+<body onload="run()">
+<p>This test verifies that CSSValue objects comparison works correctly.</p>
+<div id="test" contenteditable></div>
+
+<script type="text/javascript">
+setup({ "explicit_done": true });
+
+function run() {
+    var styleElement = document.createElement("style");
+    styleElement.type = "text/css";
+    var styleTextNode = document.createTextNode("");
+    styleElement.appendChild(styleTextNode);
+    document.getElementsByTagName("head")[0].appendChild(styleElement);
+
+    var div = document.getElementById("test");
+    div.focus();
+
+    function runTest(propertyName, styleSheetPropertyValue, inlineStylePropertyValue, expectedResult) {
+      styleTextNode.data = "div { " + propertyName + " : " + styleSheetPropertyValue + "; }";
+      document.execCommand('insertHTML', false, "<div id=\"insertedDiv\" style=\"" + propertyName + " : " + inlineStylePropertyValue + "; \"></div>");
+      var insertedDiv = document.getElementById('insertedDiv');
+      var result = expectedResult;
+      if (propertyName in insertedDiv.style)
+          result = insertedDiv.style[propertyName] === "";
+      insertedDiv.remove();
+      return result;
+    }
+
+   var tests = [ {"width" : ["20%", "2em", "2rem", "20px", "2cm", "20mm", "4in", "20pt", "10pc", "6vw", "6vh", "4vmin", "-webkit-calc(-100px + 100%)"]}, // lengths, calc
+                  {"-webkit-transform" : ["rotate(15deg)", "rotate(1.55rad)", "rotate(200grad)", "rotate(0.5turn)"]}, // angle
+                  {"background" : ["url(dummy://test.png)", "url(dummy://green.png)"]}, // uri
+                  {"font-weight" : ["bold", "inherit"]}, // ident
+                  {"content" : ["counter(a)", "counters(a, '.')"]}, // counter
+                  {"content" : ["attr(a)", "attr(p)"]}, // attr
+                  {"clip" : ["rect(40px, 0, 45px, -5px)", "rect(10px, 5px, 15px, -10px)"]}, // rect
+                  {"border-radius" : ["30px 75px 15px 15px", "164px / 82px", "40px"]}, // quads
+                  {"stop-color" : ["rgb(255,0,0)", "#FF5566"]}, // hex, rgb color
+                  {"-webkit-clip-path" : ["polygon(evenodd, 10px 75px, 180px 180px, 100px 10px, 10px 180px, 180px 75px, 10px 75px)", "polygon(nonzero, 20% 20%, 80% 20%, 80% 80%, 20% 80%)"]}, // shape value
+                  {"-webkit-animation-duration" : ["10s", "100ms"]}, // seconds, milliseconds
+                  {"color" : ["red", "blue"]}, // ident
+                  {"border-image-source" : ["url(resources/greenbox.png)", "url(resources/redbox.png)"]}, // image
+                  {"border-image-slice" : ["1 2 3 4", "2 3 4 5"]}, // border image slice
+                  {"cursor" : ["url(resources/greenbox.png) 0 0, pointer", "url(resources/cursor.png) 1 1, wait"]}, // cursor
+                  {"font" : ["italic bold 12px/30px arial", "italic bold 8px/16px helvetica"]}, // font
+                  {"background" : ["-webkit-gradient(linear, left top, left bottom, from(#ccc), to(#000))", "-webkit-gradient(radial, 45 45, 0, 52 50, 0, from(#A7D30C), to(rgba(1,159,98,0)), color-stop(90%, #019F62))"]}, // gradients
+                  {"background-image" : ["-webkit-cross-fade(url(dummy://example.png), url(dummy://example.png), 50%)", "-webkit-cross-fade(url(dummy://background.png), url(dummy://foreground.png), 80%)"]}, // crossfade
+                  {"-webkit-box-reflect" : ["below 10px", "below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), to(rgba(10, 55, 234, 1)))"]}, // reflect
+                  {"-webkit-box-shadow" : ["0 -20px 10px red, 0 20px 10px blue", "0 20px 10px blue", "5px 5px 5px rgba(0, 0, 0, 0.3)"]}, // shadow
+                  {"-webkit-transition-timing-function" : ["cubic-bezier(0.25, 0.1, 0.25, 1)", "linear", "steps(3, end)"]}, // timing functions
+                  {"-webkit-transform" : ["rotate(30deg)", "translate(50px,50px)", "scale(2,4)", "skew(30deg,20deg)", "matrix(0.4,0.5,-0.5,0.4,0,0)"]}, // transforms
+                  {"-webkit-line-box-contain" : ["inline-box", "font", "glyphs", "replaced"]}, // line-box-contain
+                  {"background-image" : ["-webkit-image-set(url(dummy://test.png) 1x, url(dummy://test.png) 2x)", "-webkit-image-set(url(dummy://small.png) 2x, url(dummy://big.png) 3x)"]}, // image set
+                  {"-webkit-filter" : ["grayscale(100%) sepia(100%)", "sepia(10%) grayscale(50%)"]}, // filter
+                  {"-webkit-dashboard-region" : ["dashboard-region(label circle)", "dashboard-region(label circle 1px 2px 3px 4px) dashboard-region(label rectangle 5px 6px 7px 8px)"]} // dashboard region
+                ];
+
+   for (var index in tests) {
+        var testMap = tests[index];
+        for (var key in testMap) {
+            var testValues = testMap[key];
+
+            // Tests for equality.
+            for(var testIndex in testValues)
+                test(function() {assert_true(runTest(key, testValues[testIndex], testValues[testIndex], true))}, "Two CSSValues \"" + testValues[testIndex] + "\" for property \"" + key + "\" are equal.");
+
+            // Test that comparison of non-equal cssvalues return false.
+            if (testValues.length > 1)
+                test(function() {assert_false(runTest(key, testValues[0], testValues[1], false))}, "Two CSSValues \"" + testValues[0] + "\" and \"" + testValues[1] + "\" for property \"" + key + "\" are not equal.");
+        }
+    }
+
+    done();
+}
+
+</script>
+</body>
+</html>
index 09b7c1631dca92d7654230fc79034a08cf6b413d..19224b8b163c40ad9403ce6eacb25a51d116ff95 100644 (file)
@@ -1,3 +1,214 @@
+2013-02-11  Alexander Shalamov  <alexander.shalamov@intel.com>
+
+        Implement CSSValue::equals(const CSSValue&) to optimise CSSValue comparison
+        https://bugs.webkit.org/show_bug.cgi?id=102901
+
+        Reviewed by Antti Koivisto.
+
+        Added comparison method to CSSValue and its children, so that the
+        css values could be compared efficiently. Before this patch, CSSValue
+        objects were compared using strings that were generated by the cssText() method.
+
+        Test: cssom/cssvalue-comparison.html
+
+        * css/CSSAspectRatioValue.cpp:
+        (WebCore::CSSAspectRatioValue::equals):
+        (WebCore):
+        * css/CSSAspectRatioValue.h:
+        (CSSAspectRatioValue):
+        * css/CSSBasicShapes.cpp:
+        (WebCore::CSSBasicShapeRectangle::equals):
+        (WebCore):
+        (WebCore::CSSBasicShapeCircle::equals):
+        (WebCore::CSSBasicShapeEllipse::equals):
+        (WebCore::CSSBasicShapePolygon::equals):
+        * css/CSSBasicShapes.h:
+        (CSSBasicShapeRectangle):
+        (CSSBasicShapeCircle):
+        (CSSBasicShapeEllipse):
+        (CSSBasicShapePolygon):
+        * css/CSSBorderImageSliceValue.cpp:
+        (WebCore::CSSBorderImageSliceValue::equals):
+        (WebCore):
+        * css/CSSBorderImageSliceValue.h:
+        (CSSBorderImageSliceValue):
+        * css/CSSCalculationValue.cpp:
+        (WebCore::CSSCalcValue::equals):
+        (WebCore):
+        (WebCore::CSSCalcPrimitiveValue::equals):
+        (CSSCalcPrimitiveValue):
+        (WebCore::CSSCalcPrimitiveValue::type):
+        (WebCore::CSSCalcBinaryOperation::equals):
+        (CSSCalcBinaryOperation):
+        (WebCore::CSSCalcBinaryOperation::type):
+        * css/CSSCalculationValue.h:
+        (WebCore::CSSCalcExpressionNode::equals):
+        (CSSCalcExpressionNode):
+        (CSSCalcValue):
+        * css/CSSCanvasValue.cpp:
+        (WebCore::CSSCanvasValue::equals):
+        (WebCore):
+        * css/CSSCanvasValue.h:
+        (CSSCanvasValue):
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
+        (WebCore::CSSComputedStyleDeclaration::cssPropertyMatches):
+        (WebCore::CSSComputedStyleDeclaration::getCSSPropertyValuesForSidesShorthand):
+        * css/CSSCrossfadeValue.cpp:
+        (WebCore::CSSCrossfadeValue::equals):
+        (WebCore):
+        * css/CSSCrossfadeValue.h:
+        (CSSCrossfadeValue):
+        * css/CSSCursorImageValue.cpp:
+        (WebCore::CSSCursorImageValue::equals):
+        (WebCore):
+        * css/CSSCursorImageValue.h:
+        (CSSCursorImageValue):
+        * css/CSSFontFaceSrcValue.cpp:
+        (WebCore::CSSFontFaceSrcValue::equals):
+        (WebCore):
+        * css/CSSFontFaceSrcValue.h:
+        (CSSFontFaceSrcValue):
+        * css/CSSFunctionValue.cpp:
+        (WebCore::CSSFunctionValue::equals):
+        (WebCore):
+        * css/CSSFunctionValue.h:
+        (CSSFunctionValue):
+        * css/CSSGradientValue.cpp:
+        (WebCore::CSSLinearGradientValue::equals):
+        (WebCore):
+        (WebCore::CSSRadialGradientValue::equals):
+        * css/CSSGradientValue.h:
+        (WebCore::CSSGradientColorStop::operator==):
+        (CSSLinearGradientValue):
+        (CSSRadialGradientValue):
+        * css/CSSImageValue.cpp:
+        (WebCore::CSSImageValue::equals):
+        (WebCore):
+        * css/CSSImageValue.h:
+        (CSSImageValue):
+        * css/CSSInheritedValue.h:
+        (WebCore::CSSInheritedValue::equals):
+        (CSSInheritedValue):
+        * css/CSSInitialValue.h:
+        (WebCore::CSSInitialValue::equals):
+        (CSSInitialValue):
+        * css/CSSLineBoxContainValue.h:
+        (WebCore::CSSLineBoxContainValue::equals):
+        * css/CSSPrimitiveValue.cpp:
+        (WebCore::CSSPrimitiveValue::equals):
+        (WebCore):
+        * css/CSSPrimitiveValue.h:
+        (CSSPrimitiveValue):
+        * css/CSSReflectValue.cpp:
+        (WebCore::CSSReflectValue::equals):
+        (WebCore):
+        * css/CSSReflectValue.h:
+        (CSSReflectValue):
+        * css/CSSTimingFunctionValue.cpp:
+        (WebCore::CSSCubicBezierTimingFunctionValue::equals):
+        (WebCore):
+        (WebCore::CSSStepsTimingFunctionValue::equals):
+        * css/CSSTimingFunctionValue.h:
+        (WebCore::CSSLinearTimingFunctionValue::equals):
+        (CSSLinearTimingFunctionValue):
+        (CSSCubicBezierTimingFunctionValue):
+        (CSSStepsTimingFunctionValue):
+        * css/CSSUnicodeRangeValue.cpp:
+        (WebCore::CSSUnicodeRangeValue::equals):
+        (WebCore):
+        * css/CSSUnicodeRangeValue.h:
+        (CSSUnicodeRangeValue):
+        * css/CSSValue.cpp:
+        (WebCore):
+        (WebCore::compareCSSValues):
+        (WebCore::CSSValue::equals):
+        * css/CSSValue.h:
+        (CSSValue):
+        (WebCore):
+        (WebCore::compareCSSValueVector):
+        (WebCore::compareCSSValuePtr):
+        * css/CSSValueList.cpp:
+        (WebCore::CSSValueList::removeAll):
+        (WebCore::CSSValueList::hasValue):
+        (WebCore::CSSValueList::equals):
+        (WebCore):
+        * css/CSSValueList.h:
+        (CSSValueList):
+        * css/CSSVariableValue.h:
+        (WebCore::CSSVariableValue::equals):
+        (CSSVariableValue):
+        * css/Counter.h:
+        (Counter):
+        (WebCore::Counter::equals):
+        * css/DashboardRegion.h:
+        (WebCore::DashboardRegion::equals):
+        * css/FontFeatureValue.cpp:
+        (WebCore::FontFeatureValue::equals):
+        (WebCore):
+        * css/FontFeatureValue.h:
+        (FontFeatureValue):
+        * css/FontValue.cpp:
+        (WebCore::FontValue::equals):
+        (WebCore):
+        * css/FontValue.h:
+        (FontValue):
+        * css/MediaQueryExp.h:
+        (WebCore::MediaQueryExp::operator==):
+        * css/Pair.h:
+        (WebCore::Pair::equals):
+        (Pair):
+        * css/Rect.h:
+        (WebCore::RectBase::equals):
+        (RectBase):
+        * css/ShadowValue.cpp:
+        (WebCore::ShadowValue::equals):
+        (WebCore):
+        * css/ShadowValue.h:
+        (ShadowValue):
+        * css/StylePropertySet.cpp:
+        (WebCore::StylePropertySet::get4Values):
+        (WebCore::StylePropertySet::propertyMatches):
+        * css/WebKitCSSArrayFunctionValue.cpp:
+        (WebCore::WebKitCSSArrayFunctionValue::equals):
+        (WebCore):
+        * css/WebKitCSSArrayFunctionValue.h:
+        (WebKitCSSArrayFunctionValue):
+        * css/WebKitCSSFilterValue.cpp:
+        (WebCore::WebKitCSSFilterValue::equals):
+        (WebCore):
+        * css/WebKitCSSFilterValue.h:
+        (WebKitCSSFilterValue):
+        * css/WebKitCSSMixFunctionValue.cpp:
+        (WebCore::WebKitCSSMixFunctionValue::equals):
+        (WebCore):
+        * css/WebKitCSSMixFunctionValue.h:
+        (WebKitCSSMixFunctionValue):
+        * css/WebKitCSSSVGDocumentValue.cpp:
+        (WebCore::WebKitCSSSVGDocumentValue::equals):
+        (WebCore):
+        * css/WebKitCSSSVGDocumentValue.h:
+        (WebKitCSSSVGDocumentValue):
+        * css/WebKitCSSShaderValue.cpp:
+        (WebCore::WebKitCSSShaderValue::equals):
+        (WebCore):
+        * css/WebKitCSSShaderValue.h:
+        (WebKitCSSShaderValue):
+        * css/WebKitCSSTransformValue.h:
+        (WebCore::WebKitCSSTransformValue::equals):
+        * editing/EditingStyle.cpp:
+        (WebCore::HTMLAttributeEquivalent::valueIsPresentInStyle):
+        * svg/SVGColor.cpp:
+        (WebCore::SVGColor::equals):
+        (WebCore):
+        * svg/SVGColor.h:
+        (SVGColor):
+        * svg/SVGPaint.cpp:
+        (WebCore::SVGPaint::equals):
+        (WebCore):
+        * svg/SVGPaint.h:
+        (SVGPaint):
+
 2013-02-11  Pan Deng  <pan.deng@intel.com>
 
         [Web Inspector] Network panel, sort by "transferSize" instead of "resourceSize".
index 830f8cf7992d7307d10c5377360b9e00f5361916..cde0f335d826453565369bde229b24d3407acd92 100644 (file)
@@ -39,6 +39,11 @@ String CSSAspectRatioValue::customCssText() const
     return String::number(m_numeratorValue) + '/' + String::number(m_denominatorValue);
 }
 
+bool CSSAspectRatioValue::equals(const CSSAspectRatioValue& other) const
+{
+    return m_numeratorValue == other.m_numeratorValue && m_denominatorValue == other.m_denominatorValue;
+}
+
 void CSSAspectRatioValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index 5cc339249bb5131ab6665d1e2820b4d8d782d41f..d9c5ded1d655c4ee57e64c94ca5532e0e6c2d8b7 100644 (file)
@@ -46,6 +46,8 @@ public:
     float numeratorValue() const { return m_numeratorValue; }
     float denominatorValue() const { return m_denominatorValue; }
 
+    bool equals(const CSSAspectRatioValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index 3fda6b1d1eeb3e77b076d9aa4fedb2d742c7aa71..1974e600d4328d1cb50b332092f4b7e55e9780cc 100644 (file)
@@ -30,6 +30,7 @@
 #include "config.h"
 
 #include "CSSBasicShapes.h"
+#include "CSSPrimitiveValueMappings.h"
 
 #include <wtf/text/StringBuilder.h>
 
@@ -74,6 +75,20 @@ String CSSBasicShapeRectangle::cssText() const
         m_radiusY.get() ? m_radiusY->cssText() : String());
 }
 
+bool CSSBasicShapeRectangle::equals(const CSSBasicShape& shape) const
+{
+    if (shape.type() != CSS_BASIC_SHAPE_RECTANGLE)
+        return false;
+
+    const CSSBasicShapeRectangle& other = static_cast<const CSSBasicShapeRectangle&>(shape);
+    return compareCSSValuePtr(m_x, other.m_x)
+        && compareCSSValuePtr(m_y, other.m_y)
+        && compareCSSValuePtr(m_width, other.m_width)
+        && compareCSSValuePtr(m_height, other.m_height)
+        && compareCSSValuePtr(m_radiusX, other.m_radiusX)
+        && compareCSSValuePtr(m_radiusY, other.m_radiusY);
+}
+
 #if ENABLE(CSS_VARIABLES)
 String CSSBasicShapeRectangle::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
 {
@@ -106,6 +121,17 @@ String CSSBasicShapeCircle::cssText() const
     return buildCircleString(m_centerX->cssText(), m_centerY->cssText(), m_radius->cssText());
 }
 
+bool CSSBasicShapeCircle::equals(const CSSBasicShape& shape) const
+{
+    if (shape.type() != CSS_BASIC_SHAPE_CIRCLE)
+        return false;
+
+    const CSSBasicShapeCircle& other = static_cast<const CSSBasicShapeCircle&>(shape);
+    return compareCSSValuePtr(m_centerX, other.m_centerX)
+        && compareCSSValuePtr(m_centerY, other.m_centerY)
+        && compareCSSValuePtr(m_radius, other.m_radius);
+}
+
 #if ENABLE(CSS_VARIABLES)
 String CSSBasicShapeCircle::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
 {
@@ -132,6 +158,18 @@ String CSSBasicShapeEllipse::cssText() const
     return buildEllipseString(m_centerX->cssText(), m_centerY->cssText(), m_radiusX->cssText(), m_radiusY->cssText());
 }
 
+bool CSSBasicShapeEllipse::equals(const CSSBasicShape& shape) const
+{
+    if (shape.type() != CSS_BASIC_SHAPE_ELLIPSE)
+        return false;
+
+    const CSSBasicShapeEllipse& other = static_cast<const CSSBasicShapeEllipse&>(shape);
+    return compareCSSValuePtr(m_centerX, other.m_centerX)
+        && compareCSSValuePtr(m_centerY, other.m_centerY)
+        && compareCSSValuePtr(m_radiusX, other.m_radiusX)
+        && compareCSSValuePtr(m_radiusY, other.m_radiusY);
+}
+
 #if ENABLE(CSS_VARIABLES)
 String CSSBasicShapeEllipse::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
 {
@@ -199,6 +237,15 @@ String CSSBasicShapePolygon::cssText() const
     return buildPolygonString(m_windRule, points);
 }
 
+bool CSSBasicShapePolygon::equals(const CSSBasicShape& shape) const
+{
+    if (shape.type() != CSS_BASIC_SHAPE_POLYGON)
+        return false;
+
+    const CSSBasicShapePolygon& rhs = static_cast<const CSSBasicShapePolygon&>(shape);
+    return compareCSSValueVector<CSSPrimitiveValue>(m_values, rhs.m_values);
+}
+
 #if ENABLE(CSS_VARIABLES)
 String CSSBasicShapePolygon::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
 {
index ef320989184463fd12b1764a8ab88dbea968e09c..8db0d2f30c63508756f37273f4195752fdcb2a64 100644 (file)
@@ -49,6 +49,7 @@ public:
 
     virtual Type type() const = 0;
     virtual String cssText() const = 0;
+    virtual bool equals(const CSSBasicShape&) const = 0;
 
 #if ENABLE(CSS_VARIABLES)
     virtual String serializeResolvingVariables(const HashMap<AtomicString, String>&) const = 0;
@@ -82,6 +83,7 @@ public:
 
     virtual Type type() const { return CSS_BASIC_SHAPE_RECTANGLE; }
     virtual String cssText() const;
+    virtual bool equals(const CSSBasicShape&) const;
 
 #if ENABLE(CSS_VARIABLES)
     virtual String serializeResolvingVariables(const HashMap<AtomicString, String>&) const;
@@ -113,6 +115,7 @@ public:
 
     virtual Type type() const { return CSS_BASIC_SHAPE_CIRCLE; }
     virtual String cssText() const;
+    virtual bool equals(const CSSBasicShape&) const;
 
 #if ENABLE(CSS_VARIABLES)
     virtual String serializeResolvingVariables(const HashMap<AtomicString, String>&) const;
@@ -143,6 +146,7 @@ public:
 
     virtual Type type() const { return CSS_BASIC_SHAPE_ELLIPSE; }
     virtual String cssText() const;
+    virtual bool equals(const CSSBasicShape&) const;
 
 #if ENABLE(CSS_VARIABLES)
     virtual String serializeResolvingVariables(const HashMap<AtomicString, String>&) const;
@@ -177,7 +181,7 @@ public:
 
     virtual Type type() const { return CSS_BASIC_SHAPE_POLYGON; }
     virtual String cssText() const;
-
+    virtual bool equals(const CSSBasicShape&) const;
 #if ENABLE(CSS_VARIABLES)
     virtual String serializeResolvingVariables(const HashMap<AtomicString, String>&) const;
     virtual bool hasVariableReference() const;
index 5c4bf04b2ea6578d3f7fb6d9933eb5a90905b5ac..93513b8e34f528b7b4eadef5923db2dc8c2a1f8a 100644 (file)
@@ -50,6 +50,11 @@ String CSSBorderImageSliceValue::customCssText() const
     return text;
 }
 
+bool CSSBorderImageSliceValue::equals(const CSSBorderImageSliceValue& other) const
+{
+    return m_fill == other.m_fill && compareCSSValuePtr(m_slices, other.m_slices);
+}
+
 void CSSBorderImageSliceValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index 488b4a41d20dfaf2c422c61438053e145ef446f6..c286e8d0bc7b4be404307a882705830332f8f15b 100644 (file)
@@ -45,6 +45,8 @@ public:
 
     Quad* slices() { return m_slices ? m_slices->getQuadValue() : 0; }
 
+    bool equals(const CSSBorderImageSliceValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
     // These four values are used to make "cuts" in the border image. They can be numbers
index b7f498d9838738c902af3d3585a5219ca5b867d6..5faa8f6058c0b5c9dbd36ed8a90cf108a11a3ee1 100644 (file)
@@ -95,6 +95,11 @@ String CSSCalcValue::customCssText() const
     return buildCssText(m_expression->customCssText());
 }
 
+bool CSSCalcValue::equals(const CSSCalcValue& other) const
+{
+    return compareCSSValuePtr(m_expression, other.m_expression);
+}
+
 #if ENABLE(CSS_VARIABLES)
 String CSSCalcValue::customSerializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
 {
@@ -223,11 +228,21 @@ public:
         return 0;        
     }
 
+    virtual bool equals(const CSSCalcExpressionNode& other) const
+    {
+        if (type() != other.type())
+            return false;
+
+        return compareCSSValuePtr(m_value, static_cast<const CSSCalcPrimitiveValue&>(other).m_value);
+    }
+
     virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const OVERRIDE
     {
         MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
         info.addMember(m_value, "value");
     }
+
+    virtual Type type() const { return CssCalcPrimitiveValue; }
     
 private:
     explicit CSSCalcPrimitiveValue(CSSPrimitiveValue* value, bool isInteger)
@@ -359,6 +374,19 @@ public:
     }
 #endif
 
+    virtual bool equals(const CSSCalcExpressionNode& exp) const
+    {
+        if (type() != exp.type())
+            return false;
+
+        const CSSCalcBinaryOperation& other = static_cast<const CSSCalcBinaryOperation&>(exp);
+        return compareCSSValuePtr(m_leftSide, other.m_leftSide)
+            && compareCSSValuePtr(m_rightSide, other.m_rightSide)
+            && m_operator == other.m_operator;
+    }
+
+    virtual Type type() const { return CssCalcBinaryOperation; }
+
 private:
     CSSCalcBinaryOperation(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op, CalculationCategory category)
         : CSSCalcExpressionNode(category, leftSide->isInteger() && rightSide->isInteger())
index 044cf32a40d3b6bb5ece048e442381d668c129ca..569dbdea0b0f2b3b898ae7a4c722f0b564badf84 100644 (file)
@@ -60,7 +60,11 @@ enum CalculationCategory {
     
 class CSSCalcExpressionNode : public RefCounted<CSSCalcExpressionNode> {
 public:
-    
+    enum Type {
+        CssCalcPrimitiveValue = 1,
+        CssCalcBinaryOperation
+    };
+
     virtual ~CSSCalcExpressionNode() = 0;
     virtual bool isZero() const = 0;
     virtual PassOwnPtr<CalcExpressionNode> toCalcValue(RenderStyle*, RenderStyle* rootStyle, double zoom = 1.0) const = 0;    
@@ -71,9 +75,10 @@ public:
     virtual String serializeResolvingVariables(const HashMap<AtomicString, String>&) const = 0;
     virtual bool hasVariableReference() const = 0;
 #endif
-
+    virtual bool equals(const CSSCalcExpressionNode& other) const { return m_category == other.m_category && m_isInteger == other.m_isInteger; }
     virtual void reportMemoryUsage(MemoryObjectInfo*) const = 0;
-    
+    virtual Type type() const = 0;
+
     CalculationCategory category() const { return m_category; }    
     bool isInteger() const { return m_isInteger; }
     
@@ -104,6 +109,7 @@ public:
     double computeLengthPx(RenderStyle* currentStyle, RenderStyle* rootStyle, double multiplier = 1.0, bool computingFontSize = false) const;
         
     String customCssText() const;
+    bool equals(const CSSCalcValue&) const;
 #if ENABLE(CSS_VARIABLES)
     String customSerializeResolvingVariables(const HashMap<AtomicString, String>&) const;
     bool hasVariableReference() const;
index 90a86b18f2bd36dc3762e12d7d38e97056c2848b..a9871aa82d2da3e1915c8f642150ab016eb32e5e 100644 (file)
@@ -96,6 +96,11 @@ PassRefPtr<Image> CSSCanvasValue::image(RenderObject* renderer, const IntSize& /
     return elt->copiedImage();
 }
 
+bool CSSCanvasValue::equals(const CSSCanvasValue& other) const
+{
+    return m_name == other.m_name;
+}
+
 void CSSCanvasValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index 13fb58741e570d5b4a53df3252e4e3c8666144c8..77228efac127951eaf93d283a8ea779a5c73fcfa 100644 (file)
@@ -47,6 +47,8 @@ public:
     bool isPending() const { return false; }
     void loadSubimages(CachedResourceLoader*) { }
 
+    bool equals(const CSSCanvasValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index 3228278eaaecf13fe8f660c12373fd11edf8de3d..c43a48f0bcbf8593a98199bc32d095e82f90c25d 100644 (file)
@@ -2648,7 +2648,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
             const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom,
                                         CSSPropertyBorderLeft };
             for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) {
-                if (value->cssText() !=  getPropertyCSSValue(properties[i], DoNotUpdateLayout)->cssText())
+                if (!compareCSSValuePtr<CSSValue>(value, getPropertyCSSValue(properties[i], DoNotUpdateLayout)))
                     return 0;
             }
             return value.release();
@@ -2872,7 +2872,7 @@ bool CSSComputedStyleDeclaration::cssPropertyMatches(const StylePropertySet::Pro
         }
     }
     RefPtr<CSSValue> value = getPropertyCSSValue(property.id());
-    return value && value->cssText() == property.value()->cssText();
+    return value && property.value() && value->equals(*property.value());
 }
 
 PassRefPtr<StylePropertySet> CSSComputedStyleDeclaration::copy() const
@@ -2908,9 +2908,9 @@ PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForSid
     if (!topValue || !rightValue || !bottomValue || !leftValue)
         return 0;
 
-    bool showLeft = rightValue->cssText() != leftValue->cssText();
-    bool showBottom = (topValue->cssText() != bottomValue->cssText()) || showLeft;
-    bool showRight = (topValue->cssText() != rightValue->cssText()) || showBottom;
+    bool showLeft = !compareCSSValuePtr(rightValue, leftValue);
+    bool showBottom = !compareCSSValuePtr(topValue, bottomValue) || showLeft;
+    bool showRight = !compareCSSValuePtr(topValue, rightValue) || showBottom;
 
     list->append(topValue);
     if (showRight)
index 10c96a7db8481fac91420e98910604df63874ee9..62af0b04f9de7f6b5035fd9d6e1e57d59fbecb15 100644 (file)
@@ -229,4 +229,11 @@ bool CSSCrossfadeValue::hasFailedOrCanceledSubresources() const
     return false;
 }
 
+bool CSSCrossfadeValue::equals(const CSSCrossfadeValue& other) const
+{
+    return compareCSSValuePtr(m_fromValue, other.m_fromValue)
+        && compareCSSValuePtr(m_toValue, other.m_toValue)
+        && compareCSSValuePtr(m_percentageValue, other.m_percentageValue);
+}
+
 } // namespace WebCore
index c074780cd0de6100ebc0a1c3718a8e4fa61794b1..fc2e8c89c3e2598fcef0c51f931b9ee22e0b02ad 100644 (file)
@@ -66,6 +66,8 @@ public:
 
     bool hasFailedOrCanceledSubresources() const;
 
+    bool equals(const CSSCrossfadeValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index b2cfb09976cf2b16ee89b45623cc52a559b2e710..f676e0ea1ba101ec7d3c03b837a6a786fec8c5d7 100644 (file)
@@ -217,6 +217,12 @@ void CSSCursorImageValue::removeReferencedElement(SVGElement* element)
 }
 #endif
 
+bool CSSCursorImageValue::equals(const CSSCursorImageValue& other) const
+{
+    return m_hasHotSpot ? other.m_hasHotSpot && m_hotSpot == other.m_hotSpot : !other.m_hasHotSpot
+        && compareCSSValuePtr(m_imageValue, other.m_imageValue);
+}
+
 void CSSCursorImageValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index cfc78ec12170da6402f70799711a3d7cc481972d..d074877bc75711c8281ff082c7a7f9786ddd3813 100644 (file)
@@ -59,6 +59,8 @@ public:
     void removeReferencedElement(SVGElement*);
 #endif
 
+    bool equals(const CSSCursorImageValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index 5c39e3750d6e6f6b9649c85475d4133ac5f5b8e5..e1a339898d42f03f44671ae4254d5e380e44796c 100644 (file)
@@ -104,6 +104,11 @@ CachedFont* CSSFontFaceSrcValue::cachedFont(Document* document)
     return m_cachedFont.get();
 }
 
+bool CSSFontFaceSrcValue::equals(const CSSFontFaceSrcValue& other) const
+{
+    return m_isLocal == other.m_isLocal && m_format == other.m_format && m_resource == other.m_resource;
+}
+
 void CSSFontFaceSrcValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index a2c5466fef99a397a5b65beed8919f8a8f9fc743..48c8394e4d542a48d64032462e996ecec2ac9af7 100644 (file)
@@ -71,6 +71,8 @@ public:
 
     CachedFont* cachedFont(Document*);
 
+    bool equals(const CSSFontFaceSrcValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index 3b808b7abcf827ae83446647b07f535d3b3c43d5..832c3ead5e9afd1408d48e0854b1c7114f85d82a 100644 (file)
@@ -59,6 +59,11 @@ String CSSFunctionValue::customCssText() const
     return result.toString();
 }
 
+bool CSSFunctionValue::equals(const CSSFunctionValue& other) const
+{
+    return m_name == other.m_name && compareCSSValuePtr(m_args, other.m_args);
+}
+
 void CSSFunctionValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index 4ccb4776fd021ee4636bf8f9d7065b120e5c2414..179c7e511f1181cd250e2b3970f9f8bd99c1421d 100644 (file)
@@ -47,6 +47,8 @@ public:
 
     String customCssText() const;
 
+    bool equals(const CSSFunctionValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index dcde178518a61cfa545afdf87d4f53408c9a6b10..8f168ab72ce30756de0341784df800fd3760bf2e 100644 (file)
@@ -723,6 +723,38 @@ PassRefPtr<Gradient> CSSLinearGradientValue::createGradient(RenderObject* render
     return gradient.release();
 }
 
+bool CSSLinearGradientValue::equals(const CSSLinearGradientValue& other) const
+{
+    if (m_gradientType == CSSDeprecatedLinearGradient)
+        return other.m_gradientType == m_gradientType
+            && compareCSSValuePtr(m_firstX, other.m_firstX)
+            && compareCSSValuePtr(m_firstY, other.m_firstY)
+            && compareCSSValuePtr(m_secondX, other.m_secondX)
+            && compareCSSValuePtr(m_secondY, other.m_secondY)
+            && m_stops == other.m_stops;
+
+    if (m_repeating != other.m_repeating)
+        return false;
+
+    if (m_angle)
+        return compareCSSValuePtr(m_angle, other.m_angle) && m_stops == other.m_stops;
+
+    if (other.m_angle)
+        return false;
+
+    bool equalXorY = false;
+    if (m_firstX && m_firstY)
+        equalXorY = compareCSSValuePtr(m_firstX, other.m_firstX) && compareCSSValuePtr(m_firstY, other.m_firstY);
+    else if (m_firstX)
+        equalXorY =compareCSSValuePtr(m_firstX, other.m_firstX) && !other.m_firstY;
+    else if (m_firstY)
+        equalXorY = compareCSSValuePtr(m_firstY, other.m_firstY) && !other.m_firstX;
+    else
+        equalXorY = !other.m_firstX || !other.m_firstY;
+
+    return equalXorY && m_stops == other.m_stops;
+}
+
 void CSSLinearGradientValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
@@ -1112,6 +1144,52 @@ PassRefPtr<Gradient> CSSRadialGradientValue::createGradient(RenderObject* render
     return gradient.release();
 }
 
+bool CSSRadialGradientValue::equals(const CSSRadialGradientValue& other) const
+{
+    if (m_gradientType == CSSDeprecatedRadialGradient)
+        return other.m_gradientType == m_gradientType
+            && compareCSSValuePtr(m_firstX, other.m_firstX)
+            && compareCSSValuePtr(m_firstY, other.m_firstY)
+            && compareCSSValuePtr(m_secondX, other.m_secondX)
+            && compareCSSValuePtr(m_secondY, other.m_secondY)
+            && compareCSSValuePtr(m_firstRadius, other.m_firstRadius)
+            && compareCSSValuePtr(m_secondRadius, other.m_secondRadius)
+            && m_stops == other.m_stops;
+
+    if (m_repeating != other.m_repeating)
+        return false;
+
+    bool equalXorY = false;
+    if (m_firstX && m_firstY)
+        equalXorY = compareCSSValuePtr(m_firstX, other.m_firstX) && compareCSSValuePtr(m_firstY, other.m_firstY);
+    else if (m_firstX)
+        equalXorY = compareCSSValuePtr(m_firstX, other.m_firstX) && !other.m_firstY;
+    else if (m_firstY)
+        equalXorY = compareCSSValuePtr(m_firstY, other.m_firstY) && !other.m_firstX;
+    else
+        equalXorY == !other.m_firstX || !other.m_firstY;
+
+    if (!equalXorY)
+        return false;
+
+    bool equalShape = true;
+    bool equalSizingBehavior = true;
+    bool equalHorizontalAndVerticalSize = true;
+
+    if (m_shape)
+        equalShape = compareCSSValuePtr(m_shape, other.m_shape);
+    else if (m_sizingBehavior)
+        equalSizingBehavior = compareCSSValuePtr(m_sizingBehavior, other.m_sizingBehavior);
+    else if (m_endHorizontalSize && m_endVerticalSize)
+        equalHorizontalAndVerticalSize = compareCSSValuePtr(m_endHorizontalSize, other.m_endHorizontalSize) && compareCSSValuePtr(m_endVerticalSize, other.m_endVerticalSize);
+    else {
+        equalShape = !other.m_shape;
+        equalSizingBehavior = !other.m_sizingBehavior;
+        equalHorizontalAndVerticalSize = !other.m_endHorizontalSize && !other.m_endVerticalSize;
+    }
+    return equalShape && equalSizingBehavior && equalHorizontalAndVerticalSize && m_stops == other.m_stops;
+}
+
 void CSSRadialGradientValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index 7a19075f819bec505b9524b986d208fd4930d765..8e1c77b64110d9967d3721b1cafc05f29f81152f 100644 (file)
@@ -53,6 +53,11 @@ struct CSSGradientColorStop {
     Color m_resolvedColor;
     bool m_colorIsDerivedFromElement;
     void reportMemoryUsage(MemoryObjectInfo*) const;
+    bool operator==(const CSSGradientColorStop& other) const
+    {
+        return compareCSSValuePtr(m_color, other.m_color)
+            && compareCSSValuePtr(m_position, other.m_position);
+    }
 };
 
 class CSSGradientValue : public CSSImageGeneratorValue {
@@ -152,6 +157,8 @@ public:
         return adoptRef(new CSSLinearGradientValue(*this));
     }
 
+    bool equals(const CSSLinearGradientValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
@@ -195,6 +202,8 @@ public:
     // Create the gradient for a given size.
     PassRefPtr<Gradient> createGradient(RenderObject*, const IntSize&);
 
+    bool equals(const CSSRadialGradientValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index 8902efb832d960cf5b867132e54fcb02b7d21067..a21383f81f67e368f96fd2bfb37c0e127a7cde3b 100644 (file)
@@ -93,6 +93,11 @@ bool CSSImageValue::hasFailedOrCanceledSubresources() const
     return cachedResource->loadFailedOrCanceled();
 }
 
+bool CSSImageValue::equals(const CSSImageValue& other) const
+{
+    return m_url == other.m_url;
+}
+
 String CSSImageValue::customCssText() const
 {
     return "url(" + quoteCSSURLIfNeeded(m_url) + ")";
index 8e4a169f240553f2ba897313bbb40fb46c203768..0ecfa9f237f01bf119a4a794cc8a871f6b944a7c 100644 (file)
@@ -50,6 +50,8 @@ public:
 
     bool hasFailedOrCanceledSubresources() const;
 
+    bool equals(const CSSImageValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
     bool knownToBeOpaque(const RenderObject*) const;
index 68c001f534266a4f7daebb0dee629d357ae9fd49..3ca1d7d50b13a9f67798817a88ef34b94a6de5e0 100644 (file)
@@ -35,6 +35,8 @@ public:
 
     String customCssText() const;
 
+    bool equals(const CSSInheritedValue&) const { return true; }
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index d523343d3d3417341313a6ae95c6a669743081ab..0813223772d464be6c507de81e75cdd4043f9eeb 100644 (file)
@@ -41,6 +41,8 @@ public:
 
     bool isImplicit() const { return m_isImplicit; }
 
+    bool equals(const CSSInitialValue&) const { return true; }
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index eeb6470c83877ec6ef2c8dc0418800f4d4c5dd16..a1925d52dfcc9f22ac800c95a9ad93e3c98fff14 100644 (file)
@@ -47,7 +47,7 @@ public:
     }
 
     String customCssText() const;
-
+    bool equals(const CSSLineBoxContainValue& other) const { return m_value == other.m_value; }
     LineBoxContain value() const { return m_value; }
 
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
index e4885c7776856fa66efe08df3918b2e62553fa68..b3cee010a9a325b0fb70ad931a90edebb5fa2f76 100644 (file)
@@ -1274,6 +1274,83 @@ PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::cloneForCSSOM() const
     return result;
 }
 
+bool CSSPrimitiveValue::equals(const CSSPrimitiveValue& other) const
+{
+    if (m_primitiveUnitType != other.m_primitiveUnitType)
+        return false;
+
+    switch (m_primitiveUnitType) {
+    case CSS_UNKNOWN:
+        return false;
+    case CSS_NUMBER:
+    case CSS_PARSER_INTEGER:
+    case CSS_PERCENTAGE:
+    case CSS_EMS:
+    case CSS_EXS:
+    case CSS_REMS:
+    case CSS_PX:
+    case CSS_CM:
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
+    case CSS_DPPX:
+    case CSS_DPI:
+    case CSS_DPCM:
+#endif
+    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_TURN:
+    case CSS_VW:
+    case CSS_VH:
+    case CSS_VMIN:
+    case CSS_DIMENSION:
+        return m_value.num == other.m_value.num;
+    case CSS_IDENT:
+        return valueOrPropertyName(m_value.ident) == valueOrPropertyName(other.m_value.ident);
+    case CSS_STRING:
+    case CSS_URI:
+    case CSS_ATTR:
+    case CSS_COUNTER_NAME:
+    case CSS_PARSER_IDENTIFIER:
+    case CSS_PARSER_HEXCOLOR:
+#if ENABLE(CSS_VARIABLES)
+    case CSS_VARIABLE_NAME:
+#endif
+        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);
+    case CSS_RECT:
+        return m_value.rect && other.m_value.rect && m_value.rect->equals(*other.m_value.rect);
+    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;
+    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: {
+        DashboardRegion* region = getDashboardRegionValue();
+        DashboardRegion* otherRegion = other.getDashboardRegionValue();
+        return region ? otherRegion && region->equals(*otherRegion) : !otherRegion;
+    }
+#endif
+    case CSS_PARSER_OPERATOR:
+        return m_value.ident == other.m_value.ident;
+    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);
+    }
+    return false;
+}
+
 void CSSPrimitiveValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index 4abb0556c0a9c33605995cf865cc3fa79de4ddf5..5fb406272527cff1edde3d0de3b862a9dd31bb80 100644 (file)
@@ -316,6 +316,8 @@ public:
     PassRefPtr<CSSPrimitiveValue> cloneForCSSOM() const;
     void setCSSOMSafe() { m_isCSSOMSafe = true; }
 
+    bool equals(const CSSPrimitiveValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index c3a250f9d3afe62a332949eb573f77bf3a108fb0..5f8117f0ac6c70865386c896dcf3231d57ea8472 100644 (file)
@@ -56,6 +56,13 @@ void CSSReflectValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const Sty
         m_mask->addSubresourceStyleURLs(urls, styleSheet);
 }
 
+bool CSSReflectValue::equals(const CSSReflectValue& other) const
+{
+    return m_direction == other.m_direction
+        && compareCSSValuePtr(m_offset, other.m_offset)
+        && compareCSSValuePtr(m_mask, other.m_mask);
+}
+
 void CSSReflectValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index ba92dfed3d94f861253294addd1a12ab525e09c4..002c3782babb19329c413c968a010426c9e99eff 100644 (file)
@@ -54,6 +54,8 @@ public:
 
     void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*) const;
 
+    bool equals(const CSSReflectValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index e1bb1d1266e0528ddc7aa47dcef8f77303feb967..2399b54cf69f05ee87f9c3c6ce122f9e5f6984ff 100644 (file)
@@ -50,6 +50,12 @@ String CSSCubicBezierTimingFunctionValue::customCssText() const
         + String::number(m_y2) + ")";
 }
 
+bool CSSCubicBezierTimingFunctionValue::equals(const CSSCubicBezierTimingFunctionValue& other) const
+{
+    return m_x1 == other.m_x1 && m_x2 == other.m_x2 && m_y1 == other.m_y1 && m_y2 == other.m_y2;
+}
+
+
 void CSSCubicBezierTimingFunctionValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
@@ -60,6 +66,12 @@ String CSSStepsTimingFunctionValue::customCssText() const
     return "steps(" + String::number(m_steps) + ", " + (m_stepAtStart ? "start" : "end") + ')';
 }
 
+bool CSSStepsTimingFunctionValue::equals(const CSSStepsTimingFunctionValue& other) const
+{
+    return m_steps == other.m_steps && m_stepAtStart == other.m_stepAtStart;
+}
+
+
 void CSSStepsTimingFunctionValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index 3eb4b2295ab976392fddf2e50c29fdc26be50d42..4c3fe0b36310371deeca38fd92c52180d92f703f 100644 (file)
@@ -40,6 +40,8 @@ public:
 
     String customCssText() const;
 
+    bool equals(const CSSLinearTimingFunctionValue&) const { return true; }
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
@@ -63,6 +65,8 @@ public:
     double x2() const { return m_x2; }
     double y2() const { return m_y2; }
 
+    bool equals(const CSSCubicBezierTimingFunctionValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
@@ -93,6 +97,8 @@ public:
 
     String customCssText() const;
 
+    bool equals(const CSSStepsTimingFunctionValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index 34d63b6bbc1895ff0c75a9430cea2cc400aab213..f1d59a7784db5a6885618b6a0fca16019903f885 100644 (file)
@@ -38,6 +38,11 @@ String CSSUnicodeRangeValue::customCssText() const
     return result;
 }
 
+bool CSSUnicodeRangeValue::equals(const CSSUnicodeRangeValue& other) const
+{
+    return m_from == other.m_from && m_to == other.m_to;
+}
+
 void CSSUnicodeRangeValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index d50f5b6815c7b76deba0501f96844c2dcf160f66..a17f116199ee531e3cc58e9312ea63f2d0e7d6e1 100644 (file)
@@ -44,6 +44,8 @@ public:
 
     String customCssText() const;
 
+    bool equals(const CSSUnicodeRangeValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index 008d3fb326fbd5835ceca4a5580d154d3585faad..9be037ba712433dd80969650c5edb0022620b34e 100644 (file)
@@ -73,7 +73,7 @@ struct SameSizeAsCSSValue : public RefCounted<SameSizeAsCSSValue> {
 };
 
 COMPILE_ASSERT(sizeof(CSSValue) == sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small);
-    
+
 class TextCloneCSSValue : public CSSValue {
 public:
     static PassRefPtr<TextCloneCSSValue> create(ClassType classType, const String& text) { return adoptRef(new TextCloneCSSValue(classType, text)); }
@@ -276,6 +276,108 @@ void CSSValue::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
     ASSERT_NOT_REACHED();
 }
 
+template<class ChildClassType>
+inline static bool compareCSSValues(const CSSValue& first, const CSSValue& second)
+{
+    return static_cast<const ChildClassType&>(first).equals(static_cast<const ChildClassType&>(second));
+}
+
+bool CSSValue::equals(const CSSValue& other) const
+{
+    if (m_isTextClone) {
+        ASSERT(isCSSOMSafe());
+        return static_cast<const TextCloneCSSValue*>(this)->cssText() == other.cssText();
+    }
+
+    if (m_classType == other.m_classType) {
+        switch (m_classType) {
+        case AspectRatioClass:
+            return compareCSSValues<CSSAspectRatioValue>(*this, other);
+        case BorderImageSliceClass:
+            return compareCSSValues<CSSBorderImageSliceValue>(*this, other);
+        case CanvasClass:
+            return compareCSSValues<CSSCanvasValue>(*this, other);
+        case CursorImageClass:
+            return compareCSSValues<CSSCursorImageValue>(*this, other);
+        case FontClass:
+            return compareCSSValues<FontValue>(*this, other);
+        case FontFaceSrcClass:
+            return compareCSSValues<CSSFontFaceSrcValue>(*this, other);
+        case FontFeatureClass:
+            return compareCSSValues<FontFeatureValue>(*this, other);
+        case FunctionClass:
+            return compareCSSValues<CSSFunctionValue>(*this, other);
+        case LinearGradientClass:
+            return compareCSSValues<CSSLinearGradientValue>(*this, other);
+        case RadialGradientClass:
+            return compareCSSValues<CSSRadialGradientValue>(*this, other);
+        case CrossfadeClass:
+            return compareCSSValues<CSSCrossfadeValue>(*this, other);
+        case ImageClass:
+            return compareCSSValues<CSSImageValue>(*this, other);
+        case InheritedClass:
+            return compareCSSValues<CSSInheritedValue>(*this, other);
+        case InitialClass:
+            return compareCSSValues<CSSInitialValue>(*this, other);
+        case PrimitiveClass:
+            return compareCSSValues<CSSPrimitiveValue>(*this, other);
+        case ReflectClass:
+            return compareCSSValues<CSSReflectValue>(*this, other);
+        case ShadowClass:
+            return compareCSSValues<ShadowValue>(*this, other);
+        case LinearTimingFunctionClass:
+            return compareCSSValues<CSSLinearTimingFunctionValue>(*this, other);
+        case CubicBezierTimingFunctionClass:
+            return compareCSSValues<CSSCubicBezierTimingFunctionValue>(*this, other);
+        case StepsTimingFunctionClass:
+            return compareCSSValues<CSSStepsTimingFunctionValue>(*this, other);
+        case UnicodeRangeClass:
+            return compareCSSValues<CSSUnicodeRangeValue>(*this, other);
+        case ValueListClass:
+            return compareCSSValues<CSSValueList>(*this, other);
+        case WebKitCSSTransformClass:
+            return compareCSSValues<WebKitCSSTransformValue>(*this, other);
+        case LineBoxContainClass:
+            return compareCSSValues<CSSLineBoxContainValue>(*this, other);
+        case CalculationClass:
+            return compareCSSValues<CSSCalcValue>(*this, other);
+#if ENABLE(CSS_IMAGE_SET)
+        case ImageSetClass:
+            return compareCSSValues<CSSImageSetValue>(*this, other);
+#endif
+#if ENABLE(CSS_FILTERS)
+        case WebKitCSSFilterClass:
+            return compareCSSValues<WebKitCSSFilterValue>(*this, other);
+#if ENABLE(CSS_SHADERS)
+        case WebKitCSSArrayFunctionValueClass:
+            return compareCSSValues<WebKitCSSArrayFunctionValue>(*this, other);
+        case WebKitCSSMixFunctionValueClass:
+            return compareCSSValues<WebKitCSSMixFunctionValue>(*this, other);
+        case WebKitCSSShaderClass:
+            return compareCSSValues<WebKitCSSShaderValue>(*this, other);
+#endif
+#endif
+#if ENABLE(CSS_VARIABLES)
+        case VariableClass:
+            return compareCSSValues<CSSVariableValue>(*this, other);
+#endif
+#if ENABLE(SVG)
+        case SVGColorClass:
+            return compareCSSValues<SVGColor>(*this, other);
+        case SVGPaintClass:
+            return compareCSSValues<SVGPaint>(*this, other);
+        case WebKitCSSSVGDocumentClass:
+            return compareCSSValues<WebKitCSSSVGDocumentValue>(*this, other);
+        }
+#endif
+        ASSERT_NOT_REACHED();
+    } else if (m_classType == ValueListClass && other.m_classType != ValueListClass)
+        return static_cast<const CSSValueList*>(this)->equals(other);
+    else if (m_classType != ValueListClass && other.m_classType == ValueListClass)
+        return static_cast<const CSSValueList&>(other).equals(*this);
+    return false;
+}
+
 String CSSValue::cssText() const
 {
     if (m_isTextClone) {
index 220f0a17c3871c5e56f97868a1636a749fa37531..8d5425d6bbdd26767993363024882eb8905370f6 100644 (file)
@@ -126,6 +126,8 @@ public:
 
     void reportMemoryUsage(MemoryObjectInfo*) const;
 
+    bool equals(const CSSValue&) const;
+
 protected:
 
     static const size_t ClassTypeBits = 6;
@@ -236,6 +238,29 @@ private:
     unsigned m_classType : ClassTypeBits; // ClassType
 };
 
+template<typename CSSValueType>
+inline bool compareCSSValueVector(const Vector<RefPtr<CSSValueType> >& firstVector, const Vector<RefPtr<CSSValueType> >& secondVector)
+{
+    size_t size = firstVector.size();
+    if (size != secondVector.size())
+        return false;
+
+    for (size_t i = 0; i < size; i++) {
+        const RefPtr<CSSValueType>& firstPtr = firstVector[i];
+        const RefPtr<CSSValueType>& secondPtr = secondVector[i];
+        if (firstPtr == secondPtr || (firstPtr && secondPtr && firstPtr->equals(*secondPtr)))
+            continue;
+        return false;
+    }
+    return true;
+}
+
+template<typename CSSValueType>
+inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<CSSValueType>& second)
+{
+    return first ? second && first->equals(*second) : !second;
+}
+
 } // namespace WebCore
 
 #endif // CSSValue_h
index 17c4b8027c21b652ef4a462ee15baa5eed8ad463..f5b1792fe1ead3180d48949e023fde9fc0d3d4d3 100644 (file)
@@ -55,10 +55,9 @@ CSSValueList::CSSValueList(CSSParserValueList* parserValues)
 bool CSSValueList::removeAll(CSSValue* val)
 {
     bool found = false;
-    // FIXME: we should be implementing operator== to CSSValue and its derived classes
-    // to make comparison more flexible and fast.
     for (size_t index = 0; index < m_values.size(); index++) {
-        if (m_values.at(index)->cssText() == val->cssText()) {
+        RefPtr<CSSValue>& value = m_values.at(index);
+        if (value && val && value->equals(*val)) {
             m_values.remove(index);
             found = true;
         }
@@ -69,10 +68,9 @@ bool CSSValueList::removeAll(CSSValue* val)
 
 bool CSSValueList::hasValue(CSSValue* val) const
 {
-    // FIXME: we should be implementing operator== to CSSValue and its derived classes
-    // to make comparison more flexible and fast.
     for (size_t index = 0; index < m_values.size(); index++) {
-        if (m_values.at(index)->cssText() == val->cssText())
+        const RefPtr<CSSValue>& value = m_values.at(index);
+        if (value && val && value->equals(*val))
             return true;
     }
     return false;
@@ -127,6 +125,20 @@ String CSSValueList::customCssText() const
     return result.toString();
 }
 
+bool CSSValueList::equals(const CSSValueList& other) const
+{
+    return m_valueListSeparator == other.m_valueListSeparator && compareCSSValueVector<CSSValue>(m_values, other.m_values);
+}
+
+bool CSSValueList::equals(const CSSValue& other) const
+{
+    if (m_values.size() != 1)
+        return false;
+
+    const RefPtr<CSSValue>& value = m_values[0];
+    return value && value->equals(other);
+}
+
 #if ENABLE(CSS_VARIABLES)
 String CSSValueList::customSerializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
 {
index 22efea11719f15cce42f446b28a1fc8e0b26e2ee..1369fe11bb7abd27466227e8e2fbbfe2440a082d 100644 (file)
@@ -60,6 +60,8 @@ public:
     PassRefPtr<CSSValueList> copy();
 
     String customCssText() const;
+    bool equals(const CSSValueList&) const;
+    bool equals(const CSSValue&) const;
 #if ENABLE(CSS_VARIABLES)
     String customSerializeResolvingVariables(const HashMap<AtomicString, String>&) const;
 #endif
index 0d91c7e3ddd976718fda6a0747b370eb696ea6a3..48c56adb7adc0ad4415181be17f1abc889439bc5 100644 (file)
@@ -48,6 +48,8 @@ public:
     const AtomicString& name() const { return m_name; }
     const String& value() const { return m_value; }
 
+    bool equals(const CSSVariableValue& other) const { return m_name == other.m_name && m_value == other.m_value; }
+
     void reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
     {
         MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index 51fa71031602f8b99c43f4b87e198a51f43d7038..fc2279f9aca47247b704abbdc6e3b9b85612b8cc 100644 (file)
@@ -42,6 +42,13 @@ public:
     void setIdentifier(PassRefPtr<CSSPrimitiveValue> identifier) { m_identifier = identifier; }
     void setListStyle(PassRefPtr<CSSPrimitiveValue> listStyle) { m_listStyle = listStyle; }
     void setSeparator(PassRefPtr<CSSPrimitiveValue> separator) { m_separator = separator; }
+
+    bool equals(const Counter& other) const
+    {
+        return identifier() == other.identifier()
+            && listStyle() == other.listStyle()
+            && separator() == other.separator();
+    }
     
     PassRefPtr<Counter> cloneForCSSOM() const
     {
index 91e5d7ae138d14541bcd1b4425d770178aa4707d..5b5f0bd2ece06bdca41d610b64ae7e82226e39b4 100644 (file)
@@ -30,6 +30,12 @@ namespace WebCore {
 class DashboardRegion : public RectBase, public RefCounted<DashboardRegion> {
 public:
     static PassRefPtr<DashboardRegion> create() { return adoptRef(new DashboardRegion); }
+    bool equals(const DashboardRegion& other) const
+    {
+        return m_label == other.m_label && m_geometryType == other.m_geometryType
+            && m_isCircle == other.m_isCircle && m_isRectangle == other.m_isRectangle
+            && m_next ? other.m_next && m_next->equals(*other.m_next) : !other.m_next;
+    }
 
     RefPtr<DashboardRegion> m_next;
     String m_label;
index 3c564c4a377d891e83d655774936cb0a5606d785..954f24073ddca3656be8ec1c5764b36c64549f39 100644 (file)
@@ -50,6 +50,11 @@ String FontFeatureValue::customCssText() const
     return builder.toString();
 }
 
+bool FontFeatureValue::equals(const FontFeatureValue& other) const
+{
+    return m_tag == other.m_tag && m_value == other.m_value;
+}
+
 void FontFeatureValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index fcab8150413c6d3866bc9d95c51dec08365ea723..214f42549db59616f275e19fc0daa69c491c8537 100644 (file)
@@ -42,6 +42,8 @@ public:
     int value() const { return m_value; }
     String customCssText() const;
 
+    bool equals(const FontFeatureValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index 6558b5d607cc2c7b3dac00b5c131f794467f1aa8..351be52cfef161a6f28e14a68c7f3406a8060418 100644 (file)
@@ -65,6 +65,16 @@ String FontValue::customCssText() const
     return result.toString();
 }
 
+bool FontValue::equals(const FontValue& other) const
+{
+    return compareCSSValuePtr(style, other.style)
+        && compareCSSValuePtr(variant, other.variant)
+        && compareCSSValuePtr(weight, other.weight)
+        && compareCSSValuePtr(size, other.size)
+        && compareCSSValuePtr(lineHeight, other.lineHeight)
+        && compareCSSValuePtr(family, other.family);
+}
+
 void FontValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index 03a61268a587470fcb8a2112a9f0bc9d0aae8469..457863b610f121f0b23b2a70e89cc0a334a6b939 100644 (file)
@@ -39,6 +39,8 @@ public:
 
     String customCssText() const;
 
+    bool equals(const FontValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
     RefPtr<CSSPrimitiveValue> style;
index 813e0f8608bf2819488d0d919d646d4ca7f4f202..c41b3806e755b38453d05339d5e3ba5158ae633f 100644 (file)
@@ -52,7 +52,7 @@ public:
     {
         return (other.m_mediaFeature == m_mediaFeature)
             && ((!other.m_value && !m_value)
-                || (other.m_value && m_value && other.m_value->cssText() == m_value->cssText()));
+                || (other.m_value && m_value && other.m_value->equals(*m_value)));
     }
 
     bool isValid() const { return m_isValid; }
index 041ee237fef856a2113158f83d44eb3dcb5a23e2..faadb20f1d801ab845ba376d7d53962498ae4c49 100644 (file)
@@ -56,6 +56,8 @@ public:
         return generateCSSString(first()->cssText(), second()->cssText());
     }
 
+    bool equals(const Pair& other) const { return compareCSSValuePtr(m_first, other.m_first) && compareCSSValuePtr(m_second, other.m_second); }
+
 #if ENABLE(CSS_VARIABLES)
     String serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
     {
index feef8752036d1342024a093b145ae5af9dfdfde1..40a2cfede1d367d76e16937bfff4e8fae3aececc 100644 (file)
@@ -39,6 +39,14 @@ public:
     void setBottom(PassRefPtr<CSSPrimitiveValue> bottom) { m_bottom = bottom; }
     void setLeft(PassRefPtr<CSSPrimitiveValue> left) { m_left = left; }
 
+    bool equals(const RectBase& other) const
+    {
+        return compareCSSValuePtr(m_top, other.m_top)
+            && compareCSSValuePtr(m_right, other.m_right)
+            && compareCSSValuePtr(m_left, other.m_left)
+            && compareCSSValuePtr(m_bottom, other.m_bottom);
+    }
+
 #if ENABLE(CSS_VARIABLES)
     bool hasVariableReference() const
     {
index b25f8f2ec7cfc204fbecb8985cdbf65631e1ffac..0e15e325ccdcd01831d5a8b221f1ffda1a3aa3c3 100644 (file)
@@ -79,6 +79,16 @@ String ShadowValue::customCssText() const
     return text.toString();
 }
 
+bool ShadowValue::equals(const ShadowValue& other) const
+{
+    return compareCSSValuePtr(color, other.color)
+        && compareCSSValuePtr(x, other.x)
+        && compareCSSValuePtr(y, other.y)
+        && compareCSSValuePtr(blur, other.blur)
+        && compareCSSValuePtr(spread, other.spread)
+        && compareCSSValuePtr(style, other.style);
+}
+
 void ShadowValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index f2d8e6f6f98bf6fff614bc3504562da232d00cd8..a353d30248583952e8f046db68f785f3a1ab6366 100644 (file)
@@ -44,6 +44,8 @@ public:
 
     String customCssText() const;
 
+    bool equals(const ShadowValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
     RefPtr<CSSPrimitiveValue> x;
index 603f508b960dfc4d1711cc5507eb84f24d8139bd..bddac054ced7c92d9e6771acdb194209f8c0e1b1 100644 (file)
@@ -322,9 +322,9 @@ String StylePropertySet::get4Values(const StylePropertyShorthand& shorthand) con
     if (top.isImportant() != right.isImportant() || right.isImportant() != bottom.isImportant() || bottom.isImportant() != left.isImportant())
         return String();
 
-    bool showLeft = right.value()->cssText() != left.value()->cssText();
-    bool showBottom = (top.value()->cssText() != bottom.value()->cssText()) || showLeft;
-    bool showRight = (top.value()->cssText() != right.value()->cssText()) || showBottom;
+    bool showLeft = !right.value()->equals(*left.value());
+    bool showBottom = !top.value()->equals(*bottom.value()) || showLeft;
+    bool showRight = !top.value()->equals(*right.value()) || showBottom;
 
     StringBuilder result;
     result.append(top.value()->cssText());
@@ -1114,7 +1114,7 @@ bool StylePropertySet::propertyMatches(const PropertyReference& property) const
     int foundPropertyIndex = findPropertyIndex(property.id());
     if (foundPropertyIndex == -1)
         return false;
-    return propertyAt(foundPropertyIndex).value()->cssText() == property.value()->cssText();
+    return propertyAt(foundPropertyIndex).value()->equals(*property.value());
 }
     
 void StylePropertySet::removeEquivalentProperties(const StylePropertySet* style)
index 2a17a44b797d1214e1adfba19ecffca6b0aa5d3c..f5640aa90824dda7e8ac136bc8b45ac2a612a820 100644 (file)
@@ -56,6 +56,11 @@ PassRefPtr<WebKitCSSArrayFunctionValue> WebKitCSSArrayFunctionValue::cloneForCSS
     return adoptRef(new WebKitCSSArrayFunctionValue(*this));
 }
 
+bool WebKitCSSArrayFunctionValue::equals(const WebKitCSSArrayFunctionValue& other) const
+{
+    return CSSValueList::equals(other);
+}
+
 void WebKitCSSArrayFunctionValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index baf27820b6580ea43cfe163898b657fe14c27405..fc3aba5f2f25dde9e93371f14a12eeb8b9f47420 100644 (file)
@@ -48,6 +48,8 @@ public:
 
     PassRefPtr<WebKitCSSArrayFunctionValue> cloneForCSSOM() const;
 
+    bool equals(const WebKitCSSArrayFunctionValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index f1a1e0ea49a5a568b320fe8bd45f37bf01806771..070efc8d9d2ca3aec904346ace76af0862bbaf6d 100644 (file)
@@ -111,6 +111,11 @@ PassRefPtr<WebKitCSSFilterValue> WebKitCSSFilterValue::cloneForCSSOM() const
     return adoptRef(new WebKitCSSFilterValue(*this));
 }
 
+bool WebKitCSSFilterValue::equals(const WebKitCSSFilterValue& other) const
+{
+    return m_type == other.m_type && CSSValueList::equals(other);
+}
+
 void WebKitCSSFilterValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index 08b3e9f9a5029a81d578583d964d58317b2dff26..b2400706885b33b5586662368f788dbd9fa476f9 100644 (file)
@@ -68,6 +68,8 @@ public:
 
     PassRefPtr<WebKitCSSFilterValue> cloneForCSSOM() const;
 
+    bool equals(const WebKitCSSFilterValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index 3af687e760e9562674152f9a20f403e74afd3e37..c08b84534278a7de683b0f74d5749e2a03bc9ca1 100644 (file)
@@ -56,6 +56,11 @@ PassRefPtr<WebKitCSSMixFunctionValue> WebKitCSSMixFunctionValue::cloneForCSSOM()
     return adoptRef(new WebKitCSSMixFunctionValue(*this));
 }
 
+bool WebKitCSSMixFunctionValue::equals(const WebKitCSSMixFunctionValue& other) const
+{
+    return CSSValueList::equals(other);
+}
+
 void WebKitCSSMixFunctionValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index 7bc07b44eab4fe15e45ebd79db4c74ab891917cf..cb9934c4f4e66f3f5fd3cfa11a21b74a20054a66 100644 (file)
@@ -48,6 +48,8 @@ public:
 
     PassRefPtr<WebKitCSSMixFunctionValue> cloneForCSSOM() const;
 
+    bool equals(const WebKitCSSMixFunctionValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index 0b0f1ba51be78847b1cb6be437667cb6ee9e0620..568d0f392e265b4faf29eac88fcedf7323fe2d40 100644 (file)
@@ -67,6 +67,11 @@ String WebKitCSSSVGDocumentValue::customCssText() const
     return quoteCSSStringIfNeeded(m_url);
 }
 
+bool WebKitCSSSVGDocumentValue::equals(const WebKitCSSSVGDocumentValue& other) const
+{
+    return m_url == other.m_url;
+}
+
 void WebKitCSSSVGDocumentValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index 96bcc8c30c49601b672c1875c6d20224230e57cd..9a3ac68f8172cc5cf665ca0e12919bdc7dfd6349 100644 (file)
@@ -44,6 +44,7 @@ public:
     String customCssText() const;
     const String& url() const { return m_url; }
     bool loadRequested() const { return m_loadRequested; }
+    bool equals(const WebKitCSSSVGDocumentValue&) const;
 
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
index e3afc8963cd02a4f1fc626e9a86a7ebae0112cf6..aae2778b4ea2119730f1df912f754fad90bcf55c 100644 (file)
@@ -83,6 +83,11 @@ String WebKitCSSShaderValue::customCssText() const
     return "url(" + quoteCSSURLIfNeeded(m_url) + ")";
 }
 
+bool WebKitCSSShaderValue::equals(const WebKitCSSShaderValue& other) const
+{
+    return m_url == other.m_url;
+}
+
 void WebKitCSSShaderValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index c43201ca2a4a164ab9363d79462e42754c2fc2ca..7b05e9d477733750153bfa7e0bed48b94aa53340 100644 (file)
@@ -50,6 +50,8 @@ public:
 
     String customCssText() const;
 
+    bool equals(const WebKitCSSShaderValue&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private:
index fd117f23294bda52182b23ae6056b3b73d918d10..e0c1464d65ec4a1f5f6732f7a913f5867c37908b 100644 (file)
@@ -66,6 +66,7 @@ public:
     }
 
     String customCssText() const;
+    bool equals(const WebKitCSSTransformValue& other) const { return m_type == other.m_type && CSSValueList::equals(other); }
 #if ENABLE(CSS_VARIABLES)
     String customSerializeResolvingVariables(const HashMap<AtomicString, String>&) const;
 #endif
index 61561b721ec2bcf5ff9092756ba05e9eb60bbf32..3ba16a5dec5aea5dd1800e0775ae0805b7e8ae1a 100644 (file)
@@ -245,9 +245,7 @@ bool HTMLAttributeEquivalent::valueIsPresentInStyle(Element* element, StylePrope
     RefPtr<CSSValue> value = attributeValueAsCSSValue(element);
     RefPtr<CSSValue> styleValue = style->getPropertyCSSValue(m_propertyID);
     
-    // FIXME: This is very inefficient way of comparing values
-    // but we can't string compare attribute value and CSS property value.
-    return value && styleValue && value->cssText() == styleValue->cssText();
+    return compareCSSValuePtr(value, styleValue);
 }
 
 void HTMLAttributeEquivalent::addToStyle(Element* element, EditingStyle* style) const
index a34ad1804c3a98e23d7eab284be7e1b76af4f7c2..09aeecf35c75a9c4d64719b6ec4041b2a1ed6ebc 100644 (file)
@@ -105,6 +105,11 @@ PassRefPtr<SVGColor> SVGColor::cloneForCSSOM() const
     return adoptRef(new SVGColor(SVGColorClass, *this));
 }
 
+bool SVGColor::equals(const SVGColor& other) const
+{
+    return m_colorType == other.m_colorType && m_color == other.m_color;
+}
+
 void SVGColor::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index 7dddcd7a9444b11cd856549a32495bff1e90dc5a..5b360aa4464e171532057cdeaa6bc2db16e55c6b 100644 (file)
@@ -75,6 +75,8 @@ public:
     
     PassRefPtr<SVGColor> cloneForCSSOM() const;
 
+    bool equals(const SVGColor&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 protected:
index c719355c3225a27a02f34e2709e0d0af0aa14fa3..f69c45a3c3bf705301a3d396a015d4b6600fb91e 100644 (file)
@@ -112,6 +112,11 @@ PassRefPtr<SVGPaint> SVGPaint::cloneForCSSOM() const
     return adoptRef(new SVGPaint(*this));
 }
 
+bool SVGPaint::equals(const SVGPaint& other) const
+{
+    return m_paintType == other.m_paintType && m_uri == other.m_uri && SVGColor::equals(other);
+}
+
 void SVGPaint::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
index ac5675b59ede0c9b90f71da3c8e62c7ee97ede7d..a6fd0d8faf07163df28348bbf96af29e33e7b4da 100644 (file)
@@ -95,6 +95,8 @@ public:
 
     PassRefPtr<SVGPaint> cloneForCSSOM() const;
 
+    bool equals(const SVGPaint&) const;
+
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
 private: