Backed out changeset 0c671ce41082 (bug 1294442) for browser_ext_pageAction_popup_resize.js failures a=backout FIREFOX_50_0b10_BUILD1 FIREFOX_50_0b10_RELEASE
authorWes Kocher <wkocher@mozilla.com>
Mon, 24 Oct 2016 17:27:52 -0700
changeset 348726 38cfded1705240c5d20baff4aef99bdd0a13bcec
parent 348725 1d8f1c457fdf22f3cda9175ac966698046d3543a
child 348727 2afe0634177930d041f324bf3bccefd3c77afb7e
child 348729 d8c32ae9dea53470a7b7f0d29a12296362c15c6a
push id6537
push userkwierso@gmail.com
push dateTue, 25 Oct 2016 00:28:26 +0000
treeherdermozilla-beta@38cfded17052 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1294442
milestone50.0
backs out0c671ce41082a2bba72b4e2340c391f9a5d83b6b
Backed out changeset 0c671ce41082 (bug 1294442) for browser_ext_pageAction_popup_resize.js failures a=backout
browser/components/extensions/ext-utils.js
browser/components/extensions/test/browser/browser_ext_pageAction_popup_resize.js
browser/components/extensions/test/browser/head.js
docshell/base/nsIContentViewer.idl
layout/base/nsDocumentViewer.cpp
--- a/browser/components/extensions/ext-utils.js
+++ b/browser/components/extensions/ext-utils.js
@@ -302,24 +302,35 @@ class BasePopup {
       // Set a maximum height on the <panelview> element to our preferred
       // maximum height, so that the PanelUI resizing code can make an accurate
       // calculation. If we don't do this, the flex sizing logic will prevent us
       // from ever reporting a preferred size smaller than the height currently
       // available to us in the panel.
       height = Math.max(height, this.viewHeight);
       this.viewNode.style.maxHeight = `${height}px`;
     } else {
-      // Adjust the size of the browser based on its content's preferred size.
-      let {contentViewer} = this.browser.docShell;
-      let ratio = this.window.devicePixelRatio;
+      let width, height;
+      try {
+        let w = {}, h = {};
+        this.browser.docShell.contentViewer.getContentSize(w, h);
+
+        width = w.value / this.window.devicePixelRatio;
+        height = h.value / this.window.devicePixelRatio;
 
-      let w = {}, h = {};
-      contentViewer.getContentSizeConstrained(800 * ratio, 600 * ratio, w, h);
-      let width = Math.ceil(w.value / ratio);
-      let height = Math.ceil(h.value / ratio);
+        // The width calculation is imperfect, and is often a fraction of a pixel
+        // too narrow, even after taking the ceiling, which causes lines of text
+        // to wrap.
+        width += 1;
+      } catch (e) {
+        // getContentSize can throw
+        [width, height] = [400, 400];
+      }
+
+      width = Math.ceil(Math.min(width, 800));
+      height = Math.ceil(Math.min(height, 600));
 
       this.browser.style.width = `${width}px`;
       this.browser.style.height = `${height}px`;
     }
 
     let event = new this.window.CustomEvent("WebExtPopupResized");
     this.browser.dispatchEvent(event);
 
--- a/browser/components/extensions/test/browser/browser_ext_pageAction_popup_resize.js
+++ b/browser/components/extensions/test/browser/browser_ext_pageAction_popup_resize.js
@@ -1,28 +1,12 @@
 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set sts=2 sw=2 et tw=80: */
 "use strict";
 
-function* awaitResize(browser) {
-  // Debouncing code makes this a bit racy.
-  // Try to skip the first, early resize, and catch the resize event we're
-  // looking for, but don't wait longer than a few seconds.
-
-  return Promise.race([
-    BrowserTestUtils.waitForEvent(browser, "WebExtPopupResized")
-      .then(() => BrowserTestUtils.waitForEvent(browser, "WebExtPopupResized")),
-    new Promise(resolve => setTimeout(resolve, 5000)),
-  ]);
-}
-
-let delay = ms => new Promise(resolve => {
-  setTimeout(resolve, ms);
-});
-
 add_task(function* testPageActionPopupResize() {
   let extension = ExtensionTestUtils.loadExtension({
     manifest: {
       "page_action": {
         "default_popup": "popup.html",
         "browser_style": true,
       },
     },
@@ -32,145 +16,55 @@ add_task(function* testPageActionPopupRe
 
         browser.pageAction.show(tabId).then(() => {
           browser.test.sendMessage("action-shown");
         });
       });
     },
 
     files: {
-      "popup.html": `<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><div></div></body></html>`,
+      "popup.html": "<html><head><meta charset=\"utf-8\"></head></html>",
     },
   });
 
   yield extension.startup();
   yield extension.awaitMessage("action-shown");
 
   clickPageAction(extension, window);
 
   let {target: panelDocument} = yield BrowserTestUtils.waitForEvent(document, "load", true, (event) => {
     info(`Loaded ${event.target.location}`);
     return event.target.location && event.target.location.href.endsWith("popup.html");
   });
 
   let panelWindow = panelDocument.defaultView;
