Title: [254861] trunk
Revision
254861
Author
[email protected]
Date
2020-01-21 10:28:17 -0800 (Tue, 21 Jan 2020)

Log Message

-webkit-image-set should support all the image functions WebKit supports, not just url()
https://bugs.webkit.org/show_bug.cgi?id=81941

Patch by Noam Rosenthal <[email protected]> on 2020-01-21
Reviewed by Darin Adler.

Source/WebCore:

Separate StyleCachedImage to 4 classes:
- StyleCachedImage: for single images only
- StyleMultiImage: for values that can contain multiple images: like cursor/image-set
- StyleImageSet
- StyleCursorImage

The new classes only deal with their own value type. Before, ImageSet and cursor were resolved
as a StyleCachedImage, which is no longer a valid assumption if image-set can contain generated images.
Though cursors still can only contain cached images, it was cleaner to refactor it out as well.

Refactored best-fit image selection from loading. Now StyleCachedImage is in charge of loading
the actual image, and StyleImageSet/StyleCursorImage perform the source selection.

Also, added the necessary logic in the CSS parser to consume generated images inside image-sets, excluding
when the image-set is a cursor value.

Tests: fast/css/image-set-parsing-generated.html
       fast/hidpi/image-set-cross-fade.html
       fast/hidpi/image-set-gradient-multi.html
       fast/hidpi/image-set-gradient-single.html
       fast/hidpi/image-set-gradient.html

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
        Added new files

* css/CSSCursorImageValue.cpp:
(WebCore::CSSCursorImageValue::selectBestFitImage):
(WebCore::CSSCursorImageValue::loadImage): Deleted.
* css/CSSCursorImageValue.h:
        Instead of cursor loading the image, it selects an image CSS value

* css/CSSImageSetValue.cpp:
(WebCore::CSSImageSetValue::CSSImageSetValue):
(WebCore::CSSImageSetValue::fillImageSet):
(WebCore::CSSImageSetValue::cachedImage const):
(WebCore::CSSImageSetValue::selectBestFitImage):
(WebCore::CSSImageSetValue::updateDeviceScaleFactor):
(WebCore::CSSImageSetValue::imageSetWithStylesResolved):
(WebCore::CSSImageSetValue::traverseSubresources const):
(WebCore::CSSImageSetValue::loadBestFitImage): Deleted.
* css/CSSImageSetValue.h:
        Refactor CSSImageSetValue to include non-cachedImage images

* css/parser/CSSPropertyParser.cpp:
(WebCore::consumeCursor):
* css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::consumeImageSet):
(WebCore::CSSPropertyParserHelpers::consumeImage):
(WebCore::CSSPropertyParserHelpers::consumeUrlOrStringAsStringView): Deleted.
* css/parser/CSSPropertyParserHelpers.h:

* page/animation/CSSPropertyAnimation.cpp:
(WebCore::blendFunc):
        When blending two images, get the selected images in case it is an image-set

* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::paintFillLayerExtended):
* rendering/RenderImageResourceStyleImage.cpp:
(WebCore::RenderImageResourceStyleImage::initialize):
* rendering/RenderLayerBacking.cpp:
(WebCore::canDirectlyCompositeBackgroundBackgroundImage):
* rendering/style/ShapeValue.cpp:
(WebCore::ShapeValue::isImageValid const):
        Use hasCachedImage() instead of isCachedImage() as a StyleImageSet is no longer an isCachedImage()

* rendering/style/StyleCachedImage.cpp:
(WebCore::StyleCachedImage::StyleCachedImage):
(WebCore::StyleCachedImage::imageURL):
(WebCore::StyleCachedImage::load):
* rendering/style/StyleCachedImage.h:
* rendering/style/StyleCursorImage.h:
* rendering/style/StyleCursorImage.cpp:
* rendering/style/StyleMultiImage.h:
* rendering/style/StyleMultiImage.cpp:
* rendering/style/StyleImageSet.h:
* rendering/style/StyleImageSet.cpp:
* rendering/style/StyleImage.h:
(WebCore::StyleImage::selectedImage):
(WebCore::StyleImage::selectedImage const):
(WebCore::StyleImage::isCursorImage const):
(WebCore::StyleImage::isImageSet const):
(WebCore::StyleImage::hasCachedImage const):
(WebCore::StyleImage::StyleImage):
        Separate cursor/image-set related stuff away from StyleCachedImage.

* style/StyleBuilderCustom.h:
(WebCore::Style::BuilderCustom::applyValueContent):
* style/StyleBuilderState.cpp:
(WebCore::Style::BuilderState::resolveImageStyles):
(WebCore::Style::BuilderState::createStyleImage):
* style/StyleBuilderState.h:
        Match the CSS values with the correct Style class. Also, ensure image-sets resolve their
        images' styles as they may contain gradients and other context-aware values.

LayoutTests:

* fast/css/cursor-parsing-expected.txt:
* fast/css/cursor-parsing.html:
        Added parsing test to ensure arrow image-sets disable generated images

* fast/css/image-set-parsing-generated-expected.txt: Added.
* fast/css/image-set-parsing-generated.html: Added.
* fast/css/image-set-parsing-invalid-expected.txt:
* fast/css/image-set-parsing-invalid.html:
        Added parsing tests for new generated-inside-image-set use cases
        Test that image-set inside image-set is not supported

* fast/hidpi/image-set-cross-fade-expected.html: Added.
* fast/hidpi/image-set-cross-fade.html: Added.
* fast/hidpi/image-set-gradient-expected.html: Added.
* fast/hidpi/image-set-gradient-multi-expected.html: Added.
* fast/hidpi/image-set-gradient-multi.html: Added.
* fast/hidpi/image-set-gradient-single-expected.html: Added.
* fast/hidpi/image-set-gradient-single.html: Added.
* fast/hidpi/image-set-gradient.html: Added.
        Added ref-tests for several generated-inside-image-set use-cases

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (254860 => 254861)


--- trunk/LayoutTests/ChangeLog	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/LayoutTests/ChangeLog	2020-01-21 18:28:17 UTC (rev 254861)
@@ -1,3 +1,31 @@
+2020-01-21  Noam Rosenthal  <[email protected]>
+
+        -webkit-image-set should support all the image functions WebKit supports, not just url()
+        https://bugs.webkit.org/show_bug.cgi?id=81941
+
+        Reviewed by Darin Adler.
+
+        * fast/css/cursor-parsing-expected.txt:
+        * fast/css/cursor-parsing.html:
+                Added parsing test to ensure arrow image-sets disable generated images
+
+        * fast/css/image-set-parsing-generated-expected.txt: Added.
+        * fast/css/image-set-parsing-generated.html: Added.
+        * fast/css/image-set-parsing-invalid-expected.txt:
+        * fast/css/image-set-parsing-invalid.html:
+                Added parsing tests for new generated-inside-image-set use cases
+                Test that image-set inside image-set is not supported
+
+        * fast/hidpi/image-set-cross-fade-expected.html: Added.
+        * fast/hidpi/image-set-cross-fade.html: Added.
+        * fast/hidpi/image-set-gradient-expected.html: Added.
+        * fast/hidpi/image-set-gradient-multi-expected.html: Added.
+        * fast/hidpi/image-set-gradient-multi.html: Added.
+        * fast/hidpi/image-set-gradient-single-expected.html: Added.
+        * fast/hidpi/image-set-gradient-single.html: Added.
+        * fast/hidpi/image-set-gradient.html: Added.
+                Added ref-tests for several generated-inside-image-set use-cases
+
 2020-01-21  Chris Dumez  <[email protected]>
 
         Regression r254652: fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload.html fails on windows

Modified: trunk/LayoutTests/fast/css/cursor-parsing-expected.txt (254860 => 254861)


--- trunk/LayoutTests/fast/css/cursor-parsing-expected.txt	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/LayoutTests/fast/css/cursor-parsing-expected.txt	2020-01-21 18:28:17 UTC (rev 254861)
@@ -62,6 +62,10 @@
 PASS roundtripCssRule("cursor: url(file:///foo.png) 12 3 5;").cssText is ""
 PASS roundtripCssRule("cursor: url(file:///foo.png) x y;").cssText is ""
 PASS roundtripCssRule("cursor: url(file:///foo.png) auto;").cssText is ""
+
+Test a bunch of cursor rules with generated images.
+PASS roundtripCssRule("cursor: linear-gradient(red, white) -1 -1, pointer;").cssText is ""
+PASS roundtripCssRule("cursor: image-set(linear-gradient(red, white) 1x) -1 -1, pointer;").cssText is ""
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/css/cursor-parsing.html (254860 => 254861)


--- trunk/LayoutTests/fast/css/cursor-parsing.html	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/LayoutTests/fast/css/cursor-parsing.html	2020-01-21 18:28:17 UTC (rev 254861)
@@ -105,6 +105,11 @@
 testInvalidCursorRule('url(file:///foo.png) x y');
 testInvalidCursorRule('url(file:///foo.png) auto');
 
+debug('');
+debug('Test a bunch of cursor rules with generated images.');
+testInvalidCursorRule('linear-gradient(red, white) -1 -1, pointer');
+testInvalidCursorRule('image-set(linear-gradient(red, white) 1x) -1 -1, pointer');
+
 successfullyParsed = true;
 </script>
 <script src=""

Added: trunk/LayoutTests/fast/css/image-set-parsing-generated-expected.txt (0 => 254861)


