author | Brian Grinstead <bgrinstead@mozilla.com> |
Fri, 20 Apr 2018 13:55:51 -0700 | |
changeset 414728 | 427e3dce92c2eec8fa9a167fef3f2a726b4010a6 |
parent 414727 | 85d1752bed2ed20849993ae3669157cbd42a3ed8 |
child 414729 | 42f5c08a4d86967ccd3df66c3fc3c30cc52c6497 |
push id | 63011 |
push user | bgrinstead@mozilla.com |
push date | Fri, 20 Apr 2018 22:38:56 +0000 |
treeherder | autoland@427e3dce92c2 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bz |
bugs | 1455680 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/base/nsContentSink.cpp +++ b/dom/base/nsContentSink.cpp @@ -1640,16 +1640,18 @@ nsContentSink::WillBuildModelImpl() DoProcessLinkHeader(); } } /* static */ void nsContentSink::NotifyDocElementCreated(nsIDocument* aDoc) { + MOZ_ASSERT(nsContentUtils::IsSafeToRunScript()); + nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService(); if (observerService) { nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc); observerService-> NotifyObservers(domDoc, "document-element-inserted", EmptyString().get()); }
--- 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/xml/nsXMLContentSink.cpp +++ b/dom/xml/nsXMLContentSink.cpp @@ -14,16 +14,17 @@ #include "nsIDocShell.h" #include "nsIStyleSheetLinkingElement.h" #include "nsHTMLParts.h" #include "nsCRT.h" #include "mozilla/StyleSheetInlines.h" #include "mozilla/css/Loader.h" #include "nsGkAtoms.h" #include "nsContentUtils.h" +#include "nsDocElementCreatedNotificationRunner.h" #include "nsIScriptContext.h" #include "nsNameSpaceManager.h" #include "nsIServiceManager.h" #include "nsIScriptSecurityManager.h" #include "nsIContentViewer.h" #include "prtime.h" #include "mozilla/Logging.h" #include "nsRect.h" @@ -1045,17 +1046,18 @@ nsXMLContentSink::HandleStartElement(con } if (IsMonolithicContainer(nodeInfo)) { mInMonolithicContainer++; } if (!mXSLTProcessor) { if (content == mDocElement) { - NotifyDocElementCreated(mDocument); + nsContentUtils::AddScriptRunner( + new nsDocElementCreatedNotificationRunner(mDocument)); if (aInterruptable && NS_SUCCEEDED(result) && mParser && !mParser->IsParserEnabled()) { return NS_ERROR_HTMLPARSER_BLOCK; } } else if (!mCurrentHead) { // This isn't the root and we're not inside an XHTML <head>. // Might need to start layout MaybeStartLayout(false);
--- a/dom/xslt/xslt/txMozillaXMLOutput.cpp +++ b/dom/xslt/xslt/txMozillaXMLOutput.cpp @@ -27,16 +27,17 @@ #include "mozilla/StyleSheetInlines.h" #include "mozilla/css/Loader.h" #include "mozilla/dom/DocumentType.h" #include "mozilla/dom/DocumentFragment.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/ScriptLoader.h" #include "mozilla/Encoding.h" #include "nsContentUtils.h" +#include "nsDocElementCreatedNotificationRunner.h" #include "txXMLUtils.h" #include "nsContentSink.h" #include "nsINode.h" #include "nsContentCreatorFunctions.h" #include "nsError.h" #include "nsIFrame.h" #include <algorithm> #include "nsTextNode.h" @@ -573,17 +574,18 @@ txMozillaXMLOutput::closePrevious(bool a NS_ENSURE_SUCCESS(rv, rv); } rv = mCurrentNode->AppendChildTo(mOpenedElement, true); NS_ENSURE_SUCCESS(rv, rv); if (currentIsDoc) { mRootContentCreated = true; - nsContentSink::NotifyDocElementCreated(mDocument); + nsContentUtils::AddScriptRunner( + new nsDocElementCreatedNotificationRunner(mDocument)); } mCurrentNode = mOpenedElement; mOpenedElement = nullptr; } else if (aFlushText && !mText.IsEmpty()) { // Text can't appear in the root of a document if (mDocument == mCurrentNode) {
--- a/dom/xul/XULDocument.cpp +++ b/dom/xul/XULDocument.cpp @@ -35,16 +35,17 @@ #include "nsITimer.h" #include "nsDocShell.h" #include "nsGkAtoms.h" #include "nsXMLContentSink.h" #include "nsXULContentSink.h" #include "nsXULContentUtils.h" #include "nsIXULOverlayProvider.h" #include "nsIStringEnumerator.h" +#include "nsDocElementCreatedNotificationRunner.h" #include "nsNetUtil.h" #include "nsParserCIID.h" #include "nsPIBoxObject.h" #include "mozilla/dom/BoxObject.h" #include "nsString.h" #include "nsPIDOMWindow.h" #include "nsPIWindowRoot.h" #include "nsXULCommandDispatcher.h" @@ -2021,16 +2022,19 @@ 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(); + + nsContentUtils::AddScriptRunner( + new nsDocElementCreatedNotificationRunner(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"