summaryrefslogtreecommitdiffstats
path: root/browser/tools/mozscreenshots/mozscreenshots/extension/Screenshot.sys.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'browser/tools/mozscreenshots/mozscreenshots/extension/Screenshot.sys.mjs')
-rw-r--r--browser/tools/mozscreenshots/mozscreenshots/extension/Screenshot.sys.mjs196
1 files changed, 196 insertions, 0 deletions
diff --git a/browser/tools/mozscreenshots/mozscreenshots/extension/Screenshot.sys.mjs b/browser/tools/mozscreenshots/mozscreenshots/extension/Screenshot.sys.mjs
new file mode 100644
index 0000000000..3db9fe3e0c
--- /dev/null
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/Screenshot.sys.mjs
@@ -0,0 +1,196 @@
+/* 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/. */
+
+import { setTimeout } from "resource://gre/modules/Timer.sys.mjs";
+import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
+
+// Create a new instance of the ConsoleAPI so we can control the maxLogLevel with a pref.
+// See LOG_LEVELS in Console.sys.mjs. Common examples: "All", "Info", "Warn", &
+// "Error".
+const PREF_LOG_LEVEL = "extensions.mozscreenshots@mozilla.org.loglevel";
+const lazy = {};
+XPCOMUtils.defineLazyGetter(lazy, "log", () => {
+ let { ConsoleAPI } = ChromeUtils.importESModule(
+ "resource://gre/modules/Console.sys.mjs"
+ );
+ let consoleOptions = {
+ maxLogLevel: "info",
+ maxLogLevelPref: PREF_LOG_LEVEL,
+ prefix: "mozscreenshots",
+ };
+ return new ConsoleAPI(consoleOptions);
+});
+
+export var Screenshot = {
+ _extensionPath: null,
+ _path: null,
+ _imagePrefix: "",
+ _imageExtension: ".png",
+ _screenshotFunction: null,
+
+ init(path, extensionPath, imagePrefix = "") {
+ this._path = path;
+
+ let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+ dir.initWithPath(this._path);
+ if (!dir.exists()) {
+ dir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
+ }
+
+ this._extensionPath = extensionPath;
+ this._imagePrefix = imagePrefix;
+ switch (Services.appinfo.OS) {
+ case "WINNT":
+ this._screenshotFunction = this._screenshotWindows;
+ break;
+ case "Darwin":
+ this._screenshotFunction = this._screenshotOSX;
+ break;
+ case "Linux":
+ this._screenshotFunction = this._screenshotLinux;
+ break;
+ default:
+ throw new Error("Unsupported operating system");
+ }
+ },
+
+ _buildImagePath(baseName) {
+ return PathUtils.join(
+ this._path,
+ this._imagePrefix + baseName + this._imageExtension
+ );
+ },
+
+ // Capture the whole screen using an external application.
+ async captureExternal(filename) {
+ let imagePath = this._buildImagePath(filename);
+ await this._screenshotFunction(imagePath);
+ lazy.log.debug("saved screenshot: " + filename);
+ return imagePath;
+ },
+
+ // helpers
+
+ _screenshotWindows(filename) {
+ return new Promise((resolve, reject) => {
+ let exe = Services.dirsvc.get("GreBinD", Ci.nsIFile);
+ exe.append("screenshot.exe");
+ if (!exe.exists()) {
+ exe = Services.dirsvc.get("CurWorkD", Ci.nsIFile).parent;
+ exe.append("bin");
+ exe.append("screenshot.exe");
+ }
+ let process = Cc["@mozilla.org/process/util;1"].createInstance(
+ Ci.nsIProcess
+ );
+ process.init(exe);
+
+ let args = [filename];
+ process.runAsync(
+ args,
+ args.length,
+ this._processObserver(resolve, reject)
+ );
+ });
+ },
+
+ async _screenshotOSX(filename) {
+ let screencapture = (windowID = null) => {
+ return new Promise((resolve, reject) => {
+ // Get the screencapture executable
+ let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+ file.initWithPath("/usr/sbin/screencapture");
+
+ let process = Cc["@mozilla.org/process/util;1"].createInstance(
+ Ci.nsIProcess
+ );
+ process.init(file);
+
+ // Run the process.
+ let args = ["-x", "-t", "png"];
+ args.push(filename);
+ process.runAsync(
+ args,
+ args.length,
+ this._processObserver(resolve, reject)
+ );
+ });
+ };
+
+ function readWindowID() {
+ return IOUtils.readUTF8("/tmp/mozscreenshots-windowid");
+ }
+
+ let promiseWindowID = () => {
+ return new Promise((resolve, reject) => {
+ // Get the window ID of the application (assuming its front-most)
+ let osascript = Cc["@mozilla.org/file/local;1"].createInstance(
+ Ci.nsIFile
+ );
+ osascript.initWithPath("/bin/bash");
+
+ let osascriptP = Cc["@mozilla.org/process/util;1"].createInstance(
+ Ci.nsIProcess
+ );
+ osascriptP.init(osascript);
+ let osaArgs = [
+ "-c",
+ "/usr/bin/osascript -e 'tell application (path to frontmost application as text) to set winID to id of window 1' > /tmp/mozscreenshots-windowid",
+ ];
+ osascriptP.runAsync(
+ osaArgs,
+ osaArgs.length,
+ this._processObserver(resolve, reject)
+ );
+ });
+ };
+
+ await promiseWindowID();
+ let windowID = await readWindowID();
+ await screencapture(windowID);
+ },
+
+ _screenshotLinux(filename) {
+ return new Promise((resolve, reject) => {
+ let exe = Services.dirsvc.get("GreBinD", Ci.nsIFile);
+ exe.append("screentopng");
+ if (!exe.exists()) {
+ exe = Services.dirsvc.get("CurWorkD", Ci.nsIFile).parent;
+ exe.append("bin");
+ exe.append("screentopng");
+ }
+ let process = Cc["@mozilla.org/process/util;1"].createInstance(
+ Ci.nsIProcess
+ );
+ process.init(exe);
+
+ let args = [filename];
+ process.runAsync(
+ args,
+ args.length,
+ this._processObserver(resolve, reject)
+ );
+ });
+ },
+
+ _processObserver(resolve, reject) {
+ return {
+ observe(subject, topic, data) {
+ switch (topic) {
+ case "process-finished":
+ try {
+ // Wait 1s after process to resolve
+ setTimeout(resolve, 1000);
+ } catch (ex) {
+ reject(ex);
+ }
+ break;
+ default:
+ reject(topic);
+ break;
+ }
+ },
+ };
+ },
+};