Bug 1510406 - Use UA Widget in XML Pretty Print r=emilio
authorTimothy Guan-tin Chien <timdream@gmail.com>
Mon, 28 Jan 2019 18:38:57 +0000
changeset 455694 f3ef27bf8c9337c09cd594cd18dd452d3669e6e5
parent 455693 1d40794bc9cf93c0ed2ab5ed2a0cf8ce4f9f04b2
child 455695 df118467fa9ac78a416cf4d1dc551fd5997813fc
push id35457
push usercsabou@mozilla.com
push dateTue, 29 Jan 2019 09:20:40 +0000
treeherdermozilla-central@84104c5031c3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
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 1510406 - Use UA Widget in XML Pretty Print r=emilio Differential Revision: https://phabricator.services.mozilla.com/D13310
--- a/dom/xml/nsXMLPrettyPrinter.cpp
+++ b/dom/xml/nsXMLPrettyPrinter.cpp
@@ -74,19 +74,21 @@ nsresult nsXMLPrettyPrinter::PrettyPrint
   if (NS_WARN_IF(err.Failed())) {
     return err.StealNSResult();
   // Find the root element
   RefPtr<Element> rootElement = aDocument->GetRootElement();
-  // Attach a closed shadow root on it.
-  RefPtr<ShadowRoot> shadowRoot =
-      rootElement->AttachShadowWithoutNameChecks(ShadowRootMode::Closed);
+  // Attach an UA Widget Shadow Root on it.
+  rootElement->AttachAndSetUAShadowRoot();
+  RefPtr<ShadowRoot> shadowRoot = rootElement->GetShadowRoot();
+  MOZ_RELEASE_ASSERT(shadowRoot && shadowRoot->IsUAWidget(),
+                     "There should be a UA Shadow Root here.");
   // Append the document fragment to the shadow dom.
   shadowRoot->AppendChild(*resultFragment, err);
   if (NS_WARN_IF(err.Failed())) {
     return err.StealNSResult();
   // Observe the document so we know when to switch to "normal" view
--- a/toolkit/content/widgets/docs/ua_widget.rst
+++ b/toolkit/content/widgets/docs/ua_widget.rst
@@ -29,16 +29,18 @@ The specialization does not apply to the
 UA Widget Shadow Root
 The UA Widget Shadow Root is a closed shadow root, with the UA Widget flag turned on. As a closed shadow root, it may not be accessed by other scripts. It is attached on host element which the spec disallow a shadow root to be attached.
 The UA Widget flag enables the security feature covered in the next section.
+**Side note**: XML pretty print hides its transformed content inside a UA Widget Shadow DOM as well, even though there isn't any JavaScript to run. This is set in order to leverage the same security feature and behaviors there.
 The JavaScript sandbox
 The sandboxes created for UA Widgets are per-origin and set to the expanded principal. This allows the script to access other DOM APIs unavailable to the web content, while keeping its principal tied to the document origin. They are created as needed, backing the lifecycle of the UA Widgets as previously mentioned. These sandbox globals are not associated with any window object because they are shared across all same-origin documents. It is the job of the UA Widget script to hold and manage the references of the window and document objects the widget is being initiated on, by accessing them from the UA Widget Shadow Root instance passed.
 While the closed shadow root technically prevents content from accessing the contents, we want a stronger guarantee to protect against accidental leakage of references to the UA Widget shadow tree into content script. Access to the UA Widget DOM is restricted by having their reflectors set in the UA Widgets scope, as opposed to the normal scope. To accomplish this, we avoid having any script (UA Widget script included) getting a hold of the reference of any created DOM element before appending to the Shadow DOM. Once the element is in the Shadow DOM, the binding mechanism will put the reflector in the desired scope as it is being accessed.
 To avoid creating reflectors before DOM insertion, the available DOM interfaces is limited. For example, instead of ``createElement()`` and ``appendChild()``, the script would have to call ``createElementAndAppendChildAt()`` available on the UA Widget Shadow Root instance, to avoid receiving a reference to the DOM element and thus triggering the creation of its reflector in the wrong scope, before the element is properly associated with the UA Widget shadow tree. To find out the differences, search for ``Func="IsChromeOrXBLOrUAWidget"`` and ``Func="IsNotUAWidget"`` in in-tree WebIDL files.