Bug 1411707 - Notify document-element-inserted in XUL documents;r=bz draft
authorBrian Grinstead <bgrinstead@mozilla.com>
Thu, 19 Apr 2018 21:08:49 -0700
changeset 785421 9fa0ddcde999181e365131686145dadccede87fb
parent 783746 5ded36cb383d3ccafd9b6c231c5120dcdae196a2
child 785422 a8f30da7e16818489669b2a02e727f87b7eff011
push id107226
push userbgrinstead@mozilla.com
push dateFri, 20 Apr 2018 04:09:18 +0000
reviewersbz
bugs1411707
milestone61.0a1
Bug 1411707 - Notify document-element-inserted in XUL documents;r=bz We'll want to use this event to inject scripts before other scripts run in XUL documents. It already fires in HTML documents. MozReview-Commit-ID: 7FW0R8r9o9G
dom/base/test/chrome/chrome.ini
dom/base/test/chrome/file_document-element-inserted-inner.xul
dom/base/test/chrome/file_document-element-inserted.xul
dom/base/test/chrome/test_document-element-inserted.xul
dom/xul/XULDocument.cpp
--- a/dom/base/test/chrome/chrome.ini
+++ b/dom/base/test/chrome/chrome.ini
@@ -60,16 +60,20 @@ support-files = ../file_bug357450.js
 [test_bug1063837.xul]
 [test_bug1139964.xul]
 [test_bug1209621.xul]
 [test_bug1346936.html]
 [test_cpows.xul]
 [test_getElementsWithGrid.html]
 [test_custom_element_content.xul]
 [test_custom_element_ep.xul]
+[test_document-element-inserted.xul]
+support-files =
+  file_document-element-inserted.xul
+  file_document-element-inserted-inner.xul
 [test_domparsing.xul]
 [test_fileconstructor.xul]
 [test_nsITextInputProcessor.xul]
 [test_node_localize.xul]
 [test_permission_isHandlingUserInput.xul]
 support-files = ../dummy.html
 [test_range_getClientRectsAndTexts.html]
 [test_title.xul]
new file mode 100644
--- /dev/null
+++ b/dom/base/test/chrome/file_document-element-inserted-inner.xul
@@ -0,0 +1,1 @@
+<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'></window>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/base/test/chrome/file_document-element-inserted.xul
@@ -0,0 +1,3 @@
+<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'>
+  <iframe src='file_document-element-inserted-inner.xul'></iframe>
+</window>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/base/test/chrome/test_document-element-inserted.xul
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1411707
+-->
+<window title="Mozilla Bug 1411707"
+  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <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=1411707"
+     target="_blank">Mozilla Bug 1411707</a>
+  </body>
+
+  <!-- test code goes here -->
+  <script type="application/javascript"><![CDATA[
+    SimpleTest.waitForExplicitFinish();
+
+    const OUTER_URL = "chrome://mochitests/content/chrome/dom/base/test/chrome/file_document-element-inserted.xul";
+    const INNER_URL = "chrome://mochitests/content/chrome/dom/base/test/chrome/file_document-element-inserted-inner.xul";
+
+    async function waitForEvent(url) {
+      return new Promise(resolve => {
+        SpecialPowers.addObserver(function inserted(document) {
+          is(document.documentURI, url, "Correct URL");
+          is(document.readyState, "uninitialized", "Correct readyState");
+          SpecialPowers.removeObserver(inserted, "document-element-inserted");
+          resolve();
+        }, "document-element-inserted");
+      })
+    }
+
+    // Load a XUL document that also has an iframe to a subdocument, and
+    // expect both events to fire with the docs in the correct state.
+    async function testEvents() {
+      info(`Waiting for events after loading ${OUTER_URL}`);
+      let win = window.openDialog(OUTER_URL, null, "chrome,dialog=no,all");
+      await waitForEvent(OUTER_URL);
+      await waitForEvent(INNER_URL);
+      win.close();
+    }
+
+    (async function() {
+      // Test the same document twice to make to make sure we are
+      // firing properly when loading the protype document.
+      await testEvents();
+      await testEvents();
+      SimpleTest.finish();
+    })();
+  ]]></script>
+</window>
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -2020,16 +2020,18 @@ XULDocument::PrepareToWalk()
         if (NS_FAILED(rv)) return rv;
 
         rv = AppendChildTo(root, false);
         if (NS_FAILED(rv)) return rv;
 
         // Block onload until we've finished building the complete
         // document content model.
         BlockOnload();
+
+        nsContentSink::NotifyDocElementCreated(this);
     }
 
     // There'd better not be anything on the context stack at this
     // point! This is the basis case for our "induction" in
     // ResumeWalk(), below, which'll assume that there's always a
     // content element on the context stack if either 1) we're in the
     // "master" document, or 2) we're in an overlay, and we've got
     // more than one prototype element (the single, root "overlay"