diff options
Diffstat (limited to '')
-rw-r--r-- | browser/extensions/screenshots/selector/shooter.js | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/browser/extensions/screenshots/selector/shooter.js b/browser/extensions/screenshots/selector/shooter.js new file mode 100644 index 0000000000..5d06fbec7b --- /dev/null +++ b/browser/extensions/screenshots/selector/shooter.js @@ -0,0 +1,163 @@ +/* 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/. */ + +/* globals global, browser, documentMetadata, util, uicontrol, ui, catcher */ +/* globals domainFromUrl, randomString, shot, blobConverters */ + +"use strict"; + +this.shooter = (function() { + // eslint-disable-line no-unused-vars + const exports = {}; + const { AbstractShot } = shot; + + const RANDOM_STRING_LENGTH = 16; + let backend; + let shotObject; + const callBackground = global.callBackground; + + function regexpEscape(str) { + // http://stackoverflow.com/questions/3115150/how-to-escape-regular-expression-special-characters-using-javascript + return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); + } + + function sanitizeError(data) { + const href = new RegExp(regexpEscape(window.location.href), "g"); + const origin = new RegExp( + `${regexpEscape(window.location.origin)}[^ \t\n\r",>]*`, + "g" + ); + const json = JSON.stringify(data) + .replace(href, "REDACTED_HREF") + .replace(origin, "REDACTED_URL"); + const result = JSON.parse(json); + return result; + } + + catcher.registerHandler(errorObj => { + callBackground("reportError", sanitizeError(errorObj)); + }); + + function hideUIFrame() { + ui.iframe.hide(); + return Promise.resolve(null); + } + + function screenshotPage(dataUrl, selectedPos, type, screenshotTaskFn) { + let promise = Promise.resolve(dataUrl); + + if (!dataUrl) { + promise = callBackground( + "screenshotPage", + selectedPos.toJSON(), + type, + window.devicePixelRatio + ); + } + + catcher.watchPromise( + promise.then(dataLoc => { + screenshotTaskFn(dataLoc); + }) + ); + } + + exports.downloadShot = function(selectedPos, previewDataUrl, type) { + const shotPromise = previewDataUrl + ? Promise.resolve(previewDataUrl) + : hideUIFrame(); + catcher.watchPromise( + shotPromise.then(dataUrl => { + screenshotPage(dataUrl, selectedPos, type, url => { + let typeFromDataUrl = blobConverters.getTypeFromDataUrl(url); + typeFromDataUrl = typeFromDataUrl + ? typeFromDataUrl.split("/", 2)[1] + : null; + shotObject.delAllClips(); + shotObject.addClip({ + createdDate: Date.now(), + image: { + url, + type: typeFromDataUrl, + location: selectedPos, + }, + }); + ui.triggerDownload(url, shotObject.filename); + uicontrol.deactivate(); + }); + }) + ); + }; + + exports.preview = function(selectedPos, type) { + catcher.watchPromise( + hideUIFrame().then(dataUrl => { + screenshotPage(dataUrl, selectedPos, type, url => { + ui.iframe.usePreview(); + ui.Preview.display(url); + }); + }) + ); + }; + + let copyInProgress = null; + exports.copyShot = function(selectedPos, previewDataUrl, type) { + // This is pretty slow. We'll ignore additional user triggered copy events + // while it is in progress. + if (copyInProgress) { + return; + } + // A max of five seconds in case some error occurs. + copyInProgress = setTimeout(() => { + copyInProgress = null; + }, 5000); + + const unsetCopyInProgress = () => { + if (copyInProgress) { + clearTimeout(copyInProgress); + copyInProgress = null; + } + }; + const shotPromise = previewDataUrl + ? Promise.resolve(previewDataUrl) + : hideUIFrame(); + catcher.watchPromise( + shotPromise.then(dataUrl => { + screenshotPage(dataUrl, selectedPos, type, url => { + const blob = blobConverters.dataUrlToBlob(url); + catcher.watchPromise( + callBackground("copyShotToClipboard", blob).then(() => { + uicontrol.deactivate(); + unsetCopyInProgress(); + }, unsetCopyInProgress) + ); + }); + }) + ); + }; + + exports.sendEvent = function(...args) { + const maybeOptions = args[args.length - 1]; + + if (typeof maybeOptions === "object") { + maybeOptions.incognito = browser.extension.inIncognitoContext; + } else { + args.push({ incognito: browser.extension.inIncognitoContext }); + } + }; + + catcher.watchFunction(() => { + shotObject = new AbstractShot( + backend, + randomString(RANDOM_STRING_LENGTH) + "/" + domainFromUrl(location), + { + origin: shot.originFromUrl(location.href), + } + ); + shotObject.update(documentMetadata()); + })(); + + return exports; +})(); +null; |