Title: [279050] trunk
Revision
279050
Author
[email protected]
Date
2021-06-19 13:31:11 -0700 (Sat, 19 Jun 2021)

Log Message

Fix CSS serialization issues affecting css-counter-styles tests
https://bugs.webkit.org/show_bug.cgi?id=226708

Reviewed by Antti Koivisto.

LayoutTests/imported/w3c:

* web-platform-tests/css/css-counter-styles/counter-style-additive-symbols-syntax-expected.txt:
* web-platform-tests/css/css-counter-styles/counter-style-symbols-syntax-expected.txt:
* web-platform-tests/css/css-syntax/url-whitespace-consumption-expected.txt:
Updated to reflect progressions.

Source/WebCore:

Fix two serialization isssues affecting css-counter-styles tests:

1) URLs were serializing the full resolved URL, rather than the
   partial URL string from the style sheet.
2) Items in additive-symbols that had both an integer and a string
   would incorrectly serialize with a comma within the item.

* css/CSSCrossfadeValue.cpp:
(WebCore::CSSCrossfadeValue::valueWithStylesResolved): Added.
Calls resolveImageStyles on the image values.
* css/CSSCrossfadeValue.h: Updated for the above.

* css/CSSCursorImageValue.cpp:
(WebCore::CSSCursorImageValue::CSSCursorImageValue): Changed the hot spot
to use std::optional instead of a separate boolean.
(WebCore::CSSCursorImageValue::create): Moved this out of the header
because it's not better for inlining to have it there.
(WebCore::CSSCursorImageValue::customCSSText const): Updated for the
m_hotSpot changes.
(WebCore::CSSCursorImageValue::updateCursorElement): Removed unneeded
check of hasFragmentIdentifier, which is already done by the
SVGURIReference::targetElementFromIRIString function. Updated to use
m_originalSpecifiedURLString, and added a FIXME about the strange way
this just keeps accumulating more and more clients in a set, but did
not change that behavior.
(WebCore::CSSCursorImageValue::cursorElementRemoved): Added a FIXME.
(WebCore::CSSCursorImageValue::cursorElementChanged): Updated for the
change to m_hotSpot and addded some FIXME.
(WebCore::CSSCursorImageValue::equals const): Updated for the m_hotSpot
change; much simpler since std::optional does the right thing.
(WebCore::CSSCursorImageValue::valueWithStylesResolved): Added.
Calls resolveImageStyles on the image value.
* css/CSSCursorImageValue.h: Updated for the above changes.

* css/CSSFilterImageValue.cpp:
(WebCore::CSSFilterImageValue::valueWithStylesResolved): Added.
Calls resolveImageStyles on the image value and also calls
createFilterOperations.
* css/CSSFilterImageValue.h: Updated for the above.

* css/CSSGradientValue.cpp:
(WebCore::CSSGradientValue::valueWithStylesResolved): Renamed from
gradientWithStylesResolved.
* css/CSSGradientValue.h: Updated for the above.

* css/CSSImageSetValue.cpp:
(WebCore::CSSImageSetValue::valueWithStylesResolved): Renamed from
imageSetWithStylesResolved. Optimized the case where the resolved
version is not different to re-use the original CSSImageSetValue.
* css/CSSImageSetValue.h: Updated for the above.

* css/CSSImageValue.cpp:
(WebCore::operator==): Added. Check if two ResolvedURL are equal.
(WebCore::makeResolvedURL): Added. Make a ResolvedURL from an
existing URL without the original specified string.
(WebCore::CSSImageValue::CSSImageValue): Take ResolvedURL instead
of a URL. Also updated to use std::optional instead of a separate
m_accessedImage boolean.
(WebCore::CSSImageValue::create): Added an overload that takes
ResolvedURL argument and also moved here from the header since we
don't get any benefit from inlining.
(WebCore::CSSImageValue::isPending const): Updates since m_cachedImage
is now a std::optional, and the std::nullopt case is used for this.
(WebCore::CSSImageValue::reresolvedURL const): Added. Used so we can
share code between the following functions.
(WebCore::CSSImageValue::valueWithStylesResolved): Added. Computes
the fully resolved URL and makes a new image value if needed that
always uses it. Also points the new value at the old one so we can
update m_cachedImage in both.
(WebCore::CSSImageValue::loadImage): Use the new reresolvedURL function.
Also update m_cachedImage in any underlying objects.
(WebCore::CSSImageValue::traverseSubresources): Updated for change
to m_cachedImage.
(WebCore::CSSImageValue::equals const): Updated for change to use
ResolvedURL.
(WebCore::CSSImageValue::customCSSText const): Ditto. This is the
only place where we use specifiedURLString.
(WebCore::CSSImageValue::createDeprecatedCSSOMWrapper const): Updated
for change from m_url.
(WebCore::CSSImageValue::knownToBeOpaque const): Updated for change
to m_cachedImage.
* css/CSSImageValue.h: Added ResolvedURL, new create
overloads. Replaced url() function with location() function, which
returns a string. Note that this always returns the resolved string,
only customCSSText returns the original string. Replaced m_url with
m_location, eliminated m_accessedImage and made m_cachedImage use
std::optional instead. Added m_unresolvedValue.

* css/StyleSheetContents.cpp:
(WebCore::StyleSheetContents::completeURL const): Deleted unused function.
* css/StyleSheetContents.h: Ditto.

* css/parser/CSSParserContext.cpp:
(WebCore::CSSParserContext::completeURL const): Updated to return
ResolvedURL instead of a URL.
* css/parser/CSSParserContext.h: Ditto.

* css/parser/CSSParserIdioms.cpp:
(WebCore::completeURL): Deleted unused function.
* css/parser/CSSParserIdioms.h: Ditto.

* css/parser/CSSPropertyParser.cpp:
(WebCore::consumeCursor): Use std::optional for the hot spot.
(WebCore::consumeCounterStyleAdditiveSymbols): Put the integer/symbol
pair into a separate space-separated list instead of appending both
to the top level command-separated list. Also removed support for
non-standard "image without symbol" and "symbol without image".
Neither the specification nor the web platform tests currently call
for that.

* css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::consumeImage): Call the new
overload of CSSImageValue::create, passing a ResolvedURL.

* css/parser/CSSPropertyParserWorkerSafe.cpp:
(WebCore::CSSPropertyParserHelpersWorkerSafe::consumeFontFaceSrcURI):
Update for the change to completeURL and refactor a bit. Later we could
make the same kind of fix for CSSFontFaceSrcValue that we did in this
patch for CSSImageValue, but did not try that for now.

* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::addCursor): Updated to take a std::optional for
the hot spot.
* rendering/style/RenderStyle.h: Ditto.

* rendering/style/StyleCachedImage.cpp:
(WebCore::StyleCachedImage::imageURL): Updated for CSSImageValue::imageURL.

* style/StyleBuilderCustom.h:
(WebCore::Style::BuilderCustom::applyValueContent): Call
resolveImageStyles consistently.

* style/StyleBuilderState.cpp:
(WebCore::Style::BuilderState::resolveImageStyles): Call the new
valueWithStylesResolved function on all the different image value
types. This unifies the approach across all 6 classes.
(WebCore::Style::BuilderState::createStyleImage): Tweaked style.

LayoutTests:

* fast/css/parse-border-image-repeat-null-crash-expected.txt: Update to reflect correct
path; the path is not really relevant to what was being tested here either way.

* fast/css/uri-token-parsing-expected.txt: Updated to expect behavior that is sensible
and also matches Firefox.
* fast/css/uri-token-parsing.html: Ditto.

* fast/fast/css/url-with-multi-byte-unicode-escape-expected.txt: Updated to expect that
URL is still encoded as UTF-8, not yet re-URL-encoded as it will be for loading. The
one that will be used for loading can still be seen in computed style. The test still
covers correclty parsig this URL.
* fast/fast/css/url-with-multi-byte-unicode-escape.html: Ditto.

* fast/filter-image/parse-filter-image-expected.txt: Updated to no longer test addition
of trailing slashes to peculiar URLs that are made by using filenames as host names.
Now this checks URLs that just contain filenames, which makes more logical sense, and
no trailing slash addition is expected.
* fast/filter-image/parse-filter-image.html: Ditto.

* fast/innerHTML/innerHTML-uri-resolution.html: Updated test to use computed style so
it no longer depends on WebKit-only behavior to run correctly.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (279049 => 279050)


--- trunk/LayoutTests/ChangeLog	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/LayoutTests/ChangeLog	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,3 +1,32 @@
+2021-06-19  Darin Adler  <[email protected]>
+
+        Fix CSS serialization issues affecting css-counter-styles tests
+        https://bugs.webkit.org/show_bug.cgi?id=226708
+
+        Reviewed by Antti Koivisto.
+
+        * fast/css/parse-border-image-repeat-null-crash-expected.txt: Update to reflect correct
+        path; the path is not really relevant to what was being tested here either way.
+
+        * fast/css/uri-token-parsing-expected.txt: Updated to expect behavior that is sensible
+        and also matches Firefox.
+        * fast/css/uri-token-parsing.html: Ditto.
+
+        * fast/fast/css/url-with-multi-byte-unicode-escape-expected.txt: Updated to expect that
+        URL is still encoded as UTF-8, not yet re-URL-encoded as it will be for loading. The
+        one that will be used for loading can still be seen in computed style. The test still
+        covers correclty parsig this URL.
+        * fast/fast/css/url-with-multi-byte-unicode-escape.html: Ditto.
+
+        * fast/filter-image/parse-filter-image-expected.txt: Updated to no longer test addition
+        of trailing slashes to peculiar URLs that are made by using filenames as host names.
+        Now this checks URLs that just contain filenames, which makes more logical sense, and
+        no trailing slash addition is expected.
+        * fast/filter-image/parse-filter-image.html: Ditto.
+
+        * fast/innerHTML/innerHTML-uri-resolution.html: Updated test to use computed style so
+        it no longer depends on WebKit-only behavior to run correctly.
+
 2021-06-18  Chris Dumez  <[email protected]>
 
         [WebIDL] Assigning a value outside the float range to a 'float' attribute should throw a TypeError

Modified: trunk/LayoutTests/fast/css/parse-border-image-repeat-null-crash-expected.txt (279049 => 279050)


