Bug 1258056 - Propagate the window opener full page zoom across the IPC layer; r=smaug
authorEhsan Akhgari <ehsan@mozilla.com>
Mon, 21 Mar 2016 13:55:55 -0400
changeset 289850 fb0dd42729b8aeb15ee55cc6a3e372a4fa81aadc
parent 289849 a55e30611e2cbbe2063fe8af038f335fb4a32249
child 289851 82c36cd54626df6cc0e8fd3aeb1c4c504058ba04
push id74015
push usereakhgari@mozilla.com
push dateTue, 22 Mar 2016 21:49:15 +0000
treeherdermozilla-inbound@fb0dd42729b8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1258056
milestone48.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 1258056 - Propagate the window opener full page zoom across the IPC layer; r=smaug
dom/base/nsGlobalWindow.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/workers/ServiceWorkerClients.cpp
embedding/components/windowwatcher/nsPIWindowWatcher.idl
embedding/components/windowwatcher/nsWindowWatcher.cpp
embedding/components/windowwatcher/nsWindowWatcher.h
embedding/test/mochitest.ini
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -11532,17 +11532,17 @@ nsGlobalWindow::OpenInternal(const nsASt
     nsAutoPopupStatePusher popupStatePusher(openAbused, true);
 
     if (!aCalledNoScript) {
       // We asserted at the top of this function that aNavigate is true for
       // !aCalledNoScript.
       rv = pwwatch->OpenWindow2(AsOuter(), url.get(), name_ptr,
                                 options_ptr, /* aCalledFromScript = */ true,
                                 aDialog, aNavigate, nullptr, argv,
-                                getter_AddRefs(domReturn));
+                                1.0f, 0, getter_AddRefs(domReturn));
     } else {
       // Force a system caller here so that the window watcher won't screw us
       // up.  We do NOT want this case looking at the JS context on the stack
       // when searching.  Compare comments on
       // nsIDOMWindow::OpenWindow and nsIWindowWatcher::OpenWindow.
 
       // Note: Because nsWindowWatcher is so broken, it's actually important
       // that we don't force a system caller here, because that screws it up
@@ -11552,17 +11552,17 @@ nsGlobalWindow::OpenInternal(const nsASt
       if (!aContentModal) {
         nojsapi.emplace();
       }
 
 
       rv = pwwatch->OpenWindow2(AsOuter(), url.get(), name_ptr,
                                 options_ptr, /* aCalledFromScript = */ false,
                                 aDialog, aNavigate, nullptr, aExtraArgument,
-                                getter_AddRefs(domReturn));
+                                1.0f, 0, getter_AddRefs(domReturn));
 
     }
   }
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   // success!
 
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -869,29 +869,36 @@ ContentChild::ProvideWindowCommon(TabChi
       }
 
       baseURI->GetSpec(baseURIString);
     }
 
     auto* opener = nsPIDOMWindowOuter::From(aParent);
     nsIDocShell* openerShell;
     RefPtr<nsDocShell> openerDocShell;
