Merge fx-team to m-c.

This commit is contained in:
Ms2ger 2013-02-28 12:06:24 +01:00
commit 53bbc1590c
9 changed files with 63 additions and 269 deletions

View File

@ -715,7 +715,6 @@ let TabItems = {
_lastUpdateTime: Date.now(),
_eventListeners: [],
_pauseUpdateForTest: false,
tempCanvas: null,
_reconnectingPaused: false,
tabItemPadding: {},
_mozAfterPaintHandler: null,
@ -744,11 +743,6 @@ let TabItems = {
.attr('moz-opaque', '');
$canvas.appendTo(iQ("body"));
$canvas.hide();
this.tempCanvas = $canvas[0];
// 150 pixels is an empirical size, below which FF's drawWindow()
// algorithm breaks down
this.tempCanvas.width = 150;
this.tempCanvas.height = 112;
let mm = gWindow.messageManager;
this._mozAfterPaintHandler = this.onMozAfterPaint.bind(this);
@ -1386,94 +1380,12 @@ TabCanvas.prototype = Utils.extend(new Subscribable(), {
return;
}
let ctx = this.canvas.getContext("2d");
let tempCanvas = TabItems.tempCanvas;
let bgColor = '#fff';
if (w < tempCanvas.width) {
// Small draw case where nearest-neighbor algorithm breaks down in Windows
// First draw to a larger canvas (150px wide), and then draw that image
// to the destination canvas.
let tempCtx = tempCanvas.getContext("2d");
this._drawWindow(tempCtx, tempCanvas.width, tempCanvas.height, bgColor);
// Now copy to tabitem canvas.
try {
this._fillCanvasBackground(ctx, w, h, bgColor);
ctx.drawImage(tempCanvas, 0, 0, w, h);
} catch (e) {
Utils.error('paint', e);
}
} else {
// General case where nearest neighbor algorithm looks good
// Draw directly to the destination canvas
this._drawWindow(ctx, w, h, bgColor);
}
let win = this.tab.linkedBrowser.contentWindow;
gPageThumbnails.captureToCanvas(win, this.canvas);
this._sendToSubscribers("painted");
},
// ----------
// Function: _fillCanvasBackground
// Draws a rectangle of <width>x<height> with color <bgColor> to the given
// canvas context.
_fillCanvasBackground: function TabCanvas__fillCanvasBackground(ctx, width, height, bgColor) {
ctx.fillStyle = bgColor;
ctx.fillRect(0, 0, width, height);
},
// ----------
// Function: _drawWindow
// Draws contents of the tabs' browser window to the given canvas context.
_drawWindow: function TabCanvas__drawWindow(ctx, width, height, bgColor) {
this._fillCanvasBackground(ctx, width, height, bgColor);
let rect = this._calculateClippingRect(width, height);
let scaler = width / rect.width;
ctx.save();
ctx.scale(scaler, scaler);
try {
let win = this.tab.linkedBrowser.contentWindow;
ctx.drawWindow(win, rect.left, rect.top, rect.width, rect.height,
bgColor, ctx.DRAWWINDOW_DO_NOT_FLUSH);
} catch (e) {
Utils.error('paint', e);
}
ctx.restore();
},
// ----------
// Function: _calculateClippingRect
// Calculate the clipping rect that will be projected to the tab's
// thumbnail canvas.
_calculateClippingRect: function TabCanvas__calculateClippingRect(origWidth, origHeight) {
let win = this.tab.linkedBrowser.contentWindow;
// TODO BUG 631593: retrieve actual scrollbar width
// 25px is supposed to be width of the vertical scrollbar
let maxWidth = Math.max(1, win.innerWidth - 25);
let maxHeight = win.innerHeight;
let height = Math.min(maxHeight, Math.floor(origHeight * maxWidth / origWidth));
let width = Math.floor(origWidth * height / origHeight);
// very short pages in combination with a very wide browser window force us
// to extend the clipping rect and add some empty space around the thumb
let factor = 0.7;
if (width < maxWidth * factor) {
width = maxWidth * factor;
height = Math.floor(origHeight * width / origWidth);
}
let left = win.scrollX + Math.max(0, Math.round((maxWidth - width) / 2));
let top = win.scrollY;
return new Rect(left, top, width, height);
},
// ----------
// Function: toImageData
toImageData: function TabCanvas_toImageData() {

View File

@ -27,7 +27,6 @@ _BROWSER_FILES = \
browser_tabview_bug590606.js \
browser_tabview_bug591706.js \
browser_tabview_bug593283.js \
browser_tabview_bug594958.js \
browser_tabview_bug595191.js \
browser_tabview_bug595436.js \
browser_tabview_bug595518.js \

View File

@ -1,144 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let win;
let cw;
let getGroupItem = function (index) {
return cw.GroupItems.groupItems[index];
}
let finishTest = function () {
win.close();
finish();
}
// very long page that produces black bars at the right
let html1 = '<html><body style="background-color: %2300f;">' +
'<div style="background: %23fff; width: 95%; height: 10000px; ' +
' margin: 0 auto;"></div></body></html>';
// very short page that produces black bars at the bottom
let html2 = '<html><body style="background-color: %2300f;"></body></html>';
let tests = [{
url: 'data:text/html,' + html1,
colors: [
{right: [255, 255, 255], bottom: [255, 255, 255]},
{right: [255, 255, 255], bottom: [255, 255, 255]},
{right: [255, 255, 255], bottom: [255, 255, 255]}
]
}, {
url: 'about:blank',
colors: [
{right: [255, 255, 255], bottom: [255, 255, 255]},
{right: [255, 255, 255], bottom: [255, 255, 255]},
{right: [255, 255, 255], bottom: [255, 255, 255]}
]
}, {
url: 'data:text/html,' + html2,
colors: [
{right: [0, 0, 255], bottom: [0, 0, 255]},
{right: [0, 0, 255], bottom: [0, 0, 255]},
{right: [0, 0, 255], bottom: [0, 0, 255]}
]
}];
let next = function () {
if (!tests.length) {
finishTest();
return;
}
let test = tests.shift();
let tab = win.gBrowser.tabs[0];
let browser = tab.linkedBrowser;
browser.addEventListener("load", function onLoad(event) {
browser.removeEventListener("load", onLoad, true);
let tabItem = tab._tabViewTabItem;
tabItem.addSubscriber("updated", function onUpdated() {
tabItem.removeSubscriber("updated", onUpdated);
checkUrl(test);
});
}, true);
browser.loadURI(test.url);
}
let checkUrl = function (test) {
let sizes = [[-400, 0], [800, -200], [-400, 200]];
let nextSize = function () {
if (!sizes.length) {
next();
return;
}
let size = sizes.shift();
let colors = test.colors.shift();
let groupItem = getGroupItem(0);
let checkWithSmallItemSize = function () {
groupItem.setSize(150, 150, true);
groupItem.setUserSize();
afterAllTabItemsUpdated(function () {
checkPixelColors(test.url, colors, nextSize);
}, win);
}
let checkWithNormalItemSize = function () {
groupItem.setSize(300, 300, true);
groupItem.setUserSize();
afterAllTabItemsUpdated(function () {
checkPixelColors(test.url, colors, checkWithSmallItemSize);
}, win);
}
win.resizeBy.apply(win, size);
checkWithNormalItemSize();
}
nextSize();
}
let checkPixelColors = function (url, colors, callback) {
let tab = win.gBrowser.tabs[0];
let $canvas = tab._tabViewTabItem.$canvas;
// Use the direct canvas sizes instead of querying
// iQ bounds, which may not be current.
let width = $canvas[0].width;
let height = $canvas[0].height;
let ctx = $canvas[0].getContext("2d");
afterAllTabItemsUpdated(function () {
checkPixelColor(ctx, url, colors.bottom, Math.floor(width / 4), height - 1, 'bottom');
checkPixelColor(ctx, url, colors.right, width - 1, Math.floor(height / 4), 'right');
callback();
}, win);
}
let checkPixelColor = function (ctx, url, color, x, y, edge) {
let data = ctx.getImageData(x, y, 1, 1).data;
let check = (data[0] == color[0] && data[1] == color[1] && data[2] == color[2]);
ok(check, url + ': ' + edge + ' edge color matches pixel value');
}
waitForExplicitFinish();
newWindowWithTabView(function(newWin) {
win = newWin;
registerCleanupFunction(function () {
if (!win.closed)
win.close();
});
cw = win.TabView.getContentWindow();
next();
}, null, 800, 600);
}

View File

@ -145,6 +145,7 @@ this.PageThumbs = {
let ctx = aCanvas.getContext("2d");
// Scale the canvas accordingly.
ctx.save();
ctx.scale(scale, scale);
try {
@ -155,6 +156,8 @@ this.PageThumbs = {
// We couldn't draw to the canvas for some reason.
}
ctx.restore();
let telemetry = Services.telemetry;
telemetry.getHistogramById("FX_THUMBNAILS_CAPTURE_TIME_MS")
.add(new Date() - telemetryCaptureTime);
@ -238,8 +241,15 @@ this.PageThumbs = {
* @return An array containing width, height and scale.
*/
_determineCropSize: function PageThumbs_determineCropSize(aWindow, aCanvas) {
let sw = aWindow.innerWidth;
let sh = aWindow.innerHeight;
let utils = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let sbWidth = {}, sbHeight = {};
utils.getScrollbarSize(false, sbWidth, sbHeight);
// Even in RTL mode, scrollbars are always on the right.
// So there's no need to determine a left offset.
let sw = aWindow.innerWidth - sbWidth.value;
let sh = aWindow.innerHeight - sbHeight.value;
let {width: thumbnailWidth, height: thumbnailHeight} = aCanvas;
let scale = Math.min(Math.max(thumbnailWidth / sw, thumbnailHeight / sh), 1);

View File

@ -19,8 +19,10 @@ _BROWSER_FILES = \
browser_thumbnails_storage.js \
browser_thumbnails_storage_migrate3.js \
browser_thumbnails_bug726727.js \
browser_thumbnails_bug727765.js \
head.js \
background_red.html \
background_red_scroll.html \
background_red_redirect.sjs \
privacy_cache_control.sjs \
$(NULL)

View File

@ -0,0 +1,3 @@
<html>
<body bgcolor=ff0000 style="overflow: scroll;"></body>
</html>

View File

@ -0,0 +1,20 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/" +
"test/background_red_scroll.html";
// Test for black borders caused by scrollbars.
function runTests() {
// Create a tab with a page with a red background and scrollbars.
yield addTab(URL);
yield captureAndCheckColor(255, 0, 0, "we have a red thumbnail");
// Check the thumbnail color of the bottom right pixel.
yield whenFileExists(URL);
yield retrieveImageDataForURL(URL, function (aData) {
let [r, g, b] = [].slice.call(aData, -4);
is("" + [r,g,b], "255,0,0", "we have a red thumbnail");
next();
});
}

View File

@ -18,5 +18,8 @@ function runTests() {
// Wait until the referrer's thumbnail's file has been written.
yield whenFileExists(URL);
yield checkThumbnailColor(URL, 255, 0, 0, "referrer has a red thumbnail");
yield retrieveImageDataForURL(URL, function ([r, g, b]) {
is("" + [r,g,b], "255,0,0", "referrer has a red thumbnail");
next();
});
}

View File

@ -3,8 +3,8 @@
let tmp = {};
Cu.import("resource://gre/modules/PageThumbs.jsm", tmp);
let PageThumbs = tmp.PageThumbs;
let PageThumbsStorage = tmp.PageThumbsStorage;
Cu.import("resource:///modules/sessionstore/SessionStore.jsm", tmp);
let {PageThumbs, PageThumbsStorage, SessionStore} = tmp;
Cu.import("resource://gre/modules/PlacesUtils.jsm");
@ -29,12 +29,15 @@ let TestRunner = {
*/
run: function () {
waitForExplicitFinish();
this._iter = runTests();
if (this._iter)
this.next();
else
finish();
SessionStore.promiseInitialized.then(function () {
this._iter = runTests();
if (this._iter) {
this.next();
} else {
finish();
}
}.bind(this));
},
/**
@ -102,19 +105,20 @@ function captureAndCheckColor(aRed, aGreen, aBlue, aMessage) {
// Capture the screenshot.
PageThumbs.captureAndStore(browser, function () {
checkThumbnailColor(browser.currentURI.spec, aRed, aGreen, aBlue, aMessage);
retrieveImageDataForURL(browser.currentURI.spec, function ([r, g, b]) {
is("" + [r,g,b], "" + [aRed, aGreen, aBlue], aMessage);
next();
});
});
}
/**
* Retrieve a thumbnail from the cache and compare its pixel color values.
* @param aURL The URL of the thumbnail's page.
* @param aRed The red component's intensity.
* @param aGreen The green component's intensity.
* @param aBlue The blue component's intensity.
* @param aMessage The info message to print when comparing the pixel color.
* For a given URL, loads the corresponding thumbnail
* to a canvas and passes its image data to the callback.
* @param aURL The url associated with the thumbnail.
* @param aCallback The function to pass the image data to.
*/
function checkThumbnailColor(aURL, aRed, aGreen, aBlue, aMessage) {
function retrieveImageDataForURL(aURL, aCallback) {
let width = 100, height = 100;
let thumb = PageThumbs.getThumbnailURL(aURL, width, height);
@ -130,25 +134,10 @@ function checkThumbnailColor(aURL, aRed, aGreen, aBlue, aMessage) {
// Draw the image to a canvas and compare the pixel color values.
let ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
checkCanvasColor(ctx, aRed, aGreen, aBlue, aMessage);
next();
aCallback(ctx.getImageData(0, 0, 100, 100).data);
});
}
/**
* Checks the top-left pixel of a given canvas' 2d context for a given color.
* @param aContext The 2D context of a canvas.
* @param aRed The red component's intensity.
* @param aGreen The green component's intensity.
* @param aBlue The blue component's intensity.
* @param aMessage The info message to print when comparing the pixel color.
*/
function checkCanvasColor(aContext, aRed, aGreen, aBlue, aMessage) {
let [r, g, b] = aContext.getImageData(0, 0, 1, 1).data;
ok(r == aRed && g == aGreen && b == aBlue, aMessage);
}
/**
* Checks if a thumbnail for the given URL exists.
* @param aURL The url associated to the thumbnail.