--- trunk/LayoutTests/fast/css/image-set-parsing-generated-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/image-set-parsing-generated-expected.txt	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,65 @@
+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 'CSSValueListPrototype'
+PASS jsWrapperClass(imageSetRule.constructor) is 'Function'
+PASS imageSetRule.length is 2
+PASS subRule.cssText is 'linear-gradient(green, white)'
+PASS subRule.cssText is '1'
+
+Single value for content with gradient : linear-gradient(green, white) 1x
+PASS jsWrapperClass(imageSetRule) is 'CSSValueList'
+PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueListPrototype'
+PASS jsWrapperClass(imageSetRule.constructor) is 'Function'
+PASS imageSetRule.length is 2
+PASS subRule.cssText is 'linear-gradient(green, white)'
+PASS subRule.cssText is '1'
+
+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 'CSSValueListPrototype'
+PASS jsWrapperClass(imageSetRule.constructor) is 'Function'
+PASS imageSetRule.length is 4
+PASS subRule.cssText is 'linear-gradient(green, white)'
+PASS subRule.cssText is '1'
+PASS subRule.cssText is 'radial-gradient(blue, white)'
+PASS subRule.cssText is '2'
+
+Combined gradient and URL : url('#a') 1x, linear-gradient(green, white) 2x
+PASS jsWrapperClass(imageSetRule) is 'CSSValueList'
+PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueListPrototype'
+PASS jsWrapperClass(imageSetRule.constructor) is 'Function'
+PASS imageSetRule.length is 4
+PASS subRule is 'a'
+PASS subRule.cssText is '1'
+PASS subRule.cssText is 'linear-gradient(green, white)'
+PASS subRule.cssText is '2'
+
+Combined gradient and URL in content : url('#a') 1x, linear-gradient(green, white) 2x
+PASS jsWrapperClass(imageSetRule) is 'CSSValueList'
+PASS jsWrapperClass(imageSetRule.__proto__) is 'CSSValueListPrototype'
+PASS jsWrapperClass(imageSetRule.constructor) is 'Function'
+PASS imageSetRule.length is 4
+PASS subRule is 'a'
+PASS subRule.cssText is '1'
+PASS subRule.cssText is 'linear-gradient(green, white)'
+PASS subRule.cssText is '2'
+
+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 'CSSValueListPrototype'
+PASS jsWrapperClass(imageSetRule.constructor) is 'Function'
+PASS imageSetRule.length is 4
+PASS subRule is 'a'
+PASS subRule.cssText is '1'
+PASS subRule.cssText is 'linear-gradient(green, white)'
+PASS subRule.cssText is '2'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Property changes on: trunk/LayoutTests/fast/css/image-set-parsing-generated-expected.txt
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/LayoutTests/fast/css/image-set-parsing-generated.html (0 => 254861)


--- trunk/LayoutTests/fast/css/image-set-parsing-generated.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/image-set-parsing-generated.html	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+description("Test the parsing of the image-set function.");
+
+function jsWrapperClass(node)
+{
+    if (!node)
+        return "[null]";
+    var string = Object.prototype.toString.apply(node);
+    return string.substr(8, string.length - 9);
+}
+
+function shouldBeType(_expression_, className, prototypeName, constructorName)
+{
+    if (!prototypeName)
+        prototypeName = className + "Prototype";
+    if (!constructorName)
+        constructorName = className + "Constructor";
+    shouldBe("jsWrapperClass(" + _expression_ + ")", "'" + className + "'");
+    shouldBe("jsWrapperClass(" + _expression_ + ".__proto__)", "'" + prototypeName + "'");
+    shouldBe("jsWrapperClass(" + _expression_ + ".constructor)", "'Function'");
+}
+
+// These have to be global for the test helpers to see them.
+var imageSetRule, subRule;
+
+function testImageSetRule(description, property, rule, expectedLength, expectedTexts)
+{
+    debug("");
+    debug(description + " : " + rule);
+
+    var div = document.createElement("div");
+    div.setAttribute("style", property + ": image-set(" + rule + ")");
+    document.body.appendChild(div);
+
+    imageSetRule = div.style.getPropertyCSSValue(property);
+    shouldBeType("imageSetRule", "CSSValueList");
+
+    if (imageSetRule) {
+        if (jsWrapperClass(imageSetRule[0]) == "CSSValueList") {
+            // The content property returns a CSSValueList anyway, so to get to the 
+            // imageSet CSS value list, we have to look at the first entry in the 
+            // content value list.
+            imageSetRule = imageSetRule[0];
+        }
+    }
+
+    shouldBe("imageSetRule.length", function() { return expectedLength; });
+
+    if (imageSetRule) {
+        for (var i = 0; i < expectedLength; i++) {
+            string = imageSetRule[i];
+            if (i % 2 == 0 && string.cssText.includes('#')) {
+                subRule = string.cssText.split('#')[1].replace('"', "");
+                subRule = subRule.split(')')[0];
+                shouldBe("subRule", "'" + expectedTexts[i] + "'");
+            } else {
+                subRule = string;
+                shouldBe("subRule.cssText", "'" + expectedTexts[i] + "'");
+            }
+        }
+    }
+
+    document.body.removeChild(div);
+}
+
+testImageSetRule("Single value for background-image with gradient",
+                "background-image",
+                "linear-gradient(green, white) 1x", 2,
+                ["linear-gradient(green, white)", "1"]);
+testImageSetRule("Single value for content with gradient",
+                "background-image",
+                "linear-gradient(green, white) 1x", 2,
+                ["linear-gradient(green, white)", "1"]);
+
+testImageSetRule("Single value for background-image with gradients",
+                "background-image",
+                "linear-gradient(green, white) 1x, radial-gradient(blue, white) 2x", 4,
+                ["linear-gradient(green, white)", "1", "radial-gradient(blue, white)", "2"]);
+
+testImageSetRule("Combined gradient and URL",
+                "background-image",
+                "url('#a') 1x, linear-gradient(green, white) 2x", 4,
+                ["a", "1", "linear-gradient(green, white)", "2"]);
+
+testImageSetRule("Combined gradient and URL in content",
+                "content",
+                "url('#a') 1x, linear-gradient(green, white) 2x", 4,
+                ["a", "1", "linear-gradient(green, white)", "2"]);
+
+testImageSetRule("Combined gradient and cross-fade",
+                "background-image",
+                "-webkit-cross-fade(url('#a'), url('#b'), 70%) 1x, linear-gradient(green, white) 2x", 4,
+                ["a", "1", "linear-gradient(green, white)", "2"]);
+
+successfullyParsed = true;
+</script>
+<script src=""
+</body>
+</html>
Property changes on: trunk/LayoutTests/fast/css/image-set-parsing-generated.html
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Modified: trunk/LayoutTests/fast/css/image-set-parsing-invalid-expected.txt (254860 => 254861)


--- trunk/LayoutTests/fast/css/image-set-parsing-invalid-expected.txt	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/LayoutTests/fast/css/image-set-parsing-invalid-expected.txt	2020-01-21 18:28:17 UTC (rev 254861)
@@ -18,6 +18,12 @@
 
 Scale factor is 0 : url('#a') 0x
 PASS cssRule is null
+
+Generated image for cursor : linear-gradient(black, white) 1x
+PASS cssRule is null
+
+Image-set inside image-set : image-set(image-set(url('#a') 1x) 1x)
+PASS cssRule is null
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/css/image-set-parsing-invalid.html (254860 => 254861)


--- trunk/LayoutTests/fast/css/image-set-parsing-invalid.html	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/LayoutTests/fast/css/image-set-parsing-invalid.html	2020-01-21 18:28:17 UTC (rev 254861)
@@ -32,6 +32,8 @@
 testInvalidImageSet("No comma", "background-image", "url('#a') 1x url('#b') 2x");
 testInvalidImageSet("Too many scale factor parameters", "background-image", "url('#a') 1x 2x");
 testInvalidImageSet("Scale factor is 0", "background-image", "url('#a') 0x");
+testInvalidImageSet("Generated image for cursor", "cursor", "linear-gradient(black, white) 1x");
+testInvalidImageSet("Image-set inside image-set", "background-image", "image-set(image-set(url('#a') 1x) 1x)");
 
 successfullyParsed = true;
 </script>

Added: trunk/LayoutTests/fast/hidpi/image-set-cross-fade-expected.html (0 => 254861)


--- trunk/LayoutTests/fast/hidpi/image-set-cross-fade-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/hidpi/image-set-cross-fade-expected.html	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,26 @@
+<html>
+<head>
+<script>
+    window._onload_ = () => {
+      if (window.testRunner) {
+        testRunner.waitUntilDone();
+        testRunner.setBackingScaleFactor(2, () => setTimeout(() => testRunner.notifyDone(), 0));
+      }
+    }
+</script>
+
+    
+<style>
+    #foo {
+        width:100px;
+        height:100px;
+        background-image: -webkit-cross-fade(url('resources/blue-100-px-square.png'), url('resources/green-200-px-square.png', 50%));
+    }
+</style>
+</head>
+
+<body>
+    <div>This test passes if the div below is a blue 100px square when the deviceScaleFactor is 1, and if it is a 100px green/blue cross-fade square when the deviceScaleFactor is 2.</div>
+<div id=foo></div>
+</body>
+</html>
Property changes on: trunk/LayoutTests/fast/hidpi/image-set-cross-fade-expected.html
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/LayoutTests/fast/hidpi/image-set-cross-fade.html (0 => 254861)


--- trunk/LayoutTests/fast/hidpi/image-set-cross-fade.html	                        (rev 0)
+++ trunk/LayoutTests/fast/hidpi/image-set-cross-fade.html	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,25 @@
+<html>
+<head>
+<script>
+    window._onload_ = () => {
+      if (window.testRunner) {
+        testRunner.waitUntilDone();
+        testRunner.setBackingScaleFactor(2, () => setTimeout(() => testRunner.notifyDone(), 0));
+      }
+    }
+</script>
+    
+<style>
+    #foo {
+        width:100px;
+        height:100px;
+        background-image: image-set(url('resources/blue-100-px-square.png') 1x, -webkit-cross-fade(url('resources/blue-100-px-square.png'), url('resources/green-200-px-square.png', 50%)) 2x);
+    }
+</style>
+</head>
+
+<body>
+    <div>This test passes if the div below is a blue 100px square when the deviceScaleFactor is 1, and if it is a 100px green/blue cross-fade square when the deviceScaleFactor is 2.</div>
+    <div id=foo></div>
+</body>
+</html>
Property changes on: trunk/LayoutTests/fast/hidpi/image-set-cross-fade.html
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/LayoutTests/fast/hidpi/image-set-gradient-expected.html (0 => 254861)


--- trunk/LayoutTests/fast/hidpi/image-set-gradient-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/hidpi/image-set-gradient-expected.html	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,26 @@
+<html>
+<head>
+<script>
+    window._onload_ = () => {
+      if (window.testRunner) {
+        testRunner.waitUntilDone();
+        testRunner.setBackingScaleFactor(2, () => setTimeout(() => testRunner.notifyDone(), 0));
+      }
+    }
+</script>
+
+    
+<style>
+    #foo {
+        width:100px;
+        height:100px;
+        background-image: linear-gradient(green, white);
+    }
+</style>
+</head>
+
+<body>
+    <div>This test passes if the div below is a blue 100px square when the deviceScaleFactor is 1, and if it is a 100px green-white gradient square when the deviceScaleFactor is 2.</div>
+    <div id=foo></div>
+</body>
+</html>
Property changes on: trunk/LayoutTests/fast/hidpi/image-set-gradient-expected.html
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/LayoutTests/fast/hidpi/image-set-gradient-multi-expected.html (0 => 254861)


