Bug 1486252 - Resolve mask-image url value as an image even if it contains reference. r=heycam
authorXidorn Quan <me@upsuper.org>
Tue, 04 Sep 2018 09:35:56 +1000
changeset 492283 c8c93f1fc5b226724c1e11584febee0e0fe9e85c
parent 492282 d630bee3155a4f3d6a0919cab6edf5ee84cbe1ab
child 492284 a00e7a0a9f19c7844a63163f94e082fe0c3166d5
child 492314 588887c7c597d2c7c84e6934768846351c04373c
push id1815
push userffxbld-merge
push dateMon, 15 Oct 2018 10:40:45 +0000
treeherdermozilla-release@18d4c09e9378 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1486252
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1486252 - Resolve mask-image url value as an image even if it contains reference. r=heycam The corresponding handling code in the old style system can be found in: https://dxr.mozilla.org/mozilla-esr60/rev/dd52b41d2b775e5c7261ce52795268b7670635fc/layout/style/nsCSSDataBlock.cpp#65-106 mask-iage-url-hash.html is the test that don't pass without this change. Differential Revision: https://phabricator.services.mozilla.com/D4831
layout/style/nsStyleStruct.cpp
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/css/css-masking/mask-image/mask-image-url-image-hash.html
testing/web-platform/tests/css/css-masking/mask-image/mask-image-url-image.html
testing/web-platform/tests/css/css-masking/mask-image/mask-image-url-local-mask.html
testing/web-platform/tests/css/css-masking/mask-image/mask-image-url-remote-mask.html
testing/web-platform/tests/css/css-masking/mask-image/reference/mask-image-ref.html
testing/web-platform/tests/css/css-masking/mask-image/support/image-with-ref.svg
testing/web-platform/tests/css/css-masking/mask-image/support/image.svg
testing/web-platform/tests/css/css-masking/mask-image/support/mask.svg
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1315,28 +1315,40 @@ nsStyleSVGReset::nsStyleSVGReset(const n
 void
 nsStyleSVGReset::FinishStyle(nsPresContext* aPresContext, const nsStyleSVGReset* aOldStyle)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, mMask) {
     nsStyleImage& image = mMask.mLayers[i].mImage;
     if (image.GetType() == eStyleImageType_Image) {
-      // If the url of mask resource contains a reference('#'), it should be a
-      // <mask-source>, mostly. For a <mask-source>, there is no need to
-      // resolve this style image, since we do not depend on it to get the
-      // SVG mask resource.
-      if (!image.GetURLValue()->HasRef()) {
-        const nsStyleImage* oldImage =
-          (aOldStyle && aOldStyle->mMask.mLayers.Length() > i)
-          ? &aOldStyle->mMask.mLayers[i].mImage
-          : nullptr;
-
-        image.ResolveImage(aPresContext, oldImage);
+      URLValueData* url = image.GetURLValue();
+      // If the url is a local ref, it must be a <mask-resource>, so we don't
+      // need to resolve the style image.
+      if (url->IsLocalRef()) {
+        continue;
       }
+#if 0
+      // XXX The old style system also checks whether this is a reference to
+      // the current document with reference, but it doesn't seem to be a
+      // behavior mentioned anywhere, so we comment out the code for now.
+      nsIURI* docURI = aPresContext->Document()->GetDocumentURI();
+      if (url->EqualsExceptRef(docURI)) {
+        continue;
+      }
+#endif
+
+      // Otherwise, we may need the image even if it has a reference, in case
+      // the referenced element isn't a valid SVG <mask> element.
+      const nsStyleImage* oldImage =
+        (aOldStyle && aOldStyle->mMask.mLayers.Length() > i)
+        ? &aOldStyle->mMask.mLayers[i].mImage
+        : nullptr;
+
+      image.ResolveImage(aPresContext, oldImage);
     }
   }
 }
 
 nsChangeHint
 nsStyleSVGReset::CalcDifference(const nsStyleSVGReset& aNewData) const
 {
   nsChangeHint hint = nsChangeHint(0);
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -125338,16 +125338,64 @@
       [
        "/css/css-masking/clip/reference/clip-no-clipping-ref.html",
        "=="
       ]
      ],
      {}
     ]
    ],
