Bug 1480195: Allow writing custom element definitions for the special XUL elements. r=smaug
authorDave Townsend <dtownsend@oxymoronical.com>
Thu, 02 Aug 2018 14:49:04 +0000
changeset 826086 ebd853eb196e0fe92e03875be88c8c5a14c2ed08
parent 826085 ee957e55c91e5a68849eef53e9a4bfacdf9d1a12
child 826087 6c78bc9cc725971b805ce09ae1d144ff64688a3e
push id118238
push userbmo:mh+mozilla@glandium.org
push dateThu, 02 Aug 2018 22:02:22 +0000
reviewerssmaug
bugs1480195
milestone63.0a1
Bug 1480195: Allow writing custom element definitions for the special XUL elements. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D2430
dom/bindings/BindingUtils.cpp
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -3810,70 +3810,66 @@ HTMLConstructor(JSContext* aCx, unsigned
   // determination of what sort of element we're planning to construct.
   // Technically, this should happen (implicitly) in step 8, but this
   // determination is side-effect-free, so it's OK.
   int32_t ns = doc->GetDefaultNamespaceID();
   if (ns != kNameSpaceID_XUL) {
     ns = kNameSpaceID_XHTML;
   }
 
+  constructorGetterCallback cb = nullptr;
+  if (ns == kNameSpaceID_XUL) {
+    if (definition->mLocalName == nsGkAtoms::menupopup ||
+        definition->mLocalName == nsGkAtoms::popup ||
+        definition->mLocalName == nsGkAtoms::panel ||
+        definition->mLocalName == nsGkAtoms::tooltip) {
+      cb = XULPopupElement_Binding::GetConstructorObject;
+    } else if (definition->mLocalName == nsGkAtoms::iframe ||
+                definition->mLocalName == nsGkAtoms::browser ||
+                definition->mLocalName == nsGkAtoms::editor) {
+      cb = XULFrameElement_Binding::GetConstructorObject;
+    } else if (definition->mLocalName == nsGkAtoms::scrollbox) {
+      cb = XULScrollElement_Binding::GetConstructorObject;
+    } else {
+      cb = XULElement_Binding::GetConstructorObject;
+    }
+  }
+
   int32_t tag = eHTMLTag_userdefined;
   if (!definition->IsCustomBuiltIn()) {
     // Step 4.
     // If the definition is for an autonomous custom element, the active
-    // function should be HTMLElement or XULElement.  We want to get the actual
-    // functions to compare to from our global's realm, not the caller
-    // realm.
+    // function should be HTMLElement or extend from XULElement.
+    if (!cb) {
+      cb = HTMLElement_Binding::GetConstructorObject;
+    }
+
+    // We want to get the constructor from our global's realm, not the
+    // caller realm.
     JSAutoRealmAllowCCW ar(aCx, global.Get());
-
-    JS::Rooted<JSObject*> constructor(aCx);
-    if (ns == kNameSpaceID_XUL) {
-      constructor = XULElement_Binding::GetConstructorObject(aCx);
-    } else {
-      constructor = HTMLElement_Binding::GetConstructorObject(aCx);
-    }
-
-    if (!constructor) {
-      return false;
-    }
+    JS::Rooted<JSObject*> constructor(aCx, cb(aCx));
 
     if (constructor != js::CheckedUnwrap(callee)) {
       return ThrowErrorMessage(aCx, MSG_ILLEGAL_CONSTRUCTOR);
     }
   } else {
-    constructorGetterCallback cb;
     if (ns == kNameSpaceID_XHTML) {
       // Step 5.
       // If the definition is for a customized built-in element, the localName
       // should be one of the ones defined in the specification for this interface.
       tag = nsHTMLTags::CaseSensitiveAtomTagToId(definition->mLocalName);
       if (tag == eHTMLTag_userdefined) {
         return ThrowErrorMessage(aCx, MSG_ILLEGAL_CONSTRUCTOR);
       }
 
       MOZ_ASSERT(tag <= NS_HTML_TAG_MAX, "tag is out of bounds");
 
       // If the definition is for a customized built-in element, the active
       // function should be the localname's element interface.
       cb = sConstructorGetterCallback[tag];
-    } else { // kNameSpaceID_XUL
-      if (definition->mLocalName == nsGkAtoms::menupopup ||
-          definition->mLocalName == nsGkAtoms::popup ||
-          definition->mLocalName == nsGkAtoms::panel ||
-          definition->mLocalName == nsGkAtoms::tooltip) {
-        cb = XULPopupElement_Binding::GetConstructorObject;
-      } else if (definition->mLocalName == nsGkAtoms::iframe ||
-                 definition->mLocalName == nsGkAtoms::browser ||
-                 definition->mLocalName == nsGkAtoms::editor) {
-        cb = XULFrameElement_Binding::GetConstructorObject;
-      } else if (definition->mLocalName == nsGkAtoms::scrollbox) {
-          cb = XULScrollElement_Binding::GetConstructorObject;
-      } else {
-        cb = XULElement_Binding::GetConstructorObject;
-      }
     }
 
     if (!cb) {
       return ThrowErrorMessage(aCx, MSG_ILLEGAL_CONSTRUCTOR);
     }
 
     // We want to get the constructor from our global's realm, not the
     // caller realm.