Backed out changeset 367ca1e16853 (bug 1528146) on request by igoldan, assignee didn't replied back on time a=backout
authorCoroiu Cristina <ccoroiu@mozilla.com>
Fri, 22 Feb 2019 10:10:33 +0200
changeset 518306 98c743692a84
parent 518305 93c4470ee3af
child 518400 a1d118e856dd
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1528146
milestone67.0a1
backs out367ca1e16853
first release with
nightly linux32
98c743692a84 / 67.0a1 / 20190222081112 / files
nightly linux64
98c743692a84 / 67.0a1 / 20190222081112 / files
nightly mac
98c743692a84 / 67.0a1 / 20190222081112 / files
nightly win32
98c743692a84 / 67.0a1 / 20190222081112 / files
nightly win64
98c743692a84 / 67.0a1 / 20190222081112 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 367ca1e16853 (bug 1528146) on request by igoldan, assignee didn't replied back on time a=backout
devtools/server/actors/addon/webextension-inspected-window.js
dom/base/Document.cpp
dom/base/nsContentSink.cpp
dom/base/nsGlobalWindowInner.cpp
dom/base/nsGlobalWindowInner.h
dom/html/nsHTMLContentSink.cpp
toolkit/components/extensions/ExtensionPageChild.jsm
toolkit/components/extensions/ExtensionPolicyService.cpp
toolkit/components/extensions/ExtensionPolicyService.h
--- a/devtools/server/actors/addon/webextension-inspected-window.js
+++ b/devtools/server/actors/addon/webextension-inspected-window.js
@@ -133,17 +133,17 @@ CustomizedReload.prototype = {
         if (this.ignoreCache) {
           reloadFlags |= Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
         }
 
         try {
           if (this.injectedScript) {
             // Listen to the newly created document elements only if there is an
             // injectedScript to evaluate.
-            Services.obs.addObserver(this, "initial-document-element-inserted");
+            Services.obs.addObserver(this, "document-element-inserted");
           }
 
           // Watch the loading progress and clear the current CustomizedReload once the
           // page has been reloaded (or if its reloading has been interrupted).
           this.docShell.addProgressListener(this,
                                             Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
 
           this.webNavigation.reload(reloadFlags);
@@ -154,17 +154,17 @@ CustomizedReload.prototype = {
         }
       });
     }
 
     return this.waitForReloadCompleted;
   },
 
   observe(subject, topic, data) {
-    if (topic !== "initial-document-element-inserted") {
+    if (topic !== "document-element-inserted") {
       return;
     }
 
     const document = subject;
     const window = document && document.defaultView;
 
     // Filter out non interesting documents.
     if (!document || !document.location || !window) {
@@ -227,17 +227,17 @@ CustomizedReload.prototype = {
   stop(error) {
     if (this.stopped) {
       return;
     }
 
     this.docShell.removeProgressListener(this);
 
     if (this.injectedScript) {
-      Services.obs.removeObserver(this, "initial-document-element-inserted");
+      Services.obs.removeObserver(this, "document-element-inserted");
     }
 
     // Reset the customized user agent.
     if (this.userAgent && this.docShell.customUserAgent == this.userAgent) {
       this.docShell.customUserAgent = null;
     }
 
     if (error) {
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -9362,17 +9362,16 @@ class UnblockParsingPromiseHandler final
       : mPromise(aPromise) {
     nsCOMPtr<nsIParser> parser = aDocument->CreatorParserOrNull();
     if (parser &&
         (aOptions.mBlockScriptCreated || !parser->IsScriptCreated())) {
       parser->BlockParser();
       mParser = do_GetWeakReference(parser);
       mDocument = aDocument;
       mDocument->BlockOnload();
-      mDocument->BlockDOMContentLoaded();
     }
   }
 
   void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override {
     MaybeUnblockParser();
 
     mPromise->MaybeResolve(aCx, aValue);
   }
@@ -9396,26 +9395,18 @@ class UnblockParsingPromiseHandler final
   void MaybeUnblockParser() {
     nsCOMPtr<nsIParser> parser = do_QueryReferent(mParser);
     if (parser) {
       MOZ_DIAGNOSTIC_ASSERT(mDocument);
       nsCOMPtr<nsIParser> docParser = mDocument->CreatorParserOrNull();
       if (parser == docParser) {
         parser->UnblockParser();
         parser->ContinueInterruptedParsingAsync();
-      }
-    }
-    if (mDocument) {
-      // We blocked DOMContentLoaded and load events on this document.  Unblock
-      // them.  Note that we want to do that no matter what's going on with the
-      // parser state for this document.  Maybe someone caused it to stop being
-      // parsed, so CreatorParserOrNull() is returning null, but we still want
-      // to unblock these.
-      mDocument->UnblockDOMContentLoaded();
-      mDocument->UnblockOnload(false);
+        mDocument->UnblockOnload(false);
+      }
     }
     mParser = nullptr;
     mDocument = nullptr;
   }
 
   nsWeakPtr mParser;
   RefPtr<Promise> mPromise;
   RefPtr<Document> mDocument;
--- a/dom/base/nsContentSink.cpp
+++ b/dom/base/nsContentSink.cpp
@@ -24,17 +24,16 @@
 #include "nsIProtocolHandler.h"
 #include "nsIHttpChannel.h"
 #include "nsIContent.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsViewManager.h"
 #include "nsAtom.h"
 #include "nsGkAtoms.h"
-#include "nsGlobalWindowInner.h"
 #include "nsNetCID.h"
 #include "nsIOfflineCacheUpdate.h"
 #include "nsIApplicationCache.h"
 #include "nsIApplicationCacheContainer.h"
 #include "nsIApplicationCacheChannel.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsICookieService.h"
 #include "nsContentUtils.h"
@@ -1549,30 +1548,20 @@ void nsContentSink::WillBuildModelImpl()
 }
 
 /* static */
 void nsContentSink::NotifyDocElementCreated(Document* aDoc) {
   MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
 
   nsCOMPtr<nsIObserverService> observerService =
       mozilla::services::GetObserverService();
-  MOZ_ASSERT(observerService);
-
-  auto* win = nsGlobalWindowInner::Cast(aDoc->GetInnerWindow());
-  bool fireInitialInsertion = !win || !win->DidFireDocElemInserted();
-  if (win) {
-    win->SetDidFireDocElemInserted();
+  if (observerService) {
+    observerService->NotifyObservers(
+        ToSupports(aDoc), "document-element-inserted", EmptyString().get());
   }
-  if (fireInitialInsertion) {
-    observerService->NotifyObservers(ToSupports(aDoc),
-                                     "initial-document-element-inserted",
-                                     EmptyString().get());
-  }
-  observerService->NotifyObservers(
-      ToSupports(aDoc), "document-element-inserted", EmptyString().get());
 
   nsContentUtils::DispatchChromeEvent(
       aDoc, ToSupports(aDoc), NS_LITERAL_STRING("DOMDocElementInserted"),
       CanBubble::eYes, Cancelable::eNo);
 }
 
 NS_IMETHODIMP
 nsContentSink::GetName(nsACString& aName) {
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -851,17 +851,16 @@ nsGlobalWindowInner::nsGlobalWindowInner
       mNotifyIdleObserversIdleOnThaw(false),
       mNotifyIdleObserversActiveOnThaw(false),
       mIsChrome(false),
       mCleanMessageManager(false),
       mNeedsFocus(true),
       mHasFocus(false),
       mShowFocusRingForContent(false),
       mFocusByKeyOccurred(false),
-      mDidFireDocElemInserted(false),
       mHasGamepad(false),
       mHasVREvents(false),
       mHasVRDisplayActivateEvents(false),
       mHasSeenGamepadInput(false),
       mSuspendDepth(0),
       mFreezeDepth(0),
 #ifdef DEBUG
       mSerial(0),
--- a/dom/base/nsGlobalWindowInner.h
+++ b/dom/base/nsGlobalWindowInner.h
@@ -858,19 +858,16 @@ class nsGlobalWindowInner final : public
   void SetFullScreen(bool aFullscreen, mozilla::ErrorResult& aError);
   bool Find(const nsAString& aString, bool aCaseSensitive, bool aBackwards,
             bool aWrapAround, bool aWholeWord, bool aSearchInFrames,
             bool aShowDialog, mozilla::ErrorResult& aError);
   uint64_t GetMozPaintCount(mozilla::ErrorResult& aError);
 
   bool ShouldResistFingerprinting();
 
-  bool DidFireDocElemInserted() const { return mDidFireDocElemInserted; }
-  void SetDidFireDocElemInserted() { mDidFireDocElemInserted = true; }
-
   mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> OpenDialog(
       JSContext* aCx, const nsAString& aUrl, const nsAString& aName,
       const nsAString& aOptions,
       const mozilla::dom::Sequence<JS::Value>& aExtraArgument,
       mozilla::ErrorResult& aError);
   void UpdateCommands(const nsAString& anAction, mozilla::dom::Selection* aSel,
                       int16_t aReason);
 
@@ -1315,20 +1312,16 @@ class nsGlobalWindowInner final : public
   // when true, show focus rings for the current focused content only.
   // This will be reset when another element is focused
   bool mShowFocusRingForContent : 1;
 
   // true if tab navigation has occurred for this window. Focus rings
   // should be displayed.
   bool mFocusByKeyOccurred : 1;
 
-  // True if we have notified document-element-inserted observers for this
-  // document.
-  bool mDidFireDocElemInserted : 1;
-
   // Indicates whether this window wants gamepad input events
   bool mHasGamepad : 1;
 
   // Indicates whether this window wants VR events
   bool mHasVREvents : 1;
 
   // Indicates whether this window wants VRDisplayActivate events
   bool mHasVRDisplayActivateEvents : 1;
--- a/dom/html/nsHTMLContentSink.cpp
+++ b/dom/html/nsHTMLContentSink.cpp
@@ -36,17 +36,16 @@
 
 #include "nsGenericHTMLElement.h"
 
 #include "nsIScriptElement.h"
 
 #include "nsIComponentManager.h"
 #include "nsIServiceManager.h"
 
-#include "nsDocElementCreatedNotificationRunner.h"
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
 #include "nsIChannel.h"
 #include "nsIHttpChannel.h"
 #include "nsIDocShell.h"
 #include "mozilla/dom/Document.h"
 #include "nsStubDocumentObserver.h"
 #include "nsIHTMLDocument.h"
@@ -901,19 +900,16 @@ void HTMLContentSink::NotifyRootInsertio
   // tag.
   mNotifiedRootInsertion = true;
   NotifyInsert(nullptr, mRoot);
 
   // Now update the notification information in all our
   // contexts, since we just inserted the root and notified on
   // our whole tree
   UpdateChildCounts();
-
-  nsContentUtils::AddScriptRunner(
-      new nsDocElementCreatedNotificationRunner(mDocument));
 }
 
 void HTMLContentSink::UpdateChildCounts() {
   uint32_t numContexts = mContextStack.Length();
   for (uint32_t i = 0; i < numContexts; i++) {
     SinkContext* sc = mContextStack.ElementAt(i);
 
     sc->UpdateChildCounts();
--- a/toolkit/components/extensions/ExtensionPageChild.jsm
+++ b/toolkit/components/extensions/ExtensionPageChild.jsm
@@ -368,17 +368,17 @@ ExtensionPageChild = {
       let context = this.extensionContexts.get(windowId);
 
       global.sendAsyncMessage("Extension:ExtensionViewLoaded",
                               {childId: context && context.childManager.id});
     });
   },
 
   /**
-   * Create a privileged context at initial-document-element-inserted.
+   * Create a privileged context at document-element-inserted.
    *
    * @param {BrowserExtensionContent} extension
    *     The extension for which the context should be created.
    * @param {nsIDOMWindow} contentWindow The global of the page.
    */
   initExtensionContext(extension, contentWindow) {
     this._init();
 
--- a/toolkit/components/extensions/ExtensionPolicyService.cpp
+++ b/toolkit/components/extensions/ExtensionPolicyService.cpp
@@ -50,18 +50,16 @@ using dom::Promise;
   "'unsafe-eval' 'unsafe-inline'; "                               \
   "object-src 'self' https://* moz-extension: blob: filesystem:;"
 
 #define DEFAULT_DEFAULT_CSP "script-src 'self'; object-src 'self';"
 
 #define OBS_TOPIC_PRELOAD_SCRIPT "web-extension-preload-content-script"
 #define OBS_TOPIC_LOAD_SCRIPT "web-extension-load-content-script"
 
-static const char kDocElementInserted[] = "initial-document-element-inserted";
-
 static mozIExtensionProcessScript& ProcessScript() {
   static nsCOMPtr<mozIExtensionProcessScript> sProcessScript;
 
   if (MOZ_UNLIKELY(!sProcessScript)) {
     nsCOMPtr<mozIExtensionProcessScriptJSM> jsm =
         do_ImportModule("resource://gre/modules/ExtensionProcessScript.jsm");
     MOZ_RELEASE_ASSERT(jsm);
 
@@ -232,35 +230,42 @@ ExtensionPolicyService::CollectReports(n
   return NS_OK;
 }
 
 /*****************************************************************************
  * Content script management
  *****************************************************************************/
 
 void ExtensionPolicyService::RegisterObservers() {
-  mObs->AddObserver(this, kDocElementInserted, false);
+  mObs->AddObserver(this, "content-document-global-created", false);
+  mObs->AddObserver(this, "document-element-inserted", false);
   mObs->AddObserver(this, "tab-content-frameloader-created", false);
   if (XRE_IsContentProcess()) {
     mObs->AddObserver(this, "http-on-opening-request", false);
   }
 }
 
 void ExtensionPolicyService::UnregisterObservers() {
-  mObs->RemoveObserver(this, kDocElementInserted);
+  mObs->RemoveObserver(this, "content-document-global-created");
+  mObs->RemoveObserver(this, "document-element-inserted");
   mObs->RemoveObserver(this, "tab-content-frameloader-created");
   if (XRE_IsContentProcess()) {
     mObs->RemoveObserver(this, "http-on-opening-request");
   }
 }
 
 nsresult ExtensionPolicyService::Observe(nsISupports* aSubject,
                                          const char* aTopic,
                                          const char16_t* aData) {
-  if (!strcmp(aTopic, kDocElementInserted)) {
+  if (!strcmp(aTopic, "content-document-global-created")) {
+    nsCOMPtr<nsPIDOMWindowOuter> win = do_QueryInterface(aSubject);
+    if (win) {
+      CheckWindow(win);
+    }
+  } else if (!strcmp(aTopic, "document-element-inserted")) {
     nsCOMPtr<Document> doc = do_QueryInterface(aSubject);
     if (doc) {
       CheckDocument(doc);
     }
   } else if (!strcmp(aTopic, "http-on-opening-request")) {
     nsCOMPtr<nsIChannel> chan = do_QueryInterface(aSubject);
     if (chan) {
       CheckRequest(chan);
@@ -464,16 +469,44 @@ void ExtensionPolicyService::CheckDocume
     if (policy) {
       bool privileged = IsExtensionProcess() && CheckParentFrames(win, *policy);
 
       ProcessScript().InitExtensionDocument(policy, aDocument, privileged);
     }
   }
 }
 
+// Checks for loads of about:blank into new window globals, and loads any
+// matching content scripts. about:blank loads do not trigger document element
+// inserted events, so they're the only load type that are special cased this
+// way.
+void ExtensionPolicyService::CheckWindow(nsPIDOMWindowOuter* aWindow) {
+  // We only care about non-initial document loads here. The initial
+  // about:blank document will usually be re-used to load another document.
+  RefPtr<Document> doc = aWindow->GetExtantDoc();
+  if (!doc || doc->IsInitialDocument() ||
+      doc->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED) {
+    return;
+  }
+
+  nsCOMPtr<nsIURI> docUri = doc->GetDocumentURI();
+  nsCOMPtr<nsIURI> uri;
+  if (!docUri || NS_FAILED(NS_GetURIWithoutRef(docUri, getter_AddRefs(uri))) ||
+      !NS_IsAboutBlank(uri)) {
+    return;
+  }
+
+  nsIDocShell* docShell = aWindow->GetDocShell();
+  if (RefPtr<ContentFrameMessageManager> mm = docShell->GetMessageManager()) {
+    if (mMessageManagers.Contains(mm)) {
+      CheckContentScripts(aWindow, false);
+    }
+  }
+}
+
 void ExtensionPolicyService::CheckContentScripts(const DocInfo& aDocInfo,
                                                  bool aIsPreload) {
   nsCOMPtr<nsPIDOMWindowInner> win;
   if (!aIsPreload) {
     win = aDocInfo.GetWindow()->GetCurrentInnerWindow();
   }
 
   for (auto iter = mExtensions.Iter(); !iter.Done(); iter.Next()) {
--- a/toolkit/components/extensions/ExtensionPolicyService.h
+++ b/toolkit/components/extensions/ExtensionPolicyService.h
@@ -98,16 +98,17 @@ class ExtensionPolicyService final : pub
  private:
   ExtensionPolicyService();
 
   void RegisterObservers();
   void UnregisterObservers();
 
   void CheckRequest(nsIChannel* aChannel);
   void CheckDocument(dom::Document* aDocument);
+  void CheckWindow(nsPIDOMWindowOuter* aWindow);
 
   void CheckContentScripts(const DocInfo& aDocInfo, bool aIsPreload);
 
   already_AddRefed<dom::Promise> ExecuteContentScript(
       nsPIDOMWindowInner* aWindow,
       extensions::WebExtensionContentScript& aScript);
 
   RefPtr<dom::Promise> ExecuteContentScripts(