Bug 1470242 - Automatically upgrade Custom Elements inside of XBL anon content before the XBL constructor runs
MozReview-Commit-ID: 7bgOVEik1gJ
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -25,16 +25,18 @@
#include "nsIXMLContentSink.h"
#include "nsContentCID.h"
#include "mozilla/dom/XMLDocument.h"
#include "jsapi.h"
#include "nsXBLService.h"
#include "nsIXPConnect.h"
#include "nsIScriptContext.h"
#include "nsCRT.h"
+#include "mozilla/dom/CustomElementRegistry.h"
+#include "mozilla/dom/DocGroup.h"
// Event listeners
#include "mozilla/EventListenerManager.h"
#include "nsIDOMEventListener.h"
#include "nsAttrName.h"
#include "nsGkAtoms.h"
@@ -622,16 +624,40 @@ nsXBLBinding::AttributeChanged(nsAtom* a
mPrototypeBinding->AttributeChanged(aAttribute, aNameSpaceID, aRemoveFlag,
mBoundElement, mContent, aNotify);
}
}
void
nsXBLBinding::ExecuteAttachedHandler()
{
+ // Trigger custom element constructions in the XBL anonymous content
+ // before calling into XBL binding constructors.
+ // Only trigger it exactly once from the base binding when scripts is allowed,
+ // so this is run before all the constructors.
+ nsIDocument *document = mBoundElement->OwnerDoc();
+ nsPIDOMWindowInner* window = document->GetInnerWindow();
+ if (window && !mNextBinding && AllowScripts()) {
+ {
+ nsAutoMicroTask mt;
+ }
+ dom::AutoCEReaction autoCEReaction(
+ document->GetDocGroup()->CustomElementReactionsStack(), nullptr);
+
+ nsINodeList* anonymousChildren =
+ document->BindingManager()->GetAnonymousNodesFor(mBoundElement);
+ if (anonymousChildren) {
+ uint32_t length = anonymousChildren->Length();
+ for (uint32_t i = 0; i < length; ++i) {
+ nsINode* node = anonymousChildren->Item(i);
+ window->CustomElements()->Upgrade(*node);
+ }
+ }
+ }
+
if (mNextBinding)
mNextBinding->ExecuteAttachedHandler();
if (AllowScripts())
mPrototypeBinding->BindingAttached(mBoundElement);
}
void
--- a/dom/xbl/test/chrome.ini
+++ b/dom/xbl/test/chrome.ini
@@ -8,9 +8,10 @@ support-files =
skip-if = (verify && debug && (os == 'linux' || os == 'mac'))
[test_bug398135.xul]
[test_bug398492.xul]
[test_bug721452.xul]
[test_bug723676.xul]
[test_bug772966.xul]
[test_bug944407.xul]
[test_bug950909.xul]
+[test_bug1470242.xul]
[test_fieldScopeChain.html]
new file mode 100644
--- /dev/null
+++ b/dom/xbl/test/test_bug1470242.xul
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1470242
+-->
+<window title="Mozilla Bug 1470242"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ onload="runTest()">
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+ <!-- test results are displayed in the html:body -->
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1470242"
+ target="_blank">Mozilla Bug 1470242</a>
+ </body>
+
+ <script>
+ window.customElements.define("content-element", class extends XULElement {
+ constructor() {
+ super();
+ this.prop1 = true;
+ }
+ get prop2() {
+ return true;
+ }
+ });
+ function runTest() {
+ ok(window.run, "XBL constructor should run.");
+ }
+ </script>
+
+ <box id="b" style="-moz-binding: url(#binding)"/>
+
+ <xbl:bindings xmlns:xbl="http://www.mozilla.org/xbl">
+ <xbl:binding id="binding">
+ <xbl:content>
+ <content-element />
+ </xbl:content>
+ <xbl:implementation>
+ <xbl:constructor><![CDATA[
+ let el = document.getAnonymousNodes(this).item(0);
+ ok(el.prop1, "Custom element constructor runs");
+ ok(el.prop2, "Custom element property exists");
+ window.run = true;
+ ]]></xbl:constructor>
+ </xbl:implementation>
+ </xbl:binding>
+ </xbl:bindings>
+
+</window>