Bug 1480195: Allow writing custom element definitions for the special XUL elements. r=smaug
Differential Revision:
https://phabricator.services.mozilla.com/D2430
--- 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.