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);