Bug 1404420: Always enable custom elements in chrome. r?edgar draft
authorDave Townsend <dtownsend@oxymoronical.com>
Fri, 20 Oct 2017 11:02:33 -0700
changeset 699872 1a47f4e09b667953cc65a8752853ec026410857c
parent 699871 08300a82bf3b92aaa185f5dc81b671d84e8f4d5e
child 740753 1da727e677206d75d233a612840eba45cd914f5c
push id89707
push userdtownsend@mozilla.com
push dateFri, 17 Nov 2017 20:49:13 +0000
reviewersedgar
bugs1404420
milestone59.0a1
Bug 1404420: Always enable custom elements in chrome. r?edgar MozReview-Commit-ID: CMiLzmp60jA
dom/base/CustomElementRegistry.cpp
dom/base/CustomElementRegistry.h
dom/base/Element.cpp
dom/base/nsContentUtils.cpp
dom/base/nsDocument.cpp
dom/base/nsNodeUtils.cpp
dom/bindings/Codegen.py
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/CycleCollectedJSContext.h"
 #include "mozilla/dom/CustomElementRegistryBinding.h"
 #include "mozilla/dom/HTMLElementBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/WebComponentsBinding.h"
 #include "mozilla/dom/DocGroup.h"
 #include "nsHTMLTags.h"
 #include "jsapi.h"