--- trunk/LayoutTests/fast/css/parse-border-image-repeat-null-crash-expected.txt	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/LayoutTests/fast/css/parse-border-image-repeat-null-crash-expected.txt	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,2 +1,2 @@
-CONSOLE MESSAGE: border-image-source: url("shadow-border.png"); border-image-slice: 10; border-image-repeat: stretch;
+CONSOLE MESSAGE: border-image-source: url("images/shadow-border.png"); border-image-slice: 10; border-image-repeat: stretch;
 This test should not crash

Modified: trunk/LayoutTests/fast/css/uri-token-parsing-expected.txt (279049 => 279050)


--- trunk/LayoutTests/fast/css/uri-token-parsing-expected.txt	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/LayoutTests/fast/css/uri-token-parsing-expected.txt	2021-06-19 20:31:11 UTC (rev 279050)
@@ -9,14 +9,14 @@
 #c { content: url("e"); }
 #d { content: url("f"); }
 #f { content: url("c"); }
-#g { content: url("d"); }
-#h { content: url("e"); }
-#i { content: url("f"); }
+#g { content: url(" d"); }
+#h { content: url("e "); }
+#i { content: url(" f "); }
 #j { content: url("url(g)"); }
 #l { content: url("c"); }
-#m { content: url("d"); }
-#n { content: url("e"); }
-#o { content: url("f"); }
+#m { content: url(" d"); }
+#n { content: url("e "); }
+#o { content: url(" f "); }
 #p { content: url("url(g)"); }
 #q { cursor: url("url(q)"), default; }
 #r { list-style-image: url("url(r)"); }
@@ -24,9 +24,9 @@
 #t { -webkit-mask-image: url("url(t)"); }
 #u { -webkit-border-image: url("url(u)") 1 2 3 4 fill stretch round; }
 #v { -webkit-mask-box-image: url("url(v)") 1 2 3 4 fill stretch round; }
-#w { content: url("ww"); }
-#x { content: url("x%20xx"); }
-#y { content: url("y%20yy"); }
+#w { content: url("w\d w"); }
+#x { content: url(" x x\9 x "); }
+#y { content: url("y y\9 y"); }
 Expected result:
 
 #a { content: url("c"); }
@@ -34,14 +34,14 @@
 #c { content: url("e"); }
 #d { content: url("f"); }
 #f { content: url("c"); }
-#g { content: url("d"); }
-#h { content: url("e"); }
-#i { content: url("f"); }
+#g { content: url(" d"); }
+#h { content: url("e "); }
+#i { content: url(" f "); }
 #j { content: url("url(g)"); }
 #l { content: url("c"); }
-#m { content: url("d"); }
-#n { content: url("e"); }
-#o { content: url("f"); }
+#m { content: url(" d"); }
+#n { content: url("e "); }
+#o { content: url(" f "); }
 #p { content: url("url(g)"); }
 #q { cursor: url("url(q)"), default; }
 #r { list-style-image: url("url(r)"); }
@@ -49,7 +49,7 @@
 #t { -webkit-mask-image: url("url(t)"); }
 #u { -webkit-border-image: url("url(u)") 1 2 3 4 fill stretch round; }
 #v { -webkit-mask-box-image: url("url(v)") 1 2 3 4 fill stretch round; }
-#w { content: url("ww"); }
-#x { content: url("x%20xx"); }
-#y { content: url("y%20yy"); }
+#w { content: url("w\d w"); }
+#x { content: url(" x x\9 x "); }
+#y { content: url("y y\9 y"); }
 

Modified: trunk/LayoutTests/fast/css/uri-token-parsing.html (279049 => 279050)


--- trunk/LayoutTests/fast/css/uri-token-parsing.html	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/LayoutTests/fast/css/uri-token-parsing.html	2021-06-19 20:31:11 UTC (rev 279050)
@@ -44,13 +44,7 @@
     var rules = document.styleSheets[0].cssRules;
     var text = "";
     for (var i = 0; i < rules.length; i++) {
-        var itemText = rules.item(i).cssText;
-
-        // Work around bug where WebKit completes the URLs in the CSS DOM.
-        // The completion of the URL should be when they are used, not in the DOM.
-        itemText = itemText.replace(/file:.*LayoutTests\/fast\/css\//, "");
-
-        text += itemText;
+        text += rules.item(i).cssText;
         text += "\n";
     }
 
@@ -83,14 +77,14 @@
 #c { content: url("e"); }
 #d { content: url("f"); }
 #f { content: url("c"); }
-#g { content: url("d"); }
-#h { content: url("e"); }
-#i { content: url("f"); }
+#g { content: url(" d"); }
+#h { content: url("e "); }
+#i { content: url(" f "); }
 #j { content: url("url(g)"); }
 #l { content: url("c"); }
-#m { content: url("d"); }
-#n { content: url("e"); }
-#o { content: url("f"); }
+#m { content: url(" d"); }
+#n { content: url("e "); }
+#o { content: url(" f "); }
 #p { content: url("url(g)"); }
 #q { cursor: url("url(q)"), default; }
 #r { list-style-image: url("url(r)"); }
@@ -98,9 +92,9 @@
 #t { -webkit-mask-image: url("url(t)"); }
 #u { -webkit-border-image: url("url(u)") 1 2 3 4 fill stretch round; }
 #v { -webkit-mask-box-image: url("url(v)") 1 2 3 4 fill stretch round; }
-#w { content: url("ww"); }
-#x { content: url("x%20xx"); }
-#y { content: url("y%20yy"); }
+#w { content: url("w\d w"); }
+#x { content: url(" x x\9 x "); }
+#y { content: url("y y\9 y"); }
 </pre>
 
 <script>

Modified: trunk/LayoutTests/fast/css/url-with-multi-byte-unicode-escape-expected.txt (279049 => 279050)


--- trunk/LayoutTests/fast/css/url-with-multi-byte-unicode-escape-expected.txt	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/LayoutTests/fast/css/url-with-multi-byte-unicode-escape-expected.txt	2021-06-19 20:31:11 UTC (rev 279050)
@@ -4,8 +4,8 @@
 
 
 PASS document.styleSheets[0].cssRules.length is 2
-PASS document.styleSheets[0].cssRules[0].style.getPropertyValue("background-image") is "url(\"data:%C4%80\")"
-PASS document.styleSheets[0].cssRules[0].style.getPropertyValue("border-image-source") is "url(\"data:%C4%80\")"
+PASS document.styleSheets[0].cssRules[0].style.getPropertyValue("background-image") is "url(\"data:Ā\")"
+PASS document.styleSheets[0].cssRules[0].style.getPropertyValue("border-image-source") is "url(\"data:Ā\")"
 PASS document.styleSheets[0].cssRules[1].style.getPropertyValue("background-color") is "green"
 PASS window.getComputedStyle(document.getElementById("test")).getPropertyValue("background-color") is "rgb(0, 128, 0)"
 PASS successfullyParsed is true

Modified: trunk/LayoutTests/fast/css/url-with-multi-byte-unicode-escape.html (279049 => 279050)


--- trunk/LayoutTests/fast/css/url-with-multi-byte-unicode-escape.html	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/LayoutTests/fast/css/url-with-multi-byte-unicode-escape.html	2021-06-19 20:31:11 UTC (rev 279050)
@@ -13,8 +13,8 @@
 <script>
     description('Test parsing a CSS URI containing a multi-byte Unicode escape sequence.');
     shouldBe('document.styleSheets[0].cssRules.length', '2');
-    shouldBeEqualToString('document.styleSheets[0].cssRules[0].style.getPropertyValue("background-image")', 'url("data:%C4%80")');
-    shouldBeEqualToString('document.styleSheets[0].cssRules[0].style.getPropertyValue("border-image-source")', 'url("data:%C4%80")');
+    shouldBeEqualToString('document.styleSheets[0].cssRules[0].style.getPropertyValue("background-image")', 'url("data:\u0100")');
+    shouldBeEqualToString('document.styleSheets[0].cssRules[0].style.getPropertyValue("border-image-source")', 'url("data:\u0100")');
     shouldBeEqualToString('document.styleSheets[0].cssRules[1].style.getPropertyValue("background-color")', 'green');
     shouldBeEqualToString('window.getComputedStyle(document.getElementById("test")).getPropertyValue("background-color")', 'rgb(0, 128, 0)');
 </script>

Modified: trunk/LayoutTests/fast/filter-image/parse-filter-image-expected.txt (279049 => 279050)


--- trunk/LayoutTests/fast/filter-image/parse-filter-image-expected.txt	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/LayoutTests/fast/filter-image/parse-filter-image-expected.txt	2021-06-19 20:31:11 UTC (rev 279050)
@@ -78,13 +78,13 @@
 PASS innerStyle("background-image", "filter(linear-gradient(white, black), hue-rotate(90deg))") is "filter(linear-gradient(white, black), hue-rotate(90deg))"
 PASS innerStyle("background-image", "filter(linear-gradient(to top left, white, black), hue-rotate(90deg))") is "filter(linear-gradient(to left top, white, black), hue-rotate(90deg))"
 PASS innerStyle("background-image", "filter(linear-gradient(0deg, white -20%, blue, black 120%), hue-rotate(90deg))") is "filter(linear-gradient(0deg, white -20%, blue, black 120%), hue-rotate(90deg))"
-PASS innerStyle("background-image", "filter(-webkit-cross-fade(url(http://image1.png), url(http://image2.png), 50%), contrast(0.5))") is "filter(-webkit-cross-fade(url(\"http://image1.png/\"), url(\"http://image2.png/\"), 0.5), contrast(0.5))"
-PASS innerStyle("background-image", "filter(url(http://image1.png), brightness(50%))") is "filter(url(\"http://image1.png/\"), brightness(50%))"
-PASS innerStyle("background-image", "filter(url('http://image1.png'), brightness(50%))") is "filter(url(\"http://image1.png/\"), brightness(50%))"
-PASS innerStyle("border-image-source", "filter(url(http://image1.png), invert(50%))") is "filter(url(\"http://image1.png/\"), invert(50%))"
-PASS innerStyle("-webkit-mask-image", "filter(url(http://image1.png), invert(50%))") is "filter(url(\"http://image1.png/\"), invert(50%))"
-PASS innerStyle("-webkit-mask-box-image-source", "filter(url(http://image1.png), invert(50%))") is "filter(url(\"http://image1.png/\"), invert(50%))"
-PASS innerStyle("content", "filter(url(http://image1.png), invert(50%))") is "filter(url(\"http://image1.png/\"), invert(50%))"
+PASS innerStyle("background-image", "filter(-webkit-cross-fade(url(image1.png), url(image2.png), 50%), contrast(0.5))") is "filter(-webkit-cross-fade(url(\"image1.png\"), url(\"image2.png\"), 0.5), contrast(0.5))"
+PASS innerStyle("background-image", "filter(url(image1.png), brightness(50%))") is "filter(url(\"image1.png\"), brightness(50%))"
+PASS innerStyle("background-image", "filter(url('image1.png'), brightness(50%))") is "filter(url(\"image1.png\"), brightness(50%))"
+PASS innerStyle("border-image-source", "filter(url(image1.png), invert(50%))") is "filter(url(\"image1.png\"), invert(50%))"
+PASS innerStyle("-webkit-mask-image", "filter(url(image1.png), invert(50%))") is "filter(url(\"image1.png\"), invert(50%))"
+PASS innerStyle("-webkit-mask-box-image-source", "filter(url(image1.png), invert(50%))") is "filter(url(\"image1.png\"), invert(50%))"
+PASS innerStyle("content", "filter(url(image1.png), invert(50%))") is "filter(url(\"image1.png\"), invert(50%))"
 PASS innerStyle("background-image", "filter()") is ""
 PASS computedStyle("background-image", "filter()") is "none"
 PASS innerStyle("background-image", "filter(url(image1.png))") is ""

Modified: trunk/LayoutTests/fast/filter-image/parse-filter-image.html (279049 => 279050)


--- trunk/LayoutTests/fast/filter-image/parse-filter-image.html	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/LayoutTests/fast/filter-image/parse-filter-image.html	2021-06-19 20:31:11 UTC (rev 279050)
@@ -345,34 +345,34 @@
     "filter(linear-gradient(0deg, white -20%, blue, black 120%), hue-rotate(90deg))");
 testInner(
     "background-image",
-    "filter(-webkit-cross-fade(url(http://image1.png), url(http://image2.png), 50%), contrast(0.5))",
-    "filter(-webkit-cross-fade(url(\"http://image1.png/\"), url(\"http://image2.png/\"), 0.5), contrast(0.5))");
+    "filter(-webkit-cross-fade(url(image1.png), url(image2.png), 50%), contrast(0.5))",
+    "filter(-webkit-cross-fade(url(\"image1.png\"), url(\"image2.png\"), 0.5), contrast(0.5))");
 testInner(
     "background-image",
-    "filter(url(http://image1.png), brightness(50%))",
-    "filter(url(\"http://image1.png/\"), brightness(50%))");
+    "filter(url(image1.png), brightness(50%))",
+    "filter(url(\"image1.png\"), brightness(50%))");
 testInner(
     "background-image",
-    "filter(url('http://image1.png'), brightness(50%))",
-    "filter(url(\"http://image1.png/\"), brightness(50%))");
+    "filter(url('image1.png'), brightness(50%))",
+    "filter(url(\"image1.png\"), brightness(50%))");
 
 // Test different properties, taking CSS Image values.
 testInner(
     "border-image-source",
-    "filter(url(http://image1.png), invert(50%))",
-    "filter(url(\"http://image1.png/\"), invert(50%))");
+    "filter(url(image1.png), invert(50%))",
+    "filter(url(\"image1.png\"), invert(50%))");
 testInner(
     "-webkit-mask-image",
-    "filter(url(http://image1.png), invert(50%))",
-    "filter(url(\"http://image1.png/\"), invert(50%))");
+    "filter(url(image1.png), invert(50%))",
+    "filter(url(\"image1.png\"), invert(50%))");
 testInner(
     "-webkit-mask-box-image-source",
-    "filter(url(http://image1.png), invert(50%))",
-    "filter(url(\"http://image1.png/\"), invert(50%))");
+    "filter(url(image1.png), invert(50%))",
+    "filter(url(\"image1.png\"), invert(50%))");
 testInner(
     "content",
-    "filter(url(http://image1.png), invert(50%))",
-    "filter(url(\"http://image1.png/\"), invert(50%))");
+    "filter(url(image1.png), invert(50%))",
+    "filter(url(\"image1.png\"), invert(50%))");
 
 // negative tests
 negativeTest("background-image", "filter()");

Modified: trunk/LayoutTests/fast/innerHTML/innerHTML-uri-resolution.html (279049 => 279050)


--- trunk/LayoutTests/fast/innerHTML/innerHTML-uri-resolution.html	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/LayoutTests/fast/innerHTML/innerHTML-uri-resolution.html	2021-06-19 20:31:11 UTC (rev 279050)
@@ -13,7 +13,7 @@
   
   var currentUri = document.location.href;
   var currentPath = currentUri.substring(0, currentUri.lastIndexOf('/'));
-  var cssUriWasResolvedAgainstDocumentUri = document.getElementById("test-span").style.backgroundImage == 'url("' + currentPath + '/image.png")';
+  var cssUriWasResolvedAgainstDocumentUri = getComputedStyle(document.getElementById("test-span")).backgroundImage == 'url("' + currentPath + '/image.png")';
   
   // Can't log the actual path since it's different depending on where the test is run.
   shouldBeTrue('cssUriWasResolvedAgainstDocumentUri');
@@ -20,4 +20,4 @@
 </script>
 <script src=""
 </body>
-</html>
\ No newline at end of file
+</html>

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (279049 => 279050)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,3 +1,15 @@
+2021-06-19  Darin Adler  <[email protected]>
+
+        Fix CSS serialization issues affecting css-counter-styles tests
+        https://bugs.webkit.org/show_bug.cgi?id=226708
+
+        Reviewed by Antti Koivisto.
+
+        * web-platform-tests/css/css-counter-styles/counter-style-additive-symbols-syntax-expected.txt:
+        * web-platform-tests/css/css-counter-styles/counter-style-symbols-syntax-expected.txt:
+        * web-platform-tests/css/css-syntax/url-whitespace-consumption-expected.txt:
+        Updated to reflect progressions.
+
 2021-06-18  Chris Dumez  <[email protected]>
 
         [WebIDL] Assigning a value outside the float range to a 'float' attribute should throw a TypeError

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-additive-symbols-syntax-expected.txt (279049 => 279050)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-additive-symbols-syntax-expected.txt	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-additive-symbols-syntax-expected.txt	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,8 +1,8 @@
 
-FAIL @counter-style 'additive-symbols: 0 "X"' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'additive-symbols: 1 "X"' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'additive-symbols: "X" 1' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'additive-symbols: 5 "V", 1 "I"' is valid assert_not_equals: got disallowed value -1
+PASS @counter-style 'additive-symbols: 0 "X"' is valid
+PASS @counter-style 'additive-symbols: 1 "X"' is valid
+PASS @counter-style 'additive-symbols: "X" 1' is valid
+PASS @counter-style 'additive-symbols: 5 "V", 1 "I"' is valid
 PASS @counter-style 'additive-symbols: ' is invalid
 PASS @counter-style 'additive-symbols: -1 "X"' is invalid
 PASS @counter-style 'additive-symbols: 1 "I", 5 "V"' is invalid

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-symbols-syntax-expected.txt (279049 => 279050)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-symbols-syntax-expected.txt	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-symbols-syntax-expected.txt	2021-06-19 20:31:11 UTC (rev 279050)
@@ -2,7 +2,7 @@
 PASS @counter-style 'symbols: "X"' is valid
 PASS @counter-style 'symbols: "X" "X"' is valid
 PASS @counter-style 'symbols: ident "X"' is valid
-FAIL @counter-style 'symbols: ident "X" url("foo.jpg")' is valid assert_not_equals: got disallowed value -1
+PASS @counter-style 'symbols: ident "X" url("foo.jpg")' is valid
 PASS @counter-style 'symbols: ' is invalid
 PASS @counter-style 'symbols: initial "X" "X"' is invalid
 PASS @counter-style 'symbols: inherit "X" "X"' is invalid

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-syntax/url-whitespace-consumption-expected.txt (279049 => 279050)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-syntax/url-whitespace-consumption-expected.txt	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-syntax/url-whitespace-consumption-expected.txt	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,3 +1,3 @@
 
