Search code examples
firefoxfirefox-addonscreenshot

Adding screenshot functionality to a firefox extension


Is there a cross-platform approach to taking screenshots from a firefox extension?

Ideally I'd like to be able to take a screenshot of a dom element (irrespective of whether it's visible on the page or not), something like:

var screenshot = screenshot(document.getElementById('example');

Any pointers or suggestions would be nice, searching https://developer.mozilla.org/ only yields screenshots they've used in various guides.


Solution

  • After examining the code of several extensions. I took the following approach (to take a snapshot of a particular dom element). This can be used in a Firefox extension to take screenshots of the whole page, to take screenshots of the browser window and to take screenshots of a particular dom element (and all of its child nodes):

    1. Add canvas to xul.
    2. Find dimensions and top-left co-ordinates of element.
    3. Copy portion of window to canvas.
    4. Convert canvas to base64 PNG file.
    function getElementScreenshot(elm) {
        var x = findPosX(elm);
        var y = findPosY(elm);
        var width = elm.clientWidth;
        var height = elm.clientHeight;
        var cnvs = document.getElementById("aCanvas");
        cnvs.width = width;
        cnvs.height = height;
        var ctx = cnvs.getContext("2d");
        // To take a snapshot of entire window
        // ctx.drawWindow(mainWindow.content, 0, 0, mainWindow.innerWidth, mainWindow.innerHeight, "rgb(255,255,255)");
        ctx.drawWindow(mainWindow.content, x, y, width, height, "rgb(255,255,255)");
        return(cnvs.toDataURL());
    }
    

    To find top left coordinate of an element

    function findPosX(obj) {
        var curleft = 0;
        if (obj.offsetParent) {
            while (1) {
                curleft += obj.offsetLeft;
                if (!obj.offsetParent) {
                    break;
                }
                obj = obj.offsetParent;
            }
        } else if (obj.x) {
            curleft += obj.x;
        }
        return curleft;
    }
    
    function findPosY(obj) {
        var curtop = 0;
        if (obj.offsetParent) {
            while (1) {
                curtop += obj.offsetTop;
                if (!obj.offsetParent) {
                    break;
                }
                obj = obj.offsetParent;
            }
        } else if (obj.y) {
            curtop += obj.y;
        }
        return curtop;
    }
    

    To get access to browser.xul from sidebar

    var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                           .getInterface(Components.interfaces.nsIWebNavigation)
                           .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
                           .rootTreeItem
                           .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                           .getInterface(Components.interfaces.nsIDOMWindow);
    
    mainWindow.gBrowser.addTab(...);