Bug 1319255 part 3. Don't create special elements for <shadow> and <content> unless webcomponents are enabled. r=wchen
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 22 Nov 2016 22:41:51 -0500
changeset 323876 03acde1081c3280af1c70ef6d7f57243b720ce87
parent 323875 93d4161c74bf02acb1273e221b7373825db2eeea
child 323877 926f21451281f50f9172366b534a684ab85f64eb
push id30985
push usercbook@mozilla.com
push dateWed, 23 Nov 2016 15:39:29 +0000
treeherdermozilla-central@47f42f21541b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswchen
bugs1319255
milestone53.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 1319255 part 3. Don't create special elements for <shadow> and <content> unless webcomponents are enabled. r=wchen
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/html/HTMLContentElement.cpp
dom/html/HTMLShadowElement.cpp
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -5726,25 +5726,46 @@ nsDocument::IsWebComponentsEnabled(JSCon
   }
 
   // Check for the webcomponents permission. See Bug 1181555.
   JSAutoCompartment ac(aCx, obj);
   JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, obj));
   nsCOMPtr<nsPIDOMWindowInner> window =
     do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(global));
 
-  if (window) {
+  return IsWebComponentsEnabled(window);
+}
+
+bool
+nsDocument::IsWebComponentsEnabled(dom::NodeInfo* aNodeInfo)
+{
+  if (Preferences::GetBool("dom.webcomponents.enabled")) {
+    return true;
+  }
+
+  nsIDocument* doc = aNodeInfo->GetDocument();
+  // Use GetScopeObject() here so that data documents work the same way as the
+  // main document they're associated with.
+  nsCOMPtr<nsPIDOMWindowInner> window =
+    do_QueryInterface(doc->GetScopeObject());
+  return IsWebComponentsEnabled(window);
+}
+
+bool
+nsDocument::IsWebComponentsEnabled(nsPIDOMWindowInner* aWindow)
+{
+  if (aWindow) {
     nsresult rv;
     nsCOMPtr<nsIPermissionManager> permMgr =
       do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, false);
 
     uint32_t perm;
     rv = permMgr->TestPermissionFromWindow(
-      window, "moz-extremely-unstable-and-will-change-webcomponents", &perm);
+      aWindow, "moz-extremely-unstable-and-will-change-webcomponents", &perm);
     NS_ENSURE_SUCCESS(rv, false);
 
     return perm == nsIPermissionManager::ALLOW_ACTION;
   }
 
   return false;
 }
 
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -1377,17 +1377,23 @@ private:
     const nsAString& aLocalName,
     uint32_t aNamespaceID,
     ErrorResult& rv);
 
 public:
   virtual already_AddRefed<mozilla::dom::CustomElementRegistry>
     GetCustomElementRegistry() override;
 
+  // Check whether web components are enabled for the global of aObject.
   static bool IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject);
+  // Check whether web components are enabled for the global of the document
+  // this nodeinfo comes from.
+  static bool IsWebComponentsEnabled(mozilla::dom::NodeInfo* aNodeInfo);
+  // Check whether web components are enabled for the given window.
+  static bool IsWebComponentsEnabled(nsPIDOMWindowInner* aWindow);
 
   RefPtr<mozilla::EventListenerManager> mListenerManager;
   RefPtr<mozilla::dom::StyleSheetList> mDOMStyleSheets;
   RefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
   RefPtr<nsScriptLoader> mScriptLoader;
   nsDocHeaderData* mHeaderData;
   /* mIdentifierMap works as follows for IDs:
    * 1) Attribute changes affect the table immediately (removing and adding
--- a/dom/html/HTMLContentElement.cpp
+++ b/dom/html/HTMLContentElement.cpp
@@ -1,29 +1,50 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLContentElement.h"
 #include "mozilla/dom/HTMLContentElementBinding.h"
+#include "mozilla/dom/HTMLUnknownElement.h"
 #include "mozilla/dom/NodeListBinding.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/css/StyleRule.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsIAtom.h"
 #include "nsCSSRuleProcessor.h"
 #include "nsRuleData.h"
 #include "nsRuleProcessorData.h"
 #include "nsRuleWalker.h"
 #include "nsCSSParser.h"
+#include "nsDocument.h"
 
-NS_IMPL_NS_NEW_HTML_ELEMENT(Content)
+// Expand NS_IMPL_NS_NEW_HTML_ELEMENT(Content) to add check for web components
+// being enabled.
+nsGenericHTMLElement*
+NS_NewHTMLContentElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
+                         mozilla::dom::FromParser aFromParser)
+{
+  // When this check is removed, remove the nsDocument.h and
+  // HTMLUnknownElement.h includes.  Also remove nsINode::IsHTMLContentElement.
+  //
+  // We have to jump through some hoops to be able to produce both NodeInfo* and
+  // already_AddRefed<NodeInfo>& for our callees.
+  RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo);
+  if (!nsDocument::IsWebComponentsEnabled(nodeInfo)) {
+    already_AddRefed<mozilla::dom::NodeInfo> nodeInfoArg(nodeInfo.forget());
+    return new mozilla::dom::HTMLUnknownElement(nodeInfoArg);
+  }
+
+  already_AddRefed<mozilla::dom::NodeInfo> nodeInfoArg(nodeInfo.forget());
+  return new mozilla::dom::HTMLContentElement(nodeInfoArg);
+}
 
 using namespace mozilla::dom;
 
 HTMLContentElement::HTMLContentElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo), mValidSelector(true), mIsInsertionPoint(false)
 {
 }
 
--- a/dom/html/HTMLShadowElement.cpp
+++ b/dom/html/HTMLShadowElement.cpp
@@ -3,20 +3,41 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/ShadowRoot.h"
 
 #include "ChildIterator.h"
 #include "nsContentUtils.h"
+#include "nsDocument.h"
 #include "mozilla/dom/HTMLShadowElement.h"
+#include "mozilla/dom/HTMLUnknownElement.h"
 #include "mozilla/dom/HTMLShadowElementBinding.h"
 
-NS_IMPL_NS_NEW_HTML_ELEMENT(Shadow)
+// Expand NS_IMPL_NS_NEW_HTML_ELEMENT(Shadow) to add check for web components
+// being enabled.
+nsGenericHTMLElement*
+NS_NewHTMLShadowElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
+                        mozilla::dom::FromParser aFromParser)
+{
+  // When this check is removed, remove the nsDocument.h and
+  // HTMLUnknownElement.h includes.  Also remove nsINode::IsHTMLShadowElement.
+  //
+  // We have to jump through some hoops to be able to produce both NodeInfo* and
+  // already_AddRefed<NodeInfo>& for our callees.
+  RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo);
+  if (!nsDocument::IsWebComponentsEnabled(nodeInfo)) {
+    already_AddRefed<mozilla::dom::NodeInfo> nodeInfoArg(nodeInfo.forget());
+    return new mozilla::dom::HTMLUnknownElement(nodeInfoArg);
+  }
+
+  already_AddRefed<mozilla::dom::NodeInfo> nodeInfoArg(nodeInfo.forget());
+  return new mozilla::dom::HTMLShadowElement(nodeInfoArg);
+}
 
 using namespace mozilla::dom;
 
 HTMLShadowElement::HTMLShadowElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo), mIsInsertionPoint(false)
 {
 }