Bug 1248772 - Trigger a OS window focus in ServiceWorkerClients::OpenWindow. r=ehsan
authorCatalin Badea <catalin.badea392@gmail.com>
Thu, 31 Mar 2016 16:06:00 +0200
changeset 291205 cce5b60332cdbbbd8e0876c0c16dbec046090f96
parent 291204 339fd895d83b1dc567b03c5a0a9556804296e51d
child 291206 8ab93deb75d746735e53dc603fb8aa026e73f75f
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1248772
milestone48.0a1
Bug 1248772 - Trigger a OS window focus in ServiceWorkerClients::OpenWindow. r=ehsan
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/workers/ServiceWorkerClients.cpp
dom/workers/ServiceWorkerWindowClient.cpp
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -3824,16 +3824,32 @@ nsContentUtils::DispatchChromeEvent(nsID
   nsEventStatus status = nsEventStatus_eIgnore;
   rv = piTarget->DispatchDOMEvent(nullptr, event, nullptr, &status);
   if (aDefaultAction) {
     *aDefaultAction = (status != nsEventStatus_eConsumeNoDefault);
   }
   return rv;
 }
 
+/* static */
+nsresult
+nsContentUtils::DispatchFocusChromeEvent(nsPIDOMWindowOuter* aWindow)
+{
+  MOZ_ASSERT(aWindow);
+
+  nsCOMPtr<nsIDocument> doc = aWindow->GetExtantDoc();
+  if (!doc) {
+    return NS_ERROR_FAILURE;
+  }
+
+  return DispatchChromeEvent(doc, aWindow,
+                             NS_LITERAL_STRING("DOMServiceWorkerFocusClient"),
+                             true, true);
+}
+
 nsresult
 nsContentUtils::DispatchEventOnlyToChrome(nsIDocument* aDoc,
                                           nsISupports* aTarget,
                                           const nsAString& aEventName,
                                           bool aCanBubble, bool aCancelable,
                                           bool* aDefaultAction)
 {
   return DispatchEvent(aDoc, aTarget, aEventName, aCanBubble, aCancelable,
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -1120,16 +1120,23 @@ public:
    */
   static nsresult DispatchChromeEvent(nsIDocument* aDoc,
                                       nsISupports* aTarget,
                                       const nsAString& aEventName,
                                       bool aCanBubble,
                                       bool aCancelable,
                                       bool *aDefaultAction = nullptr);
 
+  /**
+   * Helper function for dispatching a "DOMServiceWorkerFocusClient" event to
+   * the chrome event handler of the given DOM Window. This has the effect
+   * of focusing the corresponding tab and bringing the browser window
+   * to the foreground.
+   */
+  static nsresult DispatchFocusChromeEvent(nsPIDOMWindowOuter* aWindow);
 
   /**
    * This method creates and dispatches a trusted event.
    * If aTarget is not a chrome object, the nearest chrome object in the
    * propagation path will be used as the start of the event target chain.
    * This method is different than DispatchChromeEvent, which always dispatches
    * events to chrome event handler. DispatchEventOnlyToChrome works like
    * DispatchTrustedEvent in the case aTarget is a chrome object.
--- a/dom/workers/ServiceWorkerClients.cpp
+++ b/dom/workers/ServiceWorkerClients.cpp
@@ -498,16 +498,21 @@ public:
       return NS_OK;
     }
 
     nsCOMPtr<nsPIDOMWindowOuter> window;
     nsresult rv = OpenWindow(getter_AddRefs(window));
     if (NS_SUCCEEDED(rv)) {
       MOZ_ASSERT(window);
 
+      rv = nsContentUtils::DispatchFocusChromeEvent(window);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
+
       WorkerPrivate* workerPrivate = mPromiseProxy->GetWorkerPrivate();
       MOZ_ASSERT(workerPrivate);
 
       WorkerPrivate::LocationInfo& info = workerPrivate->GetLocationInfo();
       nsCOMPtr<nsIURI> baseURI;
       nsresult rv = NS_NewURI(getter_AddRefs(baseURI), info.mHref);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return NS_ERROR_FAILURE;
--- a/dom/workers/ServiceWorkerWindowClient.cpp
+++ b/dom/workers/ServiceWorkerWindowClient.cpp
@@ -90,20 +90,17 @@ public:
   {
     AssertIsOnMainThread();
     nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowId);
     UniquePtr<ServiceWorkerClientInfo> clientInfo;
 
     if (window) {
       nsCOMPtr<nsIDocument> doc = window->GetDocument();
       if (doc) {
-        nsContentUtils::DispatchChromeEvent(doc,
-                                            window->GetOuterWindow(),
-                                            NS_LITERAL_STRING("DOMServiceWorkerFocusClient"),
-                                            true, true);
+        nsContentUtils::DispatchFocusChromeEvent(window->GetOuterWindow());
         clientInfo.reset(new ServiceWorkerClientInfo(doc));
       }
     }
 
     DispatchResult(Move(clientInfo));
     return NS_OK;
   }