-  let panelBody = panelDocument.body.firstChild;
-  let body = panelDocument.body;
-  let root = panelDocument.documentElement;
+  let panelBody = panelDocument.body;
 
   function checkSize(expected) {
     is(panelWindow.innerHeight, expected, `Panel window should be ${expected}px tall`);
-    is(body.clientHeight, body.scrollHeight,
+    is(panelBody.clientHeight, panelBody.scrollHeight,
       "Panel body should be tall enough to fit its contents");
-    is(root.clientHeight, root.scrollHeight,
-      "Panel root should be tall enough to fit its contents");
 
     // Tolerate if it is 1px too wide, as that may happen with the current resizing method.
     ok(Math.abs(panelWindow.innerWidth - expected) <= 1, `Panel window should be ${expected}px wide`);
-    is(body.clientWidth, body.scrollWidth,
-       "Panel body should be wide enough to fit its contents");
+    is(panelBody.clientWidth, panelBody.scrollWidth,
+      "Panel body should be wide enough to fit its contents");
   }
 
   function setSize(size) {
     panelBody.style.height = `${size}px`;
     panelBody.style.width = `${size}px`;
-
-    return BrowserTestUtils.waitForEvent(panelWindow, "resize");
   }
 
   let sizes = [
     200,
     400,
     300,
   ];
 
   for (let size of sizes) {
-    yield setSize(size);
+    setSize(size);
+    yield BrowserTestUtils.waitForEvent(panelWindow, "resize");
     checkSize(size);
   }
 
-  yield setSize(1400);
-
-  // Windows has a particular slow resize animation for this panel.
-  if (AppConstants.platform == "win") {
-    while (panelWindow.innerWidth < 800) {
-      yield delay(50);
-    }
-  }
-
-  is(panelWindow.innerWidth, 800, "Panel window width");
-  ok(body.clientWidth <= 800, `Panel body width ${body.clientWidth} is less than 800`);
-  is(body.scrollWidth, 1400, "Panel body scroll width");
-
-  is(panelWindow.innerHeight, 600, "Panel window height");
-  ok(root.clientHeight <= 600, `Panel root height (${root.clientHeight}px) is less than 600px`);
-  is(root.scrollHeight, 1400, "Panel root scroll height");
-
   yield extension.unload();
 });
-
-add_task(function* testPageActionPopupReflow() {
-  let browser;
-
-  let extension = ExtensionTestUtils.loadExtension({
-    manifest: {
-      "page_action": {
-        "default_popup": "popup.html",
-        "browser_style": true,
-      },
-    },
-    background: function() {
-      browser.tabs.query({active: true, currentWindow: true}, tabs => {
-        const tabId = tabs[0].id;
-
-        browser.pageAction.show(tabId).then(() => {
-          browser.test.sendMessage("action-shown");
-        });
-      });
-    },
-
-    files: {
-      "popup.html": `<!DOCTYPE html><html><head><meta charset="utf-8"></head>
-        <body>
-          The quick mauve fox jumps over the opalescent toad, with its glowing
-          eyes, and its vantablack mouth, and its bottomless chasm where you
-          would hope to find a heart, that looks straight into the deepest
-          pits of hell. The fox shivers, and cowers, and tries to run, but
-          the toad is utterly without pity. It turns, ever so slightly...
-        </body>
-      </html>`,
-    },
-  });
-
-  yield extension.startup();
-  yield extension.awaitMessage("action-shown");
-
-  clickPageAction(extension, window);
-
-  browser = yield awaitExtensionPanel(extension);
-
-  let win = browser.contentWindow;
-  let body = win.document.body;
-  let root = win.document.documentElement;
-
-  function setSize(size) {
-    body.style.fontSize = `${size}px`;
-
-    return awaitResize(browser);
-  }
-
-  yield setSize(18);
-
-  is(win.innerWidth, 800, "Panel window should be 800px wide");
-  is(body.clientWidth, 800, "Panel body should be 800px wide");
-  is(body.clientWidth, body.scrollWidth,
-     "Panel body should be wide enough to fit its contents");
-
-  ok(win.innerHeight > 36,
-     `Panel window height (${win.innerHeight}px) should be taller than two lines of text.`);
-
-  is(body.clientHeight, body.scrollHeight,
-    "Panel body should be tall enough to fit its contents");
-  is(root.clientHeight, root.scrollHeight,
-    "Panel root should be tall enough to fit its contents");
-
-  yield extension.unload();
-});
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -6,17 +6,16 @@
  *          getBrowserActionWidget
  *          clickBrowserAction clickPageAction
  *          getBrowserActionPopup getPageActionPopup
  *          closeBrowserAction closePageAction
  *          promisePopupShown promisePopupHidden
  *          openContextMenu closeContextMenu
  *          openExtensionContextMenu closeExtensionContextMenu
  *          imageBuffer getListStyleImage getPanelForNode