+#include "nsGlobalWindow.h"
 
 namespace mozilla {
 namespace dom {
 
 void
 CustomElementCallback::Call()
 {
   IgnoredErrorResult rv;
@@ -268,16 +269,38 @@ CustomElementRegistry::CustomElementRegi
   mozilla::HoldJSObjects(this);
 }
 
 CustomElementRegistry::~CustomElementRegistry()
 {
   mozilla::DropJSObjects(this);
 }
 
+bool
+CustomElementRegistry::IsCustomElementEnabled(JSContext* aCx, JSObject* aObject)
+{
+  nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(aObject);
+  if (principal && nsContentUtils::AllowXULXBLForPrincipal(principal)) {
+    return true;
+  }
+
+  return nsContentUtils::IsCustomElementsEnabled();
+}
+
+bool
+CustomElementRegistry::IsCustomElementEnabled(nsIDocument* aDoc)
+{
+  nsIPrincipal* principal = aDoc->NodePrincipal();
+  if (principal && nsContentUtils::AllowXULXBLForPrincipal(principal)) {
+    return true;
+  }
+
+  return nsContentUtils::IsCustomElementsEnabled();
+}
+
 CustomElementDefinition*
 CustomElementRegistry::LookupCustomElementDefinition(const nsAString& aLocalName,
                                                      nsAtom* aTypeAtom) const
 {
   RefPtr<nsAtom> localNameAtom = NS_Atomize(aLocalName);
   CustomElementDefinition* data = mCustomDefinitions.GetWeak(aTypeAtom);
   if (data && data->mLocalName == localNameAtom) {
     return data;
--- a/dom/base/CustomElementRegistry.h
+++ b/dom/base/CustomElementRegistry.h
@@ -353,21 +353,18 @@ class CustomElementRegistry final : publ
   // Allow nsDocument to access mCustomDefinitions and mCandidatesMap.
   friend class ::nsDocument;
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CustomElementRegistry)
 
 public:
-  static bool IsCustomElementEnabled(JSContext* aCx = nullptr,
-                                     JSObject* aObject = nullptr)
-  {
-    return nsContentUtils::IsCustomElementsEnabled();
-  }
+  static bool IsCustomElementEnabled(JSContext* aCx, JSObject* aObject);
+  static bool IsCustomElementEnabled(nsIDocument* aDoc);
 
   explicit CustomElementRegistry(nsPIDOMWindowInner* aWindow);
 
   /**
    * Looking up a custom element definition.
    * https://html.spec.whatwg.org/#look-up-a-custom-element-definition
    */
   CustomElementDefinition* LookupCustomElementDefinition(
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -1750,17 +1750,17 @@ Element::BindToTree(nsIDocument* aDocume
     UnsetFlags(NODE_FORCE_XBL_BINDINGS | NODE_NEEDS_FRAME |
                NODE_DESCENDANTS_NEED_FRAMES | ELEMENT_ALL_RESTYLE_FLAGS);
   } else {
     // If we're not in the doc and not in a shadow tree,
     // update our subtree pointer.
     SetSubtreeRootPointer(aParent->SubtreeRoot());
   }
 
-  if (CustomElementRegistry::IsCustomElementEnabled() && IsInComposedDoc()) {
+  if (CustomElementRegistry::IsCustomElementEnabled(OwnerDoc()) && IsInComposedDoc()) {
     // Connected callback must be enqueued whenever a custom element becomes
     // connected.
     CustomElementData* data = GetCustomElementData();
     if (data) {
       if (data->mState == CustomElementData::State::eCustom) {
         nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eConnected, this);
       } else {
         // Step 7.7.2.2 https://dom.spec.whatwg.org/#concept-node-insert
@@ -2086,17 +2086,17 @@ Element::UnbindFromTree(bool aDeep, bool
           /* aNullParent */ false);
       }
     }
 
     document->ClearBoxObjectFor(this);
 
      // Disconnected must be enqueued whenever a connected custom element becomes
      // disconnected.
-    if (CustomElementRegistry::IsCustomElementEnabled()) {
+    if (CustomElementRegistry::IsCustomElementEnabled(OwnerDoc())) {
       CustomElementData* data  = GetCustomElementData();
       if (data) {
         if (data->mState == CustomElementData::State::eCustom) {
           nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eDisconnected,
                                                    this);
         } else {
           // Remove an unresolved custom element that is a candidate for
           // upgrade when a custom element is disconnected.
@@ -2774,17 +2774,17 @@ Element::SetAttrAndNotify(int32_t aNames
 
   if (aComposedDocument || HasFlag(NODE_FORCE_XBL_BINDINGS)) {
     RefPtr<nsXBLBinding> binding = GetXBLBinding();
     if (binding) {
       binding->AttributeChanged(aName, aNamespaceID, false, aNotify);
     }
   }
 
-  if (CustomElementRegistry::IsCustomElementEnabled()) {
+  if (CustomElementRegistry::IsCustomElementEnabled(OwnerDoc())) {
     if (CustomElementData* data = GetCustomElementData()) {
       if (CustomElementDefinition* definition =
             nsContentUtils::GetElementDefinitionIfObservingAttr(this,
                                                                 data->GetCustomElementType(),
                                                                 aName)) {
         MOZ_ASSERT(data->mState == CustomElementData::State::eCustom,
                    "AttributeChanged callback should fire only if "
                    "custom element state is custom");
@@ -3081,17 +3081,17 @@ Element::UnsetAttr(int32_t aNameSpaceID,
 
   if (document || HasFlag(NODE_FORCE_XBL_BINDINGS)) {
     RefPtr<nsXBLBinding> binding = GetXBLBinding();
     if (binding) {
       binding->AttributeChanged(aName, aNameSpaceID, true, aNotify);
     }
   }
 
-  if (CustomElementRegistry::IsCustomElementEnabled()) {
+  if (CustomElementRegistry::IsCustomElementEnabled(OwnerDoc())) {
     if (CustomElementData* data = GetCustomElementData()) {
       if (CustomElementDefinition* definition =
             nsContentUtils::GetElementDefinitionIfObservingAttr(this,
                                                                 data->GetCustomElementType(),
                                                                 aName)) {
         MOZ_ASSERT(data->mState == CustomElementData::State::eCustom,
                    "AttributeChanged callback should fire only if "
                    "custom element state is custom");
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -10197,17 +10197,17 @@ nsContentUtils::NewXULOrHTMLElement(Elem
 
   nsIDocument* doc = nodeInfo->GetDocument();
 
   // https://dom.spec.whatwg.org/#concept-create-element
   // We only handle the "synchronous custom elements flag is set" now.
   // For the unset case (e.g. cloning a node), see bug 1319342 for that.
   // Step 4.
   CustomElementDefinition* definition = aDefinition;
-  if (!definition && CustomElementRegistry::IsCustomElementEnabled()) {
+  if (!definition && CustomElementRegistry::IsCustomElementEnabled(doc)) {
     definition =
       nsContentUtils::LookupCustomElementDefinition(doc,
                                                     nodeInfo->LocalName(),
                                                     nodeInfo->NamespaceID(),
                                                     typeAtom);
   }
 
   // It might be a problem that parser synchronously calls constructor, so filed
@@ -10309,17 +10309,17 @@ nsContentUtils::NewXULOrHTMLElement(Elem
     isCustomElementName = nsContentUtils::IsCustomElementName(name);
     NS_IF_ADDREF(*aResult = new nsXULElement(nodeInfo.forget()));
   }
 
   if (!*aResult) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  if (CustomElementRegistry::IsCustomElementEnabled() &&
+  if (CustomElementRegistry::IsCustomElementEnabled(doc) &&
       (isCustomElementName || aIs)) {
     (*aResult)->SetCustomElementData(new CustomElementData(typeAtom));
   }
 
   return NS_OK;
 }
 
 /* static */ CustomElementDefinition*
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -6061,17 +6061,17 @@ nsDocument::CreateElement(const nsAStrin
   }
 
   const nsString* is = nullptr;
   CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo;
   if (aOptions.IsElementCreationOptions()) {
     const ElementCreationOptions& options =
       aOptions.GetAsElementCreationOptions();
 
-    if (CustomElementRegistry::IsCustomElementEnabled() &&
+    if (CustomElementRegistry::IsCustomElementEnabled(this) &&
         options.mIs.WasPassed()) {
       is = &options.mIs.Value();
     }
 
     // Check 'pseudo' and throw an exception if it's not one allowed
     // with CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC.
     if (options.mPseudo.WasPassed()) {
       pseudoType = GetPseudoElementType(options.mPseudo.Value(), rv);
@@ -6126,17 +6126,17 @@ nsDocument::CreateElementNS(const nsAStr
                                             mNodeInfoManager,
                                             nsIDOMNode::ELEMENT_NODE,
                                             getter_AddRefs(nodeInfo));
   if (rv.Failed()) {
     return nullptr;
   }
 
   const nsString* is = nullptr;
-  if (CustomElementRegistry::IsCustomElementEnabled() &&
+  if (CustomElementRegistry::IsCustomElementEnabled(this) &&
       aOptions.IsElementCreationOptions()) {
     const ElementCreationOptions& options = aOptions.GetAsElementCreationOptions();
     if (options.mIs.WasPassed()) {
       is = &options.mIs.Value();
     }
   }
 
   nsCOMPtr<Element> element;
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -458,17 +458,17 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
   nsCOMPtr<nsINode> clone;
   if (aClone) {
     nsresult rv = aNode->Clone(nodeInfo, getter_AddRefs(clone), aDeep);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       aError.Throw(rv);
       return nullptr;
     }
 
-    if (CustomElementRegistry::IsCustomElementEnabled() &&
+    if (CustomElementRegistry::IsCustomElementEnabled(nodeInfo->GetDocument()) &&
         clone->IsElement()) {
       // The cloned node may be a custom element that may require
       // enqueing upgrade reaction.
       Element* cloneElem = clone->AsElement();
       RefPtr<nsAtom> tagAtom = nodeInfo->NameAtom();
       CustomElementData* data = elem->GetCustomElementData();
 
       // Check if node may be custom element by type extension.
@@ -520,17 +520,17 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
 
     aNode->mNodeInfo.swap(newNodeInfo);
     if (elem) {
       elem->NodeInfoChanged(oldDoc);
     }
 
     nsIDocument* newDoc = aNode->OwnerDoc();
     if (newDoc) {
-      if (CustomElementRegistry::IsCustomElementEnabled()) {
+      if (CustomElementRegistry::IsCustomElementEnabled(newDoc)) {
         // Adopted callback must be enqueued whenever a node’s
         // shadow-including inclusive descendants that is custom.
         Element* element = aNode->IsElement() ? aNode->AsElement() : nullptr;
         if (element) {
           CustomElementData* data = element->GetCustomElementData();
           if (data && data->mState == CustomElementData::State::eCustom) {
             LifecycleAdoptedCallbackArgs args = {
               oldDoc,
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -7868,17 +7868,17 @@ class CGPerSignatureCall(CGThing):
                 CGIfWrapper(CGList(xraySteps),
                             "objIsXray"))
 
         if (idlNode.getExtendedAttribute('CEReactions') is not None and
             not getter):
             cgThings.append(CGGeneric(fill(
                 """
                 Maybe<AutoCEReaction> ceReaction;
-                if (CustomElementRegistry::IsCustomElementEnabled()) {
+                if (CustomElementRegistry::IsCustomElementEnabled(cx, ${obj})) {
                   CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(${obj});
                   if (reactionsStack) {
                     ceReaction.emplace(reactionsStack);
                   }
                 }
                 """, obj=objectName)))
 
         # If this is a method that was generated by a maplike/setlike