+    float fullZoom = 1.0f;
     if (opener && (openerShell = opener->GetDocShell())) {
       openerDocShell = static_cast<nsDocShell*>(openerShell);
+      nsCOMPtr<nsIContentViewer> cv;
+      openerDocShell->GetContentViewer(getter_AddRefs(cv));
+      if (cv) {
+        cv->GetFullZoom(&fullZoom);
+      }
     }
 
     nsresult rv;
     if (!SendCreateWindow(aTabOpener, newChild,
                           aChromeFlags, aCalledFromJS, aPositionSpecified,
                           aSizeSpecified, url,
                           name, features,
                           baseURIString,
                           openerDocShell
                             ? openerDocShell->GetOriginAttributes()
                             : DocShellOriginAttributes(),
+                          fullZoom,
                           &rv,
                           aWindowIsNew,
                           &frameScripts,
                           &urlToLoad)) {
       return NS_ERROR_NOT_AVAILABLE;
     }
 
     if (NS_FAILED(rv)) {
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -5328,16 +5328,17 @@ ContentParent::RecvCreateWindow(PBrowser
                                 const bool& aCalledFromJS,
                                 const bool& aPositionSpecified,
                                 const bool& aSizeSpecified,
                                 const nsCString& aURI,
                                 const nsString& aName,
                                 const nsCString& aFeatures,
                                 const nsCString& aBaseURI,
                                 const DocShellOriginAttributes& aOpenerOriginAttributes,
+                                const float& aFullZoom,
                                 nsresult* aResult,
                                 bool* aWindowIsNew,
                                 InfallibleTArray<FrameScriptInfo>* aFrameScripts,
                                 nsCString* aURLToLoad)
 {
   // We always expect to open a new window here. If we don't, it's an error.
   *aWindowIsNew = true;
 
@@ -5485,17 +5486,17 @@ ContentParent::RecvCreateWindow(PBrowser
   // nsString (since primitives are not nullable). If we detect the voided
   // nsString, we know that we need to send OpenWindow2 a nullptr for the URI.
   const char* uri = aURI.IsVoid() ? nullptr : finalURIString.get();
   const char* name = aName.IsVoid() ? nullptr : NS_ConvertUTF16toUTF8(aName).get();
   const char* features = aFeatures.IsVoid() ? nullptr : aFeatures.get();
 
   *aResult = pwwatch->OpenWindow2(parent, uri, name, features, aCalledFromJS,
                                   false, false, thisTabParent, nullptr,
-                                  getter_AddRefs(window));
+                                  aFullZoom, 1, getter_AddRefs(window));
 
   if (NS_WARN_IF(!window)) {
     return true;
   }
 
   *aResult = NS_ERROR_FAILURE;
   auto* pwindow = nsPIDOMWindowOuter::From(window);
   nsCOMPtr<nsIDocShell> windowDocShell = pwindow->GetDocShell();
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -501,16 +501,17 @@ public:
                                 const bool& aCalledFromJS,
                                 const bool& aPositionSpecified,
                                 const bool& aSizeSpecified,
                                 const nsCString& aURI,
                                 const nsString& aName,
                                 const nsCString& aFeatures,
                                 const nsCString& aBaseURI,
                                 const DocShellOriginAttributes& aOpenerOriginAttributes,
+                                const float& aFullZoom,
                                 nsresult* aResult,
                                 bool* aWindowIsNew,
                                 InfallibleTArray<FrameScriptInfo>* aFrameScripts,
                                 nsCString* aURLToLoad) override;
 
   static bool AllocateLayerTreeId(TabParent* aTabParent, uint64_t* aId);
 
 protected:
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -1170,17 +1170,18 @@ parent:
                       uint32_t aChromeFlags,
                       bool aCalledFromJS,
                       bool aPositionSpecified,
                       bool aSizeSpecified,
                       nsCString aURI,
                       nsString aName,
                       nsCString aFeatures,
                       nsCString aBaseURI,
-                      DocShellOriginAttributes aOpenerOriginAttributes)
+                      DocShellOriginAttributes aOpenerOriginAttributes,
+                      float aFullZoom)
       returns (nsresult rv,
                bool windowOpened,
                FrameScriptInfo[] frameScripts,
                nsCString urlToLoad);
 
     sync GetDeviceStorageLocation(nsString type)
         returns (nsString path);
 
--- a/dom/workers/ServiceWorkerClients.cpp
+++ b/dom/workers/ServiceWorkerClients.cpp
@@ -596,17 +596,17 @@ private:
       nsCString spec;
       uri->GetSpec(spec);
 
       nsCOMPtr<mozIDOMWindowProxy> newWindow;
       pwwatch->OpenWindow2(nullptr,
                            spec.get(),
                            nullptr,
                            nullptr,
-                           false, false, true, nullptr, nullptr,
+                           false, false, true, nullptr, nullptr, 1.0f, 0,
                            getter_AddRefs(newWindow));
       nsCOMPtr<nsPIDOMWindowOuter> pwindow = nsPIDOMWindowOuter::From(newWindow);
       pwindow.forget(aWindow);
       return NS_OK;
     }
 
     // Find the most recent browser window and open a new tab in it.
     nsCOMPtr<nsPIDOMWindowOuter> browserWindow =
--- a/embedding/components/windowwatcher/nsPIWindowWatcher.idl
+++ b/embedding/components/windowwatcher/nsPIWindowWatcher.idl
@@ -53,33 +53,38 @@ interface nsPIWindowWatcher : nsISupport
       @param aCalledFromScript true if we were called from script.
       @param aDialog use dialog defaults (see nsIDOMWindow::openDialog)
       @param aNavigate true if we should navigate the new window to the
              specified URL.
       @param aOpeningTab the nsITabParent that is opening the new window. The
                          nsITabParent is a remote tab belonging to aParent. Can
                          be nullptr if this window is not being opened from a tab.
       @param aArgs Window argument
+      @param aOpenerFullZoom the full zoom multiplier for the opener window.
+                             this can be null in the single process case where
+                             the opener full zoom is obtained from aParent.
       @return the new window
 
       @note This method may examine the JS context stack for purposes of
             determining the security context to use for the search for a given
             window named aName.
       @note This method should try to set the default charset for the new
             window to the default charset of the document in the calling window
             (which is determined based on the JS stack and the value of
             aParent).  This is not guaranteed, however.
   */