--- trunk/LayoutTests/fast/hidpi/image-set-gradient-multi-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/hidpi/image-set-gradient-multi-expected.html	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,25 @@
+<html>
+<head>    
+<script>
+    window._onload_ = () => {
+      if (window.testRunner) {
+        testRunner.waitUntilDone();
+        testRunner.setBackingScaleFactor(2, () => setTimeout(() => testRunner.notifyDone(), 0));
+      }
+    }
+</script>
+
+<style>
+    #foo {
+        width:100px;
+        height:100px;
+        background-image: radial-gradient(red, blue);
+    }
+</style>
+</head>
+
+<body>
+    <div>This test passes if the div below is a 100px green-white gradient square when devicePixelRatio is 1, a radial red-blue square when devicePixelRatio is 2, and a blue square when devicePixelRatio is 3.</div>
+    <div id=foo></div>
+</body>
+</html>
Property changes on: trunk/LayoutTests/fast/hidpi/image-set-gradient-multi-expected.html
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/LayoutTests/fast/hidpi/image-set-gradient-multi.html (0 => 254861)


--- trunk/LayoutTests/fast/hidpi/image-set-gradient-multi.html	                        (rev 0)
+++ trunk/LayoutTests/fast/hidpi/image-set-gradient-multi.html	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,25 @@
+<html>
+<head>    
+<script>
+    window._onload_ = () => {
+      if (window.testRunner) {
+        testRunner.waitUntilDone();
+        testRunner.setBackingScaleFactor(2, () => setTimeout(() => testRunner.notifyDone(), 0));
+      }
+    }
+</script>
+
+<style>
+    #foo {
+        width:100px;
+        height:100px;
+        background-image: image-set(linear-gradient(green, white) 1x, radial-gradient(red, blue) 2x, 'resources/blue-100-px-square.png' 3x);
+    }
+</style>
+</head>
+
+<body>
+    <div>This test passes if the div below is a 100px green-white gradient square when devicePixelRatio is 1, a radial red-blue square when devicePixelRatio is 2, and a blue square when devicePixelRatio is 3.</div>
+    <div id=foo></div>
+</body>
+</html>
Property changes on: trunk/LayoutTests/fast/hidpi/image-set-gradient-multi.html
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/LayoutTests/fast/hidpi/image-set-gradient-single-expected.html (0 => 254861)


--- trunk/LayoutTests/fast/hidpi/image-set-gradient-single-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/hidpi/image-set-gradient-single-expected.html	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,16 @@
+<html>
+<head>
+<style>
+    #foo {
+        width:100px;
+        height:100px;
+        background-image: linear-gradient(green, white);
+    }
+</style>
+</head>
+
+<body id="body">
+    <div>This test passes if the div below is a 100px green-white gradient square.</div>
+    <div id=foo></div>
+</body>
+</html>
Property changes on: trunk/LayoutTests/fast/hidpi/image-set-gradient-single-expected.html
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/LayoutTests/fast/hidpi/image-set-gradient-single.html (0 => 254861)


--- trunk/LayoutTests/fast/hidpi/image-set-gradient-single.html	                        (rev 0)
+++ trunk/LayoutTests/fast/hidpi/image-set-gradient-single.html	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,16 @@
+<html>
+<head>    
+<style>
+    #foo {
+        width:100px;
+        height:100px;
+        background-image: image-set(linear-gradient(green, white) 1x);
+    }
+</style>
+</head>
+
+<body id="body">
+    <div>This test passes if the div below is a 100px green-white gradient square.</div>
+    <div id=foo></div>
+</body>
+</html>
Property changes on: trunk/LayoutTests/fast/hidpi/image-set-gradient-single.html
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/LayoutTests/fast/hidpi/image-set-gradient.html (0 => 254861)


--- trunk/LayoutTests/fast/hidpi/image-set-gradient.html	                        (rev 0)
+++ trunk/LayoutTests/fast/hidpi/image-set-gradient.html	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,25 @@
+<html>
+<head>
+<script>
+    window._onload_ = () => {
+      if (window.testRunner) {
+        testRunner.waitUntilDone();
+        testRunner.setBackingScaleFactor(2, () => setTimeout(() => testRunner.notifyDone(), 0));
+      }
+    }
+</script>
+
+<style>
+    #foo {
+        width:100px;
+        height:100px;
+        background-image: image-set(url('resources/blue-100-px-square.png') 1x, linear-gradient(green, white) 2x);
+    }
+</style>
+</head>
+
+<body>
+    <div>This test passes if the div below is a blue 100px square when the deviceScaleFactor is 1, and if it is a 100px green-white gradient square when the deviceScaleFactor is 2.</div>
+    <div id=foo></div>
+</body>
+</html>
Property changes on: trunk/LayoutTests/fast/hidpi/image-set-gradient.html
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Modified: trunk/Source/WebCore/ChangeLog (254860 => 254861)


--- trunk/Source/WebCore/ChangeLog	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/ChangeLog	2020-01-21 18:28:17 UTC (rev 254861)
@@ -1,3 +1,105 @@
+2020-01-21  Noam Rosenthal  <[email protected]>
+
+        -webkit-image-set should support all the image functions WebKit supports, not just url()
+        https://bugs.webkit.org/show_bug.cgi?id=81941
+
+        Reviewed by Darin Adler.
+
+        Separate StyleCachedImage to 4 classes:
+        - StyleCachedImage: for single images only
+        - StyleMultiImage: for values that can contain multiple images: like cursor/image-set
+        - StyleImageSet
+        - StyleCursorImage
+
+        The new classes only deal with their own value type. Before, ImageSet and cursor were resolved
+        as a StyleCachedImage, which is no longer a valid assumption if image-set can contain generated images.
+        Though cursors still can only contain cached images, it was cleaner to refactor it out as well.
+
+        Refactored best-fit image selection from loading. Now StyleCachedImage is in charge of loading
+        the actual image, and StyleImageSet/StyleCursorImage perform the source selection.
+
+        Also, added the necessary logic in the CSS parser to consume generated images inside image-sets, excluding
+        when the image-set is a cursor value.
+
+        Tests: fast/css/image-set-parsing-generated.html
+               fast/hidpi/image-set-cross-fade.html
+               fast/hidpi/image-set-gradient-multi.html
+               fast/hidpi/image-set-gradient-single.html
+               fast/hidpi/image-set-gradient.html
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+                Added new files
+
+        * css/CSSCursorImageValue.cpp:
+        (WebCore::CSSCursorImageValue::selectBestFitImage):
+        (WebCore::CSSCursorImageValue::loadImage): Deleted.
+        * css/CSSCursorImageValue.h:
+                Instead of cursor loading the image, it selects an image CSS value
+
+        * css/CSSImageSetValue.cpp:
+        (WebCore::CSSImageSetValue::CSSImageSetValue):
+        (WebCore::CSSImageSetValue::fillImageSet):
+        (WebCore::CSSImageSetValue::cachedImage const):
+        (WebCore::CSSImageSetValue::selectBestFitImage):
+        (WebCore::CSSImageSetValue::updateDeviceScaleFactor):
+        (WebCore::CSSImageSetValue::imageSetWithStylesResolved):
+        (WebCore::CSSImageSetValue::traverseSubresources const):
+        (WebCore::CSSImageSetValue::loadBestFitImage): Deleted.
+        * css/CSSImageSetValue.h:
+                Refactor CSSImageSetValue to include non-cachedImage images
+
+        * css/parser/CSSPropertyParser.cpp:
+        (WebCore::consumeCursor):
+        * css/parser/CSSPropertyParserHelpers.cpp:
+        (WebCore::CSSPropertyParserHelpers::consumeImageSet):
+        (WebCore::CSSPropertyParserHelpers::consumeImage):
+        (WebCore::CSSPropertyParserHelpers::consumeUrlOrStringAsStringView): Deleted.
+        * css/parser/CSSPropertyParserHelpers.h:
+                
+        * page/animation/CSSPropertyAnimation.cpp:
+        (WebCore::blendFunc):
+                When blending two images, get the selected images in case it is an image-set
+
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+        * rendering/RenderImageResourceStyleImage.cpp:
+        (WebCore::RenderImageResourceStyleImage::initialize):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::canDirectlyCompositeBackgroundBackgroundImage):
+        * rendering/style/ShapeValue.cpp:
+        (WebCore::ShapeValue::isImageValid const):
+                Use hasCachedImage() instead of isCachedImage() as a StyleImageSet is no longer an isCachedImage()
+
+        * rendering/style/StyleCachedImage.cpp:
+        (WebCore::StyleCachedImage::StyleCachedImage):
+        (WebCore::StyleCachedImage::imageURL):
+        (WebCore::StyleCachedImage::load):
+        * rendering/style/StyleCachedImage.h:
+        * rendering/style/StyleCursorImage.h:
+        * rendering/style/StyleCursorImage.cpp:
+        * rendering/style/StyleMultiImage.h:
+        * rendering/style/StyleMultiImage.cpp:
+        * rendering/style/StyleImageSet.h:
+        * rendering/style/StyleImageSet.cpp:
+        * rendering/style/StyleImage.h:
+        (WebCore::StyleImage::selectedImage):
+        (WebCore::StyleImage::selectedImage const):
+        (WebCore::StyleImage::isCursorImage const):
+        (WebCore::StyleImage::isImageSet const):
+        (WebCore::StyleImage::hasCachedImage const):
+        (WebCore::StyleImage::StyleImage):
+                Separate cursor/image-set related stuff away from StyleCachedImage.
+
+        * style/StyleBuilderCustom.h:
+        (WebCore::Style::BuilderCustom::applyValueContent):
+        * style/StyleBuilderState.cpp:
+        (WebCore::Style::BuilderState::resolveImageStyles):
+        (WebCore::Style::BuilderState::createStyleImage):
+        * style/StyleBuilderState.h:
+                Match the CSS values with the correct Style class. Also, ensure image-sets resolve their 
+                images' styles as they may contain gradients and other context-aware values.
+
 2020-01-21  Chris Dumez  <[email protected]>
 
         Minor improvements to StorageAreaMap

Modified: trunk/Source/WebCore/Sources.txt (254860 => 254861)


--- trunk/Source/WebCore/Sources.txt	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/Sources.txt	2020-01-21 18:28:17 UTC (rev 254861)
@@ -2262,6 +2262,7 @@
 rendering/style/StyleBackgroundData.cpp
 rendering/style/StyleBoxData.cpp
 rendering/style/StyleCachedImage.cpp
+rendering/style/StyleCursorImage.cpp
 rendering/style/StyleDeprecatedFlexibleBoxData.cpp
 rendering/style/StyleFilterData.cpp
 rendering/style/StyleFlexibleBoxData.cpp
@@ -2268,9 +2269,11 @@
 rendering/style/StyleGeneratedImage.cpp
 rendering/style/StyleGridData.cpp
 rendering/style/StyleGridItemData.cpp