- *          awaitExtensionPanel
  */
 
 var {AppConstants} = Cu.import("resource://gre/modules/AppConstants.jsm");
 var {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm");
 
 // Bug 1239884: Our tests occasionally hit a long GC pause at unpredictable
 // times in debug builds, which results in intermittent timeouts. Until we have
 // a better solution, we force a GC after certain strategic tests, which tend to
@@ -86,35 +85,16 @@ function promisePopupHidden(popup) {
 
 function getPanelForNode(node) {
   while (node.localName != "panel") {
     node = node.parentNode;
   }
   return node;
 }
 
-var awaitExtensionPanel = Task.async(function* (extension, win = window, filename = "popup.html") {
-  let {target} = yield BrowserTestUtils.waitForEvent(win.document, "load", true, (event) => {
-    return event.target.location && event.target.location.href.endsWith(filename);
-  });
-
-  let browser = target.defaultView
-                      .QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDocShell)
-                      .chromeEventHandler;
-
-  if (browser.matches(".webextension-preload-browser")) {
-    let event = yield BrowserTestUtils.waitForEvent(browser, "SwapDocShells");
-    browser = event.detail;
-  }
-
-  yield promisePopupShown(getPanelForNode(browser));
-
-  return browser;
-});
-
 function getBrowserActionWidget(extension) {
   return CustomizableUI.getWidget(makeWidgetId(extension.id) + "-browser-action");
 }
 
 function getBrowserActionPopup(extension, win = window) {
   let group = getBrowserActionWidget(extension);
 
   if (group.areaType == CustomizableUI.TYPE_TOOLBAR) {
--- a/docshell/base/nsIContentViewer.idl
+++ b/docshell/base/nsIContentViewer.idl
@@ -222,26 +222,16 @@ interface nsIContentViewer : nsISupports
    */
   attribute int32_t hintCharacterSetSource;
 
   /**
    * Requests the size of the content to the container.
    */
   void getContentSize(out long width, out long height);
 
-  /**
-   * Returns the preferred width and height of the content, constrained to the
-   * given maximum values. If either maxWidth or maxHeight is less than zero,
-   * that dimension is not constrained.
-   *
-   * All input and output values are in device pixels, rather than CSS pixels.
-   */
-  void getContentSizeConstrained(in long maxWidth, in long maxHeight,
-                                 out long width, out long height);
-
   /** The minimum font size  */
   attribute long minFontSize;
 
   /**
    * Append |this| and all of its descendants to the given array,
    * in depth-first pre-order traversal.
    */
   [noscript] void appendSubtree(in nsIContentViewerTArray array);
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -295,19 +295,16 @@ private:
    * reflow
    */
   nsresult InitPresentationStuff(bool aDoInitialReflow);
 
   nsresult GetPopupNode(nsIDOMNode** aNode);
   nsresult GetPopupLinkNode(nsIDOMNode** aNode);
   nsresult GetPopupImageNode(nsIImageLoadingContent** aNode);
 
-  nsresult GetContentSizeInternal(int32_t* aWidth, int32_t* aHeight,
-                                  nscoord aMaxWidth, nscoord aMaxHeight);
-
   void PrepareToStartLoad(void);
 
   nsresult SyncParentSubDocMap();
 
   mozilla::dom::Selection* GetDocumentSelection();
 
   void DestroyPresShell();
   void DestroyPresContext();
@@ -3266,105 +3263,67 @@ nsDocumentViewer::ResumePainting()
   nsIPresShell* presShell = GetPresShell();
   if (presShell) {
     presShell->ResumePainting();
   }
 
   return NS_OK;
 }
 
-nsresult
-nsDocumentViewer::GetContentSizeInternal(int32_t* aWidth, int32_t* aHeight,
-                                         nscoord aMaxWidth, nscoord aMaxHeight)
+NS_IMETHODIMP
+nsDocumentViewer::GetContentSize(int32_t* aWidth, int32_t* aHeight)
 {
-  NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
-
-  nsCOMPtr<nsIPresShell> presShell;
-  GetPresShell(getter_AddRefs(presShell));
-  NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
-
-  // Flush out all content and style updates. We can't use a resize reflow
-  // because it won't change some sizes that a style change reflow will.
-  mDocument->FlushPendingNotifications(Flush_Layout);
+   NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
+
+   // Skip doing this on docshell-less documents for now
+   nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(mContainer);
+   NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_NOT_AVAILABLE);
+   
+   nsCOMPtr<nsIDocShellTreeItem> docShellParent;
+   docShellAsItem->GetSameTypeParent(getter_AddRefs(docShellParent));
+
+   // It's only valid to access this from a top frame.  Doesn't work from
+   // sub-frames.
+   NS_ENSURE_TRUE(!docShellParent, NS_ERROR_FAILURE);
+
+   nsCOMPtr<nsIPresShell> presShell;
+   GetPresShell(getter_AddRefs(presShell));
+   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
+
+   // Flush out all content and style updates. We can't use a resize reflow
+   // because it won't change some sizes that a style change reflow will.
+   mDocument->FlushPendingNotifications(Flush_Layout);
 
   nsIFrame *root = presShell->GetRootFrame();
   NS_ENSURE_TRUE(root, NS_ERROR_FAILURE);
 
   nscoord prefWidth;
   {
     nsRenderingContext rcx(presShell->CreateReferenceRenderingContext());
     prefWidth = root->GetPrefISize(&rcx);
   }
-  if (prefWidth > aMaxWidth) {
-    prefWidth = aMaxWidth;
-  }
 
   nsresult rv = presShell->ResizeReflow(prefWidth, NS_UNCONSTRAINEDSIZE);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  RefPtr<nsPresContext> presContext;
-  GetPresContext(getter_AddRefs(presContext));
-  NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
-
-  // so how big is it?
-  nsRect shellArea = presContext->GetVisibleArea();
-  if (shellArea.height > aMaxHeight) {
-    // Reflow to max height if we would up too tall.
-    rv = presShell->ResizeReflow(prefWidth, aMaxHeight);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    shellArea = presContext->GetVisibleArea();
-  }
-
-  // Protect against bogus returns here
-  NS_ENSURE_TRUE(shellArea.width != NS_UNCONSTRAINEDSIZE &&
-                 shellArea.height != NS_UNCONSTRAINEDSIZE,
-                 NS_ERROR_FAILURE);
-
-  *aWidth = presContext->AppUnitsToDevPixels(shellArea.width);
-  *aHeight = presContext->AppUnitsToDevPixels(shellArea.height);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocumentViewer::GetContentSize(int32_t* aWidth, int32_t* aHeight)
-{
-  // Skip doing this on docshell-less documents for now
-  nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(mContainer);
-  NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_NOT_AVAILABLE);
-
-  nsCOMPtr<nsIDocShellTreeItem> docShellParent;
-  docShellAsItem->GetSameTypeParent(getter_AddRefs(docShellParent));
-
-  // It's only valid to access this from a top frame.  Doesn't work from
-  // sub-frames.
-  NS_ENSURE_TRUE(!docShellParent, NS_ERROR_FAILURE);
-
-  return GetContentSizeInternal(aWidth, aHeight, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
-}
-
-NS_IMETHODIMP
-nsDocumentViewer::GetContentSizeConstrained(int32_t aMaxWidth, int32_t aMaxHeight,
-                                            int32_t* aWidth, int32_t* aHeight)
-{
-  RefPtr<nsPresContext> presContext;
-  GetPresContext(getter_AddRefs(presContext));
-  NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
-
-  nscoord maxWidth = NS_UNCONSTRAINEDSIZE;
-  nscoord maxHeight = NS_UNCONSTRAINEDSIZE;
-  if (aMaxWidth > 0) {
-    maxWidth = presContext->DevPixelsToAppUnits(aMaxWidth);
-  }
-  if (aMaxHeight > 0) {
-    maxHeight = presContext->DevPixelsToAppUnits(aMaxHeight);
-  }
-
-  return GetContentSizeInternal(aWidth, aHeight, maxWidth, maxHeight);
+   RefPtr<nsPresContext> presContext;
+   GetPresContext(getter_AddRefs(presContext));
+   NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
+
+   // so how big is it?
+   nsRect shellArea = presContext->GetVisibleArea();
+   // Protect against bogus returns here
+   NS_ENSURE_TRUE(shellArea.width != NS_UNCONSTRAINEDSIZE &&
+                  shellArea.height != NS_UNCONSTRAINEDSIZE,
+                  NS_ERROR_FAILURE);
+
+   *aWidth = presContext->AppUnitsToDevPixels(shellArea.width);
+   *aHeight = presContext->AppUnitsToDevPixels(shellArea.height);
+
+   return NS_OK;
 }
 
 
 NS_IMPL_ISUPPORTS(nsDocViewerSelectionListener, nsISelectionListener)
 
 nsresult nsDocViewerSelectionListener::Init(nsDocumentViewer *aDocViewer)
 {
   mDocViewer = aDocViewer;