browser/base/content/browser-thumbnails.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 #ifdef 0
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     4  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #endif
     7 Cu.import("resource://gre/modules/NewTabUtils.jsm");
     9 /**
    10  * Keeps thumbnails of open web pages up-to-date.
    11  */
    12 let gBrowserThumbnails = {
    13   /**
    14    * Pref that controls whether we can store SSL content on disk
    15    */
    16   PREF_DISK_CACHE_SSL: "browser.cache.disk_cache_ssl",
    18   _captureDelayMS: 1000,
    20   /**
    21    * Used to keep track of disk_cache_ssl preference
    22    */
    23   _sslDiskCacheEnabled: null,
    25   /**
    26    * Map of capture() timeouts assigned to their browsers.
    27    */
    28   _timeouts: null,
    30   /**
    31    * List of tab events we want to listen for.
    32    */
    33   _tabEvents: ["TabClose", "TabSelect"],
    35   init: function Thumbnails_init() {
    36     // Bug 863512 - Make page thumbnails work in electrolysis
    37     if (gMultiProcessBrowser)
    38       return;
    40     PageThumbs.addExpirationFilter(this);
    41     gBrowser.addTabsProgressListener(this);
    42     Services.prefs.addObserver(this.PREF_DISK_CACHE_SSL, this, false);
    44     this._sslDiskCacheEnabled =
    45       Services.prefs.getBoolPref(this.PREF_DISK_CACHE_SSL);
    47     this._tabEvents.forEach(function (aEvent) {
    48       gBrowser.tabContainer.addEventListener(aEvent, this, false);
    49     }, this);
    51     this._timeouts = new WeakMap();
    52   },
    54   uninit: function Thumbnails_uninit() {
    55     // Bug 863512 - Make page thumbnails work in electrolysis
    56     if (gMultiProcessBrowser)
    57       return;
    59     PageThumbs.removeExpirationFilter(this);
    60     gBrowser.removeTabsProgressListener(this);
    61     Services.prefs.removeObserver(this.PREF_DISK_CACHE_SSL, this);
    63     this._tabEvents.forEach(function (aEvent) {
    64       gBrowser.tabContainer.removeEventListener(aEvent, this, false);
    65     }, this);
    66   },
    68   handleEvent: function Thumbnails_handleEvent(aEvent) {
    69     switch (aEvent.type) {
    70       case "scroll":
    71         let browser = aEvent.currentTarget;
    72         if (this._timeouts.has(browser))
    73           this._delayedCapture(browser);
    74         break;
    75       case "TabSelect":
    76         this._delayedCapture(aEvent.target.linkedBrowser);
    77         break;
    78       case "TabClose": {
    79         this._clearTimeout(aEvent.target.linkedBrowser);
    80         break;
    81       }
    82     }
    83   },
    85   observe: function Thumbnails_observe() {
    86     this._sslDiskCacheEnabled =
    87       Services.prefs.getBoolPref(this.PREF_DISK_CACHE_SSL);
    88   },
    90   filterForThumbnailExpiration:
    91   function Thumbnails_filterForThumbnailExpiration(aCallback) {
    92     aCallback(this._topSiteURLs);
    93   },
    95   /**
    96    * State change progress listener for all tabs.
    97    */
    98   onStateChange: function Thumbnails_onStateChange(aBrowser, aWebProgress,
    99                                                    aRequest, aStateFlags, aStatus) {
   100     if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
   101         aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK)
   102       this._delayedCapture(aBrowser);
   103   },
   105   _capture: function Thumbnails_capture(aBrowser) {
   106     if (this._shouldCapture(aBrowser))
   107       PageThumbs.captureAndStoreIfStale(aBrowser);
   108   },
   110   _delayedCapture: function Thumbnails_delayedCapture(aBrowser) {
   111     if (this._timeouts.has(aBrowser))
   112       clearTimeout(this._timeouts.get(aBrowser));
   113     else
   114       aBrowser.addEventListener("scroll", this, true);
   116     let timeout = setTimeout(function () {
   117       this._clearTimeout(aBrowser);
   118       this._capture(aBrowser);
   119     }.bind(this), this._captureDelayMS);
   121     this._timeouts.set(aBrowser, timeout);
   122   },
   124   _shouldCapture: function Thumbnails_shouldCapture(aBrowser) {
   125     // Capture only if it's the currently selected tab.
   126     if (aBrowser != gBrowser.selectedBrowser)
   127       return false;
   129     // Only capture about:newtab top sites.
   130     if (this._topSiteURLs.indexOf(aBrowser.currentURI.spec) < 0)
   131       return false;
   133     // Don't capture in per-window private browsing mode.
   134     if (PrivateBrowsingUtils.isWindowPrivate(window))
   135       return false;
   137     let doc = aBrowser.contentDocument;
   139     // FIXME Bug 720575 - Don't capture thumbnails for SVG or XML documents as
   140     //       that currently regresses Talos SVG tests.
   141     if (doc instanceof SVGDocument || doc instanceof XMLDocument)
   142       return false;
   144     // There's no point in taking screenshot of loading pages.
   145     if (aBrowser.docShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
   146       return false;
   148     // Don't take screenshots of about: pages.
   149     if (aBrowser.currentURI.schemeIs("about"))
   150       return false;
   152     let channel = aBrowser.docShell.currentDocumentChannel;
   154     // No valid document channel. We shouldn't take a screenshot.
   155     if (!channel)
   156       return false;
   158     // Don't take screenshots of internally redirecting about: pages.
   159     // This includes error pages.
   160     let uri = channel.originalURI;
   161     if (uri.schemeIs("about"))
   162       return false;
   164     let httpChannel;
   165     try {
   166       httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
   167     } catch (e) { /* Not an HTTP channel. */ }
   169     if (httpChannel) {
   170       // Continue only if we have a 2xx status code.
   171       try {
   172         if (Math.floor(httpChannel.responseStatus / 100) != 2)
   173           return false;
   174       } catch (e) {
   175         // Can't get response information from the httpChannel
   176         // because mResponseHead is not available.
   177         return false;
   178       }
   180       // Cache-Control: no-store.
   181       if (httpChannel.isNoStoreResponse())
   182         return false;
   184       // Don't capture HTTPS pages unless the user explicitly enabled it.
   185       if (uri.schemeIs("https") && !this._sslDiskCacheEnabled)
   186         return false;
   187     }
   189     return true;
   190   },
   192   get _topSiteURLs() {
   193     return NewTabUtils.links.getLinks().reduce((urls, link) => {
   194       if (link)
   195         urls.push(link.url);
   196       return urls;
   197     }, []);
   198   },
   200   _clearTimeout: function Thumbnails_clearTimeout(aBrowser) {
   201     if (this._timeouts.has(aBrowser)) {
   202       aBrowser.removeEventListener("scroll", this, false);
   203       clearTimeout(this._timeouts.get(aBrowser));
   204       this._timeouts.delete(aBrowser);
   205     }
   206   }
   207 };

mercurial