+rendering/style/StyleImageSet.cpp
 rendering/style/StyleInheritedData.cpp
 rendering/style/StyleMarqueeData.cpp
 rendering/style/StyleMultiColData.cpp
+rendering/style/StyleMultiImage.cpp
 rendering/style/StyleRareInheritedData.cpp
 rendering/style/StyleRareNonInheritedData.cpp
 rendering/style/StyleScrollSnapPoints.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (254860 => 254861)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-01-21 18:28:17 UTC (rev 254861)
@@ -13722,9 +13722,15 @@
 		C9DADBC91B1D3B25001F17D8 /* JSMediaSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaSession.cpp; sourceTree = "<group>"; };
 		C9DADBCA1B1D3B25001F17D8 /* JSMediaSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaSession.h; sourceTree = "<group>"; };
 		C9F87CFD1B28E5F600979B83 /* MediaSessionEvents.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; path = MediaSessionEvents.h; sourceTree = "<group>"; };
+		CA091D8623CF907800AD4346 /* StyleImageSet.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = StyleImageSet.cpp; sourceTree = "<group>"; };
+		CA091D8923CF908800AD4346 /* StyleImageSet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StyleImageSet.h; sourceTree = "<group>"; };
 		CA1635DC2072E76900E7D2CE /* ReferrerPolicy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReferrerPolicy.cpp; sourceTree = "<group>"; };
 		CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollAnimator.cpp; sourceTree = "<group>"; };
 		CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollAnimator.h; sourceTree = "<group>"; };
+		CA52BAE523D0AF1600DE0B84 /* StyleCursorImage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = StyleCursorImage.cpp; sourceTree = "<group>"; };
+		CA52BAE723D0AF1700DE0B84 /* StyleMultiImage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = StyleMultiImage.cpp; sourceTree = "<group>"; };
+		CA52BAE823D0AF1800DE0B84 /* StyleMultiImage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StyleMultiImage.h; sourceTree = "<group>"; };
+		CA52BAE923D0AF1900DE0B84 /* StyleCursorImage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StyleCursorImage.h; sourceTree = "<group>"; };
 		CA6C152F220B4A550055CBFC /* JSIDBRequestCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBRequestCustom.cpp; sourceTree = "<group>"; };
 		CA6C1537220D1EB30055CBFC /* JSIDBCursorCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBCursorCustom.cpp; sourceTree = "<group>"; };
 		CA6C1538220D1EB30055CBFC /* JSIDBCursorWithValueCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBCursorWithValueCustom.cpp; sourceTree = "<group>"; };
@@ -25562,6 +25568,8 @@
 				BCEF444C0E674628001C1287 /* StyleCachedImage.h */,
 				1C0AA16A21940DC700896829 /* StyleColorScheme.h */,
 				9DAC7C561AF2CB6400437C44 /* StyleContentAlignmentData.h */,
+				CA52BAE523D0AF1600DE0B84 /* StyleCursorImage.cpp */,
+				CA52BAE923D0AF1900DE0B84 /* StyleCursorImage.h */,
 				BC779E151BB226A200CAA8BF /* StyleCustomPropertyData.h */,
 				BC5EB8B60E8201BD00B25965 /* StyleDeprecatedFlexibleBoxData.cpp */,
 				BC5EB8B70E8201BD00B25965 /* StyleDeprecatedFlexibleBoxData.h */,
@@ -25576,6 +25584,8 @@
 				A110DB9C14F5DF8700A03B93 /* StyleGridItemData.cpp */,
 				A110DB9A14F5DF7700A03B93 /* StyleGridItemData.h */,
 				BCEF43CE0E673DA1001C1287 /* StyleImage.h */,
+				CA091D8623CF907800AD4346 /* StyleImageSet.cpp */,
+				CA091D8923CF908800AD4346 /* StyleImageSet.h */,
 				BC2273010E82F1E600E7F975 /* StyleInheritedData.cpp */,
 				BC2273020E82F1E600E7F975 /* StyleInheritedData.h */,
 				BC5EB7270E81DE8100B25965 /* StyleMarqueeData.cpp */,
@@ -25582,6 +25592,8 @@
 				BC5EB7280E81DE8100B25965 /* StyleMarqueeData.h */,
 				BC5EB74B0E81E06700B25965 /* StyleMultiColData.cpp */,
 				BC5EB74C0E81E06700B25965 /* StyleMultiColData.h */,
+				CA52BAE723D0AF1700DE0B84 /* StyleMultiImage.cpp */,
+				CA52BAE823D0AF1800DE0B84 /* StyleMultiImage.h */,
 				BC2272E10E82EE9B00E7F975 /* StyleRareInheritedData.cpp */,
 				BC2272E20E82EE9B00E7F975 /* StyleRareInheritedData.h */,
 				BC2272BA0E82EAAE00E7F975 /* StyleRareNonInheritedData.cpp */,
@@ -31368,6 +31380,7 @@
 				1199FA46208E35A3002358CC /* LayoutContainer.h in Headers */,
 				6F26BB6C23343E6F002F2BEA /* LayoutContext.h in Headers */,
 				11310CF520BA4A4C0065A8D0 /* LayoutDescendantIterator.h in Headers */,
+				E418025523D4549B00FFB071 /* LayoutIntegrationBoxTree.h in Headers */,
 				E4ABABDD236088FE00FA4345 /* LayoutIntegrationLineLayout.h in Headers */,
 				11310CF420BA4A3D0065A8D0 /* LayoutIterator.h in Headers */,
 				931D72F615FE695300C4C07E /* LayoutMilestone.h in Headers */,
@@ -32062,7 +32075,6 @@
 				458FE40A1589DF0B005609E6 /* RenderSearchField.h in Headers */,
 				0F11A54F0F39233100C37884 /* RenderSelectionInfo.h in Headers */,
 				AB247A6D0AFD6383003FA5FD /* RenderSlider.h in Headers */,
-				E418025523D4549B00FFB071 /* LayoutIntegrationBoxTree.h in Headers */,
 				31955A88160D199200858025 /* RenderSnapshottedPlugIn.h in Headers */,
 				BC8C8FAE0DDCD31B00B592F4 /* RenderStyle.h in Headers */,
 				BC5EB6680E81CB7100B25965 /* RenderStyleConstants.h in Headers */,

Modified: trunk/Source/WebCore/css/CSSCursorImageValue.cpp (254860 => 254861)


--- trunk/Source/WebCore/css/CSSCursorImageValue.cpp	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/css/CSSCursorImageValue.cpp	2020-01-21 18:28:17 UTC (rev 254861)
@@ -95,17 +95,17 @@
     m_hotSpot.setY(static_cast<int>(y));
 }
 
