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
+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
--- /dev/null
+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.
+
--- /dev/null
+<!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>
+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".
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);
float numeratorValue() const { return m_numeratorValue; }
float denominatorValue() const { return m_denominatorValue; }
+ bool equals(const CSSAspectRatioValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
#include "config.h"
#include "CSSBasicShapes.h"
+#include "CSSPrimitiveValueMappings.h"
#include <wtf/text/StringBuilder.h>
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
{
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
{
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
{
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
{
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;
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;
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;
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;
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;
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);
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
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
{
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)
}
#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())
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;
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; }
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;
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);
bool isPending() const { return false; }
void loadSubimages(CachedResourceLoader*) { }
+ bool equals(const CSSCanvasValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
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();
}
}
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
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)
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
bool hasFailedOrCanceledSubresources() const;
+ bool equals(const CSSCrossfadeValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
}
#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);
void removeReferencedElement(SVGElement*);
#endif
+ bool equals(const CSSCursorImageValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
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);
CachedFont* cachedFont(Document*);
+ bool equals(const CSSFontFaceSrcValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
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);
String customCssText() const;
+ bool equals(const CSSFunctionValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
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);
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);
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 {
return adoptRef(new CSSLinearGradientValue(*this));
}
+ bool equals(const CSSLinearGradientValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
// Create the gradient for a given size.
PassRefPtr<Gradient> createGradient(RenderObject*, const IntSize&);
+ bool equals(const CSSRadialGradientValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
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) + ")";
bool hasFailedOrCanceledSubresources() const;
+ bool equals(const CSSImageValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
bool knownToBeOpaque(const RenderObject*) const;
String customCssText() const;
+ bool equals(const CSSInheritedValue&) const { return true; }
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
bool isImplicit() const { return m_isImplicit; }
+ bool equals(const CSSInitialValue&) const { return true; }
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
}
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;
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);
PassRefPtr<CSSPrimitiveValue> cloneForCSSOM() const;
void setCSSOMSafe() { m_isCSSOMSafe = true; }
+ bool equals(const CSSPrimitiveValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
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);
void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*) const;
+ bool equals(const CSSReflectValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
+ 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);
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);
String customCssText() const;
+ bool equals(const CSSLinearTimingFunctionValue&) const { return true; }
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
double x2() const { return m_x2; }
double y2() const { return m_y2; }
+ bool equals(const CSSCubicBezierTimingFunctionValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
String customCssText() const;
+ bool equals(const CSSStepsTimingFunctionValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
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);
String customCssText() const;
+ bool equals(const CSSUnicodeRangeValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
};
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)); }
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) {
void reportMemoryUsage(MemoryObjectInfo*) const;
+ bool equals(const CSSValue&) const;
+
protected:
static const size_t ClassTypeBits = 6;
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
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;
}
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;
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
{
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
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);
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
{
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;
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);
int value() const { return m_value; }
String customCssText() const;
+ bool equals(const FontFeatureValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
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);
String customCssText() const;
+ bool equals(const FontValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
RefPtr<CSSPrimitiveValue> style;
{
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; }
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
{
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
{
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);
String customCssText() const;
+ bool equals(const ShadowValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
RefPtr<CSSPrimitiveValue> x;
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());
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)
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);
PassRefPtr<WebKitCSSArrayFunctionValue> cloneForCSSOM() const;
+ bool equals(const WebKitCSSArrayFunctionValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
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);
PassRefPtr<WebKitCSSFilterValue> cloneForCSSOM() const;
+ bool equals(const WebKitCSSFilterValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
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);
PassRefPtr<WebKitCSSMixFunctionValue> cloneForCSSOM() const;
+ bool equals(const WebKitCSSMixFunctionValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
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);
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;
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);
String customCssText() const;
+ bool equals(const WebKitCSSShaderValue&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
}
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
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
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);
PassRefPtr<SVGColor> cloneForCSSOM() const;
+ bool equals(const SVGColor&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
protected:
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);
PassRefPtr<SVGPaint> cloneForCSSOM() const;
+ bool equals(const SVGPaint&) const;
+
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private: