mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
237 lines
8.4 KiB
JavaScript
237 lines
8.4 KiB
JavaScript
/* 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");
|
|
|
|
// String used as an indication to generate default file name in the following
|
|
// format: "Screen Shot yyyy-mm-dd at HH.MM.SS.png"
|
|
const FILENAME_DEFAULT_VALUE = " ";
|
|
|
|
/**
|
|
* 'screenshot' command
|
|
*/
|
|
gcli.addCommand({
|
|
name: "screenshot",
|
|
description: gcli.lookup("screenshotDesc"),
|
|
manual: gcli.lookup("screenshotManual"),
|
|
returnType: "html",
|
|
params: [
|
|
{
|
|
name: "filename",
|
|
type: "string",
|
|
defaultValue: FILENAME_DEFAULT_VALUE,
|
|
description: gcli.lookup("screenshotFilenameDesc"),
|
|
manual: gcli.lookup("screenshotFilenameManual")
|
|
},
|
|
{
|
|
group: gcli.lookup("screenshotGroupOptions"),
|
|
params: [
|
|
{
|
|
name: "clipboard",
|
|
type: "boolean",
|
|
description: gcli.lookup("screenshotClipboardDesc"),
|
|
manual: gcli.lookup("screenshotClipboardManual")
|
|
},
|
|
{
|
|
name: "chrome",
|
|
type: "boolean",
|
|
description: gcli.lookup("screenshotChromeDesc"),
|
|
manual: gcli.lookup("screenshotChromeManual")
|
|
},
|
|
{
|
|
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: "selector",
|
|
type: "node",
|
|
defaultValue: null,
|
|
description: gcli.lookup("inspectNodeDesc"),
|
|
manual: gcli.lookup("inspectNodeManual")
|
|
}
|
|
]
|
|
}
|
|
],
|
|
exec: function Command_screenshot(args, context) {
|
|
if (args.chrome && args.selector) {
|
|
// Node screenshot with chrome option does not work as inteded
|
|
// Refer https://bugzilla.mozilla.org/show_bug.cgi?id=659268#c7
|
|
// throwing for now.
|
|
throw new Error(gcli.lookup("screenshotSelectorChromeConflict"));
|
|
}
|
|
var document = args.chrome? context.environment.chromeDocument
|
|
: context.environment.contentDocument;
|
|
if (args.delay > 0) {
|
|
var promise = context.createPromise();
|
|
document.defaultView.setTimeout(function Command_screenshotDelay() {
|
|
let reply = this.grabScreen(document, args.filename, args.clipboard,
|
|
args.fullpage);
|
|
promise.resolve(reply);
|
|
}.bind(this), args.delay * 1000);
|
|
return promise;
|
|
}
|
|
else {
|
|
return this.grabScreen(document, args.filename, args.clipboard,
|
|
args.fullpage, args.selector);
|
|
}
|
|
},
|
|
grabScreen:
|
|
function Command_screenshotGrabScreen(document, filename, clipboard,
|
|
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 div = document.createElementNS("http://www.w3.org/1999/xhtml", "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 (clipboard) {
|
|
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);
|
|
let loadContext = document.defaultView
|
|
.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
.getInterface(Ci.nsIWebNavigation)
|
|
.QueryInterface(Ci.nsILoadContext);
|
|
trans.init(loadContext);
|
|
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.textContent = gcli.lookup("screenshotCopied");
|
|
return div;
|
|
}
|
|
}
|
|
catch (ex) {
|
|
div.textContent = gcli.lookup("screenshotErrorCopying");
|
|
return div;
|
|
}
|
|
|
|
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
|
|
|
// Create a name for the file if not present
|
|
if (filename == FILENAME_DEFAULT_VALUE) {
|
|
let date = new Date();
|
|
let dateString = date.getFullYear() + "-" + (date.getMonth() + 1) +
|
|
"-" + date.getDate();
|
|
dateString = dateString.split("-").map(function(part) {
|
|
if (part.length == 1) {
|
|
part = "0" + part;
|
|
}
|
|
return part;
|
|
}).join("-");
|
|
let timeString = date.toTimeString().replace(/:/g, ".").split(" ")[0];
|
|
filename = gcli.lookupFormat("screenshotGeneratedFilename",
|
|
[dateString, timeString]) + ".png";
|
|
}
|
|
// Check there is a .png extension to filename
|
|
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.textContent = gcli.lookup("screenshotErrorSavingToFile") + " " + 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.textContent = gcli.lookup("screenshotSavedToFile") + " \"" + filename +
|
|
"\"";
|
|
div.addEventListener("click", function openFile() {
|
|
div.removeEventListener("click", openFile);
|
|
file.reveal();
|
|
});
|
|
div.style.cursor = "pointer";
|
|
let image = document.createElement("div");
|
|
let previewHeight = parseInt(256*height/width);
|
|
image.setAttribute("style",
|
|
"width:256px; height:" + previewHeight + "px;" +
|
|
"max-height: 256px;" +
|
|
"background-image: url('" + data + "');" +
|
|
"background-size: 256px " + previewHeight + "px;" +
|
|
"margin: 4px; display: block");
|
|
div.appendChild(image);
|
|
return div;
|
|
}
|
|
}); |