+   "css/css-masking/mask-image/mask-image-url-image-hash.html": [
+    [
+     "/css/css-masking/mask-image/mask-image-url-image-hash.html",
+     [
+      [
+       "/css/css-masking/mask-image/reference/mask-image-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-masking/mask-image/mask-image-url-image.html": [
+    [
+     "/css/css-masking/mask-image/mask-image-url-image.html",
+     [
+      [
+       "/css/css-masking/mask-image/reference/mask-image-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-masking/mask-image/mask-image-url-local-mask.html": [
+    [
+     "/css/css-masking/mask-image/mask-image-url-local-mask.html",
+     [
+      [
+       "/css/css-masking/mask-image/reference/mask-image-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-masking/mask-image/mask-image-url-remote-mask.html": [
+    [
+     "/css/css-masking/mask-image/mask-image-url-remote-mask.html",
+     [
+      [
+       "/css/css-masking/mask-image/reference/mask-image-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-masking/test-mask.html": [
     [
      "/css/css-masking/test-mask.html",
      [
       [
        "/css/css-masking/test-mask-ref.html",
        "=="
       ]
@@ -256691,16 +256739,36 @@
      {}
     ]
    ],
    "css/css-masking/clip/reference/clip-vertical-stripe-ref.html": [
     [
      {}
     ]
    ],
+   "css/css-masking/mask-image/reference/mask-image-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-masking/mask-image/support/image-with-ref.svg": [
+    [
+     {}
+    ]
+   ],
+   "css/css-masking/mask-image/support/image.svg": [
+    [
+     {}
+    ]
+   ],
+   "css/css-masking/mask-image/support/mask.svg": [
+    [
+     {}
+    ]
+   ],
    "css/css-masking/parsing/support/parsing-testcommon.js": [
     [
      {}
     ]
    ],
    "css/css-masking/test-mask-ref.html": [
     [
      {}
@@ -540547,16 +540615,48 @@
   "css/css-masking/clip/reference/clip-vertical-stripe-ref.html": [
    "96ccc2c19c428ddf3717c641db07bce710bb6690",
    "support"
   ],
   "css/css-masking/idlharness.html": [
    "c415eaaa67a2bc9a4b621700049eb0c0b60ec0a3",
    "testharness"
   ],
+  "css/css-masking/mask-image/mask-image-url-image-hash.html": [
+   "b1efc90818bec85d5022a9b908a14c2e0c35ff3b",
+   "reftest"
+  ],
+  "css/css-masking/mask-image/mask-image-url-image.html": [
+   "40a1ff9b281647a03cd90046cb62a088c0ed7081",
+   "reftest"
+  ],
+  "css/css-masking/mask-image/mask-image-url-local-mask.html": [
+   "18abc54f85eb4bfd93962dbef92dd5cffe5ba62b",
+   "reftest"
+  ],
+  "css/css-masking/mask-image/mask-image-url-remote-mask.html": [
+   "cfa3a6166cdcb41b2feaab2ffd5c087a568771f5",
+   "reftest"
+  ],
+  "css/css-masking/mask-image/reference/mask-image-ref.html": [
+   "4e121163f9d093b468e710882cb164bb965d9aa8",
+   "support"
+  ],
+  "css/css-masking/mask-image/support/image-with-ref.svg": [
+   "fe77fb37ac60a8a503d849d019c9ca391d9cf523",
+   "support"
+  ],
+  "css/css-masking/mask-image/support/image.svg": [
+   "28dbaa0238353b47b0d7877cac054d002352078a",
+   "support"
+  ],
+  "css/css-masking/mask-image/support/mask.svg": [
+   "30e601c87c32a08912e261dab22734033df1ef8e",
+   "support"
+  ],
   "css/css-masking/parsing/clip-invalid.html": [
    "18ae8b552a5904097a4b9f0f639b3d0ca123242b",
    "testharness"
   ],
   "css/css-masking/parsing/clip-path-invalid.html": [
    "3d33de251f6c046a6cd15a6cb84416563e2dc293",
    "testharness"
   ],
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-masking/mask-image/mask-image-url-image-hash.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>CSS Test: mask-image: url(image.svg#hash)</title>
+<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://drafts.fxtf.org/css-masking-1/#mask-layer-image">
+<link rel="match" href="reference/mask-image-ref.html">
+<meta name="assert" content="mask-image can use an SVG file as an image with element reference">
+<style>
+#back {
+  position: absolute;
+  box-sizing: border-box;
+  width: 200px;
+  height: 200px;
+  border: 60px solid green;
+  background: red;
+}
+#front {
+  position: absolute;
+  box-sizing: border-box;
+  width: 200px;
+  height: 200px;
+  border: 40px solid red;
+  background: green;
+  mask-image: url(support/image-with-ref.svg#ref);
+}
+</style>
+<p>The test passes if there is a green square and no red below.</p>
+<div id="back"></div><div id="front"></div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-masking/mask-image/mask-image-url-image.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>CSS Test: mask-image: url(image.svg)</title>
+<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://drafts.fxtf.org/css-masking-1/#mask-layer-image">
+<link rel="match" href="reference/mask-image-ref.html">
+<meta name="assert" content="mask-image can use an SVG file as an image">
+<style>
+#back {
+  position: absolute;
+  box-sizing: border-box;
+  width: 200px;
+  height: 200px;
+  border: 60px solid green;
+  background: red;
+}
+#front {
+  position: absolute;
+  box-sizing: border-box;
+  width: 200px;
+  height: 200px;
+  border: 40px solid red;
+  background: green;
+  mask-image: url(support/image.svg);
+}
+</style>
+<p>The test passes if there is a green square and no red below.</p>
+<div id="back"></div><div id="front"></div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-masking/mask-image/mask-image-url-local-mask.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<title>CSS Test: mask-image: url(#local-mask)</title>
+<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://drafts.fxtf.org/css-masking-1/#mask-layer-image">
+<link rel="match" href="reference/mask-image-ref.html">
+<meta name="assert" content="mask-image can use local reference to a &lt;mask&gt; element">
+<style>
+#back {
+  position: absolute;
+  box-sizing: border-box;
+  width: 200px;
+  height: 200px;
+  border: 60px solid green;
+  background: red;
+}
+#front {
+  position: absolute;
+  box-sizing: border-box;
+  width: 200px;
+  height: 200px;
+  border: 40px solid red;
+  background: green;
+  mask-image: url(#localmask);
+}
+</style>
+<p>The test passes if there is a green square and no red below.</p>
+<div id="back"></div><div id="front"></div>
+<svg viewBox="0 0 200 200" style="width: 0; height: 0">
+  <mask id="localmask">
+    <rect x="50" y="50" width="100" height="100" fill="white">
+  </mask>
+</svg>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-masking/mask-image/mask-image-url-remote-mask.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<title>CSS Test: mask-image: url(remote.svg#mask)</title>
+<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://drafts.fxtf.org/css-masking-1/#mask-layer-image">
+<link rel="match" href="reference/mask-image-ref.html">
+<meta name="assert" content="mask-image can use reference to a &lt;mask&gt; element from a remote SVG document">
+<style>
+#back {
+  position: absolute;
+  box-sizing: border-box;
+  width: 200px;
+  height: 200px;
+  border: 60px solid green;
+  background: red;
+}
+#front {
+  position: absolute;
+  box-sizing: border-box;
+  width: 200px;
+  height: 200px;
+  border: 40px solid red;
+  background: green;
+  mask-image: url(support/mask.svg#mask);
+}
+</style>
+<p>The test passes if there is a green square and no red below.</p>
+<div id="back"></div><div id="front"></div>
+<svg>
+  <!-- mask-image doesn't block onload, so we use an empty g here to
+       force mask.svg to load before onload. -->
+  <use href="support/mask.svg#empty"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-masking/mask-image/reference/mask-image-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>CSS Reference: mask-image</title>
+<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<style>
+#ref {
+  position: absolute;
+  width: 200px;
+  height: 200px;
+  background: green;
+}
+</style>
+<p>The test passes if there is a green square and no red below.</p>
+<div id="ref"></div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-masking/mask-image/support/image-with-ref.svg
@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
+  <style>
+    g { display: none; }
+    g:target { display: inline; }
+  </style>
+  <g id="ref">
+    <rect x="50" y="50" width="100" height="100" fill="black"/>
+  </g>
+</svg>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-masking/mask-image/support/image.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
+  <rect x="50" y="50" width="100" height="100" fill="black"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-masking/mask-image/support/mask.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
+  <mask id="mask">
+    <rect x="50" y="50" width="100" height="100" fill="white"/>
+  </mask>
+  <g id="empty"/>
+</svg>