Bug 1280876 - don't take screenshots of pages that have the findbar open. r?mconley,jaws draft
authorMike de Boer <mdeboer@mozilla.com>
Wed, 10 Aug 2016 11:23:47 +0200
changeset 399055 002aa704f8097f0106654fcc4b25f1a443d6e4f3
parent 399054 3269dd1a824d1b42cb021d1fb6858885179940b0
child 527826 8b51b2356452a5c20e6b7b76be9a36dc319fb962
push id25718
push usermdeboer@mozilla.com
push dateWed, 10 Aug 2016 09:24:08 +0000
reviewersmconley, jaws
bugs1280876
milestone51.0a1
Bug 1280876 - don't take screenshots of pages that have the findbar open. r?mconley,jaws MozReview-Commit-ID: Dmz0MaukNVq
toolkit/components/thumbnails/PageThumbUtils.jsm
toolkit/content/widgets/findbar.xml
toolkit/modules/BrowserUtils.jsm
toolkit/modules/Finder.jsm
toolkit/modules/RemoteFinder.jsm
--- a/toolkit/components/thumbnails/PageThumbUtils.jsm
+++ b/toolkit/components/thumbnails/PageThumbUtils.jsm
@@ -11,16 +11,19 @@ this.EXPORTED_SYMBOLS = ["PageThumbUtils
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Promise.jsm", this);
 Cu.import("resource://gre/modules/AppConstants.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
+  "resource://gre/modules/BrowserUtils.jsm");
+
 this.PageThumbUtils = {
   // The default background color for page thumbnails.
   THUMBNAIL_BG_COLOR: "#fff",
   // The namespace for thumbnail canvas elements.
   HTML_NAMESPACE: "http://www.w3.org/1999/xhtml",
 
   /**
    * Creates a new canvas element in the context of aWindow, or if aWindow
@@ -258,16 +261,20 @@ this.PageThumbUtils = {
 
     if (scaledWidth > thumbnailWidth)
       width -= Math.floor(Math.abs(scaledWidth - thumbnailWidth) * scale);
 
     return [width, height, scale];
   },
 
   shouldStoreContentThumbnail: function (aDocument, aDocShell) {
+    if (BrowserUtils.isToolbarVisible(aDocShell, "findbar")) {
+      return false;
+    }
+
     // FIXME Bug 720575 - Don't capture thumbnails for SVG or XML documents as
     //       that currently regresses Talos SVG tests.
     if (aDocument instanceof Ci.nsIDOMXMLDocument) {
       return false;
     }
 
     let webNav = aDocShell.QueryInterface(Ci.nsIWebNavigation);
 
--- a/toolkit/content/widgets/findbar.xml
+++ b/toolkit/content/widgets/findbar.xml
@@ -755,16 +755,18 @@
             this.hidden = false;
 
             this._updateStatusUI(this.nsITypeAheadFind.FIND_FOUND);
 
             let event = document.createEvent("Events");
             event.initEvent("findbaropen", true, false);
             this.dispatchEvent(event);
 
+            this.browser.finder.onFindbarOpen();
+
             return true;
           }
           return false;
         ]]></body>
       </method>
 
       <!--
         - Closes the findbar.
--- a/toolkit/modules/BrowserUtils.jsm
+++ b/toolkit/modules/BrowserUtils.jsm
@@ -298,16 +298,72 @@ this.BrowserUtils = {
     if ((loc.protocol == "about:" || loc.protocol == "chrome:") &&
         (win.document.documentElement &&
          win.document.documentElement.getAttribute("disablefastfind") == "true"))
       return false;
 
     return true;
   },
 
+  _visibleToolbarsMap: new WeakMap(),
+
+  /**
+   * Return true if any or a specific toolbar that interacts with the content
+   * document is visible.
+   *
+   * @param  {nsIDocShell} docShell The docShell instance that a toolbar should
+   *                                be interacting with
+   * @param  {String}      which    Identifier of a specific toolbar
+   * @return {Boolean}
+   */
+  isToolbarVisible(docShell, which) {
+    let window = this.getRootWindow(docShell);
+    if (!this._visibleToolbarsMap.has(window))
+      return false;
+    let toolbars = this._visibleToolbarsMap.get(window);
+    return !!toolbars && toolbars.has(which);
+  },
+
+  /**
+   * Track whether a toolbar is visible for a given a docShell.
+   *
+   * @param  {nsIDocShell} docShell  The docShell instance that a toolbar should
+   *                                 be interacting with
+   * @param  {String}      which     Identifier of a specific toolbar
+   * @param  {Boolean}     [visible] Whether the toolbar is visible. Optional,
+   *                                 defaults to `true`.
+   */
+  trackToolbarVisibility(docShell, which, visible = true) {
+    // We have to get the root window object, because XPConnect WrappedNatives
+    // can't be used as WeakMap keys.
+    let window = this.getRootWindow(docShell);
+    let toolbars = this._visibleToolbarsMap.get(window);
+    if (!toolbars) {
+      toolbars = new Set();
+      this._visibleToolbarsMap.set(window, toolbars);
+    }
+    if (!visible)
+      toolbars.delete(which);
+    else
+      toolbars.add(which);
+  },
+
+  /**
+   * Retrieve the root window object (i.e. the top-most content global) for a
+   * specific docShell object.
+   *
+   * @param  {nsIDocShell} docShell
+   * @return {nsIDOMWindow}
+   */
+  getRootWindow(docShell) {
+    return docShell.QueryInterface(Ci.nsIDocShellTreeItem)
+      .sameTypeRootTreeItem.QueryInterface(Ci.nsIInterfaceRequestor)
+      .getInterface(Ci.nsIDOMWindow);
+  },
+
   getSelectionDetails: function(topWindow, aCharLen) {
     // selections of more than 150 characters aren't useful
     const kMaxSelectionLen = 150;
     const charLen = Math.min(aCharLen || kMaxSelectionLen, kMaxSelectionLen);
 
     let focusedWindow = {};
     let focusedElement = Services.focus.getFocusedElementForWindow(topWindow, true, focusedWindow);
     focusedWindow = focusedWindow.value;
--- a/toolkit/modules/Finder.jsm
+++ b/toolkit/modules/Finder.jsm
@@ -7,16 +7,19 @@ this.EXPORTED_SYMBOLS = ["Finder","GetCl
 
 const { interfaces: Ci, classes: Cc, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Geometry.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
+  "resource://gre/modules/BrowserUtils.jsm");
+
 XPCOMUtils.defineLazyServiceGetter(this, "TextToSubURIService",
                                          "@mozilla.org/intl/texttosuburi;1",
                                          "nsITextToSubURI");
 XPCOMUtils.defineLazyServiceGetter(this, "Clipboard",
                                          "@mozilla.org/widget/clipboard;1",
                                          "nsIClipboard");
 XPCOMUtils.defineLazyServiceGetter(this, "ClipboardHelper",
                                          "@mozilla.org/widget/clipboardhelper;1",
@@ -311,16 +314,21 @@ Finder.prototype = {
         this._getWindow().focus()
       }
     } catch (e) {}
   },
 
   onFindbarClose: function() {
     this.enableSelection();
     this.highlighter.highlight(false);
+    BrowserUtils.trackToolbarVisibility(this._docShell, "findbar", false);
+  },
+
+  onFindbarOpen: function() {
+    BrowserUtils.trackToolbarVisibility(this._docShell, "findbar", true);
   },
 
   onModalHighlightChange(useModalHighlight) {
     if (this._highlighter)
       this._highlighter.onModalHighlightChange(useModalHighlight);
   },
 
   onHighlightAllChange(highlightAll) {
--- a/toolkit/modules/RemoteFinder.jsm
+++ b/toolkit/modules/RemoteFinder.jsm
@@ -180,16 +180,20 @@ RemoteFinder.prototype = {
     this._browser.focus();
     this._browser.messageManager.sendAsyncMessage("Finder:FocusContent");
   },
 
   onFindbarClose: function () {
     this._browser.messageManager.sendAsyncMessage("Finder:FindbarClose");
   },
 
+  onFindbarOpen: function () {
+    this._browser.messageManager.sendAsyncMessage("Finder:FindbarOpen");
+  },
+
   onModalHighlightChange: function(aUseModalHighlight) {
     this._browser.messageManager.sendAsyncMessage("Finder:ModalHighlightChange", {
       useModalHighlight: aUseModalHighlight
     });
   },
 
   onHighlightAllChange: function(aHighlightAll) {
     this._browser.messageManager.sendAsyncMessage("Finder:HighlightAllChange", {
@@ -235,16 +239,17 @@ RemoteFinderListener.prototype = {
     "Finder:SetSearchStringToSelection",
     "Finder:GetInitialSelection",
     "Finder:Highlight",
     "Finder:HighlightAllChange",
     "Finder:EnableSelection",
     "Finder:RemoveSelection",
     "Finder:FocusContent",
     "Finder:FindbarClose",
+    "Finder:FindbarOpen",
     "Finder:KeyPress",
     "Finder:MatchesCount",
     "Finder:ModalHighlightChange"
   ],
 
   onFindResult: function (aData) {
     this._global.sendAsyncMessage("Finder:Result", aData);
   },
@@ -318,16 +323,20 @@ RemoteFinderListener.prototype = {
       case "Finder:FocusContent":
         this._finder.focusContent();
         break;
 
       case "Finder:FindbarClose":
         this._finder.onFindbarClose();
         break;
 
+      case "Finder:FindbarOpen":
+        this._finder.onFindbarOpen();
+        break;
+
       case "Finder:KeyPress":
         this._finder.keyPress(data);
         break;
 
       case "Finder:MatchesCount":
         this._finder.requestMatchesCount(data.searchString, data.matchLimit, data.linksOnly);
         break;