-std::pair<CachedImage*, float> CSSCursorImageValue::loadImage(CachedResourceLoader& loader, const ResourceLoaderOptions& options)
+ImageWithScale CSSCursorImageValue::selectBestFitImage(const Document& document)
 {
     if (is<CSSImageSetValue>(m_imageValue.get()))
-        return downcast<CSSImageSetValue>(m_imageValue.get()).loadBestFitImage(loader, options);
+        return downcast<CSSImageSetValue>(m_imageValue.get()).selectBestFitImage(document);
 
-    if (auto* cursorElement = updateCursorElement(*loader.document())) {
+    if (auto* cursorElement = updateCursorElement(document)) {
         if (cursorElement->href() != downcast<CSSImageValue>(m_imageValue.get()).url())
-            m_imageValue = CSSImageValue::create(loader.document()->completeURL(cursorElement->href()), m_loadedFromOpaqueSource);
+            m_imageValue = CSSImageValue::create(document.completeURL(cursorElement->href()), m_loadedFromOpaqueSource);
     }
 
-    return { downcast<CSSImageValue>(m_imageValue.get()).loadImage(loader, options), 1 };
+    return { m_imageValue.ptr() , 1 };
 }
 
 bool CSSCursorImageValue::equals(const CSSCursorImageValue& other) const

Modified: trunk/Source/WebCore/css/CSSCursorImageValue.h (254860 => 254861)


--- trunk/Source/WebCore/css/CSSCursorImageValue.h	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/css/CSSCursorImageValue.h	2020-01-21 18:28:17 UTC (rev 254861)
@@ -34,6 +34,12 @@
 class SVGCursorElement;
 class SVGElement;
 
+struct ImageWithScale;
+
+namespace Style {
+class BuilderState;
+}
+
 class CSSCursorImageValue final : public CSSValue {
 public:
     static Ref<CSSCursorImageValue> create(Ref<CSSValue>&& imageValue, bool hasHotSpot, const IntPoint& hotSpot, LoadedFromOpaqueSource loadedFromOpaqueSource)
@@ -56,7 +62,7 @@
 
     String customCSSText() const;
 
-    std::pair<CachedImage*, float> loadImage(CachedResourceLoader&, const ResourceLoaderOptions&);
+    ImageWithScale selectBestFitImage(const Document&);
 
     void removeReferencedElement(SVGElement*);
 

Modified: trunk/Source/WebCore/css/CSSImageSetValue.cpp (254860 => 254861)


--- trunk/Source/WebCore/css/CSSImageSetValue.cpp	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/css/CSSImageSetValue.cpp	2020-01-21 18:28:17 UTC (rev 254861)
@@ -28,19 +28,20 @@
 
 #include "CSSImageValue.h"
 #include "CSSPrimitiveValue.h"
-#include "CachedImage.h"
-#include "CachedResourceLoader.h"
-#include "CachedResourceRequest.h"
-#include "CachedResourceRequestInitiators.h"
 #include "Document.h"
 #include "Page.h"
+#include "StyleBuilderState.h"
 #include <wtf/text/StringBuilder.h>
 
 namespace WebCore {
 
-CSSImageSetValue::CSSImageSetValue(LoadedFromOpaqueSource loadedFromOpaqueSource)
+Ref<CSSImageSetValue> CSSImageSetValue::create()
+{
+    return adoptRef(*new CSSImageSetValue);
+}
+
+CSSImageSetValue::CSSImageSetValue()
     : CSSValueList(ImageSetClass, CommaSeparator)
-    , m_loadedFromOpaqueSource(loadedFromOpaqueSource)
 {
 }
 
@@ -52,8 +53,7 @@
     size_t i = 0;
     while (i < length) {
         CSSValue* imageValue = item(i);
-        URL imageURL = downcast<CSSImageValue>(*imageValue).url();
-
+        ASSERT(is<CSSImageValue>(imageValue) || is<CSSImageGeneratorValue>(imageValue));
         ++i;
         ASSERT_WITH_SECURITY_IMPLICATION(i < length);
         CSSValue* scaleFactorValue = item(i);
@@ -60,7 +60,7 @@
         float scaleFactor = downcast<CSSPrimitiveValue>(*scaleFactorValue).floatValue();
 
         ImageWithScale image;
-        image.imageURL = imageURL;
+        image.value = imageValue;
         image.scaleFactor = scaleFactor;
         m_imagesInSet.append(image);
         ++i;
@@ -70,7 +70,7 @@
     std::sort(m_imagesInSet.begin(), m_imagesInSet.end(), CSSImageSetValue::compareByScaleFactor);
 }
 
-CSSImageSetValue::ImageWithScale CSSImageSetValue::bestImageForScaleFactor()
+ImageWithScale CSSImageSetValue::bestImageForScaleFactor()
 {
     if (!m_imagesInSet.size())
         fillImageSet();
@@ -85,44 +85,51 @@
     return image;
 }
 
-std::pair<CachedImage*, float> CSSImageSetValue::loadBestFitImage(CachedResourceLoader& loader, const ResourceLoaderOptions& options)
+CachedImage* CSSImageSetValue::cachedImage() const
 {
-    Document* document = loader.document();
-    ASSERT(document);
+    if (is<CSSImageValue>(m_selectedImageValue))
+        return downcast<CSSImageValue>(*m_selectedImageValue).cachedImage();
+    return nullptr;
+}
 
-    updateDeviceScaleFactor(*document);
+ImageWithScale CSSImageSetValue::selectBestFitImage(const Document& document)
+{
+    updateDeviceScaleFactor(document);
 
     if (!m_accessedBestFitImage) {
         m_accessedBestFitImage = true;
+        m_bestFitImage = bestImageForScaleFactor();
+    }
 
-        // FIXME: In the future, we want to take much more than deviceScaleFactor into acount here.
-        // All forms of scale should be included: Page::pageScaleFactor(), Frame::pageZoomFactor(),
-        // and any CSS transforms. https://bugs.webkit.org/show_bug.cgi?id=81698
-        ImageWithScale image = bestImageForScaleFactor();
-
-        ResourceLoaderOptions loadOptions = options;
-        loadOptions.loadedFromOpaqueSource = m_loadedFromOpaqueSource;
-        CachedResourceRequest request(ResourceRequest(document->completeURL(image.imageURL)), loadOptions);
-        request.setInitiator(cachedResourceRequestInitiators().css);
-        if (options.mode == FetchOptions::Mode::Cors)
-            request.updateForAccessControl(*document);
-
-        m_cachedImage = loader.requestImage(WTFMove(request)).value_or(nullptr);
-        m_bestFitImageScaleFactor = image.scaleFactor;
-    }
-    return { m_cachedImage.get(), m_bestFitImageScaleFactor };
+    return m_bestFitImage;
 }
 
 void CSSImageSetValue::updateDeviceScaleFactor(const Document& document)
 {
+
+    // FIXME: In the future, we want to take much more than deviceScaleFactor into acount here.
+    // All forms of scale should be included: Page::pageScaleFactor(), Frame::pageZoomFactor(),
+    // and any CSS transforms. https://bugs.webkit.org/show_bug.cgi?id=81698
     float deviceScaleFactor = document.page() ? document.page()->deviceScaleFactor() : 1;
     if (deviceScaleFactor == m_deviceScaleFactor)
         return;
     m_deviceScaleFactor = deviceScaleFactor;
     m_accessedBestFitImage = false;
-    m_cachedImage = nullptr;
+    m_selectedImageValue = nullptr;
 }
 
+Ref<CSSImageSetValue> CSSImageSetValue::imageSetWithStylesResolved(Style::BuilderState& builderState)
+{
+    Ref<CSSImageSetValue> result = CSSImageSetValue::create();
+    size_t length = this->length();
+    for (size_t i = 0; i + 1 < length; i += 2) {
+        result->append(builderState.resolveImageStyles(*itemWithoutBoundsCheck(i)));
+        result->append(*itemWithoutBoundsCheck(i + 1));
+    }
+
+    return result;
+}
+
 String CSSImageSetValue::customCSSText() const
 {
     StringBuilder result;
@@ -155,9 +162,7 @@
 
 bool CSSImageSetValue::traverseSubresources(const WTF::Function<bool (const CachedResource&)>& handler) const
 {
-    if (!m_cachedImage)
-        return false;
-    return handler(*m_cachedImage);
+    return m_selectedImageValue && m_selectedImageValue->traverseSubresources(handler);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/CSSImageSetValue.h (254860 => 254861)


--- trunk/Source/WebCore/css/CSSImageSetValue.h	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/css/CSSImageSetValue.h	2020-01-21 18:28:17 UTC (rev 254861)
@@ -29,53 +29,54 @@
 #include "CachedResourceHandle.h"
 #include "ResourceLoaderOptions.h"
 #include <wtf/Function.h>
+#include <wtf/RefPtr.h>
 
 namespace WebCore {
 
 class CachedImage;
 class CachedResourceLoader;
+class CSSImageValue;
 class Document;
 
+namespace Style {
+class BuilderState;
+}
+
+struct ImageWithScale {
+    RefPtr<CSSValue> value;
+    float scaleFactor { 1 };
+};
+
 class CSSImageSetValue final : public CSSValueList {
 public:
-    static Ref<CSSImageSetValue> create(LoadedFromOpaqueSource loadedFromOpaqueSource)
-    {
-        return adoptRef(*new CSSImageSetValue(loadedFromOpaqueSource));
-    }
+    static Ref<CSSImageSetValue> create();
     ~CSSImageSetValue();
 
-    std::pair<CachedImage*, float>  loadBestFitImage(CachedResourceLoader&, const ResourceLoaderOptions&);
-    CachedImage* cachedImage() const { return m_cachedImage.get(); }
+    ImageWithScale selectBestFitImage(const Document&);
+    CachedImage* cachedImage() const;
 
     String customCSSText() const;
 
-    struct ImageWithScale {
-        URL imageURL;
-        float scaleFactor;
-    };
-
     bool traverseSubresources(const WTF::Function<bool (const CachedResource&)>& handler) const;
 
     void updateDeviceScaleFactor(const Document&);
 
-    URL bestImageForScaleFactorURL() { return bestImageForScaleFactor().imageURL; }
+    Ref<CSSImageSetValue> imageSetWithStylesResolved(Style::BuilderState&);
 
 protected:
     ImageWithScale bestImageForScaleFactor();
 
 private:
-    explicit CSSImageSetValue(LoadedFromOpaqueSource);
+    CSSImageSetValue();
 
     void fillImageSet();
     static inline bool compareByScaleFactor(ImageWithScale first, ImageWithScale second) { return first.scaleFactor < second.scaleFactor; }
 
-    CachedResourceHandle<CachedImage> m_cachedImage;
+    RefPtr<CSSValue> m_selectedImageValue;
     bool m_accessedBestFitImage { false };
-    float m_bestFitImageScaleFactor { 1 };
+    ImageWithScale m_bestFitImage;
     float m_deviceScaleFactor { 1 };
-
     Vector<ImageWithScale> m_imagesInSet;
-    LoadedFromOpaqueSource m_loadedFromOpaqueSource { LoadedFromOpaqueSource::No };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp (254860 => 254861)


--- trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp	2020-01-21 18:28:17 UTC (rev 254861)
@@ -2151,7 +2151,7 @@
 static RefPtr<CSSValue> consumeCursor(CSSParserTokenRange& range, const CSSParserContext& context, bool inQuirksMode)
 {
     RefPtr<CSSValueList> list;
-    while (RefPtr<CSSValue> image = consumeImage(range, context, ConsumeGeneratedImage::Forbid)) {
+    while (RefPtr<CSSValue> image = consumeImage(range, context, { AllowedImageType::URLFunction, AllowedImageType::ImageSet })) {
         double num;
         IntPoint hotSpot(-1, -1);
         bool hotSpotSpecified = false;

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (254860 => 254861)


--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2020-01-21 18:28:17 UTC (rev 254861)
@@ -1479,24 +1479,16 @@
     return result;
 }
 
-static StringView consumeUrlOrStringAsStringView(CSSParserTokenRange& args)
+static RefPtr<CSSValue> consumeImageSet(CSSParserTokenRange& range, const CSSParserContext& context, OptionSet<AllowedImageType> allowedImageType)
 {
-    if (args.peek().type() == StringToken)
-        return args.consumeIncludingWhitespace().value();
-    return consumeUrlAsStringView(args);
-}
-
-static RefPtr<CSSValue> consumeImageSet(CSSParserTokenRange& range, const CSSParserContext& context)
-{
     CSSParserTokenRange rangeCopy = range;
     CSSParserTokenRange args = consumeFunction(rangeCopy);
-    RefPtr<CSSImageSetValue> imageSet = CSSImageSetValue::create(context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No);
+    RefPtr<CSSImageSetValue> imageSet = CSSImageSetValue::create();
     do {
-        AtomString urlValue = consumeUrlOrStringAsStringView(args).toAtomString();
-        if (urlValue.isNull())
+        RefPtr<CSSValue> image = consumeImage(args, context, (allowedImageType | AllowedImageType::RawStringAsURL) - AllowedImageType::ImageSet);
+        if (!image)
             return nullptr;
 
-        RefPtr<CSSValue> image = CSSImageValue::create(completeURL(context, urlValue), context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No);
         imageSet->append(image.releaseNonNull());
 
         const CSSParserToken& token = args.consumeIncludingWhitespace();
@@ -1711,19 +1703,25 @@
     return CSSShadowValue::create(WTFMove(horizontalOffset), WTFMove(verticalOffset), WTFMove(blurRadius), WTFMove(spreadDistance), WTFMove(style), WTFMove(color));
 }
 
-RefPtr<CSSValue> consumeImage(CSSParserTokenRange& range, CSSParserContext context, ConsumeGeneratedImage generatedImage)
+RefPtr<CSSValue> consumeImage(CSSParserTokenRange& range, CSSParserContext context, OptionSet<AllowedImageType> AllowedImageType)
 {
-    AtomString uri = consumeUrlAsStringView(range).toAtomString();
-    if (!uri.isNull())
-        return CSSImageValue::create(completeURL(context, uri), context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No);
+    if ((range.peek().type() == StringToken) && (AllowedImageType & AllowedImageType::RawStringAsURL))
+        return CSSImageValue::create(completeURL(context, range.consumeIncludingWhitespace().value().toAtomString()), context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No);
 
     if (range.peek().type() == FunctionToken) {
         CSSValueID id = range.peek().functionId();
-        if (id == CSSValueWebkitImageSet || id == CSSValueImageSet)
-            return consumeImageSet(range, context);
-        if (generatedImage == ConsumeGeneratedImage::Allow && isGeneratedImage(id))
+        if ((AllowedImageType & AllowedImageType::ImageSet) && (id == CSSValueWebkitImageSet || id == CSSValueImageSet))
+            return consumeImageSet(range, context, AllowedImageType);
+        if ((AllowedImageType & AllowedImageType::GeneratedImage) && isGeneratedImage(id))
             return consumeGeneratedImage(range, context);
     }
+
+    if (AllowedImageType & AllowedImageType::URLFunction) {
+        auto uri = consumeUrlAsStringView(range);
+        if (!uri.isNull())
+            return CSSImageValue::create(completeURL(context, uri.toAtomString()), context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No);
+    }
+
     return nullptr;
 }
 

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h (254860 => 254861)


--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h	2020-01-21 18:28:17 UTC (rev 254861)
@@ -36,6 +36,7 @@
 #include "CSSShadowValue.h"
 #include "CSSValuePool.h"
 #include "Length.h" // For ValueRange
+#include <wtf/OptionSet.h>
 
 namespace WebCore {
 
@@ -89,12 +90,15 @@
 bool consumePosition(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk, PositionSyntax, RefPtr<CSSPrimitiveValue>& resultX, RefPtr<CSSPrimitiveValue>& resultY);
 bool consumeOneOrTwoValuedPosition(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk, RefPtr<CSSPrimitiveValue>& resultX, RefPtr<CSSPrimitiveValue>& resultY);
 
-enum class ConsumeGeneratedImage {
-    Allow,
-    Forbid
+enum class AllowedImageType : uint8_t {
+    URLFunction = 1 << 0,
+    RawStringAsURL = 1 << 1,
+    ImageSet = 1 << 2,
+    GeneratedImage = 1 << 3
 };
 
-RefPtr<CSSValue> consumeImage(CSSParserTokenRange&, CSSParserContext, ConsumeGeneratedImage = ConsumeGeneratedImage::Allow);
+RefPtr<CSSValue> consumeImage(CSSParserTokenRange&, CSSParserContext, OptionSet<AllowedImageType> = { AllowedImageType::URLFunction, AllowedImageType::ImageSet, AllowedImageType::GeneratedImage });
+
 RefPtr<CSSValue> consumeImageOrNone(CSSParserTokenRange&, CSSParserContext);
 
 enum class AllowedFilterFunctions {

Modified: trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp (254860 => 254861)


--- trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp	2020-01-21 18:28:17 UTC (rev 254861)
@@ -333,6 +333,12 @@
     if (!from || !to)
         return to;
 
+    from = from->selectedImage();
+    to = to->selectedImage();
+
+    if (!from || !to)
+        return to;    
+
     // Animation between two generated images. Cross fade for all other cases.
     if (is<StyleGeneratedImage>(*from) && is<StyleGeneratedImage>(*to)) {
         CSSImageGeneratorValue& fromGenerated = downcast<StyleGeneratedImage>(*from).imageValue();

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (254860 => 254861)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2020-01-21 18:28:17 UTC (rev 254861)
@@ -962,7 +962,7 @@
 
             auto drawResult = context.drawTiledImage(*image, geometry.destRect(), toLayoutPoint(geometry.relativePhase()), geometry.tileSize(), geometry.spaceSize(), options);
             if (drawResult == ImageDrawResult::DidRequestDecoding) {
-                ASSERT(bgImage->isCachedImage());
+                ASSERT(bgImage->hasCachedImage());
                 bgImage->cachedImage()->addClientWaitingForAsyncDecoding(*this);
             }
         }

Modified: trunk/Source/WebCore/rendering/RenderImageResourceStyleImage.cpp (254860 => 254861)


--- trunk/Source/WebCore/rendering/RenderImageResourceStyleImage.cpp	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/rendering/RenderImageResourceStyleImage.cpp	2020-01-21 18:28:17 UTC (rev 254861)
@@ -44,7 +44,7 @@
 
 void RenderImageResourceStyleImage::initialize(RenderElement& renderer)
 {
-    RenderImageResource::initialize(renderer, m_styleImage->isCachedImage() ? m_styleImage.get().cachedImage() : nullptr);
+    RenderImageResource::initialize(renderer, m_styleImage->hasCachedImage() ? m_styleImage.get().cachedImage() : nullptr);
     m_styleImage->addClient(this->renderer());
 }
 

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (254860 => 254861)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2020-01-21 18:28:17 UTC (rev 254861)
@@ -2107,7 +2107,7 @@
 
     // FIXME: support gradients with isGeneratedImage.
     auto* styleImage = fillLayer.image();
-    if (!styleImage->isCachedImage())
+    if (!styleImage->hasCachedImage())
         return false;
 
     auto* image = styleImage->cachedImage()->image();

Modified: trunk/Source/WebCore/rendering/style/ShapeValue.cpp (254860 => 254861)


--- trunk/Source/WebCore/rendering/style/ShapeValue.cpp	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/rendering/style/ShapeValue.cpp	2020-01-21 18:28:17 UTC (rev 254861)
@@ -35,7 +35,7 @@
 {
     if (!m_image)
         return false;
-    if (m_image->isCachedImage()) {
+    if (m_image->hasCachedImage()) {
         auto* cachedImage = m_image->cachedImage();
         return cachedImage && cachedImage->hasImage();
     }

Modified: trunk/Source/WebCore/rendering/style/StyleCachedImage.cpp (254860 => 254861)


--- trunk/Source/WebCore/rendering/style/StyleCachedImage.cpp	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/rendering/style/StyleCachedImage.cpp	2020-01-21 18:28:17 UTC (rev 254861)
@@ -24,8 +24,6 @@
 #include "config.h"
 #include "StyleCachedImage.h"
 
-#include "CSSCursorImageValue.h"
-#include "CSSImageSetValue.h"
 #include "CSSImageValue.h"
 #include "CachedImage.h"
 #include "RenderElement.h"
@@ -33,19 +31,19 @@
 
 namespace WebCore {
 
-StyleCachedImage::StyleCachedImage(CSSValue& cssValue)
+Ref<StyleCachedImage> StyleCachedImage::create(CSSImageValue& cssValue, float scaleFactor)
+{
+    return adoptRef(*new StyleCachedImage(cssValue, scaleFactor));
+}
+
+StyleCachedImage::StyleCachedImage(CSSImageValue& cssValue, float scaleFactor)
     : m_cssValue(cssValue)
+    , m_scaleFactor(scaleFactor)
 {
-    ASSERT(is<CSSImageValue>(m_cssValue) || is<CSSImageSetValue>(m_cssValue) || is<CSSCursorImageValue>(m_cssValue));
-
     m_isCachedImage = true;
-
-    // CSSImageValue doesn't get invalidated so we can grab the CachedImage immediately if it exists.
-    if (is<CSSImageValue>(m_cssValue)) {
-        m_cachedImage = downcast<CSSImageValue>(m_cssValue.get()).cachedImage();
-        if (m_cachedImage)
-            m_isPending = false;
-    }
+    m_cachedImage = m_cssValue->cachedImage();
+    if (m_cachedImage)
+        m_isPending = false;
 }
 
 StyleCachedImage::~StyleCachedImage() = default;
@@ -68,17 +66,7 @@
 
 URL StyleCachedImage::imageURL()
 {
-    if (is<CSSImageValue>(m_cssValue))
-        return downcast<CSSImageValue>(m_cssValue.get()).url();
-
-    if (is<CSSImageSetValue>(m_cssValue))
-        return downcast<CSSImageSetValue>(m_cssValue.get()).bestImageForScaleFactorURL();
-
-    if (is<CSSCursorImageValue>(m_cssValue.get()))
-        return downcast<CSSCursorImageValue>(m_cssValue.get()).imageURL();
-
-    ASSERT_NOT_REACHED();
-    return { };
+    return m_cssValue->url();
 }
 
 void StyleCachedImage::load(CachedResourceLoader& loader, const ResourceLoaderOptions& options)
@@ -85,24 +73,7 @@
 {
     ASSERT(m_isPending);
     m_isPending = false;
-
-    if (is<CSSImageValue>(m_cssValue)) {
-        auto& imageValue = downcast<CSSImageValue>(m_cssValue.get());
-        m_cachedImage = imageValue.loadImage(loader, options);
-        return;
-    }
-
-    if (is<CSSImageSetValue>(m_cssValue)) {
-        auto& imageSetValue = downcast<CSSImageSetValue>(m_cssValue.get());
-        std::tie(m_cachedImage, m_scaleFactor) = imageSetValue.loadBestFitImage(loader, options);
-        return;
-    }
-
-    if (is<CSSCursorImageValue>(m_cssValue.get())) {
-        auto& cursorValue = downcast<CSSCursorImageValue>(m_cssValue.get());
-        std::tie(m_cachedImage, m_scaleFactor) = cursorValue.loadImage(loader, options);
-        return;
-    }
+    m_cachedImage = m_cssValue->loadImage(loader, options);
 }
 
 CachedImage* StyleCachedImage::cachedImage() const

Modified: trunk/Source/WebCore/rendering/style/StyleCachedImage.h (254860 => 254861)


--- trunk/Source/WebCore/rendering/style/StyleCachedImage.h	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/rendering/style/StyleCachedImage.h	2020-01-21 18:28:17 UTC (rev 254861)
@@ -29,6 +29,7 @@
 namespace WebCore {
 
 class CSSValue;
+class CSSImageValue;
 class CachedImage;
 class Document;
 
@@ -35,7 +36,7 @@
 class StyleCachedImage final : public StyleImage {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static Ref<StyleCachedImage> create(CSSValue& cssValue) { return adoptRef(*new StyleCachedImage(cssValue)); }
+    static Ref<StyleCachedImage> create(CSSImageValue& cssValue, float scaleFactor = 1);
     virtual ~StyleCachedImage();
 
     bool operator==(const StyleImage& other) const final;
@@ -64,10 +65,10 @@
     bool knownToBeOpaque(const RenderElement*) const final;
 
 private:
-    StyleCachedImage(CSSValue&);
+    StyleCachedImage(CSSImageValue&, float);
     URL imageURL();
 
-    Ref<CSSValue> m_cssValue;
+    Ref<CSSImageValue> m_cssValue;
     bool m_isPending { true };
     mutable float m_scaleFactor { 1 };
     mutable CachedResourceHandle<CachedImage> m_cachedImage;

Added: trunk/Source/WebCore/rendering/style/StyleCursorImage.cpp (0 => 254861)


--- trunk/Source/WebCore/rendering/style/StyleCursorImage.cpp	                        (rev 0)
+++ trunk/Source/WebCore/rendering/style/StyleCursorImage.cpp	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2000 Lars Knoll ([email protected])
+ *           (C) 2000 Antti Koivisto ([email protected])
+ *           (C) 2000 Dirk Mueller ([email protected])
+ * Copyright (C) 2003, 2005-2008, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2020 Noam Rosenthal ([email protected])
+  *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "StyleCursorImage.h"
+
+#include "CSSCursorImageValue.h"
+#include "CSSImageSetValue.h"
+#include "CachedImage.h"
+#include "FloatSize.h"
+#include "RenderElement.h"
+
+namespace WebCore {
+
+Ref<StyleCursorImage> StyleCursorImage::create(CSSCursorImageValue& cssValue)
+{ 
+    return adoptRef(*new StyleCursorImage(cssValue)); 
+}
+
+bool StyleCursorImage::operator==(const StyleImage& other) const
+{
+    return is<StyleCursorImage>(other) && equals(downcast<StyleCursorImage>(other));
+}
+
+Ref<CSSValue> StyleCursorImage::cssValue() const
+{ 
+    return m_cssValue.copyRef(); 
+}
+
+StyleCursorImage::StyleCursorImage(CSSCursorImageValue& cssValue)
+    : m_cssValue(cssValue)
+{
+    m_isCursorImage = true;
+}
+
+StyleCursorImage::~StyleCursorImage() = default;
+
+ImageWithScale StyleCursorImage::selectBestFitImage(const Document& document) const
+{
+    return m_cssValue->selectBestFitImage(document);
+}
+
+void StyleCursorImage::setContainerContextForRenderer(const RenderElement& renderer, const FloatSize& containerSize, float containerZoom)
+{
+    if (!hasCachedImage())
+        return;
+    cachedImage()->setContainerContextForClient(renderer, LayoutSize(containerSize), containerZoom, m_cssValue->imageURL());
+}
+
+}
Property changes on: trunk/Source/WebCore/rendering/style/StyleCursorImage.cpp
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/Source/WebCore/rendering/style/StyleCursorImage.h (0 => 254861)


--- trunk/Source/WebCore/rendering/style/StyleCursorImage.h	                        (rev 0)
+++ trunk/Source/WebCore/rendering/style/StyleCursorImage.h	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2000 Lars Knoll ([email protected])
+ *           (C) 2000 Antti Koivisto ([email protected])
+ *           (C) 2000 Dirk Mueller ([email protected])
+ * Copyright (C) 2003, 2005-2008, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2020 Noam Rosenthal ([email protected])
+  *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#pragma once
+
+#include "StyleMultiImage.h"
+
+namespace WebCore {
+
+class CSSCursorImageValue;
+
+struct ImageWithScale;
+
+class StyleCursorImage final : public StyleMultiImage {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static Ref<StyleCursorImage> create(CSSCursorImageValue&);
+    virtual ~StyleCursorImage();
+    bool operator==(const StyleImage& other) const;
+
+private:
+    void setContainerContextForRenderer(const RenderElement& renderer, const FloatSize& containerSize, float containerZoom) final;
+    Ref<CSSValue> cssValue() const final;
+    ImageWithScale selectBestFitImage(const Document&) const final;
+
+    explicit StyleCursorImage(CSSCursorImageValue&);
+    Ref<CSSCursorImageValue> m_cssValue;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_STYLE_IMAGE(StyleCursorImage, isCursorImage)
Property changes on: trunk/Source/WebCore/rendering/style/StyleCursorImage.h
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Modified: trunk/Source/WebCore/rendering/style/StyleImage.h (254860 => 254861)


--- trunk/Source/WebCore/rendering/style/StyleImage.h	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/rendering/style/StyleImage.h	2020-01-21 18:28:17 UTC (rev 254861)
@@ -67,18 +67,28 @@
     virtual float imageScaleFactor() const { return 1; }
     virtual bool knownToBeOpaque(const RenderElement*) const = 0;
     virtual CachedImage* cachedImage() const { return 0; }
+    virtual StyleImage* selectedImage() { return this; }
+    virtual const StyleImage* selectedImage() const { return this; }
 
     ALWAYS_INLINE bool isCachedImage() const { return m_isCachedImage; }
     ALWAYS_INLINE bool isGeneratedImage() const { return m_isGeneratedImage; }
+    ALWAYS_INLINE bool isCursorImage() const { return m_isCursorImage; }
+    ALWAYS_INLINE bool isImageSet() const { return m_isImageSet; }
 
+    bool hasCachedImage() const { return m_isCachedImage || selectedImage()->isCachedImage(); }
+
 protected:
     StyleImage()
         : m_isCachedImage(false)
         , m_isGeneratedImage(false)
+        , m_isImageSet(false)
+        , m_isCursorImage(false)
     {
     }
     bool m_isCachedImage : 1;
     bool m_isGeneratedImage : 1;
+    bool m_isImageSet : 1;
+    bool m_isCursorImage : 1;
 };
 
 } // namespace WebCore

Added: trunk/Source/WebCore/rendering/style/StyleImageSet.cpp (0 => 254861)


--- trunk/Source/WebCore/rendering/style/StyleImageSet.cpp	                        (rev 0)
+++ trunk/Source/WebCore/rendering/style/StyleImageSet.cpp	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2000 Lars Knoll ([email protected])
+ *           (C) 2000 Antti Koivisto ([email protected])
+ *           (C) 2000 Dirk Mueller ([email protected])
+ * Copyright (C) 2003, 2005-2008, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2020 Noam Rosenthal ([email protected])
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "StyleImageSet.h"
+
+#include "CSSImageSetValue.h"
+
+namespace WebCore {
+
+Ref<StyleImageSet> StyleImageSet::create(CSSImageSetValue& cssValue)
+{ 
+    return adoptRef(*new StyleImageSet(cssValue));
+}
+
+StyleImageSet::StyleImageSet(CSSImageSetValue& cssValue)
+    : m_cssValue(cssValue)
+{
+    m_isImageSet = true;
+}
+
+bool StyleImageSet::operator==(const StyleImage& other) const
+{
+    return is<StyleImageSet>(other) && equals(downcast<StyleImageSet>(other));
+}
+
+StyleImageSet::~StyleImageSet() = default;
+
+Ref<CSSValue> StyleImageSet::cssValue() const
+{ 
+    return m_cssValue.copyRef(); 
+}
+
+ImageWithScale StyleImageSet::selectBestFitImage(const Document& document) const
+{
+    return m_cssValue->selectBestFitImage(document);
+}
+
+}
Property changes on: trunk/Source/WebCore/rendering/style/StyleImageSet.cpp
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/Source/WebCore/rendering/style/StyleImageSet.h (0 => 254861)


--- trunk/Source/WebCore/rendering/style/StyleImageSet.h	                        (rev 0)
+++ trunk/Source/WebCore/rendering/style/StyleImageSet.h	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,49 @@
+/*
+* Copyright (C) 2000 Lars Knoll ([email protected])
+*           (C) 2000 Antti Koivisto ([email protected])
+*           (C) 2000 Dirk Mueller ([email protected])
+* Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+* Copyright (C) 2020 Noam Rosenthal ([email protected])
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Library General Public
+* License as published by the Free Software Foundation; either
+* version 2 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Library General Public License for more details.
+*
+* You should have received a copy of the GNU Library General Public License
+* along with this library; see the file COPYING.LIB.  If not, write to
+* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+* Boston, MA 02110-1301, USA.
+*
+*/
+
+#pragma once
+
+#include "StyleMultiImage.h"
+
+namespace WebCore {
+
+class CSSImageSetValue;
+
+class StyleImageSet final : public StyleMultiImage {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static Ref<StyleImageSet> create(CSSImageSetValue&);
+    virtual ~StyleImageSet();
+    bool operator==(const StyleImage& other) const;
+
+private:
+    explicit StyleImageSet(CSSImageSetValue&);
+    Ref<CSSValue> cssValue() const final;
+    ImageWithScale selectBestFitImage(const Document&) const final;
+    Ref<CSSImageSetValue> m_cssValue;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_STYLE_IMAGE(StyleImageSet, isImageSet)
Property changes on: trunk/Source/WebCore/rendering/style/StyleImageSet.h
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/Source/WebCore/rendering/style/StyleMultiImage.cpp (0 => 254861)


--- trunk/Source/WebCore/rendering/style/StyleMultiImage.cpp	                        (rev 0)
+++ trunk/Source/WebCore/rendering/style/StyleMultiImage.cpp	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2003, 2005-2008, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2020 Noam Rosenthal ([email protected])
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "StyleMultiImage.h"
+
+#include "CSSImageGeneratorValue.h"
+#include "CSSImageSetValue.h"
+#include "CSSImageValue.h"
+#include "CachedImage.h"
+#include "CachedResourceLoader.h"
+#include "RenderElement.h"
+#include "RenderView.h"
+#include "StyleCachedImage.h"
+#include "StyleGeneratedImage.h"
+
+namespace WebCore {
+
+StyleMultiImage::StyleMultiImage() = default;
+
+StyleMultiImage::~StyleMultiImage() = default;
+
+bool StyleMultiImage::equals(const StyleMultiImage& other) const
+{
+    return (!m_isPending && !other.m_isPending && m_selectedImage.get() == other.m_selectedImage.get());
+}
+
+void StyleMultiImage::load(CachedResourceLoader& loader, const ResourceLoaderOptions& options)
+{
+    ASSERT(m_isPending);
+    ASSERT(loader.document());
+
+    m_isPending = false;
+    auto imageWithScale = selectBestFitImage(*loader.document());
+    ASSERT(is<CSSImageValue>(imageWithScale.value) || is<CSSImageGeneratorValue>(imageWithScale.value));
+
+    if (is<CSSImageGeneratorValue>(imageWithScale.value)) {
+        m_selectedImage = StyleGeneratedImage::create(downcast<CSSImageGeneratorValue>(*imageWithScale.value.get()));
+        m_selectedImage->load(loader, options);
+    }
+    
+    if (is<CSSImageValue>(imageWithScale.value)) {
+        m_selectedImage = StyleCachedImage::create(downcast<CSSImageValue>(*imageWithScale.value.get()), imageWithScale.scaleFactor);
+        if (m_selectedImage->isPending())
+            m_selectedImage->load(loader, options);
+    }
+}
+
+CachedImage* StyleMultiImage::cachedImage() const
+{
+    if (!m_selectedImage)
+        return nullptr;
+    return m_selectedImage->cachedImage();
+}
+
+WrappedImagePtr StyleMultiImage::data() const
+{
+    if (!m_selectedImage)
+        return nullptr;
+    return m_selectedImage->data();
+}
+
+bool StyleMultiImage::canRender(const RenderElement* renderer, float multiplier) const
+{
+    return m_selectedImage && m_selectedImage->canRender(renderer, multiplier);
+}
+
+bool StyleMultiImage::isPending() const
+{
+    return m_isPending;
+}
+
+bool StyleMultiImage::isLoaded() const
+{
+    return m_selectedImage && m_selectedImage->isLoaded();
+}
+
+bool StyleMultiImage::errorOccurred() const
+{
+    return m_selectedImage && m_selectedImage->errorOccurred();
+}
+
+FloatSize StyleMultiImage::imageSize(const RenderElement* renderer, float multiplier) const
+{
+    if (!m_selectedImage)
+        return { };
+    return m_selectedImage->imageSize(renderer, multiplier);
+}
+
+bool StyleMultiImage::imageHasRelativeWidth() const
+{
+    return m_selectedImage && m_selectedImage->imageHasRelativeWidth();
+}
+
+bool StyleMultiImage::imageHasRelativeHeight() const
+{
+    return m_selectedImage && m_selectedImage->imageHasRelativeHeight();
+}
+
+void StyleMultiImage::computeIntrinsicDimensions(const RenderElement* element, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio)
+{
+    if (!m_selectedImage)
+        return;
+    m_selectedImage->computeIntrinsicDimensions(element, intrinsicWidth, intrinsicHeight, intrinsicRatio);
+}
+
+bool StyleMultiImage::usesImageContainerSize() const
+{
+    return m_selectedImage && m_selectedImage->usesImageContainerSize();
+}
+
+void StyleMultiImage::setContainerContextForRenderer(const RenderElement& renderer, const FloatSize& containerSize, float containerZoom)
+{
+    if (!m_selectedImage)
+        return;
+    m_selectedImage->setContainerContextForRenderer(renderer, containerSize, containerZoom);
+}
+
+void StyleMultiImage::addClient(RenderElement* renderer)
+{
+    if (!m_selectedImage)
+        return;
+    m_selectedImage->addClient(renderer);
+}
+
+void StyleMultiImage::removeClient(RenderElement* renderer)
+{
+    if (!m_selectedImage)
+        return;
+    m_selectedImage->removeClient(renderer);
+}
+
+RefPtr<Image> StyleMultiImage::image(RenderElement* renderer, const FloatSize& size) const
+{
+    if (!m_selectedImage)
+        return nullptr;
+    return m_selectedImage->image(renderer, size);
+}
+
+float StyleMultiImage::imageScaleFactor() const
+{
+    if (!m_selectedImage)
+        return 1;
+    return m_selectedImage->imageScaleFactor();
+}
+
+bool StyleMultiImage::knownToBeOpaque(const RenderElement* renderer) const
+{
+    return m_selectedImage && m_selectedImage->knownToBeOpaque(renderer);
+}
+
+}
Property changes on: trunk/Source/WebCore/rendering/style/StyleMultiImage.cpp
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/Source/WebCore/rendering/style/StyleMultiImage.h (0 => 254861)


--- trunk/Source/WebCore/rendering/style/StyleMultiImage.h	                        (rev 0)
+++ trunk/Source/WebCore/rendering/style/StyleMultiImage.h	2020-01-21 18:28:17 UTC (rev 254861)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2000 Lars Knoll ([email protected])
+ *           (C) 2000 Antti Koivisto ([email protected])
+ *           (C) 2000 Dirk Mueller ([email protected])
+ * Copyright (C) 2003, 2005-2008, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2020 Noam Rosenthal ([email protected])
+ *
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Library General Public
+* License as published by the Free Software Foundation; either
+* version 2 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Library General Public License for more details.
+*
+* You should have received a copy of the GNU Library General Public License
+* along with this library; see the file COPYING.LIB.  If not, write to
+* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+* Boston, MA 02110-1301, USA.
+*
+*/
+
+#pragma once
+
+#include "StyleImage.h"
+
+namespace WebCore {
+
+class Document;
+
+struct ImageWithScale;
+
+class StyleMultiImage : public StyleImage {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    virtual ~StyleMultiImage();
+
+protected:
+    StyleMultiImage();
+    bool equals(const StyleMultiImage& other) const;
+    virtual ImageWithScale selectBestFitImage(const Document&) const = 0;
+    CachedImage* cachedImage() const final;
+
+private:
+    WrappedImagePtr data() const final;
+
+    bool canRender(const RenderElement*, float multiplier) const final;
+    bool isPending() const final;
+    void load(CachedResourceLoader&, const ResourceLoaderOptions&) final;
+    bool isLoaded() const final;
+    bool errorOccurred() const final;
+    FloatSize imageSize(const RenderElement*, float multiplier) const final;
+    bool imageHasRelativeWidth() const final;
+    bool imageHasRelativeHeight() const final;
+    void computeIntrinsicDimensions(const RenderElement*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) final;
+    bool usesImageContainerSize() const final;
+    void setContainerContextForRenderer(const RenderElement&, const FloatSize&, float);
+    void addClient(RenderElement*) final;
+    void removeClient(RenderElement*) final;
+    RefPtr<Image> image(RenderElement*, const FloatSize&) const final;
+    float imageScaleFactor() const final;
+    bool knownToBeOpaque(const RenderElement*) const final;
+    const StyleImage* selectedImage() const final { return m_selectedImage.get(); }
+    StyleImage* selectedImage() final { return m_selectedImage.get(); }
+
+    RefPtr<StyleImage> m_selectedImage;
+    bool m_isPending { true };
+};
+
+} // namespace WebCore
Property changes on: trunk/Source/WebCore/rendering/style/StyleMultiImage.h
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Modified: trunk/Source/WebCore/style/StyleBuilderCustom.h (254860 => 254861)


--- trunk/Source/WebCore/style/StyleBuilderCustom.h	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/style/StyleBuilderCustom.h	2020-01-21 18:28:17 UTC (rev 254861)
@@ -46,8 +46,10 @@
 #include "SVGRenderStyle.h"
 #include "StyleBuilderConverter.h"
 #include "StyleCachedImage.h"
+#include "StyleCursorImage.h"
 #include "StyleFontSizeFunctions.h"
 #include "StyleGeneratedImage.h"
+#include "StyleImageSet.h"
 #include "StyleResolver.h"
 #include "WillChangeData.h"
 
@@ -1324,13 +1326,15 @@
             else
                 builderState.style().setContent(StyleGeneratedImage::create(downcast<CSSImageGeneratorValue>(item.get())), didSet);
             didSet = true;
-        } else if (is<CSSImageSetValue>(item)) {
-            builderState.style().setContent(StyleCachedImage::create(item), didSet);
+        }
+        
+        if (is<CSSImageSetValue>(item)) {
+            builderState.style().setContent(StyleImageSet::create(downcast<CSSImageSetValue>(item.get()).imageSetWithStylesResolved(builderState)), didSet);
             didSet = true;
         }
 
         if (is<CSSImageValue>(item)) {
-            builderState.style().setContent(StyleCachedImage::create(item), didSet);
+            builderState.style().setContent(StyleCachedImage::create(downcast<CSSImageValue>(item.get())), didSet);
             didSet = true;
             continue;
         }

Modified: trunk/Source/WebCore/style/StyleBuilderState.cpp (254860 => 254861)


--- trunk/Source/WebCore/style/StyleBuilderState.cpp	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/style/StyleBuilderState.cpp	2020-01-21 18:28:17 UTC (rev 254861)
@@ -45,8 +45,10 @@
 #include "Settings.h"
 #include "StyleBuilder.h"
 #include "StyleCachedImage.h"
+#include "StyleCursorImage.h"
 #include "StyleFontSizeFunctions.h"
 #include "StyleGeneratedImage.h"
+#include "StyleImageSet.h"
 #include "TransformFunctions.h"
 
 namespace WebCore {
@@ -79,21 +81,34 @@
     return is<SVGElement>(element()) && !(is<SVGSVGElement>(*element()) && element()->parentNode());
 }
 
+Ref<CSSValue> BuilderState::resolveImageStyles(CSSValue& value)
+{
+    if (is<CSSGradientValue>(value))
+        return downcast<CSSGradientValue>(value).gradientWithStylesResolved(*this);
+
+    if (is<CSSImageSetValue>(value))
+        return downcast<CSSImageSetValue>(value).imageSetWithStylesResolved(*this);
+
+    // Creating filter operations doesn't create a new CSSValue reference.
+    if (is<CSSFilterImageValue>(value))
+        downcast<CSSFilterImageValue>(value).createFilterOperations(*this);
+
+    return makeRef(value);
+}
+
 RefPtr<StyleImage> BuilderState::createStyleImage(CSSValue& value)
 {
-    if (is<CSSImageGeneratorValue>(value)) {
-        if (is<CSSGradientValue>(value))
-            return StyleGeneratedImage::create(downcast<CSSGradientValue>(value).gradientWithStylesResolved(*this));
+    if (is<CSSImageValue>(value))
+        return StyleCachedImage::create(downcast<CSSImageValue>(value));
 
-        if (is<CSSFilterImageValue>(value)) {
-            // FilterImage needs to calculate FilterOperations.
-            downcast<CSSFilterImageValue>(value).createFilterOperations(*this);
-        }
-        return StyleGeneratedImage::create(downcast<CSSImageGeneratorValue>(value));
-    }
+    if (is<CSSCursorImageValue>(value))
+        return StyleCursorImage::create(downcast<CSSCursorImageValue>(value));
 
-    if (is<CSSImageValue>(value) || is<CSSImageSetValue>(value) || is<CSSCursorImageValue>(value))
-        return StyleCachedImage::create(value);
+    if (is<CSSImageGeneratorValue>(value))
+        return StyleGeneratedImage::create(downcast<CSSImageGeneratorValue>(resolveImageStyles(value).get()));
+    
+    if (is<CSSImageSetValue>(value))
+        return StyleImageSet::create(downcast<CSSImageSetValue>(resolveImageStyles(value).get()));
 
     return nullptr;
 }

Modified: trunk/Source/WebCore/style/StyleBuilderState.h (254860 => 254861)


--- trunk/Source/WebCore/style/StyleBuilderState.h	2020-01-21 18:07:18 UTC (rev 254860)
+++ trunk/Source/WebCore/style/StyleBuilderState.h	2020-01-21 18:28:17 UTC (rev 254861)
@@ -82,6 +82,7 @@
     bool useSVGZoomRulesForLength() const;
     ScopeOrdinal styleScopeOrdinal() const { return m_styleScopeOrdinal; }
 
+    Ref<CSSValue> resolveImageStyles(CSSValue&);
     RefPtr<StyleImage> createStyleImage(CSSValue&);
     bool createFilterOperations(const CSSValue&, FilterOperations& outOperations);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to