From f9b1ad4c0847a6799049abdb764a5ca7367b4800 Mon Sep 17 00:00:00 2001 From: Ryan Reno Date: Thu, 23 Feb 2023 12:21:37 -0800 Subject: [PATCH] [Image Set]: Refactor CSSImageSetValue to accept optional resolution and MIME type parameters https://bugs.webkit.org/show_bug.cgi?id=252137 rdar://105367742 Reviewed by Antti Koivisto. The standardized image-set differs from -webkit-image-set in that each option has three arguments instead of two - an image, an optional resolution, and an optional type() function declaring the MIME type of the image. This refactors the CSSImageSetValue to hold an CSSImageSetOptionValue object instead of placing the image and resolution values in a vector and using a stride of 2 to represent each option. The actual parsing of resolution and type() will be in a follow-on patch. * LayoutTests/TestExpectations: Unskip newly passing WPT ref tests. * LayoutTests/fast/css/image-set-parsing-expected.txt: * LayoutTests/fast/css/image-set-parsing-generated-expected.txt: Removed. * LayoutTests/fast/css/image-set-parsing-generated.html: Removed. * LayoutTests/fast/css/image-set-parsing.html: * LayoutTests/imported/w3c/web-platform-tests/css/css-images/image-set/image-set-parsing-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/css/css-images/image-set/image-set-parsing.html: Refactor the internal parsing tests in the following ways: 1) Move and dedup all tests of standard properties (e.g. background-image) to WPT. 2) Move generated image tests (gradients, for example) to the main image-set-parsing test. 3) Test that -webkit-image-set is an alias to image-set 4) Test that the serialization is as expected (per WPT). * Source/WebCore/css/CSSImageSetOptionValue.cpp: Added. (WebCore::CSSImageSetOptionValue::Type::Type): (WebCore::CSSImageSetOptionValue::Type::cssText const): (WebCore::CSSImageSetOptionValue::CSSImageSetOptionValue): (WebCore::CSSImageSetOptionValue::create): (WebCore::CSSImageSetOptionValue::equals const): (WebCore::CSSImageSetOptionValue::customCSSText const): (WebCore::CSSImageSetOptionValue::image const): (WebCore::CSSImageSetOptionValue::resolution const): (WebCore::CSSImageSetOptionValue::setResolution): (WebCore::CSSImageSetOptionValue::type const): (WebCore::CSSImageSetOptionValue::setType): * Source/WebCore/css/CSSImageSetOptionValue.h: Copied from Source/WebCore/css/CSSImageSetValue.h. Create a new CSSImageSetOptionValue class to represent the arguments to the image-set function. This object holds a Ref to either a CSSImageValue or a generated image (e.g. a linear-gradient), and optionally holds a resolution (scale factor) and a MIME type string. * Source/WebCore/css/CSSImageSetValue.cpp: (WebCore::CSSImageSetValue::create): (WebCore::CSSImageSetValue::CSSImageSetValue): (WebCore::CSSImageSetValue::customCSSText const): (WebCore::CSSImageSetValue::createStyleImage const): * Source/WebCore/css/CSSImageSetValue.h: With -webkit-image-set, the image and resolution were the only two arguments and they were both required. The standardized image-set makes resolution and type optional. Instead of holding all the arguments as individual elements in the underlying CSSListValue storage we hold the new CSSImageSetOptionValues in the internal vector instead. We also now filter the image set on provided MIME type if it's supported or not when creating the StyleImage. * Source/WebCore/css/CSSValue.cpp: (WebCore::CSSValue::visitDerived): * Source/WebCore/css/CSSValue.h: (WebCore::CSSValue::isImageSetOptionValue const): Updates for support for the new CSSImageSetOptionValue. * Source/WebCore/css/calc/CSSCalcPrimitiveValueNode.cpp: * Source/WebCore/css/parser/CSSPropertyParser.cpp: * Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp: * Source/WebCore/css/CSSValuePair.cpp: Adding a new file caused build errors due to missing includes/incomplete types from forward decls. I added the needed includes. (WebCore::CSSPropertyParserHelpers::consumeImageSetOptionalArguments): (WebCore::CSSPropertyParserHelpers::consumeImageSet): Use the new CSSImageSetOptionValue/CSSImageSetValue API when constructing those objects. Also created a stub function which will eventually dispatch to parsing the resolution and type() optional parameters in a forthcoming patch. * Source/WebCore/rendering/style/StyleImageSet.cpp: (WebCore::StyleImageSet::computedStyleValue const): * Source/WebCore/Sources.txt: * Source/WebCore/WebCore.xcodeproj/project.pbxproj: Canonical link: https://commits.webkit.org/260760@main --- LayoutTests/TestExpectations | 4 +- .../fast/css/image-set-parsing-expected.txt | 118 ++++--------- .../image-set-parsing-generated-expected.txt | 73 -------- .../fast/css/image-set-parsing-generated.html | 109 ------------ LayoutTests/fast/css/image-set-parsing.html | 166 ++++++------------ .../image-set/image-set-parsing-expected.txt | 28 +-- .../image-set/image-set-parsing.html | 8 + Source/WebCore/Sources.txt | 1 + .../WebCore/WebCore.xcodeproj/project.pbxproj | 4 + Source/WebCore/css/CSSImageSetOptionValue.cpp | 132 ++++++++++++++ Source/WebCore/css/CSSImageSetOptionValue.h | 74 ++++++++ Source/WebCore/css/CSSImageSetValue.cpp | 26 +-- Source/WebCore/css/CSSValue.cpp | 3 + Source/WebCore/css/CSSValue.h | 2 + Source/WebCore/css/CSSValuePair.cpp | 1 + .../css/calc/CSSCalcPrimitiveValueNode.cpp | 1 + .../WebCore/css/parser/CSSPropertyParser.cpp | 1 + .../css/parser/CSSPropertyParserHelpers.cpp | 18 +- .../WebCore/rendering/style/StyleImageSet.cpp | 10 +- 19 files changed, 368 insertions(+), 411 deletions(-) delete mode 100755 LayoutTests/fast/css/image-set-parsing-generated-expected.txt delete mode 100755 LayoutTests/fast/css/image-set-parsing-generated.html create mode 100644 Source/WebCore/css/CSSImageSetOptionValue.cpp create mode 100644 Source/WebCore/css/CSSImageSetOptionValue.h diff --git a/LayoutTests/TestExpectations b/LayoutTests/TestExpectations index aeed1be7b881..dc4f1ccb2f11 100644 --- a/LayoutTests/TestExpectations +++ b/LayoutTests/TestExpectations @@ -3543,8 +3543,6 @@ webkit.org/b/200207 imported/w3c/web-platform-tests/css/css-images/css-image-fal webkit.org/b/200209 imported/w3c/web-platform-tests/css/css-images/multiple-position-color-stop-radial.html [ ImageOnlyFailure ] # wpt image-set failures -webkit.org/b/251811 imported/w3c/web-platform-tests/css/css-images/image-set/image-set-no-res-rendering-2.html [ ImageOnlyFailure ] -webkit.org/b/251811 imported/w3c/web-platform-tests/css/css-images/image-set/image-set-no-res-rendering.html [ ImageOnlyFailure ] webkit.org/b/251811 imported/w3c/web-platform-tests/css/css-images/image-set/image-set-type-first-match-rendering.html [ ImageOnlyFailure ] webkit.org/b/251811 imported/w3c/web-platform-tests/css/css-images/image-set/image-set-type-rendering-2.html [ ImageOnlyFailure ] webkit.org/b/251811 imported/w3c/web-platform-tests/css/css-images/image-set/image-set-type-rendering-3.html [ ImageOnlyFailure ] @@ -6270,3 +6268,5 @@ webkit.org/b/252183 imported/w3c/web-platform-tests/css/css-box/margin-trim/bloc imported/w3c/web-platform-tests/css/css-text/text-spacing/tentative/parsing/text-spacing-computed.html [ Skip ] imported/w3c/web-platform-tests/css/css-text/text-spacing/tentative/parsing/text-spacing-invalid.html [ Skip ] imported/w3c/web-platform-tests/css/css-text/text-spacing/tentative/parsing/text-spacing-valid.html [ Skip ] +imported/w3c/web-platform-tests/css/css-text/text-spacing/tentative/parsing [ Skip ] + diff --git a/LayoutTests/fast/css/image-set-parsing-expected.txt b/LayoutTests/fast/css/image-set-parsing-expected.txt index 0da786186f8c..a47a40ccec58 100644 --- a/LayoutTests/fast/css/image-set-parsing-expected.txt +++ b/LayoutTests/fast/css/image-set-parsing-expected.txt @@ -1,156 +1,104 @@ -Test the parsing of the -webkit-image-set function. +Test the parsing of the image-set and -webkit-image-set functions. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -Single value for background-image : url('#a') 1x +Single value for -webkit-mask-box-image-source: image-set(url('#a')) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 2 -PASS subRule is 'a' -PASS subRule.cssText is '1x' +PASS Image Set rule serializes as expected. -Multiple values for background-image : url('#a') 1x, url('#b') 2x +Single value for -webkit-mask-box-image-source: -webkit-image-set(url('#a')) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 4 -PASS subRule is 'a' -PASS subRule.cssText is '1x' -PASS subRule is 'b' -PASS subRule.cssText is '2x' +PASS Image Set rule serializes as expected. -Single value for background-image without url() function : '#a' 1x +Multiple values for -webkit-mask-box-image-source: image-set(url('#a'), url('#b') 2x) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 2 -PASS subRule is 'a' -PASS subRule.cssText is '1x' +PASS Image Set rule serializes as expected. -Multiple values for background-image without url() function : '#a' 1x, '#b' 2x +Multiple values for -webkit-mask-box-image-source: -webkit-image-set(url('#a'), url('#b') 2x) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 4 -PASS subRule is 'a' -PASS subRule.cssText is '1x' -PASS subRule is 'b' -PASS subRule.cssText is '2x' +PASS Image Set rule serializes as expected. -Mix values with and without url() function : '#a' 1x, url('#b') 2x +Single value for -webkit-mask-box-image-source with gradient.: image-set(linear-gradient(green, white)) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 4 -PASS subRule is 'a' -PASS subRule.cssText is '1x' -PASS subRule is 'b' -PASS subRule.cssText is '2x' +PASS Image Set rule serializes as expected. -Multiple values for background-image, out of order : url('#c') 3x, url('#b') 2x, url('#a') 1x +Single value for -webkit-mask-box-image-source with gradient.: -webkit-image-set(linear-gradient(green, white)) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 6 -PASS subRule is 'c' -PASS subRule.cssText is '3x' -PASS subRule is 'b' -PASS subRule.cssText is '2x' -PASS subRule is 'a' -PASS subRule.cssText is '1x' +PASS Image Set rule serializes as expected. -Single value for content : url('#a') 1x +Multiple values for -webkit-mask-box-image-source with gradients: image-set(linear-gradient(green, white) 1x, radial-gradient(blue, white) 2x) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 2 -PASS subRule is 'a' -PASS subRule.cssText is '1x' +PASS Image Set rule serializes as expected. -Multiple values for content : url('#a') 1x, url('#b') 2x +Multiple values for -webkit-mask-box-image-source with gradients: -webkit-image-set(linear-gradient(green, white) 1x, radial-gradient(blue, white) 2x) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 4 -PASS subRule is 'a' -PASS subRule.cssText is '1x' -PASS subRule is 'b' -PASS subRule.cssText is '2x' +PASS Image Set rule serializes as expected. -Single value for border-image-source : url('#a') 1x +Combined gradient and URL for -webkit-mask-box-image-source: image-set(url("#a"), linear-gradient(green, white) 2x) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 2 -PASS subRule is 'a' -PASS subRule.cssText is '1x' +PASS Image Set rule serializes as expected. -Multiple values for border-image-source : url('#a') 1x, url('#b') 2x +Combined gradient and URL for -webkit-mask-box-image-source: -webkit-image-set(url("#a"), linear-gradient(green, white) 2x) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 4 -PASS subRule is 'a' -PASS subRule.cssText is '1x' -PASS subRule is 'b' -PASS subRule.cssText is '2x' +PASS Image Set rule serializes as expected. -Single value for -webkit-mask-box-image-source : url('#a') 1x +Single -webkit-cross-fade for -webkit-mask-box-image-source: image-set(-webkit-cross-fade(url("#a"), url("#b"), 70%)) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 2 -PASS subRule is 'a' -PASS subRule.cssText is '1x' +PASS Image Set rule serializes as expected. -Multiple values for -webkit-mask-box-image-source : url('#a') 1x, url('#b') 2x +Single -webkit-cross-fade for -webkit-mask-box-image-source: -webkit-image-set(-webkit-cross-fade(url("#a"), url("#b"), 70%)) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 4 -PASS subRule is 'a' -PASS subRule.cssText is '1x' -PASS subRule is 'b' -PASS subRule.cssText is '2x' +PASS Image Set rule serializes as expected. -Single value with dppx : url('#a') 1dppx +Combined gradient and cross-fade for -webkit-mask-box-image-source: image-set(-webkit-cross-fade(url("#a"), url("#b"), 70%), linear-gradient(green, white) 2x) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 2 -PASS subRule is 'a' -PASS subRule.cssText is '1dppx' +PASS Image Set rule serializes as expected. -Single value with dpi : url('#a') 192dpi +Combined gradient and cross-fade for -webkit-mask-box-image-source: -webkit-image-set(-webkit-cross-fade(url("#a"), url("#b"), 70%), linear-gradient(green, white) 2x) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 2 -PASS subRule is 'a' -PASS subRule.cssText is '192dpi' +PASS Image Set rule serializes as expected. -Single value with dpcm : url('#a') 102dpcm +Single value for -webkit-mask-box-image-source with gradient and dpi: image-set(linear-gradient(green, white) 192dpi) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 2 -PASS subRule is 'a' -PASS subRule.cssText is '102dpcm' +PASS Image Set rule serializes as expected. -Multiple values with dpi, dppx and x : url('#a') 1x, url('#b') 2dppx, url('#c') 250dpi +Single value for -webkit-mask-box-image-source with gradient and dpi: -webkit-image-set(linear-gradient(green, white) 192dpi) PASS jsWrapperClass(imageSetRule) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 6 -PASS subRule is 'a' -PASS subRule.cssText is '1x' -PASS subRule is 'b' -PASS subRule.cssText is '2dppx' -PASS subRule is 'c' -PASS subRule.cssText is '250dpi' +PASS Image Set rule serializes as expected. PASS successfullyParsed is true TEST COMPLETE diff --git a/LayoutTests/fast/css/image-set-parsing-generated-expected.txt b/LayoutTests/fast/css/image-set-parsing-generated-expected.txt deleted file mode 100755 index e65fac12f508..000000000000 --- a/LayoutTests/fast/css/image-set-parsing-generated-expected.txt +++ /dev/null @@ -1,73 +0,0 @@ -Test the parsing of the image-set function. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - - -Single value for background-image with gradient : linear-gradient(green, white) 1x -PASS jsWrapperClass(imageSetRule) is 'CSSValueList' -PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' -PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 2 -PASS subRule.cssText is 'linear-gradient(green, white)' -PASS subRule.cssText is '1x' - -Single value for content with gradient : linear-gradient(green, white) 1x -PASS jsWrapperClass(imageSetRule) is 'CSSValueList' -PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' -PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 2 -PASS subRule.cssText is 'linear-gradient(green, white)' -PASS subRule.cssText is '1x' - -Single value for background-image with gradients : linear-gradient(green, white) 1x, radial-gradient(blue, white) 2x -PASS jsWrapperClass(imageSetRule) is 'CSSValueList' -PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' -PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 4 -PASS subRule.cssText is 'linear-gradient(green, white)' -PASS subRule.cssText is '1x' -PASS subRule.cssText is 'radial-gradient(blue, white)' -PASS subRule.cssText is '2x' - -Combined gradient and URL : url('#a') 1x, linear-gradient(green, white) 2x -PASS jsWrapperClass(imageSetRule) is 'CSSValueList' -PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' -PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 4 -PASS subRule is 'a' -PASS subRule.cssText is '1x' -PASS subRule.cssText is 'linear-gradient(green, white)' -PASS subRule.cssText is '2x' - -Combined gradient and URL in content : url('#a') 1x, linear-gradient(green, white) 2x -PASS jsWrapperClass(imageSetRule) is 'CSSValueList' -PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' -PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 4 -PASS subRule is 'a' -PASS subRule.cssText is '1x' -PASS subRule.cssText is 'linear-gradient(green, white)' -PASS subRule.cssText is '2x' - -Combined gradient and cross-fade : -webkit-cross-fade(url('#a'), url('#b'), 70%) 1x, linear-gradient(green, white) 2x -PASS jsWrapperClass(imageSetRule) is 'CSSValueList' -PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' -PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 4 -PASS subRule is 'a' -PASS subRule.cssText is '1x' -PASS subRule.cssText is 'linear-gradient(green, white)' -PASS subRule.cssText is '2x' - -Single value for background-image with gradient and dpi : linear-gradient(green, white) 192dpi -PASS jsWrapperClass(imageSetRule) is 'CSSValueList' -PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueList' -PASS jsWrapperClass(imageSetRule.constructor) is 'Function' -PASS imageSetRule.length is 2 -PASS subRule.cssText is 'linear-gradient(green, white)' -PASS subRule.cssText is '192dpi' -PASS successfullyParsed is true - -TEST COMPLETE - diff --git a/LayoutTests/fast/css/image-set-parsing-generated.html b/LayoutTests/fast/css/image-set-parsing-generated.html deleted file mode 100755 index d4a0333c1f1e..000000000000 --- a/LayoutTests/fast/css/image-set-parsing-generated.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - -

