I am looking for firefox addon api to take screenshot of visible area of document.
Chrome and Safari have api's to achieve this. And they are pretty fast. I could not find anything specific for firefox.
I found a workaround at How do I use the canvas drawWindow function in an addon created using the addon sdk? but this solution takes full page screenshot with scrolls including (hidden parts of document). There are 2 issues for this solution;
1- if page has long scroll, it takes long time to complete screenshot process. Because it is using canvas based drawing.
2- I would like to get screenshot of visible area of document, not whole document.
Is there any workaround for this?
Thanks.
Using the SDK you can do something like this:
const { window: { document } } = require('sdk/addon/window');
const { getTabContentWindow, getActiveTab } = require('sdk/tabs/utils');
const { getMostRecentBrowserWindow } = require('sdk/window/utils');
const canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
document.documentElement.appendChild(canvas);
function captureTab(tab=getActiveTab(getMostRecentBrowserWindow())) {
let contentWindow = getTabContentWindow(tab);
let w = contentWindow.innerWidth;
let h = contentWindow.innerHeight;
let x = contentWindow.scrollX;
let y = contentWindow.scrollY;
canvas.width = w;
canvas.height = h;
let ctx = canvas.getContext('2d');
ctx.drawWindow(contentWindow, x, y, w, h, '#000');
return canvas.toDataURL();
}
That should takes only the visible area. By default, it grabs the active tab, but you can pass any other tab – because is designed as low level API it takes a native tab, however, not a SDK tab.
You can put in a module and exports just the captureTab
function.
Edit: e10s version
The code above is not currently compatible with Firefox with e10s available, as Ian Bicking noted in the comment. An easy way to workaround this issue, is create a temporary canvas in the same document and content process we want to capture the screenshot:
const { getTabContentWindow, getActiveTab } = require('sdk/tabs/utils');
const { getMostRecentBrowserWindow } = require('sdk/window/utils');
function captureTab(tab=getActiveTab(getMostRecentBrowserWindow())) {
let contentWindow = getTabContentWindow(tab);
let { document } = contentWindow;
let w = contentWindow.innerWidth;
let h = contentWindow.innerHeight;
let x = contentWindow.scrollX;
let y = contentWindow.scrollY;
let canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
canvas.width = w;
canvas.height = h;
let ctx = canvas.getContext('2d');
ctx.drawWindow(contentWindow, x, y, w, h, '#000');
let dataURL = canvas.toDataURL();
canvas = null;
return dataURL;
}
That works in both e10s and no-e10s FF version; the downside comparing to the previous one is creating a canvas every time we want to take a screenshot, but I think is acceptable.