From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../mozscreenshots/extension/Screenshot.sys.mjs | 196 +++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 browser/tools/mozscreenshots/mozscreenshots/extension/Screenshot.sys.mjs (limited to 'browser/tools/mozscreenshots/mozscreenshots/extension/Screenshot.sys.mjs') 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; + } + }, + }; + }, +}; -- cgit v1.2.3