-FAIL whitespace is optional between url( token and the string token assert_equals: expected "url(\"foo\")" but got "url(\"http://localhost:8800/css/css-syntax/foo\")"
+PASS whitespace is optional between url( token and the string token
 

Modified: trunk/Source/WebCore/ChangeLog (279049 => 279050)


--- trunk/Source/WebCore/ChangeLog	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/ChangeLog	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,3 +1,148 @@
+2021-06-19  Darin Adler  <[email protected]>
+
+        Fix CSS serialization issues affecting css-counter-styles tests
+        https://bugs.webkit.org/show_bug.cgi?id=226708
+
+        Reviewed by Antti Koivisto.
+
+        Fix two serialization isssues affecting css-counter-styles tests:
+
+        1) URLs were serializing the full resolved URL, rather than the
+           partial URL string from the style sheet.
+        2) Items in additive-symbols that had both an integer and a string
+           would incorrectly serialize with a comma within the item.
+
+        * css/CSSCrossfadeValue.cpp:
+        (WebCore::CSSCrossfadeValue::valueWithStylesResolved): Added.
+        Calls resolveImageStyles on the image values.
+        * css/CSSCrossfadeValue.h: Updated for the above.
+
+        * css/CSSCursorImageValue.cpp:
+        (WebCore::CSSCursorImageValue::CSSCursorImageValue): Changed the hot spot
+        to use std::optional instead of a separate boolean.
+        (WebCore::CSSCursorImageValue::create): Moved this out of the header
+        because it's not better for inlining to have it there.
+        (WebCore::CSSCursorImageValue::customCSSText const): Updated for the
+        m_hotSpot changes.
+        (WebCore::CSSCursorImageValue::updateCursorElement): Removed unneeded
+        check of hasFragmentIdentifier, which is already done by the
+        SVGURIReference::targetElementFromIRIString function. Updated to use
+        m_originalSpecifiedURLString, and added a FIXME about the strange way
+        this just keeps accumulating more and more clients in a set, but did
+        not change that behavior.
+        (WebCore::CSSCursorImageValue::cursorElementRemoved): Added a FIXME.
+        (WebCore::CSSCursorImageValue::cursorElementChanged): Updated for the
+        change to m_hotSpot and addded some FIXME.
+        (WebCore::CSSCursorImageValue::equals const): Updated for the m_hotSpot
+        change; much simpler since std::optional does the right thing.
+        (WebCore::CSSCursorImageValue::valueWithStylesResolved): Added.
+        Calls resolveImageStyles on the image value.
+        * css/CSSCursorImageValue.h: Updated for the above changes.
+
+        * css/CSSFilterImageValue.cpp:
+        (WebCore::CSSFilterImageValue::valueWithStylesResolved): Added.
+        Calls resolveImageStyles on the image value and also calls
+        createFilterOperations.
+        * css/CSSFilterImageValue.h: Updated for the above.
+
+        * css/CSSGradientValue.cpp:
+        (WebCore::CSSGradientValue::valueWithStylesResolved): Renamed from
+        gradientWithStylesResolved.
+        * css/CSSGradientValue.h: Updated for the above.
+
+        * css/CSSImageSetValue.cpp:
+        (WebCore::CSSImageSetValue::valueWithStylesResolved): Renamed from
+        imageSetWithStylesResolved. Optimized the case where the resolved
+        version is not different to re-use the original CSSImageSetValue.
+        * css/CSSImageSetValue.h: Updated for the above.
+
+        * css/CSSImageValue.cpp:
+        (WebCore::operator==): Added. Check if two ResolvedURL are equal.
+        (WebCore::makeResolvedURL): Added. Make a ResolvedURL from an
+        existing URL without the original specified string.
+        (WebCore::CSSImageValue::CSSImageValue): Take ResolvedURL instead
+        of a URL. Also updated to use std::optional instead of a separate
+        m_accessedImage boolean.
+        (WebCore::CSSImageValue::create): Added an overload that takes
+        ResolvedURL argument and also moved here from the header since we
+        don't get any benefit from inlining.
+        (WebCore::CSSImageValue::isPending const): Updates since m_cachedImage
+        is now a std::optional, and the std::nullopt case is used for this.
+        (WebCore::CSSImageValue::reresolvedURL const): Added. Used so we can
+        share code between the following functions.
+        (WebCore::CSSImageValue::valueWithStylesResolved): Added. Computes
+        the fully resolved URL and makes a new image value if needed that
+        always uses it. Also points the new value at the old one so we can
+        update m_cachedImage in both.
+        (WebCore::CSSImageValue::loadImage): Use the new reresolvedURL function.
+        Also update m_cachedImage in any underlying objects.
+        (WebCore::CSSImageValue::traverseSubresources): Updated for change
+        to m_cachedImage.
+        (WebCore::CSSImageValue::equals const): Updated for change to use
+        ResolvedURL.
+        (WebCore::CSSImageValue::customCSSText const): Ditto. This is the
+        only place where we use specifiedURLString.
+        (WebCore::CSSImageValue::createDeprecatedCSSOMWrapper const): Updated
+        for change from m_url.
+        (WebCore::CSSImageValue::knownToBeOpaque const): Updated for change
+        to m_cachedImage.
+        * css/CSSImageValue.h: Added ResolvedURL, new create
+        overloads. Replaced url() function with location() function, which
+        returns a string. Note that this always returns the resolved string,
+        only customCSSText returns the original string. Replaced m_url with
+        m_location, eliminated m_accessedImage and made m_cachedImage use
+        std::optional instead. Added m_unresolvedValue.
+
+        * css/StyleSheetContents.cpp:
+        (WebCore::StyleSheetContents::completeURL const): Deleted unused function.
+        * css/StyleSheetContents.h: Ditto.
+
+        * css/parser/CSSParserContext.cpp:
+        (WebCore::CSSParserContext::completeURL const): Updated to return
+        ResolvedURL instead of a URL.
+        * css/parser/CSSParserContext.h: Ditto.
+
+        * css/parser/CSSParserIdioms.cpp:
+        (WebCore::completeURL): Deleted unused function.
+        * css/parser/CSSParserIdioms.h: Ditto.
+
+        * css/parser/CSSPropertyParser.cpp:
+        (WebCore::consumeCursor): Use std::optional for the hot spot.
+        (WebCore::consumeCounterStyleAdditiveSymbols): Put the integer/symbol
+        pair into a separate space-separated list instead of appending both
+        to the top level command-separated list. Also removed support for
+        non-standard "image without symbol" and "symbol without image".
+        Neither the specification nor the web platform tests currently call
+        for that.
+
+        * css/parser/CSSPropertyParserHelpers.cpp:
+        (WebCore::CSSPropertyParserHelpers::consumeImage): Call the new
+        overload of CSSImageValue::create, passing a ResolvedURL.
+
+        * css/parser/CSSPropertyParserWorkerSafe.cpp:
+        (WebCore::CSSPropertyParserHelpersWorkerSafe::consumeFontFaceSrcURI):
+        Update for the change to completeURL and refactor a bit. Later we could
+        make the same kind of fix for CSSFontFaceSrcValue that we did in this
+        patch for CSSImageValue, but did not try that for now.
+
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::addCursor): Updated to take a std::optional for
+        the hot spot.
+        * rendering/style/RenderStyle.h: Ditto.
+
+        * rendering/style/StyleCachedImage.cpp:
+        (WebCore::StyleCachedImage::imageURL): Updated for CSSImageValue::imageURL.
+
+        * style/StyleBuilderCustom.h:
+        (WebCore::Style::BuilderCustom::applyValueContent): Call
+        resolveImageStyles consistently.
+
+        * style/StyleBuilderState.cpp:
+        (WebCore::Style::BuilderState::resolveImageStyles): Call the new
+        valueWithStylesResolved function on all the different image value
+        types. This unifies the approach across all 6 classes.
+        (WebCore::Style::BuilderState::createStyleImage): Tweaked style.
+
 2021-06-18  Chris Dumez  <[email protected]>
 
         [WebIDL] Assigning a value outside the float range to a 'float' attribute should throw a TypeError

Modified: trunk/Source/WebCore/css/CSSCrossfadeValue.cpp (279049 => 279050)


--- trunk/Source/WebCore/css/CSSCrossfadeValue.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/CSSCrossfadeValue.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc.  All rights reserved.
+ * Copyright (C) 2011-2021 Apple Inc.  All rights reserved.
  * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
 #include "CachedResourceLoader.h"
 #include "CrossfadeGeneratedImage.h"
 #include "RenderElement.h"
+#include "StyleBuilderState.h"
 #include "StyleCachedImage.h"
-#include <wtf/text/StringBuilder.h>
 
 namespace WebCore {
 
@@ -228,10 +228,18 @@
     return equalInputImages(other) && compareCSSValue(m_percentageValue, other.m_percentageValue);
 }
 
-
 bool CSSCrossfadeValue::equalInputImages(const CSSCrossfadeValue& other) const
 {
     return compareCSSValue(m_fromValue, other.m_fromValue) && compareCSSValue(m_toValue, other.m_toValue);
 }
 
