This is imported from https://github.com/mozilla-services/screenshots/. It has been reviewed as patches landed, but also reviewed by Mossop and kmag. This also includes the patch from bug 1356394 MozReview-Commit-ID: FXIVw7WjxlN
129 lines
4.0 KiB
JavaScript
129 lines
4.0 KiB
JavaScript
/* globals communication, shot, main, auth, catcher, analytics, browser */
|
|
|
|
"use strict";
|
|
|
|
this.takeshot = (function () {
|
|
let exports = {};
|
|
const Shot = shot.AbstractShot;
|
|
const { sendEvent } = analytics;
|
|
|
|
communication.register("takeShot", catcher.watchFunction((sender, options) => {
|
|
let { captureType, captureText, scroll, selectedPos, shotId, shot } = options;
|
|
shot = new Shot(main.getBackend(), shotId, shot);
|
|
let capturePromise = Promise.resolve();
|
|
let openedTab;
|
|
if (! shot.clipNames().length) {
|
|
// canvas.drawWindow isn't available, so we fall back to captureVisibleTab
|
|
capturePromise = screenshotPage(selectedPos, scroll).then((dataUrl) => {
|
|
shot.addClip({
|
|
createdDate: Date.now(),
|
|
image: {
|
|
url: dataUrl,
|
|
captureType,
|
|
text: captureText,
|
|
location: selectedPos,
|
|
dimensions: {
|
|
x: selectedPos.right - selectedPos.left,
|
|
y: selectedPos.bottom - selectedPos.top
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
let shotAbTests = {};
|
|
let abTests = auth.getAbTests();
|
|
for (let testName of Object.keys(abTests)) {
|
|
if (abTests[testName].shotField) {
|
|
shotAbTests[testName] = abTests[testName].value;
|
|
}
|
|
}
|
|
if (Object.keys(shotAbTests).length) {
|
|
shot.abTests = shotAbTests;
|
|
}
|
|
return catcher.watchPromise(capturePromise.then(() => {
|
|
return browser.tabs.create({url: shot.creatingUrl})
|
|
}).then((tab) => {
|
|
openedTab = tab;
|
|
return uploadShot(shot);
|
|
}).then(() => {
|
|
return browser.tabs.update(openedTab.id, {url: shot.viewUrl});
|
|
}).then(() => {
|
|
return shot.viewUrl;
|
|
}).catch((error) => {
|
|
browser.tabs.remove(openedTab.id);
|
|
throw error;
|
|
}));
|
|
}));
|
|
|
|
communication.register("screenshotPage", (sender, selectedPos, scroll) => {
|
|
return screenshotPage(selectedPos, scroll);
|
|
});
|
|
|
|
function screenshotPage(pos, scroll) {
|
|
pos = {
|
|
top: pos.top - scroll.scrollY,
|
|
left: pos.left - scroll.scrollX,
|
|
bottom: pos.bottom - scroll.scrollY,
|
|
right: pos.right - scroll.scrollX
|
|
};
|
|
pos.width = pos.right - pos.left;
|
|
pos.height = pos.bottom - pos.top;
|
|
return catcher.watchPromise(browser.tabs.captureVisibleTab(
|
|
null,
|
|
{format: "png"}
|
|
).then((dataUrl) => {
|
|
let image = new Image();
|
|
image.src = dataUrl;
|
|
return new Promise((resolve, reject) => {
|
|
image.onload = catcher.watchFunction(() => {
|
|
let xScale = image.width / scroll.innerWidth;
|
|
let yScale = image.height / scroll.innerHeight;
|
|
let canvas = document.createElement("canvas");
|
|
canvas.height = pos.height * yScale;
|
|
canvas.width = pos.width * xScale;
|
|
let context = canvas.getContext("2d");
|
|
context.drawImage(
|
|
image,
|
|
pos.left * xScale, pos.top * yScale,
|
|
pos.width * xScale, pos.height * yScale,
|
|
0, 0,
|
|
pos.width * xScale, pos.height * yScale
|
|
);
|
|
let result = canvas.toDataURL();
|
|
resolve(result);
|
|
});
|
|
});
|
|
}));
|
|
}
|
|
|
|
function uploadShot(shot) {
|
|
return auth.authHeaders().then((headers) => {
|
|
headers["content-type"] = "application/json";
|
|
let body = JSON.stringify(shot.asJson());
|
|
let req = new Request(shot.jsonUrl, {
|
|
method: "PUT",
|
|
mode: "cors",
|
|
headers,
|
|
body
|
|
});
|
|
sendEvent("upload", "started", {eventValue: Math.floor(body.length / 1000)});
|
|
return fetch(req);
|
|
}).then((resp) => {
|
|
if (! resp.ok) {
|
|
sendEvent("upload-failed", `status-${resp.status}`);
|
|
let exc = new Error(`Response failed with status ${resp.status}`);
|
|
exc.popupMessage = "REQUEST_ERROR";
|
|
throw exc;
|
|
} else {
|
|
sendEvent("upload", "success");
|
|
}
|
|
}, (error) => {
|
|
// FIXME: I'm not sure what exceptions we can expect
|
|
sendEvent("upload-failed", "connection");
|
|
throw error;
|
|
});
|
|
}
|
|
|
|
return exports;
|
|
})();
|