diff --git a/browser/base/content/browser-tabPreviews.js b/browser/base/content/browser-tabPreviews.js index 7fbfc6aea0ea..14e7e97e5c64 100644 --- a/browser/base/content/browser-tabPreviews.js +++ b/browser/base/content/browser-tabPreviews.js @@ -10,18 +10,6 @@ * Tab previews utility, produces thumbnails */ var tabPreviews = { - aspectRatio: 0.5625, // 16:9 - - get width() { - delete this.width; - return this.width = Math.ceil(screen.availWidth / 5.75); - }, - - get height() { - delete this.height; - return this.height = Math.round(this.width * this.aspectRatio); - }, - init: function tabPreviews_init() { if (this._selectedTab) return; @@ -29,6 +17,12 @@ var tabPreviews = { gBrowser.tabContainer.addEventListener("TabSelect", this, false); gBrowser.tabContainer.addEventListener("SSTabRestored", this, false); + + let screenManager = Cc["@mozilla.org/gfx/screenmanager;1"] + .getService(Ci.nsIScreenManager); + let left = {}, top = {}, width = {}, height = {}; + screenManager.primaryScreen.GetRectDisplayPix(left, top, width, height); + this.aspectRatio = height.value / width.value; }, get: function tabPreviews_get(aTab) { @@ -52,31 +46,35 @@ var tabPreviews = { return this.capture(aTab, !aTab.hasAttribute("busy")); }, - capture: function tabPreviews_capture(aTab, aStore) { - var thumbnail = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); - thumbnail.mozOpaque = true; - thumbnail.height = this.height; - thumbnail.width = this.width; + capture: function tabPreviews_capture(aTab, aShouldCache) { + let browser = aTab.linkedBrowser; + let uri = browser.currentURI.spec; - // drawWindow doesn't yet work with e10s (bug 698371) - if (gMultiProcessBrowser) - return thumbnail; + // FIXME: The gBrowserThumbnails._shouldCapture determines whether + // thumbnails should be written to disk. This should somehow be part + // of the PageThumbs API. (bug 1062414) + if (aShouldCache && + gBrowserThumbnails._shouldCapture(browser)) { + let img = new Image; - var ctx = thumbnail.getContext("2d"); - var win = aTab.linkedBrowser.contentWindow; - var snippetWidth = win.innerWidth * .6; - var scale = this.width / snippetWidth; - ctx.scale(scale, scale); - ctx.drawWindow(win, win.scrollX, win.scrollY, - snippetWidth, snippetWidth * this.aspectRatio, "rgb(255,255,255)"); + PageThumbs.captureAndStore(browser, function () { + img.src = PageThumbs.getThumbnailURL(uri); + }); - if (aStore && - aTab.linkedBrowser /* bug 795608: the tab may got removed while drawing the thumbnail */) { - aTab.__thumbnail = thumbnail; - aTab.__thumbnail_lastURI = aTab.linkedBrowser.currentURI.spec; + aTab.__thumbnail = img; + aTab.__thumbnail_lastURI = uri; + return img; } - return thumbnail; + let canvas = PageThumbs.createCanvas(window); + + if (aShouldCache) { + aTab.__thumbnail = canvas; + aTab.__thumbnail_lastURI = uri; + } + + PageThumbs.captureToCanvas(aTab.linkedBrowser.contentWindow, canvas); + return canvas; }, handleEvent: function tabPreviews_handleEvent(event) { @@ -182,8 +180,7 @@ var ctrlTab = { get isOpen () this.panel.state == "open" || this.panel.state == "showing" || this._timer, get tabCount () this.tabList.length, get tabPreviewCount () Math.min(this.previews.length - 1, this.tabCount), - get canvasWidth () Math.min(tabPreviews.width, - Math.ceil(screen.availWidth * .85 / this.tabPreviewCount)), + get canvasWidth () Math.ceil(screen.availWidth * .85 / this.tabPreviewCount), get canvasHeight () Math.round(this.canvasWidth * tabPreviews.aspectRatio), get tabList () { @@ -505,6 +502,15 @@ var ctrlTab = { } }, + filterForThumbnailExpiration: function (aCallback) { + let urls = []; + let previewCount = this.tabPreviewCount; + for (let i = 0; i < previewCount; i++) + urls.push(this.tabList[i].linkedBrowser.currentURI.spec); + + aCallback(urls); + }, + _initRecentlyUsedTabs: function () { this._recentlyUsedTabs = Array.filter(gBrowser.tabs, tab => !tab.closing) @@ -525,6 +531,11 @@ var ctrlTab = { document[toggleEventListener]("keypress", this, false); gBrowser.mTabBox.handleCtrlTab = !enable; + if (enable) + PageThumbs.addExpirationFilter(this); + else + PageThumbs.removeExpirationFilter(this); + // If we're not running, hide the "Show All Tabs" menu item, // as Shift+Ctrl+Tab will be handled by the tab bar. document.getElementById("menu_showAllTabs").hidden = !enable; diff --git a/browser/base/content/browser-thumbnails.js b/browser/base/content/browser-thumbnails.js index 6d68dd5a3ddb..bb2d2bce328c 100644 --- a/browser/base/content/browser-thumbnails.js +++ b/browser/base/content/browser-thumbnails.js @@ -103,7 +103,9 @@ let gBrowserThumbnails = { }, _capture: function Thumbnails_capture(aBrowser) { - if (this._shouldCapture(aBrowser)) + // Only capture about:newtab top sites. + if (this._topSiteURLs.indexOf(aBrowser.currentURI.spec) >= 0 && + this._shouldCapture(aBrowser)) PageThumbs.captureAndStoreIfStale(aBrowser); }, @@ -121,15 +123,12 @@ let gBrowserThumbnails = { this._timeouts.set(aBrowser, timeout); }, + // FIXME: This should be part of the PageThumbs API. (bug 1062414) _shouldCapture: function Thumbnails_shouldCapture(aBrowser) { // Capture only if it's the currently selected tab. if (aBrowser != gBrowser.selectedBrowser) return false; - // Only capture about:newtab top sites. - if (this._topSiteURLs.indexOf(aBrowser.currentURI.spec) < 0) - return false; - // Don't capture in per-window private browsing mode. if (PrivateBrowsingUtils.isWindowPrivate(window)) return false; diff --git a/browser/base/content/test/general/browser_tabopen_reflows.js b/browser/base/content/test/general/browser_tabopen_reflows.js index 2e3c35af6567..95cd78873ef2 100644 --- a/browser/base/content/test/general/browser_tabopen_reflows.js +++ b/browser/base/content/test/general/browser_tabopen_reflows.js @@ -49,14 +49,6 @@ const EXPECTED_REFLOWS = [ "ssi_updateWindowFeatures/<@resource:///modules/sessionstore/SessionStore.jsm|" + "ssi_updateWindowFeatures@resource:///modules/sessionstore/SessionStore.jsm|" + "ssi_collectWindowData@resource:///modules/sessionstore/SessionStore.jsm|", - - // tabPreviews.capture() - "tabPreviews_capture@chrome://browser/content/browser.js|" + - "tabPreviews_handleEvent/<@chrome://browser/content/browser.js|", - - // tabPreviews.capture() - "tabPreviews_capture@chrome://browser/content/browser.js|" + - "@chrome://browser/content/browser.js|" ]; const PREF_PRELOAD = "browser.newtab.preload"; diff --git a/toolkit/components/thumbnails/PageThumbs.jsm b/toolkit/components/thumbnails/PageThumbs.jsm index 12983407ebbf..984efef8e1d1 100644 --- a/toolkit/components/thumbnails/PageThumbs.jsm +++ b/toolkit/components/thumbnails/PageThumbs.jsm @@ -179,7 +179,7 @@ this.PageThumbs = { return; } - let canvas = this._createCanvas(); + let canvas = this.createCanvas(); this.captureToCanvas(aWindow, canvas); // Fetch the canvas data on the next event loop tick so that we allow @@ -203,7 +203,7 @@ this.PageThumbs = { return null; } - let canvas = this._createCanvas(); + let canvas = this.createCanvas(); this.captureToCanvas(aWindow, canvas); let deferred = Promise.defer(); @@ -418,7 +418,7 @@ this.PageThumbs = { * canvas. If not given, the hidden window will be used. * @return The newly created canvas. */ - _createCanvas: function PageThumbs_createCanvas(aWindow) { + createCanvas: function PageThumbs_createCanvas(aWindow) { let doc = (aWindow || Services.appShell.hiddenDOMWindow).document; let canvas = doc.createElementNS(HTML_NAMESPACE, "canvas"); canvas.mozOpaque = true; diff --git a/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js b/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js index dac1cbf56903..278c5290d600 100644 --- a/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js +++ b/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js @@ -127,7 +127,7 @@ const backgroundPageThumbsContent = { capture.finalURL = this._webNav.currentURI.spec; capture.pageLoadTime = new Date() - capture.pageLoadStartDate; - let canvas = PageThumbs._createCanvas(content); + let canvas = PageThumbs.createCanvas(content); let canvasDrawDate = new Date(); PageThumbs._captureToCanvas(content, canvas); capture.canvasDrawTime = new Date() - canvasDrawDate;