+Ref<CSSCrossfadeValue> CSSCrossfadeValue::valueWithStylesResolved(Style::BuilderState& state)
+{
+    auto fromValue = state.resolveImageStyles(m_fromValue.get());
+    auto toValue = state.resolveImageStyles(m_toValue.get());
+    if (fromValue.ptr() == m_fromValue.ptr() && toValue.ptr() == m_toValue.ptr())
+        return *this;
+    return create(WTFMove(fromValue), WTFMove(toValue), Ref { m_percentageValue }, m_isPrefixed);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/CSSCrossfadeValue.h (279049 => 279050)


--- trunk/Source/WebCore/css/CSSCrossfadeValue.h	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/CSSCrossfadeValue.h	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -60,6 +60,8 @@
     bool equals(const CSSCrossfadeValue&) const;
     bool equalInputImages(const CSSCrossfadeValue&) const;
 
+    Ref<CSSCrossfadeValue> valueWithStylesResolved(Style::BuilderState&);
+
 private:
     CSSCrossfadeValue(Ref<CSSValue>&& fromValue, Ref<CSSValue>&& toValue, Ref<CSSPrimitiveValue>&& percentageValue, bool prefixed);
 

Modified: trunk/Source/WebCore/css/CSSCursorImageValue.cpp (279049 => 279050)


--- trunk/Source/WebCore/css/CSSCursorImageValue.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/CSSCursorImageValue.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2006 Rob Buis <[email protected]>
  *           (C) 2008 Nikolas Zimmermann <[email protected]>
- * Copyright (C) 2008-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2021 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -24,28 +24,29 @@
 
 #include "CSSImageSetValue.h"
 #include "CSSImageValue.h"
-#include "CachedImage.h"
-#include "CachedResourceLoader.h"
 #include "SVGCursorElement.h"
 #include "SVGLengthContext.h"
 #include "SVGURIReference.h"
 #include <wtf/MathExtras.h>
-#include <wtf/text/StringBuilder.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
-CSSCursorImageValue::CSSCursorImageValue(Ref<CSSValue>&& imageValue, bool hasHotSpot, const IntPoint& hotSpot, LoadedFromOpaqueSource loadedFromOpaqueSource)
+CSSCursorImageValue::CSSCursorImageValue(Ref<CSSValue>&& imageValue, const std::optional<IntPoint>& hotSpot, LoadedFromOpaqueSource loadedFromOpaqueSource)
     : CSSValue(CursorImageClass)
     , m_imageValue(WTFMove(imageValue))
-    , m_hasHotSpot(hasHotSpot)
     , m_hotSpot(hotSpot)
     , m_loadedFromOpaqueSource(loadedFromOpaqueSource)
 {
     if (is<CSSImageValue>(m_imageValue.get()))
-        m_originalURL = downcast<CSSImageValue>(m_imageValue.get()).url();
+        m_originalURL = downcast<CSSImageValue>(m_imageValue.get()).imageURL();
 }
 
+Ref<CSSCursorImageValue> CSSCursorImageValue::create(Ref<CSSValue>&& imageValue, const std::optional<IntPoint>& hotSpot, LoadedFromOpaqueSource loadedFromOpaqueSource)
+{
+    return adoptRef(*new CSSCursorImageValue(WTFMove(imageValue), hotSpot, loadedFromOpaqueSource));
+}
+
 CSSCursorImageValue::~CSSCursorImageValue()
 {
     for (auto* element : m_cursorElements)
@@ -55,21 +56,19 @@
 String CSSCursorImageValue::customCSSText() const
 {
     String text = m_imageValue.get().cssText();
-    if (!m_hasHotSpot)
+    if (!m_hotSpot)
         return text;
-    return makeString(text, ' ', m_hotSpot.x(), ' ', m_hotSpot.y());
+    return makeString(text, ' ', m_hotSpot->x(), ' ', m_hotSpot->y());
 }
 
 // FIXME: Should this function take a TreeScope instead?
 SVGCursorElement* CSSCursorImageValue::updateCursorElement(const Document& document)
 {
-    if (!m_originalURL.hasFragmentIdentifier())
-        return nullptr;
-
     auto element = SVGURIReference::targetElementFromIRIString(m_originalURL.string(), document).element;
     if (!is<SVGCursorElement>(element))
         return nullptr;
 
+    // FIXME: Not right to keep old cursor elements as clients. The new one should replace the old, not join it in a set.
     auto& cursorElement = downcast<SVGCursorElement>(*element);
     if (m_cursorElements.add(&cursorElement).isNewEntry) {
         cursorElementChanged(cursorElement);
@@ -80,19 +79,22 @@
 
 void CSSCursorImageValue::cursorElementRemoved(SVGCursorElement& cursorElement)
 {
+    // FIXME: Not right to stay a client of a cursor element until the element is destroyed. We'd want to stop being a client once it's no longer a valid target, like when it's disconnected.
     m_cursorElements.remove(&cursorElement);
 }
 
 void CSSCursorImageValue::cursorElementChanged(SVGCursorElement& cursorElement)
 {
-    // FIXME: This will override hot spot specified in CSS, which is probably incorrect.
+    // FIXME: Seems wrong that changing an old cursor element, one that that is no longer the target, changes the hot spot.
+    // FIXME: This will override a hot spot that was specified in CSS, which is probably incorrect.
+    // FIXME: Should we clamp from float to int instead of just casting here?
     SVGLengthContext lengthContext(nullptr);
-    m_hasHotSpot = true;
-    float x = std::round(cursorElement.x().value(lengthContext));
-    m_hotSpot.setX(static_cast<int>(x));
+    m_hotSpot = IntPoint {
+        static_cast<int>(std::round(cursorElement.x().value(lengthContext))),
+        static_cast<int>(std::round(cursorElement.y().value(lengthContext)))
+    };
 
-    float y = std::round(cursorElement.y().value(lengthContext));
-    m_hotSpot.setY(static_cast<int>(y));
+    // FIXME: Why doesn't this funtion check for a change to the href of the cursor element? Why would we dynamically track changes to x/y but not href?
 }
 
 ImageWithScale CSSCursorImageValue::selectBestFitImage(const Document& document)
@@ -101,8 +103,9 @@
         return downcast<CSSImageSetValue>(m_imageValue.get()).selectBestFitImage(document);
 
     if (auto* cursorElement = updateCursorElement(document)) {
-        if (cursorElement->href() != downcast<CSSImageValue>(m_imageValue.get()).url())
-            m_imageValue = CSSImageValue::create(document.completeURL(cursorElement->href()), m_loadedFromOpaqueSource);
+        auto location = document.completeURL(cursorElement->href());
+        if (location != downcast<CSSImageValue>(m_imageValue.get()).imageURL())
+            m_imageValue = CSSImageValue::create(WTFMove(location), m_loadedFromOpaqueSource);
     }
 
     return { m_imageValue.ptr() , 1 };
@@ -110,8 +113,15 @@
 
 bool CSSCursorImageValue::equals(const CSSCursorImageValue& other) const
 {
-    return m_hasHotSpot ? other.m_hasHotSpot && m_hotSpot == other.m_hotSpot : !other.m_hasHotSpot
-        && compareCSSValue(m_imageValue, other.m_imageValue);
+    return m_hotSpot == other.m_hotSpot && compareCSSValue(m_imageValue, other.m_imageValue);
 }
 
+Ref<CSSCursorImageValue> CSSCursorImageValue::valueWithStylesResolved(Style::BuilderState& state)
+{
+    auto imageValue = state.resolveImageStyles(m_imageValue.get());
+    if (imageValue.ptr() == m_imageValue.ptr())
+        return *this;
+    return create(WTFMove(imageValue), m_hotSpot, m_loadedFromOpaqueSource);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/CSSCursorImageValue.h (279049 => 279050)


--- trunk/Source/WebCore/css/CSSCursorImageValue.h	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/CSSCursorImageValue.h	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2006 Rob Buis <[email protected]>
- * Copyright (C) 2008 Apple Inc. All right reserved.
+ * Copyright (C) 2008-2021 Apple Inc. All right reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -27,12 +27,8 @@
 
 namespace WebCore {
 
-class CachedImage;
-class CachedResourceLoader;
 class Document;
-class Element;
 class SVGCursorElement;
-class SVGElement;
 
 struct ImageWithScale;
 
@@ -42,22 +38,11 @@
 
 class CSSCursorImageValue final : public CSSValue {
 public:
-    static Ref<CSSCursorImageValue> create(Ref<CSSValue>&& imageValue, bool hasHotSpot, const IntPoint& hotSpot, LoadedFromOpaqueSource loadedFromOpaqueSource)
-    {
-        return adoptRef(*new CSSCursorImageValue(WTFMove(imageValue), hasHotSpot, hotSpot, loadedFromOpaqueSource));
-    }
-
+    static Ref<CSSCursorImageValue> create(Ref<CSSValue>&& imageValue, const std::optional<IntPoint>& hotSpot, LoadedFromOpaqueSource);
     ~CSSCursorImageValue();
 
-    bool hasHotSpot() const { return m_hasHotSpot; }
+    std::optional<IntPoint> hotSpot() const { return m_hotSpot; }
 
-    IntPoint hotSpot() const
-    {
-        if (m_hasHotSpot)
-            return m_hotSpot;
-        return IntPoint(-1, -1);
-    }
-
     const URL& imageURL() const { return m_originalURL; }
 
     String customCSSText() const;
@@ -64,23 +49,21 @@
 
     ImageWithScale selectBestFitImage(const Document&);
 
-    void removeReferencedElement(SVGElement*);
-
     bool equals(const CSSCursorImageValue&) const;
 
     void cursorElementRemoved(SVGCursorElement&);
     void cursorElementChanged(SVGCursorElement&);
 
+    Ref<CSSCursorImageValue> valueWithStylesResolved(Style::BuilderState&);
+
 private:
-    CSSCursorImageValue(Ref<CSSValue>&& imageValue, bool hasHotSpot, const IntPoint& hotSpot, LoadedFromOpaqueSource);
+    CSSCursorImageValue(Ref<CSSValue>&& imageValue, const std::optional<IntPoint>& hotSpot, LoadedFromOpaqueSource);
 
     SVGCursorElement* updateCursorElement(const Document&);
 
     URL m_originalURL;
     Ref<CSSValue> m_imageValue;
-
-    bool m_hasHotSpot;
-    IntPoint m_hotSpot;
+    std::optional<IntPoint> m_hotSpot;
     HashSet<SVGCursorElement*> m_cursorElements;
     LoadedFromOpaqueSource m_loadedFromOpaqueSource { LoadedFromOpaqueSource::No };
 };

Modified: trunk/Source/WebCore/css/CSSFilterImageValue.cpp (279049 => 279050)


--- trunk/Source/WebCore/css/CSSFilterImageValue.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/CSSFilterImageValue.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2021 Apple Inc. All right reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,7 +36,6 @@
 #include "RenderElement.h"
 #include "StyleBuilderState.h"
 #include "StyleCachedImage.h"
-#include <wtf/text/StringBuilder.h>
 
 namespace WebCore {
 
@@ -173,4 +173,16 @@
     return compareCSSValue(m_imageValue, other.m_imageValue);
 }
 
+Ref<CSSFilterImageValue> CSSFilterImageValue::valueWithStylesResolved(Style::BuilderState& state)
+{
+    auto imageValue = state.resolveImageStyles(m_imageValue.get());
+    if (imageValue.ptr() == m_imageValue.ptr()) {
+        createFilterOperations(state);
+        return *this;
+    }
+    auto filterImageValue = create(WTFMove(imageValue), Ref { m_filterValue });
+    filterImageValue->createFilterOperations(state);
+    return filterImageValue;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/CSSFilterImageValue.h (279049 => 279050)


--- trunk/Source/WebCore/css/CSSFilterImageValue.h	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/CSSFilterImageValue.h	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,10 +36,8 @@
 
 namespace WebCore {
 
-class CachedImage;
 class FilterSubimageObserverProxy;
 class RenderElement;
-class Document;
 
 namespace Style {
 class BuilderState;
@@ -71,15 +70,12 @@
 
     bool equalInputImages(const CSSFilterImageValue&) const;
 
-    void createFilterOperations(Style::BuilderState&);
-
     const FilterOperations& filterOperations() const { return m_filterOperations; }
-    void setFilterOperations(const FilterOperations& filterOperations)
-    {
-        m_filterOperations = filterOperations;
-    }
+    void setFilterOperations(const FilterOperations& filterOperations) { m_filterOperations = filterOperations; }
     CachedImage* cachedImage() const { return m_cachedImage.get(); }
 
+    Ref<CSSFilterImageValue> valueWithStylesResolved(Style::BuilderState&);
+
 private:
     CSSFilterImageValue(Ref<CSSValue>&& imageValue, Ref<CSSValue>&& filterValue)
         : CSSImageGeneratorValue(FilterImageClass)
@@ -106,6 +102,7 @@
     };
 
     void filterImageChanged(const IntRect&);
+    void createFilterOperations(Style::BuilderState&);
 
     Ref<CSSValue> m_imageValue;
     Ref<CSSValue> m_filterValue;

Modified: trunk/Source/WebCore/css/CSSGradientValue.cpp (279049 => 279050)


--- trunk/Source/WebCore/css/CSSGradientValue.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/CSSGradientValue.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -107,7 +107,7 @@
     return *m_hasColorDerivedFromElement;
 }
 
-Ref<CSSGradientValue> CSSGradientValue::gradientWithStylesResolved(Style::BuilderState& builderState)
+Ref<CSSGradientValue> CSSGradientValue::valueWithStylesResolved(Style::BuilderState& builderState)
 {
     auto result = hasColorDerivedFromElement() ? clone(*this) : makeRef(*this);
     resolveStopColors(result->m_stops, [&](const CSSPrimitiveValue& colorValue) {

Modified: trunk/Source/WebCore/css/CSSGradientValue.h (279049 => 279050)


--- trunk/Source/WebCore/css/CSSGradientValue.h	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/CSSGradientValue.h	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -78,7 +78,7 @@
     static constexpr bool isPending() { return false; }
     static void loadSubimages(CachedResourceLoader&, const ResourceLoaderOptions&) { }
 
-    Ref<CSSGradientValue> gradientWithStylesResolved(Style::BuilderState&);
+    Ref<CSSGradientValue> valueWithStylesResolved(Style::BuilderState&);
 
 protected:
     CSSGradientValue(ClassType classType, CSSGradientRepeat repeat, CSSGradientType gradientType)

Modified: trunk/Source/WebCore/css/CSSImageSetValue.cpp (279049 => 279050)


--- trunk/Source/WebCore/css/CSSImageSetValue.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/CSSImageSetValue.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -113,16 +113,14 @@
     m_selectedImageValue = nullptr;
 }
 
-Ref<CSSImageSetValue> CSSImageSetValue::imageSetWithStylesResolved(Style::BuilderState& builderState)
+Ref<CSSImageSetValue> CSSImageSetValue::valueWithStylesResolved(Style::BuilderState& builderState)
 {
-    Ref<CSSImageSetValue> result = CSSImageSetValue::create();
-    size_t length = this->length();
-    for (size_t i = 0; i + 1 < length; i += 2) {
+    auto result = create();
+    for (size_t i = 0, length = this->length(); i + 1 < length; i += 2) {
         result->append(builderState.resolveImageStyles(*itemWithoutBoundsCheck(i)));
         result->append(*itemWithoutBoundsCheck(i + 1));
     }
-
-    return result;
+    return equals(result) ? Ref { *this } : result;
 }
 
 String CSSImageSetValue::customCSSText() const

Modified: trunk/Source/WebCore/css/CSSImageSetValue.h (279049 => 279050)


--- trunk/Source/WebCore/css/CSSImageSetValue.h	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/CSSImageSetValue.h	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -61,7 +61,7 @@
 
     void updateDeviceScaleFactor(const Document&);
 
-    Ref<CSSImageSetValue> imageSetWithStylesResolved(Style::BuilderState&);
+    Ref<CSSImageSetValue> valueWithStylesResolved(Style::BuilderState&);
 
 private:
     CSSImageSetValue();

Modified: trunk/Source/WebCore/css/CSSImageValue.cpp (279049 => 279050)


--- trunk/Source/WebCore/css/CSSImageValue.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/CSSImageValue.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,6 +1,6 @@
 /*
  * (C) 1999-2003 Lars Knoll ([email protected])
- * Copyright (C) 2004-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2021 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -34,10 +34,20 @@
 
 namespace WebCore {
 
-CSSImageValue::CSSImageValue(URL&& url, LoadedFromOpaqueSource loadedFromOpaqueSource)
+static bool operator==(const ResolvedURL& a, const ResolvedURL& b)
+{
+    return a.specifiedURLString == b.specifiedURLString && a.resolvedURL == b.resolvedURL;
+}
+
+static ResolvedURL makeResolvedURL(URL&& resolvedURL)
+{
+    auto string = resolvedURL.string();
+    return { WTFMove(string), WTFMove(resolvedURL) };
+}
+
+CSSImageValue::CSSImageValue(ResolvedURL&& location, LoadedFromOpaqueSource loadedFromOpaqueSource)
     : CSSValue(ImageClass)
-    , m_url(WTFMove(url))
-    , m_accessedImage(false)
+    , m_location(WTFMove(location))
     , m_loadedFromOpaqueSource(loadedFromOpaqueSource)
 {
 }
@@ -44,70 +54,97 @@
 
 CSSImageValue::CSSImageValue(CachedImage& image)
     : CSSValue(ImageClass)
-    , m_url(image.url())
+    , m_location { image.url().string(), image.url() }
     , m_cachedImage(&image)
-    , m_accessedImage(true)
 {
 }
 
+Ref<CSSImageValue> CSSImageValue::create(ResolvedURL&& location, LoadedFromOpaqueSource loadedFromOpaqueSource)
+{
+    return adoptRef(*new CSSImageValue(WTFMove(location), loadedFromOpaqueSource));
+}
 
+Ref<CSSImageValue> CSSImageValue::create(URL&& imageURL, LoadedFromOpaqueSource loadedFromOpaqueSource)
+{
+    return create(makeResolvedURL(WTFMove(imageURL)), loadedFromOpaqueSource);
+}
+
+Ref<CSSImageValue> CSSImageValue::create(CachedImage& image)
+{
+    return adoptRef(*new CSSImageValue(image));
+}
+
 CSSImageValue::~CSSImageValue() = default;
 
 bool CSSImageValue::isPending() const
 {
-    return !m_accessedImage;
+    return !m_cachedImage;
 }
 
+URL CSSImageValue::reresolvedURL(const Document& document) const
+{
+    // Re-resolving the URL is important for cases where resolvedURL is still not an absolute URL.
+    // This can happen if there was no absolute base URL when the value was created, like a style from a document without a base URL.
+    return document.completeURL(m_location.resolvedURL.string());
+}
+
+Ref<CSSImageValue> CSSImageValue::valueWithStylesResolved(Style::BuilderState& state)
+{
+    auto location = makeResolvedURL(reresolvedURL(state.document()));
+    if (m_location == location)
+        return *this;
+    auto result = create(WTFMove(location), m_loadedFromOpaqueSource);
+    result->m_cachedImage = m_cachedImage;
+    result->m_initiatorName = m_initiatorName;
+    result->m_unresolvedValue = this;
+    return result;
+}
+
 CachedImage* CSSImageValue::loadImage(CachedResourceLoader& loader, const ResourceLoaderOptions& options)
 {
-    if (!m_accessedImage) {
-        m_accessedImage = true;
-
+    if (!m_cachedImage) {
         ResourceLoaderOptions loadOptions = options;
         loadOptions.loadedFromOpaqueSource = m_loadedFromOpaqueSource;
-        CachedResourceRequest request(ResourceRequest(loader.document()->completeURL(m_url.string())), loadOptions);
+        CachedResourceRequest request(ResourceRequest(reresolvedURL(*loader.document())), loadOptions);
         if (m_initiatorName.isEmpty())
             request.setInitiator(cachedResourceRequestInitiators().css);
         else
             request.setInitiator(m_initiatorName);
-
         if (options.mode == FetchOptions::Mode::Cors) {
             ASSERT(loader.document());
             request.updateForAccessControl(*loader.document());
         }
         m_cachedImage = loader.requestImage(WTFMove(request)).value_or(nullptr);
+        for (auto imageValue = this; (imageValue = imageValue->m_unresolvedValue.get()); )
+            imageValue->m_cachedImage = m_cachedImage;
     }
-    return m_cachedImage.get();
+    return m_cachedImage.value().get();
 }
 
 bool CSSImageValue::traverseSubresources(const WTF::Function<bool (const CachedResource&)>& handler) const
 {
-    if (!m_cachedImage)
-        return false;
-    return handler(*m_cachedImage);
+    return m_cachedImage.value_or(nullptr) && handler(**m_cachedImage);
 }
 
 bool CSSImageValue::equals(const CSSImageValue& other) const
 {
-    return m_url == other.m_url;
+    return m_location == other.m_location;
 }
 
 String CSSImageValue::customCSSText() const
 {
-    return serializeURL(m_url.string());
+    return serializeURL(m_location.specifiedURLString);
 }
 
 Ref<DeprecatedCSSOMValue> CSSImageValue::createDeprecatedCSSOMWrapper(CSSStyleDeclaration& styleDeclaration) const
 {
     // NOTE: We expose CSSImageValues as URI primitive values in CSSOM to maintain old behavior.
-    return DeprecatedCSSOMPrimitiveValue::create(CSSPrimitiveValue::create(m_url.string(), CSSUnitType::CSS_URI), styleDeclaration);
+    return DeprecatedCSSOMPrimitiveValue::create(CSSPrimitiveValue::create(m_location.resolvedURL.string(), CSSUnitType::CSS_URI), styleDeclaration);
 }
 
 bool CSSImageValue::knownToBeOpaque(const RenderElement& renderer) const
 {
-    if (!m_cachedImage)
-        return false;
-    return m_cachedImage->currentFrameKnownToBeOpaque(&renderer);
+    return m_cachedImage.value_or(nullptr) && (**m_cachedImage).currentFrameKnownToBeOpaque(&renderer);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/CSSImageValue.h (279049 => 279050)


--- trunk/Source/WebCore/css/CSSImageValue.h	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/CSSImageValue.h	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1,6 +1,6 @@
 /*
  * (C) 1999-2003 Lars Knoll ([email protected])
- * Copyright (C) 2004, 2005, 2006, 2008, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2021 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -9,7 +9,7 @@
  *
  * 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
+ * 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
@@ -34,17 +34,27 @@
 class CSSStyleDeclaration;
 class RenderElement;
 
+namespace Style {
+class BuilderState;
+}
+
+struct ResolvedURL {
+    String specifiedURLString;
+    URL resolvedURL;
+};
+
 class CSSImageValue final : public CSSValue {
 public:
-    static Ref<CSSImageValue> create(URL&& url, LoadedFromOpaqueSource loadedFromOpaqueSource) { return adoptRef(*new CSSImageValue(WTFMove(url), loadedFromOpaqueSource)); }
-    static Ref<CSSImageValue> create(CachedImage& image) { return adoptRef(*new CSSImageValue(image)); }
+    static Ref<CSSImageValue> create(ResolvedURL&&, LoadedFromOpaqueSource);
+    static Ref<CSSImageValue> create(URL&&, LoadedFromOpaqueSource);
+    static Ref<CSSImageValue> create(CachedImage&);
     ~CSSImageValue();
 
     bool isPending() const;
     CachedImage* loadImage(CachedResourceLoader&, const ResourceLoaderOptions&);
-    CachedImage* cachedImage() const { return m_cachedImage.get(); }
+    CachedImage* cachedImage() const { return m_cachedImage ? m_cachedImage.value().get() : nullptr; }
 
-    const URL& url() const { return m_url; }
+    const URL& imageURL() const { return m_location.resolvedURL; }
 
     String customCSSText() const;
 
@@ -58,15 +68,19 @@
 
     void setInitiator(const AtomString& name) { m_initiatorName = name; }
 
+    Ref<CSSImageValue> valueWithStylesResolved(Style::BuilderState&);
+
 private:
-    CSSImageValue(URL&&, LoadedFromOpaqueSource);
+    CSSImageValue(ResolvedURL&&, LoadedFromOpaqueSource);
     explicit CSSImageValue(CachedImage&);
 
-    URL m_url;
-    CachedResourceHandle<CachedImage> m_cachedImage;
-    bool m_accessedImage;
+    URL reresolvedURL(const Document&) const;
+
+    ResolvedURL m_location;
+    std::optional<CachedResourceHandle<CachedImage>> m_cachedImage;
     AtomString m_initiatorName;
     LoadedFromOpaqueSource m_loadedFromOpaqueSource { LoadedFromOpaqueSource::No };
+    RefPtr<CSSImageValue> m_unresolvedValue;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/StyleSheetContents.cpp (279049 => 279050)


--- trunk/Source/WebCore/css/StyleSheetContents.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/StyleSheetContents.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -417,11 +417,6 @@
     return ownerNode ? &ownerNode->document() : 0;
 }
 
-URL StyleSheetContents::completeURL(const String& url) const
-{
-    return m_parserContext.completeURL(url);
-}
-
 static bool traverseRulesInVector(const Vector<RefPtr<StyleRuleBase>>& rules, const WTF::Function<bool (const StyleRuleBase&)>& handler)
 {
     for (auto& rule : rules) {

Modified: trunk/Source/WebCore/css/StyleSheetContents.h (279049 => 279050)


--- trunk/Source/WebCore/css/StyleSheetContents.h	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/StyleSheetContents.h	2021-06-19 20:31:11 UTC (rev 279050)
@@ -86,7 +86,6 @@
 
     bool loadCompleted() const { return m_loadCompleted; }
 
-    URL completeURL(const String& url) const;
     bool traverseRules(const WTF::Function<bool (const StyleRuleBase&)>& handler) const;
     bool traverseSubresources(const WTF::Function<bool (const CachedResource&)>& handler) const;
 

Modified: trunk/Source/WebCore/css/parser/CSSParserContext.cpp (279049 => 279050)


--- trunk/Source/WebCore/css/parser/CSSParserContext.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/parser/CSSParserContext.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "CSSParserContext.h"
 
+#include "CSSImageValue.h"
 #include "Document.h"
 #include "DocumentLoader.h"
 #include "Page.h"
@@ -220,22 +221,21 @@
     }
 }
 
-URL CSSParserContext::completeURL(const String& url) const
+ResolvedURL CSSParserContext::completeURL(const String& string) const
 {
-    auto completedURL = [&] {
-        if (url.isNull())
-            return URL();
+    auto result = [&] () -> ResolvedURL {
+        if (string.isNull())
+            return { };
         if (charset.isEmpty())
-            return URL(baseURL, url);
-        TextEncoding encoding(charset);
-        auto& encodingForURLParsing = encoding.encodingForFormSubmissionOrURLParsing();
-        return URL(baseURL, url, encodingForURLParsing == UTF8Encoding() ? nullptr : &encodingForURLParsing);
+            return { string, { baseURL, string } };
+        auto encodingForURLParsing = TextEncoding { charset }.encodingForFormSubmissionOrURLParsing();
+        return { string, { baseURL, string, encodingForURLParsing == UTF8Encoding() ? nullptr : &encodingForURLParsing } };
     }();
 
-    if (mode == WebVTTMode && !completedURL.protocolIsData())
-        return URL();
+    if (mode == WebVTTMode && !result.resolvedURL.protocolIsData())
+        return { };
 
-    return completedURL;
+    return result;
 }
 
 }

Modified: trunk/Source/WebCore/css/parser/CSSParserContext.h (279049 => 279050)


--- trunk/Source/WebCore/css/parser/CSSParserContext.h	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/parser/CSSParserContext.h	2021-06-19 20:31:11 UTC (rev 279050)
@@ -37,6 +37,8 @@
 
 class Document;
 
+struct ResolvedURL;
+
 struct CSSParserContext {
     WTF_MAKE_STRUCT_FAST_ALLOCATED;
 
@@ -88,7 +90,7 @@
     CSSParserContext(CSSParserMode, const URL& baseURL = URL());
     WEBCORE_EXPORT CSSParserContext(const Document&, const URL& baseURL = URL(), const String& charset = emptyString());
     bool isPropertyRuntimeDisabled(CSSPropertyID) const;
-    URL completeURL(const String& relativeURL) const;
+    ResolvedURL completeURL(const String&) const;
 };
 
 bool operator==(const CSSParserContext&, const CSSParserContext&);

Modified: trunk/Source/WebCore/css/parser/CSSParserIdioms.cpp (279049 => 279050)


--- trunk/Source/WebCore/css/parser/CSSParserIdioms.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/parser/CSSParserIdioms.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -45,9 +45,4 @@
     }
 }
 
-URL completeURL(const CSSParserContext& context, const String& url)
-{
-    return context.completeURL(url);
-}
-
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/parser/CSSParserIdioms.h (279049 => 279050)


--- trunk/Source/WebCore/css/parser/CSSParserIdioms.h	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/parser/CSSParserIdioms.h	2021-06-19 20:31:11 UTC (rev 279050)
@@ -59,6 +59,4 @@
 
 bool isValueAllowedInMode(unsigned short, CSSParserMode);
 
-URL completeURL(const CSSParserContext&, const String& url);
-
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp (279049 => 279050)


--- trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -2258,22 +2258,20 @@
 static RefPtr<CSSValue> consumeCursor(CSSParserTokenRange& range, const CSSParserContext& context, bool inQuirksMode)
 {
     RefPtr<CSSValueList> list;
-    while (RefPtr<CSSValue> image = consumeImage(range, context, { AllowedImageType::URLFunction, AllowedImageType::ImageSet })) {
-        IntPoint hotSpot(-1, -1);
-        bool hotSpotSpecified = false;
+    while (auto image = consumeImage(range, context, { AllowedImageType::URLFunction, AllowedImageType::ImageSet })) {
+        std::optional<IntPoint> hotSpot;
         if (auto x = consumeNumberRaw(range)) {
-            hotSpot.setX(static_cast<int>(*x));
             auto y = consumeNumberRaw(range);
             if (!y)
                 return nullptr;
-            hotSpot.setY(static_cast<int>(*y));
-            hotSpotSpecified = true;
+            // FIXME: Should we clamp or round instead of just casting from double to int?
+            hotSpot = IntPoint { static_cast<int>(*x), static_cast<int>(*y) };
         }
 
         if (!list)
             list = CSSValueList::createCommaSeparated();
 
-        list->append(CSSCursorImageValue::create(image.releaseNonNull(), hotSpotSpecified, hotSpot, context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No));
+        list->append(CSSCursorImageValue::create(image.releaseNonNull(), hotSpot, context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No));
         if (!consumeCommaIncludingWhitespace(range))
             return nullptr;
     }
@@ -4668,37 +4666,32 @@
 static RefPtr<CSSValue> consumeCounterStyleAdditiveSymbols(CSSParserTokenRange& range, const CSSParserContext& context)
 {
     auto values = CSSValueList::createCommaSeparated();
-    RefPtr<CSSPrimitiveValue> lastInteger;
+    std::optional<int> lastWeight;
     do {
-        RefPtr<CSSPrimitiveValue> integer;
-        RefPtr<CSSValue> symbol;
-        while (!integer || !symbol) {
-            if (!integer) {
-                integer = consumeInteger(range, 0);
-                if (integer)
-                    continue;
-            }
-            if (!symbol) {
-                symbol = consumeCounterStyleSymbol(range, context);
-                if (symbol)
-                    continue;
-            }
-            return nullptr;
+        auto integer = consumeInteger(range, 0);
+        auto symbol = consumeCounterStyleSymbol(range, context);
+        if (!integer) {
+            if (!symbol)
+                return nullptr;
+            integer = consumeInteger(range, 0);
+            if (!integer)
+                return nullptr;
         }
 
-        if (lastInteger) {
-            // The additive tuples must be specified in order of strictly descending
-            // weight; otherwise, the declaration is invalid and must be ignored.
-            if (integer->intValue() >= lastInteger->intValue())
-                return nullptr;
-        }
-        lastInteger = integer;
-        values->append(integer.releaseNonNull());
-        values->append(symbol.releaseNonNull());
+        // Additive tuples must be specified in order of strictly descending weight.
+        auto weight = integer->intValue();
+        if (lastWeight && !(weight < lastWeight))
+            return nullptr;
+        lastWeight = weight;
+
+        auto pair = CSSValueList::createSpaceSeparated();
+        pair->append(integer.releaseNonNull());
+        pair->append(symbol.releaseNonNull());
+        values->append(WTFMove(pair));
     } while (consumeCommaIncludingWhitespace(range));
     if (!range.atEnd() || !values->length())
         return nullptr;
-    return values;
+    return WTFMove(values);
 }
 
 // https://www.w3.org/TR/css-counter-styles-3/#counter-style-speak-as

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (279049 => 279050)


--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -3502,9 +3502,9 @@
 
 RefPtr<CSSValue> consumeImage(CSSParserTokenRange& range, const CSSParserContext& context, OptionSet<AllowedImageType> allowedImageTypes)
 {
-    if ((range.peek().type() == StringToken) && (allowedImageTypes.contains(AllowedImageType::RawStringAsURL))) {
-        auto urlStringView = range.consumeIncludingWhitespace().value();
-        return CSSImageValue::create(completeURL(context, urlStringView.toAtomString()), context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No);
+    if (range.peek().type() == StringToken && allowedImageTypes.contains(AllowedImageType::RawStringAsURL)) {
+        return CSSImageValue::create(context.completeURL(range.consumeIncludingWhitespace().value().toAtomString().string()),
+            context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No);
     }
 
     if (range.peek().type() == FunctionToken) {
@@ -3521,9 +3521,10 @@
     }
 
     if (allowedImageTypes.contains(AllowedImageType::URLFunction)) {
-        auto uri = consumeUrlAsStringView(range);
-        if (!uri.isNull())
-            return CSSImageValue::create(completeURL(context, uri.toAtomString()), context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No);
+        if (auto string = consumeUrlAsStringView(range); !string.isNull()) {
+            return CSSImageValue::create(context.completeURL(string.toAtomString().string()),
+                context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No);
+        }
     }
 
     return nullptr;

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserWorkerSafe.cpp (279049 => 279050)


--- trunk/Source/WebCore/css/parser/CSSPropertyParserWorkerSafe.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserWorkerSafe.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -198,28 +198,28 @@
 
 namespace CSSPropertyParserHelpersWorkerSafe {
 
-static RefPtr<CSSValue> consumeFontFaceSrcURI(CSSParserTokenRange& range, const CSSParserContext& context)
+static RefPtr<CSSFontFaceSrcValue> consumeFontFaceSrcURI(CSSParserTokenRange& range, const CSSParserContext& context)
 {
-    String url = ""
-    if (url.isNull())
+    auto location = context.completeURL(CSSPropertyParserHelpers::consumeUrlAsStringView(range).toString()).resolvedURL.string();
+    if (location.isNull())
         return nullptr;
 
-    RefPtr<CSSFontFaceSrcValue> uriValue = CSSFontFaceSrcValue::create(context.completeURL(url).string(), context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No);
+    String format;
+    if (range.peek().functionId() == CSSValueFormat) {
+        // https://drafts.csswg.org/css-fonts/#descdef-font-face-src
+        // FIXME: The format should be a comma-separated list; at this time we support only one.
+        // FIXME: We allow any identifier here and convert all to strings; specification calls for only certain identifiers.
+        auto args = CSSPropertyParserHelpers::consumeFunction(range);
+        auto& arg = args.consumeIncludingWhitespace();
+        if ((arg.type() != StringToken && arg.type() != IdentToken) || !args.atEnd())
+            return nullptr;
+        format = arg.value().toString();
+    }
 
-    if (range.peek().functionId() != CSSValueFormat)
-        return uriValue;
-
-    // FIXME: https://drafts.csswg.org/css-fonts says that format() contains a comma-separated list of strings,
-    // but CSSFontFaceSrcValue stores only one format. Allowing one format for now.
-    // FIXME: We're allowing the format to be an identifier as well as a string, because the old
-    // parser did. It's not clear if we need to continue to support this behavior, but we have lots of
-    // layout tests that rely on it.
-    CSSParserTokenRange args = CSSPropertyParserHelpers::consumeFunction(range);
-    const CSSParserToken& arg = args.consumeIncludingWhitespace();
-    if ((arg.type() != StringToken && arg.type() != IdentToken) || !args.atEnd())
-        return nullptr;
-    uriValue->setFormat(arg.value().toString());
-    return uriValue;
+    // FIXME: Change CSSFontFaceSrcValue::create to take format so we don't need a separate setFormat call.
+    auto srcValue = CSSFontFaceSrcValue::create(location, context.isContentOpaque ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No);
+    srcValue->setFormat(format);
+    return WTFMove(srcValue);
 }
 
 static RefPtr<CSSValue> consumeFontFaceSrcLocal(CSSParserTokenRange& range)

Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (279049 => 279050)


--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1261,12 +1261,14 @@
     data.clip.left() = WTFMove(left);
 }
 
-void RenderStyle::addCursor(RefPtr<StyleImage>&& image, const IntPoint& hotSpot)
+void RenderStyle::addCursor(RefPtr<StyleImage>&& image, const std::optional<IntPoint>& hotSpot)
 {
     auto& cursorData = m_rareInheritedData.access().cursorData;
     if (!cursorData)
         cursorData = CursorList::create();
-    cursorData->append(CursorData(WTFMove(image), hotSpot));
+    // Point outside the image is how we tell the cursor machinery there is no hot spot, and it should generate one (done in the Cursor class).
+    // FIXME: Would it be better to extend the concept of "no hot spot" deeper, into CursorData and beyond, rather than using -1/-1 for it?
+    cursorData->append(CursorData(WTFMove(image), hotSpot.value_or(IntPoint { -1, -1 })));
 }
 
 void RenderStyle::setCursorList(RefPtr<CursorList>&& list)

Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (279049 => 279050)


--- trunk/Source/WebCore/rendering/style/RenderStyle.h	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1071,7 +1071,7 @@
     void setPaddingRight(Length&& length) { SET_VAR(m_surroundData, padding.right(), WTFMove(length)); }
 
     void setCursor(CursorType c) { m_inheritedFlags.cursor = static_cast<unsigned>(c); }
-    void addCursor(RefPtr<StyleImage>&&, const IntPoint& hotSpot = IntPoint());
+    void addCursor(RefPtr<StyleImage>&&, const std::optional<IntPoint>& hotSpot);
     void setCursorList(RefPtr<CursorList>&&);
     void clearCursorList();
 

Modified: trunk/Source/WebCore/rendering/style/StyleCachedImage.cpp (279049 => 279050)


--- trunk/Source/WebCore/rendering/style/StyleCachedImage.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/rendering/style/StyleCachedImage.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -66,7 +66,7 @@
 
 URL StyleCachedImage::imageURL()
 {
-    return m_cssValue->url();
+    return m_cssValue->imageURL();
 }
 
 void StyleCachedImage::load(CachedResourceLoader& loader, const ResourceLoaderOptions& options)

Modified: trunk/Source/WebCore/style/StyleBuilderCustom.h (279049 => 279050)


--- trunk/Source/WebCore/style/StyleBuilderCustom.h	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/style/StyleBuilderCustom.h	2021-06-19 20:31:11 UTC (rev 279050)
@@ -1538,19 +1538,19 @@
     for (auto& item : downcast<CSSValueList>(value)) {
         if (is<CSSImageGeneratorValue>(item)) {
             if (is<CSSGradientValue>(item))
-                builderState.style().setContent(StyleGeneratedImage::create(downcast<CSSGradientValue>(item.get()).gradientWithStylesResolved(builderState)), didSet);
+                builderState.style().setContent(StyleGeneratedImage::create(downcast<CSSGradientValue>(builderState.resolveImageStyles(item.get()).get())), didSet);
             else
-                builderState.style().setContent(StyleGeneratedImage::create(downcast<CSSImageGeneratorValue>(item.get())), didSet);
+                builderState.style().setContent(StyleGeneratedImage::create(downcast<CSSImageGeneratorValue>(builderState.resolveImageStyles(item.get()).get())), didSet);
             didSet = true;
         }
-        
+
         if (is<CSSImageSetValue>(item)) {
-            builderState.style().setContent(StyleImageSet::create(downcast<CSSImageSetValue>(item.get()).imageSetWithStylesResolved(builderState)), didSet);
+            builderState.style().setContent(StyleImageSet::create(downcast<CSSImageSetValue>(builderState.resolveImageStyles(item.get()).get())), didSet);
             didSet = true;
         }
 
         if (is<CSSImageValue>(item)) {
-            builderState.style().setContent(StyleCachedImage::create(downcast<CSSImageValue>(item.get())), didSet);
+            builderState.style().setContent(StyleCachedImage::create(downcast<CSSImageValue>(builderState.resolveImageStyles(item.get()).get())), didSet);
             didSet = true;
             continue;
         }

Modified: trunk/Source/WebCore/style/StyleBuilderState.cpp (279049 => 279050)


--- trunk/Source/WebCore/style/StyleBuilderState.cpp	2021-06-19 08:25:14 UTC (rev 279049)
+++ trunk/Source/WebCore/style/StyleBuilderState.cpp	2021-06-19 20:31:11 UTC (rev 279050)
@@ -30,6 +30,7 @@
 #include "config.h"
 #include "StyleBuilderState.h"
 
+#include "CSSCrossfadeValue.h"
 #include "CSSCursorImageValue.h"
 #include "CSSFilterImageValue.h"
 #include "CSSFontSelector.h"
@@ -41,7 +42,6 @@
 #include "FontCache.h"
 #include "HTMLElement.h"
 #include "RenderTheme.h"
-#include "SVGElement.h"
 #include "SVGSVGElement.h"
 #include "Settings.h"
 #include "StyleBuilder.h"
@@ -84,16 +84,18 @@
 
 Ref<CSSValue> BuilderState::resolveImageStyles(CSSValue& value)
 {
+    if (is<CSSCrossfadeValue>(value))
+        return downcast<CSSCrossfadeValue>(value).valueWithStylesResolved(*this);
+    if (is<CSSCursorImageValue>(value))
+        return downcast<CSSCursorImageValue>(value).valueWithStylesResolved(*this);
+    if (is<CSSFilterImageValue>(value))
+        return downcast<CSSFilterImageValue>(value).valueWithStylesResolved(*this);
     if (is<CSSGradientValue>(value))
-        return downcast<CSSGradientValue>(value).gradientWithStylesResolved(*this);
-
+        return downcast<CSSGradientValue>(value).valueWithStylesResolved(*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 downcast<CSSImageSetValue>(value).valueWithStylesResolved(*this);
+    if (is<CSSImageValue>(value))
+        return downcast<CSSImageValue>(value).valueWithStylesResolved(*this);
     return makeRef(value);
 }
 
@@ -100,17 +102,13 @@
 RefPtr<StyleImage> BuilderState::createStyleImage(CSSValue& value)
 {
     if (is<CSSImageValue>(value))
-        return StyleCachedImage::create(downcast<CSSImageValue>(value));
-
+        return StyleCachedImage::create(downcast<CSSImageValue>(resolveImageStyles(value).get()));
     if (is<CSSCursorImageValue>(value))
-        return StyleCursorImage::create(downcast<CSSCursorImageValue>(value));
-
+        return StyleCursorImage::create(downcast<CSSCursorImageValue>(resolveImageStyles(value).get()));
     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;
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to