-
- - - - diff --git a/LayoutTests/fast/css/image-set-parsing.html b/LayoutTests/fast/css/image-set-parsing.html index a55b3686886f..c7aa033d6b7f 100644 --- a/LayoutTests/fast/css/image-set-parsing.html +++ b/LayoutTests/fast/css/image-set-parsing.html @@ -7,7 +7,7 @@

diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-images/image-set/image-set-parsing-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-images/image-set/image-set-parsing-expected.txt index 15ae13d49d57..c072b55341a5 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/css/css-images/image-set/image-set-parsing-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-images/image-set/image-set-parsing-expected.txt @@ -5,6 +5,8 @@ PASS e.style['background-image'] = "image-set('example.jpg' 1x)" should set the PASS e.style['background-image'] = "-webkit-image-set('example.jpg' 1x)" should set the property value PASS e.style['background-image'] = "image-set(url(example.png) 1x, 'example.png' 2x)" should set the property value PASS e.style['background-image'] = "-webkit-image-set(url(example.png) 1x, 'example.png' 2x)" should set the property value +PASS e.style['background-image'] = "image-set(\"example.png\" 1x, \"example.png\" 2x)" should set the property value +PASS e.style['background-image'] = "-webkit-image-set(\"example.png\" 1x, \"example.png\" 2x)" should set the property value PASS e.style['background-image'] = "image-set(url(example.png) 1dpcm, 'example.png' 2x)" should set the property value PASS e.style['background-image'] = "-webkit-image-set(url(example.png) 1dpcm, 'example.png' 2x)" should set the property value PASS e.style['background-image'] = "image-set('example.jpeg' 222dpi, url(example.png) 3.5x)" should set the property value @@ -21,6 +23,10 @@ PASS e.style['content'] = "image-set(linear-gradient(black, white) 1x, 'example. PASS e.style['content'] = "-webkit-image-set(linear-gradient(black, white) 1x, 'example.png' 4x)" should set the property value PASS e.style['content'] = "image-set(url(\"example.png\") 192dpi, linear-gradient(black, white) 1x)" should set the property value PASS e.style['content'] = "-webkit-image-set(url(\"example.png\") 192dpi, linear-gradient(black, white) 1x)" should set the property value +PASS e.style['border-image-source'] = "image-set(url(\"example.png\") 1x)" should set the property value +PASS e.style['border-image-source'] = "-webkit-image-set(url(\"example.png\") 1x)" should set the property value +PASS e.style['border-image-source'] = "image-set(url(\"example.png\") 1x, \"example.png\" 3x)" should set the property value +PASS e.style['border-image-source'] = "-webkit-image-set(url(\"example.png\") 1x, \"example.png\" 3x)" should set the property value PASS e.style['background-image'] = "image-set(none, url(example.png) 1x)" should not set the property value PASS e.style['background-image'] = "-webkit-image-set(none, url(example.png) 1x)" should not set the property value PASS e.style['background-image'] = "image-set()" should not set the property value @@ -47,16 +53,16 @@ PASS e.style['background-image'] = "image-set(url(example.png) 1x 2x)" should no PASS e.style['background-image'] = "-webkit-image-set(url(example.png) 1x 2x)" should not set the property value PASS e.style['background-image'] = "image-set(image-set(url(example.png)) 2x)" should not set the property value PASS e.style['background-image'] = "-webkit-image-set(image-set(url(example.png)) 2x)" should not set the property value -FAIL e.style['background-image'] = "image-set(url(foo))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['background-image'] = "-webkit-image-set(url(foo))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['background-image'] = "image-set(url(foo), url(bar) 1x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['background-image'] = "-webkit-image-set(url(foo), url(bar) 1x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['background-image'] = "image-set(url(foo) 1x, url(bar))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['background-image'] = "-webkit-image-set(url(foo) 1x, url(bar))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['background-image'] = "image-set(url(foo), url(bar))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['background-image'] = "-webkit-image-set(url(foo), url(bar))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['background-image'] = "image-set(url(foo) 1x, url(bar), url(baz) 2x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['background-image'] = "-webkit-image-set(url(foo) 1x, url(bar), url(baz) 2x)" should set the property value assert_not_equals: property should be set got disallowed value "" +PASS e.style['background-image'] = "image-set(url(foo))" should set the property value +PASS e.style['background-image'] = "-webkit-image-set(url(foo))" should set the property value +PASS e.style['background-image'] = "image-set(url(foo), url(bar) 1x)" should set the property value +PASS e.style['background-image'] = "-webkit-image-set(url(foo), url(bar) 1x)" should set the property value +PASS e.style['background-image'] = "image-set(url(foo) 1x, url(bar))" should set the property value +PASS e.style['background-image'] = "-webkit-image-set(url(foo) 1x, url(bar))" should set the property value +PASS e.style['background-image'] = "image-set(url(foo), url(bar))" should set the property value +PASS e.style['background-image'] = "-webkit-image-set(url(foo), url(bar))" should set the property value +PASS e.style['background-image'] = "image-set(url(foo) 1x, url(bar), url(baz) 2x)" should set the property value +PASS e.style['background-image'] = "-webkit-image-set(url(foo) 1x, url(bar), url(baz) 2x)" should set the property value PASS e.style['background-image'] = "image-set(url(\"example.png\") 1x)" should set the property value PASS e.style['background-image'] = "-webkit-image-set(url(\"example.png\") 1x)" should set the property value PASS e.style['background-image'] = "image-set(url(\"example.png\") calc(2x * 3))" should set the property value @@ -77,6 +83,8 @@ PASS e.style['content'] = "image-set(url(\"example.png\") 1dpi)" should set the PASS e.style['content'] = "-webkit-image-set(url(\"example.png\") 1dpi)" should set the property value PASS e.style['content'] = "image-set(url(\"example.png\") calc(1 * 96dpi))" should set the property value PASS e.style['content'] = "-webkit-image-set(url(\"example.png\") calc(1 * 96dpi))" should set the property value +PASS e.style['background-image'] = "image-set(url(\"example.jpg\") 1x, url(\"example.png\") 2dppx, \"example.png\" 250dpi, \"example.png\" 1dpcm)" should set the property value +PASS e.style['background-image'] = "-webkit-image-set(url(\"example.jpg\") 1x, url(\"example.png\") 2dppx, \"example.png\" 250dpi, \"example.png\" 1dpcm)" should set the property value PASS e.style['background-image'] = "image-set(url(\"example.png\") 1invalidResUnit)" should not set the property value PASS e.style['background-image'] = "-webkit-image-set(url(\"example.png\") 1invalidResUnit)" should not set the property value PASS e.style['background-image'] = "image-set(url(\"example.png\") calc(3 * 4))" should not set the property value diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-images/image-set/image-set-parsing.html b/LayoutTests/imported/w3c/web-platform-tests/css/css-images/image-set/image-set-parsing.html index b2e20fcd621b..fd691d7197b7 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/css/css-images/image-set/image-set-parsing.html +++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-images/image-set/image-set-parsing.html @@ -113,6 +113,11 @@ 'image-set(url("example.png") calc(1 * 96dpi))', 'image-set(url("example.png") calc(1dppx))' ); + test_valid_value_variants( + 'background-image', + 'image-set(url("example.jpg") 1x, url("example.png") 2dppx, "example.png" 250dpi, "example.png" 1dpcm)', + 'image-set(url("example.jpg") 1x, url("example.png") 2dppx, url("example.png") 250dpi, url("example.png") 1dpcm)', + ); test_invalid_value_variants( 'background-image', @@ -140,6 +145,7 @@ test_valid_value_variants('background-image', "image-set(url(example.png) 1x)", 'image-set(url("example.png") 1x)'); test_valid_value_variants('background-image', "image-set('example.jpg' 1x)", 'image-set(url("example.jpg") 1x)'); test_valid_value_variants('background-image', "image-set(url(example.png) 1x, 'example.png' 2x)", 'image-set(url("example.png") 1x, url("example.png") 2x)'); + test_valid_value_variants('background-image', 'image-set("example.png" 1x, "example.png" 2x)', 'image-set(url("example.png") 1x, url("example.png") 2x)'); test_valid_value_variants('background-image', "image-set(url(example.png) 1dpcm, 'example.png' 2x)", 'image-set(url("example.png") 1dpcm, url("example.png") 2x)'); test_valid_value_variants('background-image', "image-set('example.jpeg' 222dpi, url(example.png) 3.5x)", 'image-set(url("example.jpeg") 222dpi, url("example.png") 3.5x)'); test_valid_value_variants('background-image', "image-set(linear-gradient(black, white) 1x)"); @@ -148,6 +154,8 @@ test_valid_value_variants('background-image', "image-set(url(example.png) type('image/png') 1x)", 'image-set(url("example.png") 1x type("image/png"))'); test_valid_value_variants('content', "image-set(linear-gradient(black, white) 1x, 'example.png' 4x)", 'image-set(linear-gradient(black, white) 1x, url("example.png") 4x)'); test_valid_value_variants('content', 'image-set(url("example.png") 192dpi, linear-gradient(black, white) 1x)'); + test_valid_value_variants('border-image-source', 'image-set(url("example.png") 1x)', 'image-set(url("example.png") 1x)'); + test_valid_value_variants('border-image-source', 'image-set(url("example.png") 1x, "example.png" 3x)', 'image-set(url("example.png") 1x, url("example.png") 3x)'); test_invalid_value_variants('background-image', "image-set(none, url(example.png) 1x)"); test_invalid_value_variants('background-image', "image-set()"); diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt index c7e6f3ed90aa..4493dad3d926 100644 --- a/Source/WebCore/Sources.txt +++ b/Source/WebCore/Sources.txt @@ -775,6 +775,7 @@ css/CSSGridIntegerRepeatValue.cpp css/CSSGridLineNamesValue.cpp css/CSSGridTemplateAreasValue.cpp css/CSSGroupingRule.cpp +css/CSSImageSetOptionValue.cpp css/CSSImageSetValue.cpp css/CSSImageValue.cpp css/CSSImportRule.cpp diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj index 54a37910fd6a..dff22cdbbe59 100644 --- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj +++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj @@ -9725,6 +9725,8 @@ 4512502115DCE37D002F84E2 /* SpinButtonElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpinButtonElement.h; sourceTree = ""; }; 451A49F8F8726BE071518BE2 /* ISOProtectionSystemSpecificHeaderBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ISOProtectionSystemSpecificHeaderBox.cpp; sourceTree = ""; }; 453EB635159C570400001BB7 /* DateTimeFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateTimeFormat.h; sourceTree = ""; }; + 45517921299A8F8E00D246B2 /* CSSImageSetOptionValue.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CSSImageSetOptionValue.cpp; sourceTree = ""; }; + 45517922299A8F8E00D246B2 /* CSSImageSetOptionValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSImageSetOptionValue.h; sourceTree = ""; }; 457CECE328ECF8C1006FE9FB /* PolicyContainer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PolicyContainer.cpp; sourceTree = ""; }; 45830D4B1679B4F800ACF8C3 /* AutoscrollController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AutoscrollController.cpp; sourceTree = ""; }; 45830D4C1679B4F800ACF8C3 /* AutoscrollController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoscrollController.h; sourceTree = ""; }; @@ -33616,6 +33618,8 @@ FB3056C1169E5DAC0096A232 /* CSSGroupingRule.h */, 930AAC9B250EC2F30013DA9F /* CSSGroupingRule.idl */, BC772B360C4EA91E0083285F /* CSSHelper.h */, + 45517921299A8F8E00D246B2 /* CSSImageSetOptionValue.cpp */, + 45517922299A8F8E00D246B2 /* CSSImageSetOptionValue.h */, 9393E5FD151A99F200066F06 /* CSSImageSetValue.cpp */, 9393E5FE151A99F200066F06 /* CSSImageSetValue.h */, A80E6CD40A1989CA007FB8C5 /* CSSImageValue.cpp */, diff --git a/Source/WebCore/css/CSSImageSetOptionValue.cpp b/Source/WebCore/css/CSSImageSetOptionValue.cpp new file mode 100644 index 000000000000..b3e2da1abcc2 --- /dev/null +++ b/Source/WebCore/css/CSSImageSetOptionValue.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2023 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "CSSImageSetOptionValue.h" + +#include "CSSImageValue.h" +#include "CSSPrimitiveValue.h" +#include "MIMETypeRegistry.h" + +namespace WebCore { + +CSSImageSetOptionValue::Type::Type(String mimeType) + : m_isSupported(MIMETypeRegistry::isSupportedImageMIMEType(mimeType)) + , m_mimeType(mimeType) +{ +} + +String CSSImageSetOptionValue::Type::cssText() const +{ + return makeString("type("_s, m_mimeType, ')'); +} + +CSSImageSetOptionValue::CSSImageSetOptionValue(Ref&& image) + : CSSValue(ImageSetOptionClass) + , m_image(WTFMove(image)) +{ +} + +CSSImageSetOptionValue::CSSImageSetOptionValue(Ref&& image, Ref&& resolution) + : CSSValue(ImageSetOptionClass) + , m_image(WTFMove(image)) + , m_resolution(resolution.ptr()) +{ +} + +Ref CSSImageSetOptionValue::create(Ref&& image) +{ + ASSERT(is(image) || image->isImageGeneratorValue()); + return adoptRef(*new CSSImageSetOptionValue(WTFMove(image))); +} + +Ref CSSImageSetOptionValue::create(Ref&& image, Ref&& resolution) +{ + ASSERT(is(image) || image->isImageGeneratorValue()); + return adoptRef(*new CSSImageSetOptionValue(WTFMove(image), WTFMove(resolution))); +} + +bool CSSImageSetOptionValue::equals(const CSSImageSetOptionValue& other) const +{ + if (!m_image->equals(other.m_image)) + return false; + + if ((m_resolution && !other.m_resolution) || (!m_resolution && other.m_resolution)) + return false; + + if ((m_resolution && other.m_resolution) && !m_resolution->equals(*other.m_resolution)) + return false; + + if ((m_type && !other.m_type) || (!m_type && other.m_type)) + return false; + + if (m_type && other.m_type) { + if ((m_type->isSupported() != other.m_type->isSupported()) || (m_type->mimeType() != other.m_type->mimeType())) + return false; + } + + return true; +} + +String CSSImageSetOptionValue::customCSSText() const +{ + StringBuilder result; + result.append(m_image->cssText()); + if (m_resolution) + result.append(' ', m_resolution->cssText()); + else + result.append(" 1x"_s); + if (m_type) + result.append(' ', m_type->cssText()); + + return result.toString(); +} + +Ref CSSImageSetOptionValue::image() const +{ + return m_image; +} + +RefPtr CSSImageSetOptionValue::resolution() const +{ + return m_resolution; +} + +void CSSImageSetOptionValue::setResolution(Ref&& resolution) +{ + m_resolution = resolution.ptr(); +} + +std::optional CSSImageSetOptionValue::type() const +{ + return m_type; +} + +void CSSImageSetOptionValue::setType(Type&& type) +{ + m_type = WTFMove(type); +} + +} // namespace WebCore diff --git a/Source/WebCore/css/CSSImageSetOptionValue.h b/Source/WebCore/css/CSSImageSetOptionValue.h new file mode 100644 index 000000000000..a853d8d99202 --- /dev/null +++ b/Source/WebCore/css/CSSImageSetOptionValue.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2023 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "CSSValue.h" + +namespace WebCore { + +class CSSPrimitiveValue; + +class CSSImageSetOptionValue final : public CSSValue { +public: + class Type { + public: + explicit Type(String); + + bool isSupported() const { return m_isSupported; } + String mimeType() const { return m_mimeType; } + String cssText() const; + + private: + bool m_isSupported; + String m_mimeType; + }; + + static Ref create(Ref&&); + static Ref create(Ref&&, Ref&&); + + bool equals(const CSSImageSetOptionValue&) const; + String customCSSText() const; + + Ref image() const; + + RefPtr resolution() const; + void setResolution(Ref&&); + + std::optional type() const; + void setType(Type&&); + +private: + CSSImageSetOptionValue(Ref&&); + CSSImageSetOptionValue(Ref&&, Ref&&); + + Ref m_image; + RefPtr m_resolution; + std::optional m_type; +}; + +} // namespace WebCore + +SPECIALIZE_TYPE_TRAITS_CSS_VALUE(CSSImageSetOptionValue, isImageSetOptionValue()) diff --git a/Source/WebCore/css/CSSImageSetValue.cpp b/Source/WebCore/css/CSSImageSetValue.cpp index a0347abc9bbf..38e8b5ef57e0 100644 --- a/Source/WebCore/css/CSSImageSetValue.cpp +++ b/Source/WebCore/css/CSSImageSetValue.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "CSSImageSetValue.h" +#include "CSSImageSetOptionValue.h" #include "CSSImageValue.h" #include "CSSPrimitiveValue.h" #include "StyleBuilderState.h" @@ -48,11 +49,11 @@ String CSSImageSetValue::customCSSText() const { StringBuilder result; result.append("image-set("_s); - size_t length = this->length(); - for (size_t i = 0; i + 1 < length; i += 2) { + for (size_t i = 0; i < this->length(); ++i) { if (i > 0) result.append(", "_s); - result.append(item(i)->cssText(), ' ', item(i + 1)->cssText()); + ASSERT(is(item(i))); + result.append(item(i)->cssText()); } result.append(')'); return result.toString(); @@ -63,17 +64,20 @@ RefPtr CSSImageSetValue::createStyleImage(Style::BuilderState& state size_t length = this->length(); Vector images; - images.reserveInitialCapacity(length / 2); + images.reserveInitialCapacity(length); + + for (size_t i = 0; i < length; ++i) { + ASSERT(is(item(i))); + auto option = downcast(item(i)); - for (size_t i = 0; i + 1 < length; i += 2) { - auto* imageValue = item(i); - auto* scaleFactorValue = item(i + 1); + if (option->type() && !option->type()->isSupported()) + continue; - ASSERT(is(imageValue) || imageValue->isImageGeneratorValue()); - ASSERT(is(scaleFactorValue)); + float scaleFactor = 1.0; + if (option->resolution()) + scaleFactor = option->resolution()->floatValue(CSSUnitType::CSS_DPPX); - float scaleFactor = downcast(scaleFactorValue)->floatValue(CSSUnitType::CSS_DPPX); - images.uncheckedAppend({ state.createStyleImage(*imageValue), scaleFactor }); + images.uncheckedAppend({ state.createStyleImage(option->image()), scaleFactor }); } // Sort the images so that they are stored in order from lowest resolution to highest. diff --git a/Source/WebCore/css/CSSValue.cpp b/Source/WebCore/css/CSSValue.cpp index acd49d351e59..77604126a137 100644 --- a/Source/WebCore/css/CSSValue.cpp +++ b/Source/WebCore/css/CSSValue.cpp @@ -56,6 +56,7 @@ #include "CSSGridIntegerRepeatValue.h" #include "CSSGridLineNamesValue.h" #include "CSSGridTemplateAreasValue.h" +#include "CSSImageSetOptionValue.h" #include "CSSImageSetValue.h" #include "CSSImageValue.h" #include "CSSLineBoxContainValue.h" @@ -160,6 +161,8 @@ template constexpr decltype(auto) CSSValue::visitDerived(Visit return std::invoke(std::forward(visitor), downcast(*this)); case ImageClass: return std::invoke(std::forward(visitor), downcast(*this)); + case ImageSetOptionClass: + return std::invoke(std::forward(visitor), downcast(*this)); case ImageSetClass: return std::invoke(std::forward(visitor), downcast(*this)); case InsetShapeClass: diff --git a/Source/WebCore/css/CSSValue.h b/Source/WebCore/css/CSSValue.h index 0daae0973cb5..9c630614df1b 100644 --- a/Source/WebCore/css/CSSValue.h +++ b/Source/WebCore/css/CSSValue.h @@ -97,6 +97,7 @@ class CSSValue { bool isGridIntegerRepeatValue() const { return m_classType == GridIntegerRepeatClass; } bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass; } bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAreasClass; } + bool isImageSetOptionValue() const { return m_classType == ImageSetOptionClass; } bool isImageSetValue() const { return m_classType == ImageSetClass; } bool isImageValue() const { return m_classType == ImageClass; } bool isInsetShape() const { return m_classType == InsetShapeClass; } @@ -185,6 +186,7 @@ class CSSValue { // Image classes. ImageClass, + ImageSetOptionClass, CursorImageClass, // Image generator classes. diff --git a/Source/WebCore/css/CSSValuePair.cpp b/Source/WebCore/css/CSSValuePair.cpp index 294974152ea0..6855948a7994 100644 --- a/Source/WebCore/css/CSSValuePair.cpp +++ b/Source/WebCore/css/CSSValuePair.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "CSSValuePair.h" +#include namespace WebCore { diff --git a/Source/WebCore/css/calc/CSSCalcPrimitiveValueNode.cpp b/Source/WebCore/css/calc/CSSCalcPrimitiveValueNode.cpp index fb0b6b143336..88ba27a321cb 100644 --- a/Source/WebCore/css/calc/CSSCalcPrimitiveValueNode.cpp +++ b/Source/WebCore/css/calc/CSSCalcPrimitiveValueNode.cpp @@ -31,6 +31,7 @@ #include "CSSPrimitiveValueMappings.h" #include "CalcExpressionLength.h" #include "CalcExpressionNumber.h" +#include "CalculationValue.h" #include "Logging.h" #include diff --git a/Source/WebCore/css/parser/CSSPropertyParser.cpp b/Source/WebCore/css/parser/CSSPropertyParser.cpp index 782d1a675b50..db941feb556f 100644 --- a/Source/WebCore/css/parser/CSSPropertyParser.cpp +++ b/Source/WebCore/css/parser/CSSPropertyParser.cpp @@ -46,6 +46,7 @@ #include "CSSPendingSubstitutionValue.h" #include "CSSPrimitiveValueMappings.h" #include "CSSPropertyParsing.h" +#include "CSSQuadValue.h" #include "CSSTokenizer.h" #include "CSSTransformListValue.h" #include "CSSValuePair.h" diff --git a/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp b/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp index d54e54a28872..4ed547fe821b 100644 --- a/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp +++ b/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp @@ -29,6 +29,7 @@ #include "config.h" #include "CSSPropertyParserHelpers.h" +#include "CSSPropertyParser.h" #include "CSSPropertyParsing.h" #include "CSSBackgroundRepeatValue.h" @@ -55,6 +56,7 @@ #include "CSSGridIntegerRepeatValue.h" #include "CSSGridLineNamesValue.h" #include "CSSGridTemplateAreasValue.h" +#include "CSSImageSetOptionValue.h" #include "CSSImageSetValue.h" #include "CSSImageValue.h" #include "CSSLineBoxContainValue.h" @@ -73,6 +75,7 @@ #include "CSSTimingFunctionValue.h" #include "CSSTransformListValue.h" #include "CSSUnresolvedColor.h" +#include "CSSValuePair.h" #include "CSSValuePool.h" #include "CSSVariableData.h" #include "CSSVariableParser.h" @@ -4426,11 +4429,18 @@ static RefPtr consumeImageSet(CSSParserTokenRange& range, const CSSPar auto image = consumeImage(args, context, allowedImageTypes); if (!image) return nullptr; + + auto option = CSSImageSetOptionValue::create(image.releaseNonNull()); + auto resolution = consumeResolution(args); - if (!resolution || resolution->floatValue() <= 0) - return nullptr; - imageSet.append(image.releaseNonNull()); - imageSet.append(resolution.releaseNonNull()); + if (resolution) { + if (resolution->floatValue() <= 0) + return nullptr; + option->setResolution(resolution.releaseNonNull()); + } + + imageSet.append(WTFMove(option)); + } while (consumeCommaIncludingWhitespace(args)); if (!args.atEnd()) return nullptr; diff --git a/Source/WebCore/rendering/style/StyleImageSet.cpp b/Source/WebCore/rendering/style/StyleImageSet.cpp index 70e43a91d218..38d8f9278499 100644 --- a/Source/WebCore/rendering/style/StyleImageSet.cpp +++ b/Source/WebCore/rendering/style/StyleImageSet.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "StyleImageSet.h" +#include "CSSImageSetOptionValue.h" #include "CSSImageSetValue.h" #include "CSSPrimitiveValue.h" #include "Document.h" @@ -58,10 +59,11 @@ bool StyleImageSet::equals(const StyleImageSet& other) const Ref StyleImageSet::computedStyleValue(const RenderStyle& style) const { CSSValueListBuilder builder; - for (auto& image : m_images) { - builder.append(image.image->computedStyleValue(style)); - builder.append(CSSPrimitiveValue::create(image.scaleFactor, CSSUnitType::CSS_DPPX)); - } + builder.reserveInitialCapacity(m_images.size()); + + for (auto& image : m_images) + builder.uncheckedAppend(CSSImageSetOptionValue::create(image.image->computedStyleValue(style), CSSPrimitiveValue::create(image.scaleFactor, CSSUnitType::CSS_DPPX))); + return CSSImageSetValue::create(WTFMove(builder)); }