Bug 1390445 - Fix select popup positioning for oop extensions options_ui pages. r=billm,kats,kmag
authorLuca Greco <lgreco@mozilla.com>
Wed, 20 Sep 2017 20:03:58 +0200
changeset 679125 acdd6207bc522485ad0ea058bfdcc503ab488fd7
parent 679124 c2bb5a120db9b3e9b0fca315610efd6643962ee0
child 679126 60115421ca851d2acd767609a85153fe4ff69d32
push id84141
push userbmo:schien@mozilla.com
push dateThu, 12 Oct 2017 11:13:04 +0000
reviewersbillm, kats, kmag
bugs1390445
milestone58.0a1
Bug 1390445 - Fix select popup positioning for oop extensions options_ui pages. r=billm,kats,kmag MozReview-Commit-ID: Izt10SuUK0i
dom/base/nsFrameLoader.cpp
dom/base/nsFrameLoader.h
dom/ipc/TabParent.h
dom/webidl/FrameLoader.webidl
toolkit/mozapps/extensions/content/extensions.js
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -3791,16 +3791,28 @@ nsFrameLoader::RequestFrameLoaderClose()
     // OwnerElement other than nsIBrowser is not supported yet.
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   return browser->CloseBrowser();
 }
 
 void
+nsFrameLoader::RequestUpdatePosition(ErrorResult& aRv)
+{
+  if (auto* tabParent = TabParent::GetFrom(GetRemoteBrowser())) {
+    nsresult rv = tabParent->UpdatePosition();
+
+    if (NS_FAILED(rv)) {
+      aRv.Throw(rv);
+    }
+  }
+}
+
+void
 nsFrameLoader::Print(uint64_t aOuterWindowID,
                      nsIPrintSettings* aPrintSettings,
                      nsIWebProgressListener* aProgressListener,
                      ErrorResult& aRv)
 {
   nsresult rv = Print(aOuterWindowID, aPrintSettings, aProgressListener);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
--- a/dom/base/nsFrameLoader.h
+++ b/dom/base/nsFrameLoader.h
@@ -160,16 +160,18 @@ public:
   void ActivateFrameEvent(const nsAString& aType,
                           bool aCapture,
                           mozilla::ErrorResult& aRv);
 
   void RequestNotifyAfterRemotePaint(mozilla::ErrorResult& aRv);
 
   void RequestFrameLoaderClose(mozilla::ErrorResult& aRv);
 
+  void RequestUpdatePosition(mozilla::ErrorResult& aRv);
+
   void Print(uint64_t aOuterWindowID,
              nsIPrintSettings* aPrintSettings,
              nsIWebProgressListener* aProgressListener,
              mozilla::ErrorResult& aRv);
 
   already_AddRefed<nsIGroupedSHistory> EnsureGroupedSHistory(mozilla::ErrorResult& aRv);
 
   void StartPersistence(uint64_t aOuterWindowID,
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -349,16 +349,18 @@ public:
   // message-sending functions under a layer of indirection and
   // eating the return values
   void Show(const ScreenIntSize& aSize, bool aParentIsActive);
 
   void UpdateDimensions(const nsIntRect& aRect, const ScreenIntSize& aSize);
 
   DimensionInfo GetDimensionInfo();
 
+  nsresult UpdatePosition();
+
   void SizeModeChanged(const nsSizeMode& aSizeMode);
 
   void UIResolutionChanged();
 
   void ThemeChanged();
 
   void HandleAccessKey(const WidgetKeyboardEvent& aEvent,
                        nsTArray<uint32_t>& aCharCodes);
@@ -664,18 +666,16 @@ private:
   void DestroyInternal();
 
   already_AddRefed<nsFrameLoader>
   GetFrameLoader(bool aUseCachedFrameLoaderAfterDestroy = false) const;
 
   RefPtr<nsIContentParent> mManager;
   void TryCacheDPIAndScale();
 
-  nsresult UpdatePosition();
-
   bool AsyncPanZoomEnabled() const;
 
   // Cached value indicating the docshell active state of the remote browser.
   bool mDocShellIsActive;
 
   // Update state prior to routing an APZ-aware event to the child process.
   // |aOutTargetGuid| will contain the identifier
   // of the APZC instance that handled the event. aOutTargetGuid may be null.
--- a/dom/webidl/FrameLoader.webidl
+++ b/dom/webidl/FrameLoader.webidl
@@ -157,16 +157,22 @@ interface FrameLoader {
 
   /**
    * Close the window through the ownerElement.
    */
   [Throws]
   void requestFrameLoaderClose();
 
   /**
+   * Force a remote browser to recompute its dimension and screen position.
+   */
+  [Throws]
+  void requestUpdatePosition();
+
+  /**
    * Print the current document.
    *
    * @param aOuterWindowID the ID of the outer window to print
    * @param aPrintSettings optional print settings to use; printSilent can be
    *                       set to prevent prompting.
    * @param aProgressListener optional print progress listener.
    */
   [Throws]
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -8,16 +8,17 @@
 /* globals XMLStylesheetProcessingInstruction */
 /* exported UPDATES_RELEASENOTES_TRANSFORMFILE, XMLURI_PARSE_ERROR, loadView, gBrowser */
 
 var Cc = Components.classes;
 var Ci = Components.interfaces;
 var Cu = Components.utils;
 var Cr = Components.results;
 
+Cu.import("resource://gre/modules/DeferredTask.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/DownloadUtils.jsm");
 Cu.import("resource://gre/modules/AddonManager.jsm");
 Cu.import("resource://gre/modules/AppConstants.jsm");
 Cu.import("resource://gre/modules/addons/AddonRepository.jsm");
 Cu.import("resource://gre/modules/addons/AddonSettings.jsm");
 
@@ -4146,8 +4147,26 @@ var gBrowser = {
 
     if (parentWindow.gBrowser) {
       return parentWindow.gBrowser.getTabModalPromptBox(browser);
     }
 
     return null;
   }
 };
+
+// Force the options_ui remote browser to recompute window.mozInnerScreenX and
+// window.mozInnerScreenY when the "addon details" page has been scrolled
+// (See Bug 1390445 for rationale).
+{
+  const UPDATE_POSITION_DELAY = 100;
+
+  const updatePositionTask = new DeferredTask(() => {
+    const browser = document.getElementById("addon-options");
+    if (browser && browser.isRemoteBrowser) {
+      browser.frameLoader.requestUpdatePosition();
+    }
+  }, UPDATE_POSITION_DELAY);
+
+  window.addEventListener("scroll", () => {
+    updatePositionTask.arm();
+  }, true);
+}