From 54b5a9f5f5eacfd3a74e73e18fb6b25e04f236a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 20 Aug 2020 11:29:45 +0000 Subject: [PATCH] Bug 1659457 - Do clone xml-pretty-printer's UA widget. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D87714 --- dom/base/ShadowRoot.cpp | 12 +++++++++-- dom/base/ShadowRoot.h | 20 ++++++++++++++++++- dom/base/nsINode.cpp | 2 +- dom/xml/nsXMLPrettyPrinter.cpp | 1 + layout/base/tests/chrome/chrome.ini | 2 ++ .../tests/chrome/printpreview_helper.xhtml | 5 +++++ .../tests/chrome/printpreview_prettyprint.xml | 1 + .../chrome/printpreview_prettyprint_ref.xhtml | 3 +++ 8 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 layout/base/tests/chrome/printpreview_prettyprint.xml create mode 100644 layout/base/tests/chrome/printpreview_prettyprint_ref.xhtml diff --git a/dom/base/ShadowRoot.cpp b/dom/base/ShadowRoot.cpp index 0be0faaa7fa3..5f602a22a413 100644 --- a/dom/base/ShadowRoot.cpp +++ b/dom/base/ShadowRoot.cpp @@ -50,7 +50,8 @@ ShadowRoot::ShadowRoot(Element* aElement, ShadowRootMode aMode, : DocumentFragment(std::move(aNodeInfo)), DocumentOrShadowRoot(this), mMode(aMode), - mIsUAWidget(false) { + mIsUAWidget(false), + mIsStaticUAWidget(false) { SetHost(aElement); // Nodes in a shadow tree should never store a value @@ -95,7 +96,14 @@ JSObject* ShadowRoot::WrapNode(JSContext* aCx, } void ShadowRoot::CloneInternalDataFrom(ShadowRoot* aOther) { - MOZ_ASSERT(!aOther->IsUAWidget()); + MOZ_ASSERT(aOther->ShouldStaticClone()); + + if (aOther->IsUAWidget()) { + SetIsUAWidget(); + } + if (aOther->IsStaticUAWidget()) { + SetIsStaticUAWidget(); + } size_t sheetCount = aOther->SheetCount(); for (size_t i = 0; i < sheetCount; ++i) { diff --git a/dom/base/ShadowRoot.h b/dom/base/ShadowRoot.h index 442327bc73a6..2f249c25b362 100644 --- a/dom/base/ShadowRoot.h +++ b/dom/base/ShadowRoot.h @@ -105,6 +105,9 @@ class ShadowRoot final : public DocumentFragment, nsresult Bind(); private: + bool IsStaticUAWidget() const { return mIsStaticUAWidget; } + + void InsertSheetIntoAuthorData(size_t aIndex, StyleSheet&, const nsTArray>&); @@ -200,12 +203,24 @@ class ShadowRoot final : public DocumentFragment, bool IsUAWidget() const { return mIsUAWidget; } + // Whether we should clone this shadow root for printing. We usually don't + // clone UA widgets (because they're attached and setup on bind), but we need + // to clone "static" UA widgets, which don't. + bool ShouldStaticClone() const { + return !IsUAWidget() || IsStaticUAWidget(); + } + void SetIsUAWidget() { MOZ_ASSERT(!HasChildren()); SetFlags(NODE_HAS_BEEN_IN_UA_WIDGET); mIsUAWidget = true; } + void SetIsStaticUAWidget() { + MOZ_ASSERT(IsUAWidget()); + mIsStaticUAWidget = true; + } + void GetEventTargetParent(EventChainPreVisitor& aVisitor) override; // nsIRadioGroupContainer @@ -274,7 +289,10 @@ class ShadowRoot final : public DocumentFragment, // tree. nsTArray mParts; - bool mIsUAWidget; + bool mIsUAWidget : 1; + // Whether this shadow root is "static" and should be cloned for static + // documents. + bool mIsStaticUAWidget : 1; nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override; }; diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp index e89d0f7c7dd6..f5e2e0641a5f 100644 --- a/dom/base/nsINode.cpp +++ b/dom/base/nsINode.cpp @@ -3305,7 +3305,7 @@ already_AddRefed nsINode::CloneAndAdopt( // Clone the Shadow DOM ShadowRoot* originalShadowRoot = aNode->AsElement()->GetShadowRoot(); - if (originalShadowRoot && !originalShadowRoot->IsUAWidget()) { + if (originalShadowRoot && originalShadowRoot->ShouldStaticClone()) { RefPtr newShadowRoot = clone->AsElement()->AttachShadowWithoutNameChecks( originalShadowRoot->Mode()); diff --git a/dom/xml/nsXMLPrettyPrinter.cpp b/dom/xml/nsXMLPrettyPrinter.cpp index c8c941feebf0..17ecd3102cdd 100644 --- a/dom/xml/nsXMLPrettyPrinter.cpp +++ b/dom/xml/nsXMLPrettyPrinter.cpp @@ -89,6 +89,7 @@ nsresult nsXMLPrettyPrinter::PrettyPrint(Document* aDocument, RefPtr shadowRoot = rootElement->GetShadowRoot(); MOZ_RELEASE_ASSERT(shadowRoot && shadowRoot->IsUAWidget(), "There should be a UA Shadow Root here."); + shadowRoot->SetIsStaticUAWidget(); // Append the document fragment to the shadow dom. shadowRoot->AppendChild(*resultFragment, err); diff --git a/layout/base/tests/chrome/chrome.ini b/layout/base/tests/chrome/chrome.ini index ab41d4608825..ef676ce26a12 100644 --- a/layout/base/tests/chrome/chrome.ini +++ b/layout/base/tests/chrome/chrome.ini @@ -27,6 +27,8 @@ support-files = printpreview_images_sw.html printpreview_images_sw_ref.html printpreview_images_sw.js + printpreview_prettyprint.xml + printpreview_prettyprint_ref.xhtml color_adjust.html color_adjust_ref.html test_document_adopted_styles.html diff --git a/layout/base/tests/chrome/printpreview_helper.xhtml b/layout/base/tests/chrome/printpreview_helper.xhtml index 2f44c1bbde85..438edb56544a 100644 --- a/layout/base/tests/chrome/printpreview_helper.xhtml +++ b/layout/base/tests/chrome/printpreview_helper.xhtml @@ -636,6 +636,11 @@ async function runTest22() { exitprintpreview(); } + requestAnimationFrame(() => setTimeout(runTest23)); +} + +async function runTest23() { + await compareFiles("printpreview_prettyprint.xml", "printpreview_prettyprint_ref.xhtml"); finish(); } diff --git a/layout/base/tests/chrome/printpreview_prettyprint.xml b/layout/base/tests/chrome/printpreview_prettyprint.xml new file mode 100644 index 000000000000..759d5066cf0f --- /dev/null +++ b/layout/base/tests/chrome/printpreview_prettyprint.xml @@ -0,0 +1 @@ +Here be sea hags diff --git a/layout/base/tests/chrome/printpreview_prettyprint_ref.xhtml b/layout/base/tests/chrome/printpreview_prettyprint_ref.xhtml new file mode 100644 index 000000000000..7309425fb4b8 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_prettyprint_ref.xhtml @@ -0,0 +1,3 @@ +
<out>Here be sea hags</out>