Bug 1018619 - Feedback for screenshot button. r=bgrins

--HG--
extra : transplant_source : 9%BAu%E31%B8%BA%A5%18-%5E5%40%E8%0F6%C2%CA%90a
This commit is contained in:
J. Ryan Stinnett 2015-04-24 15:26:55 -05:00
parent b60abed0f9
commit a4c067f55d

View File

@ -180,15 +180,18 @@ exports.items = [
throw new Error(l10n.lookup("screenshotSelectorChromeConflict")); throw new Error(l10n.lookup("screenshotSelectorChromeConflict"));
} }
let capture;
if (!args.chrome) { if (!args.chrome) {
// Re-execute the command on the server // Re-execute the command on the server
const command = context.typed.replace(/^screenshot/, "screenshot_server"); const command = context.typed.replace(/^screenshot/, "screenshot_server");
return context.updateExec(command).then(output => { capture = context.updateExec(command).then(output => {
return output.error ? Promise.reject(output.data) : output.data; return output.error ? Promise.reject(output.data) : output.data;
}); });
} else {
capture = captureScreenshot(args, context.environment.chromeDocument);
} }
return processScreenshot(args, context.environment.chromeDocument); return capture.then(saveScreenshot.bind(null, args, context));
}, },
}, },
{ {
@ -199,53 +202,45 @@ exports.items = [
returnType: "imageSummary", returnType: "imageSummary",
params: [ filenameParam, standardParams ], params: [ filenameParam, standardParams ],
exec: function(args, context) { exec: function(args, context) {
return processScreenshot(args, context.environment.document); return captureScreenshot(args, context.environment.document);
}, },
} }
]; ];
/** /**
* This function simply handles the --delay argument before calling * This function simply handles the --delay argument before calling
* processScreenshotNow * createScreenshotData
*/ */
function processScreenshot(args, document) { function captureScreenshot(args, document) {
if (args.delay > 0) { if (args.delay > 0) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
document.defaultView.setTimeout(() => { document.defaultView.setTimeout(() => {
processScreenshotNow(args, document).then(resolve, reject); createScreenshotData(document, args).then(resolve, reject);
}, args.delay * 1000); }, args.delay * 1000);
}); });
} }
else { else {
return processScreenshotNow(args, document); return createScreenshotData(document, args);
} }
} }
/** /**
* There are several possible destinations for the screenshot, SKIP is used * There are several possible destinations for the screenshot, SKIP is used
* in processScreenshotNow() whenever one of them is not used * in saveScreenshot() whenever one of them is not used
*/ */
const SKIP = Promise.resolve(); const SKIP = Promise.resolve();
/** /**
* This is just like exec, except the 'delay' has been handled already so * Save the captured screenshot to one of several destinations.
* this is where we do that actual work of process the screenshot
*/ */
function processScreenshotNow(args, document) { function saveScreenshot(args, context, reply) {
const reply = createScreenshotData(document, args);
const loadContext = document.defaultView
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsILoadContext);
const fileNeeded = args.filename != FILENAME_DEFAULT_VALUE || const fileNeeded = args.filename != FILENAME_DEFAULT_VALUE ||
(!args.imgur && !args.clipboard); (!args.imgur && !args.clipboard);
return Promise.all([ return Promise.all([
args.clipboard ? saveToClipboard(loadContext, reply) : SKIP, args.clipboard ? saveToClipboard(context, reply) : SKIP,
args.imgur ? uploadToImgur(reply) : SKIP, args.imgur ? uploadToImgur(reply) : SKIP,
fileNeeded ? saveToFile(loadContext, reply) : SKIP, fileNeeded ? saveToFile(context, reply) : SKIP,
]).then(() => reply); ]).then(() => reply);
} }
@ -300,13 +295,13 @@ function createScreenshotData(document, args) {
window.scrollTo(currentX, currentY); window.scrollTo(currentX, currentY);
} }
return { return Promise.resolve({
destinations: [], destinations: [],
data: data, data: data,
height: height, height: height,
width: width, width: width,
filename: getFilename(args.filename), filename: getFilename(args.filename),
}; });
} }
/** /**
@ -339,8 +334,12 @@ function getFilename(defaultName) {
* be treated exactly like imgur / file processing, but it's really sync * be treated exactly like imgur / file processing, but it's really sync
* for now. * for now.
*/ */
function saveToClipboard(loadContext, reply) { function saveToClipboard(context, reply) {
try { try {
const loadContext = context.environment.chromeWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsILoadContext);
const io = Cc["@mozilla.org/network/io-service;1"] const io = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService); .getService(Ci.nsIIOService);
const channel = io.newChannel2(reply.data, null, null, const channel = io.newChannel2(reply.data, null, null,
@ -422,37 +421,21 @@ function uploadToImgur(reply) {
* Save the screenshot data to disk, returning a promise which * Save the screenshot data to disk, returning a promise which
* is resolved on completion * is resolved on completion
*/ */
function saveToFile(loadContext, reply) { function saveToFile(context, reply) {
return Task.spawn(function*() { return Task.spawn(function*() {
try { try {
let document = context.environment.chromeDocument;
let window = context.environment.chromeWindow;
let filename = reply.filename; let filename = reply.filename;
// Check there is a .png extension to filename // Check there is a .png extension to filename
if (!filename.match(/.png$/i)) { if (!filename.match(/.png$/i)) {
filename += ".png"; filename += ".png";
} }
// If the filename is relative, tack it onto the download directory window.saveURL(reply.data, filename, null,
if (!filename.match(/[\\\/]/)) { true /* aShouldBypassCache */, true /* aSkipPrompt */,
const preferredDir = yield Downloads.getPreferredDownloadsDirectory(); document.documentURIObject, document);
filename = OS.Path.join(preferredDir, filename);
reply.filename = filename;
}
const file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
file.initWithPath(filename);
const ioService = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
const Persist = Ci.nsIWebBrowserPersist;
const persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(Persist);
persist.persistFlags = Persist.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
Persist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
// TODO: UTF8? For an image?
const source = ioService.newURI(reply.data, "UTF8", null);
persist.saveURI(source, null, null, 0, null, null, file, loadContext);
reply.destinations.push(l10n.lookup("screenshotSavedToFile") + " \"" + filename + "\""); reply.destinations.push(l10n.lookup("screenshotSavedToFile") + " \"" + filename + "\"");
} }