Skip to content

Instantly share code, notes, and snippets.

@grssam
Created September 6, 2012 11:21
Show Gist options
  • Save grssam/3655030 to your computer and use it in GitHub Desktop.
Save grssam/3655030 to your computer and use it in GitHub Desktop.
screenshot copy
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
let EXPORTED_SYMBOLS = [ ];
Cu.import("resource:///modules/devtools/gcli.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "LayoutHelpers",
"resource:///modules/devtools/LayoutHelpers.jsm");
/**
* 'screenshot' command
*/
gcli.addCommand({
name: "screenshot",
description: gcli.lookup("screenshotDesc"),
manual: gcli.lookup("screenshotManual"),
returnType: "html",
params: [
{
name: "filename",
type: "string",
defaultValue: " ",
description: gcli.lookup("screenshotFilenameDesc"),
manual: gcli.lookup("screenshotFilenameManual")
},
{
group: "Options",
params: [
{
name: "copy",
type: "boolean"
},
{
name: "delay",
type: { name: "number", min: 0 },
defaultValue: 0,
description: gcli.lookup("screenshotDelayDesc"),
manual: gcli.lookup("screenshotDelayManual")
},
{
name: "fullpage",
type: "boolean",
description: gcli.lookup("screenshotFullPageDesc"),
manual: gcli.lookup("screenshotFullPageManual")
},
{
name: "node",
type: "node",
defaultValue: null,
description: gcli.lookup("inspectNodeDesc"),
manual: gcli.lookup("inspectNodeManual")
}
]
}
],
exec: function Command_screenshot(args, context) {
var document = context.environment.contentDocument;
if (args.delay > 0) {
var promise = context.createPromise();
document.defaultView.setTimeout(function Command_screenshotDelay() {
let reply = this.grabScreen(document, args.filename);
promise.resolve(reply);
}.bind(this), args.delay * 1000);
return promise;
}
else {
return this.grabScreen(document, args.filename, args.copy, args.fullpage, args.node);
}
},
grabScreen:
function Command_screenshotGrabScreen(document, filename, copy, fullpage, node) {
let window = document.defaultView;
let canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
let left = 0;
let top = 0;
let width;
let height;
let HTML = "http://www.w3.org/1999/xhtml";
let div = document.createElementNS(HTML, "div");
if (!fullpage) {
if (!node) {
left = window.scrollX;
top = window.scrollY;
width = window.innerWidth;
height = window.innerHeight;
} else {
let rect = LayoutHelpers.getRect(node, window);
top = rect.top;
left = rect.left;
width = rect.width;
height = rect.height;
}
} else {
width = window.innerWidth + window.scrollMaxX;
height = window.innerHeight + window.scrollMaxY;
}
canvas.width = width;
canvas.height = height;
let ctx = canvas.getContext("2d");
ctx.drawWindow(window, left, top, width, height, "#fff");
let data = canvas.toDataURL("image/png", "");
try {
if (copy) {
let io = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
let channel = io.newChannel(data, null, null);
let input = channel.open();
let imgTools = Cc["@mozilla.org/image/tools;1"]
.getService(Ci.imgITools);
let container = {};
imgTools.decodeImageData(input, channel.contentType, container);
let wrapped = Cc["@mozilla.org/supports-interface-pointer;1"]
.createInstance(Ci.nsISupportsInterfacePointer);
wrapped.data = container.value;
let trans = Cc["@mozilla.org/widget/transferable;1"]
.createInstance(Ci.nsITransferable);
trans.addDataFlavor(channel.contentType);
trans.setTransferData(channel.contentType, wrapped, -1);
let clipid = Ci.nsIClipboard;
let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(clipid);
clip.setData(trans, null, clipid.kGlobalClipboard);
div.innerHTML = "Image copied to clipboard.";
return div;
}
}
catch (ex) {
div.innerHTML = "Error occured while copying the image.";
return div;
}
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
// Check there is a .png extension to filename
if (filename == " ") {
let date = new Date();
let dateString = date.getFullYear() + "-" + date.getMonth() +
"-" + date.getDate();
dateString = dateString.split("-").map(function(part) {
if (part.length == 1) {
part = "0" + part;
}
return part;
}).join("-");
filename = "Screen Shot " + dateString + " at " +
date.toTimeString().replace(/:/g, ".").split(" ")[0] +
".png";
}
else if (!filename.match(/.png$/i)) {
filename += ".png";
}
// If the filename is relative, tack it onto the download directory
if (!filename.match(/[\\\/]/)) {
let downloadMgr = Cc["@mozilla.org/download-manager;1"]
.getService(Ci.nsIDownloadManager);
let tempfile = downloadMgr.userDownloadsDirectory;
tempfile.append(filename);
filename = tempfile.path;
}
try {
file.initWithPath(filename);
} catch (ex) {
div.innerHTML = "Error saving to " + filename;
return div;
}
let ioService = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
let Persist = Ci.nsIWebBrowserPersist;
let persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(Persist);
persist.persistFlags = Persist.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
Persist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
let source = ioService.newURI(data, "UTF8", null);
persist.saveURI(source, null, null, null, null, file);
div.innerHTML = "Saved to " + filename;
div.style.cursor = "pointer";
div.addEventListener("click", file.reveal);
let span = document.createElement("div");
span.setAttribute("style", "max-width:256px !important; min-width:256px !important;" +
"max-height:100px !important; min-height:100px !important;" +
"height:100px !important; background-image: url('" + data +
"') !important; background-size: 256px 160px !important;" +
"margin: 4px !important; ");
div.appendChild(span);
return div;
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment