Bug 1594752, expose WindowGlobalParent's document title attribute to script, and fire a pagetitlechanged event on the frame/browser when it changes, r=nika
authorNeil Deakin <neil@mozilla.com>
Wed, 13 May 2020 19:25:45 +0000
changeset 529711 e781cf38f088c02d2b336aa8ec990756447683c9
parent 529710 217394da44ac9b55df2f91bf639944ea47949b3d
child 529712 66cc44b67170c7e48411180d5785f861b04a7719
push id37414
push usernbeleuzu@mozilla.com
push dateThu, 14 May 2020 02:40:10 +0000
treeherdermozilla-central@045d696faa87 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnika
bugs1594752
milestone78.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
Bug 1594752, expose WindowGlobalParent's document title attribute to script, and fire a pagetitlechanged event on the frame/browser when it changes, r=nika Differential Revision: https://phabricator.services.mozilla.com/D72561
dom/chrome-webidl/WindowGlobalActors.webidl
dom/ipc/WindowGlobalParent.cpp
dom/ipc/WindowGlobalParent.h
dom/media/mediasession/MediaSessionController.cpp
--- a/dom/chrome-webidl/WindowGlobalActors.webidl
+++ b/dom/chrome-webidl/WindowGlobalActors.webidl
@@ -48,16 +48,17 @@ interface WindowGlobalParent : WindowCon
   readonly attribute FrameLoader? rootFrameLoader; // Embedded (browser) only
 
   readonly attribute WindowGlobalChild? childActor; // in-process only
 
   // Information about the currently loaded document.
   readonly attribute Principal documentPrincipal;
   readonly attribute Principal? contentBlockingAllowListPrincipal;
   readonly attribute URI? documentURI;
+  readonly attribute DOMString documentTitle;
 
   // Bit mask containing content blocking events that are recorded in
   // the document's content blocking log.
   readonly attribute unsigned long contentBlockingEvents;
 
   // String containing serialized content blocking log.
   readonly attribute DOMString contentBlockingLog;
 
--- a/dom/ipc/WindowGlobalParent.cpp
+++ b/dom/ipc/WindowGlobalParent.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
 /* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/WindowGlobalParent.h"
 
+#include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/ipc/InProcessParent.h"
 #include "mozilla/dom/BrowserBridgeParent.h"
 #include "mozilla/dom/CanonicalBrowsingContext.h"
 #include "mozilla/dom/ClientInfo.h"
 #include "mozilla/dom/ClientIPCTypes.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/BrowserHost.h"
@@ -274,17 +275,37 @@ IPCResult WindowGlobalParent::RecvUpdate
                     "Trying to reuse WindowGlobalParent but the principal of "
                     "the new document does not match the old one");
   }
   mDocumentPrincipal = aNewDocumentPrincipal;
   return IPC_OK();
 }
 mozilla::ipc::IPCResult WindowGlobalParent::RecvUpdateDocumentTitle(
     const nsString& aTitle) {
+  if (mDocumentTitle == aTitle) {
+    return IPC_OK();
+  }
+
   mDocumentTitle = aTitle;
+
+  // Send a pagetitlechanged event only for changes to the title
+  // for top-level frames.
+  if (!BrowsingContext()->IsTop()) {
+    return IPC_OK();
+  }
+
+  Element* frameElement = BrowsingContext()->GetEmbedderElement();
+  if (!frameElement) {
+    return IPC_OK();
+  }
+
+  (new AsyncEventDispatcher(frameElement, NS_LITERAL_STRING("pagetitlechanged"),
+                            CanBubble::eYes, ChromeOnlyDispatch::eYes))
+      ->RunDOMEventWhenSafe();
+
   return IPC_OK();
 }
 
 IPCResult WindowGlobalParent::RecvUpdateDocumentHasLoaded(
     bool aDocumentHasLoaded) {
   mDocumentHasLoaded = aDocumentHasLoaded;
   return IPC_OK();
 }
--- a/dom/ipc/WindowGlobalParent.h
+++ b/dom/ipc/WindowGlobalParent.h
@@ -115,17 +115,17 @@ class WindowGlobalParent final : public 
   // which this WindowGlobal is a part of. This will be the nsFrameLoader
   // holding the BrowserParent for remote tabs, and the root content frameloader
   // for non-remote tabs.
   already_AddRefed<nsFrameLoader> GetRootFrameLoader();
 
   // The current URI which loaded in the document.
   nsIURI* GetDocumentURI() override { return mDocumentURI; }
 
-  const nsString& GetDocumentTitle() const { return mDocumentTitle; }
+  void GetDocumentTitle(nsAString& aTitle) const { aTitle = mDocumentTitle; }
 
   nsIPrincipal* GetContentBlockingAllowListPrincipal() const {
     return mDocContentBlockingAllowListPrincipal;
   }
 
   Maybe<ClientInfo> GetClientInfo() { return mClientInfo; }
 
   uint64_t ContentParentId();
--- a/dom/media/mediasession/MediaSessionController.cpp
+++ b/dom/media/mediasession/MediaSessionController.cpp
@@ -171,17 +171,17 @@ nsString MediaSessionController::GetDefa
       nsCString appName;
       appInfo->GetName(appName);
       CopyUTF8toUTF16(appName, defaultTitle);
     } else {
       defaultTitle.AssignLiteral("Firefox");
     }
     defaultTitle.AppendLiteral(" is playing media");
   } else {
-    defaultTitle = globalParent->GetDocumentTitle();
+    globalParent->GetDocumentTitle(defaultTitle);
   }
   return defaultTitle;
 }
 
 nsString MediaSessionController::GetDefaultFaviconURL() const {
 #ifdef MOZ_PLACES
   nsCOMPtr<nsIURI> faviconURI;
   nsresult rv = NS_NewURI(getter_AddRefs(faviconURI),