Bug 1487649 - Don't do a name check when cloning a shadow root for print preview. r=smaug
authorEmilio Cobos Álvarez <emilio@crisal.io>
Mon, 03 Sep 2018 14:10:58 +0000
changeset 434485 5254a8f44df4ac705bf05fe55476f476a37bf8b9
parent 434484 a596012f29db4681255057a35690f251a73b7282
child 434486 658c3662b01c215899d53c75b34a3a80f7e624f2
push id34562
push userdvarga@mozilla.com
push dateMon, 03 Sep 2018 21:52:32 +0000
treeherdermozilla-central@42469f001fcb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1487649
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 1487649 - Don't do a name check when cloning a shadow root for print preview. r=smaug Otherwise the ShadowRoot for <use> or other internal ones may not get cloned properly. Differential Revision: https://phabricator.services.mozilla.com/D4756
dom/base/nsNodeUtils.cpp
layout/base/tests/chrome/printpreview_helper.xul
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -605,23 +605,18 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
     }
   }
 
   if (aDeep && aNode->IsElement()) {
     if (aClone) {
       if (clone->OwnerDoc()->IsStaticDocument()) {
         ShadowRoot* originalShadowRoot = aNode->AsElement()->GetShadowRoot();
         if (originalShadowRoot) {
-          ShadowRootInit init;
-          init.mMode = originalShadowRoot->Mode();
           RefPtr<ShadowRoot> newShadowRoot =
-            clone->AsElement()->AttachShadow(init, aError);
-          if (NS_WARN_IF(aError.Failed())) {
-            return nullptr;
-          }
+            clone->AsElement()->AttachShadowWithoutNameChecks(originalShadowRoot->Mode());
 
           newShadowRoot->CloneInternalDataFrom(originalShadowRoot);
           for (nsIContent* origChild = originalShadowRoot->GetFirstChild();
                origChild;
                origChild = origChild->GetNextSibling()) {
             nsCOMPtr<nsINode> child =
               CloneAndAdopt(origChild, aClone, aDeep, nodeInfoManager,
                             aReparentScope, aNodesWithProperties, newShadowRoot,
--- a/layout/base/tests/chrome/printpreview_helper.xul
+++ b/layout/base/tests/chrome/printpreview_helper.xul
@@ -301,16 +301,54 @@ async function runTest8() {
     iframeElement.addEventListener("message", resolve, { capture: true, once: true });
     iframeElement.setAttribute("src", "printpreview_font_api.html");
   });
   printpreview();
   ctx2.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)");
   exitprintpreview();
   ok(compareCanvases(), "Printing pages with fonts loaded from CSS and JS should be the same.");
 
+  requestAnimationFrame(function() { setTimeout(runTest9); } );
+}
+
+// Test for bug 1487649
+async function runTest9() {
+  window.frames[0].document.body.innerHTML = `
+    <svg width="100" height="100">
+      <rect width='100' height='100' fill='lime'/>
+    </svg>
+  `;
+
+  printpreview();
+  ctx1.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)");
+  exitprintpreview();
+
+  window.frames[0].document.body.innerHTML = `
+    <svg width="100" height="100">
+      <defs>
+        <g id="useme">
+          <rect width='100' height='100' fill='lime'/>
+        </g>
+      </defs>
+      <use />
+    </svg>
+  `;
+
+  // Set the attribute explicitly because this is a chrome document, and the
+  // href attribute would get sanitized.
+  window.frames[0].document.querySelector("use").setAttribute("href", "#useme");
+
+  // Ensure the <use> shadow tree is created so we test what we want to test.
+  window.frames[0].document.body.offsetTop;
+
+  printpreview();
+  ctx2.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)");
+  exitprintpreview();
+  ok(compareCanvases(), "Printing <use> subtrees should create same output");
+
   finish();
 }
 
 ]]></script>
 <table style="border: 1px solid black;" xmlns="http://www.w3.org/1999/xhtml">
 <tr><th>Print preview canvas 1</th><th>Print preview canvas 2</th></tr>
 <tr>
 <td><canvas height="400" width="400"></canvas></td>