+  [optional_argc]
   mozIDOMWindowProxy openWindow2(in mozIDOMWindowProxy aParent, in string aUrl,
                                  in string aName, in string aFeatures,
                                  in boolean aCalledFromScript,
                                  in boolean aDialog,
                                  in boolean aNavigate,
                                  in nsITabParent aOpeningTab,
-                                 in nsISupports aArgs);
+                                 in nsISupports aArgs,
+                                 [optional] in float aOpenerFullZoom);
 
   /**
    * Find a named docshell tree item amongst all windows registered
    * with the window watcher.  This may be a subframe in some window,
    * for example.
    *
    * @param aName the name of the window.  Must not be null.
    * @param aRequestor the tree item immediately making the request.
--- a/embedding/components/windowwatcher/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/nsWindowWatcher.cpp
@@ -363,17 +363,18 @@ nsWindowWatcher::OpenWindow(mozIDOMWindo
   uint32_t argc = 0;
   if (argv) {
     argv->GetLength(&argc);
   }
   bool dialog = (argc != 0);
 
   return OpenWindowInternal(aParent, aUrl, aName, aFeatures,
                             /* calledFromJS = */ false, dialog,
-                            /* navigate = */ true, nullptr, argv, aResult);
+                            /* navigate = */ true, nullptr, argv,
+                            /* openerFullZoom = */ nullptr, aResult);
 }
 
 struct SizeSpec
 {
   SizeSpec()
     : mLeftSpecified(false)
     , mTopSpecified(false)
     , mOuterWidthSpecified(false)
@@ -421,16 +422,18 @@ nsWindowWatcher::OpenWindow2(mozIDOMWind
                              const char* aUrl,
                              const char* aName,
                              const char* aFeatures,
                              bool aCalledFromScript,
                              bool aDialog,
                              bool aNavigate,
                              nsITabParent* aOpeningTab,
                              nsISupports* aArguments,
+                             float aOpenerFullZoom,
+                             uint8_t aOptionalArgc,
                              mozIDOMWindowProxy** aResult)
 {
   nsCOMPtr<nsIArray> argv = ConvertArgsToArray(aArguments);
 
   uint32_t argc = 0;
   if (argv) {
     argv->GetLength(&argc);
   }
@@ -440,17 +443,19 @@ nsWindowWatcher::OpenWindow2(mozIDOMWind
   // called from script.  Fixing this is bug 779939.
   bool dialog = aDialog;
   if (!aCalledFromScript) {
     dialog = argc > 0;
   }
 
   return OpenWindowInternal(aParent, aUrl, aName, aFeatures,
                             aCalledFromScript, dialog,
-                            aNavigate, aOpeningTab, argv, aResult);
+                            aNavigate, aOpeningTab, argv,
+                            aOptionalArgc >= 1 ? &aOpenerFullZoom : nullptr,
+                            aResult);
 }
 
 // This static function checks if the aDocShell uses an UserContextId equal to
 // nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID or equal to the
 // userContextId of subjectPrincipal, if not null.
 static bool
 CheckUserContextCompatibility(nsIDocShell* aDocShell)
 {
@@ -483,16 +488,17 @@ nsWindowWatcher::OpenWindowInternal(mozI
                                     const char* aUrl,
                                     const char* aName,
                                     const char* aFeatures,
                                     bool aCalledFromJS,
                                     bool aDialog,
                                     bool aNavigate,
                                     nsITabParent* aOpeningTab,
                                     nsIArray* aArgv,
+                                    float* aOpenerFullZoom,
                                     mozIDOMWindowProxy** aResult)
 {
   nsresult rv = NS_OK;
   bool isNewToplevelWindow = false;
   bool windowIsNew = false;
   bool windowNeedsName = false;
   bool windowIsModal = false;
   bool uriToLoadIsChrome = false;
@@ -1070,17 +1076,18 @@ nsWindowWatcher::OpenWindowInternal(mozI
                                        getter_AddRefs(storage));
       if (storage) {
         newStorageManager->CloneStorage(storage);
       }
     }
   }
 
   if (isNewToplevelWindow) {
-    SizeOpenedDocShellItem(newDocShellItem, aParent, isCallerChrome, sizeSpec);
+    SizeOpenedDocShellItem(newDocShellItem, aParent, isCallerChrome, sizeSpec,
+                           aOpenerFullZoom);
   }
 
   // XXXbz isn't windowIsModal always true when windowIsModalContentDialog?
   if (windowIsModal || windowIsModalContentDialog) {
     nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner;
     newDocShellItem->GetTreeOwner(getter_AddRefs(newTreeOwner));
     nsCOMPtr<nsIWebBrowserChrome> newChrome(do_GetInterface(newTreeOwner));
 
@@ -2050,35 +2057,36 @@ nsWindowWatcher::CalcSizeSpec(const char
    is assumed to be called after the window has already been given
    a default position and size; thus its current position and size are
    accurate defaults. The new window is made visible at method end.
 */
 void
 nsWindowWatcher::SizeOpenedDocShellItem(nsIDocShellTreeItem* aDocShellItem,
                                         mozIDOMWindowProxy* aParent,
                                         bool aIsCallerChrome,
-                                        const SizeSpec& aSizeSpec)
+                                        const SizeSpec& aSizeSpec,
+                                        float* aOpenerFullZoom)
 {
   // position and size of window
   int32_t left = 0, top = 0, width = 100, height = 100;
   // difference between chrome and content size
   int32_t chromeWidth = 0, chromeHeight = 0;
   // whether the window size spec refers to chrome or content
   bool sizeChromeWidth = true, sizeChromeHeight = true;
 
   // get various interfaces for aDocShellItem, used throughout this method
   nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
   aDocShellItem->GetTreeOwner(getter_AddRefs(treeOwner));
   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin(do_QueryInterface(treeOwner));
   if (!treeOwnerAsWin) { // we'll need this to actually size the docshell
     return;
   }
 
-  double openerZoom = 1.0;
-  if (aParent) {
+  double openerZoom = aOpenerFullZoom ? *aOpenerFullZoom : 1.0;
+  if (aParent && !aOpenerFullZoom) {
     nsCOMPtr<nsPIDOMWindowOuter> piWindow = nsPIDOMWindowOuter::From(aParent);
     if (nsIDocument* doc = piWindow->GetDoc()) {
       if (nsIPresShell* shell = doc->GetShell()) {
         if (nsPresContext* presContext = shell->GetPresContext()) {
           openerZoom = presContext->GetFullZoom();
         }
       }
     }
--- a/embedding/components/windowwatcher/nsWindowWatcher.h
+++ b/embedding/components/windowwatcher/nsWindowWatcher.h
@@ -79,16 +79,17 @@ protected:
                               const char* aUrl,
                               const char* aName,
                               const char* aFeatures,
                               bool aCalledFromJS,
                               bool aDialog,
                               bool aNavigate,
                               nsITabParent* aOpeningTab,
                               nsIArray* aArgv,
+                              float* aOpenerFullZoom,
                               mozIDOMWindowProxy** aResult);
 
   static nsresult URIfromURL(const char* aURL,
                              mozIDOMWindowProxy* aParent,
                              nsIURI** aURI);
 
   static uint32_t CalculateChromeFlags(mozIDOMWindowProxy* aParent,
                                        const char* aFeatures,
@@ -104,17 +105,18 @@ protected:
   static void CalcSizeSpec(const char* aFeatures, SizeSpec& aResult);
   static nsresult ReadyOpenedDocShellItem(nsIDocShellTreeItem* aOpenedItem,
                                           nsPIDOMWindowOuter* aParent,
                                           bool aWindowIsNew,
                                           mozIDOMWindowProxy** aOpenedWindow);
   static void SizeOpenedDocShellItem(nsIDocShellTreeItem* aDocShellItem,
                                      mozIDOMWindowProxy* aParent,
                                      bool aIsCallerChrome,
-                                     const SizeSpec& aSizeSpec);
+                                     const SizeSpec& aSizeSpec,
+                                     float* aOpenerFullZoom);
   static void GetWindowTreeItem(mozIDOMWindowProxy* aWindow,
                                 nsIDocShellTreeItem** aResult);
   static void GetWindowTreeOwner(nsPIDOMWindowOuter* aWindow,
                                  nsIDocShellTreeOwner** aResult);
 
   nsTArray<nsWatcherWindowEnumerator*> mEnumeratorList;
   nsWatcherWindowEntry* mOldestWindow;
   mozilla::Mutex mListLock;
--- a/embedding/test/mochitest.ini
+++ b/embedding/test/mochitest.ini
@@ -7,9 +7,9 @@ support-files =
 skip-if = (toolkit == "cocoa" && e10s) # bug 1252223
 [test_bug499115.html]
 [test_nsFind.html]
 [test_private_window_from_content.html]
 # Next two tests are disabled in e10s because of bug 989501.
 [test_window_open_position_constraint.html]
 skip-if = toolkit == 'android' || buildapp == 'mulet'
 [test_window_open_units.html]
-skip-if = toolkit == 'android' || e10s || buildapp == 'mulet'
+skip-if = toolkit == 'android' || buildapp == 'mulet'