diff options
Diffstat (limited to 'devtools/shared/gcli/commands/paintflashing.js')
-rw-r--r-- | devtools/shared/gcli/commands/paintflashing.js | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/devtools/shared/gcli/commands/paintflashing.js b/devtools/shared/gcli/commands/paintflashing.js new file mode 100644 index 000000000..7e21911a7 --- /dev/null +++ b/devtools/shared/gcli/commands/paintflashing.js @@ -0,0 +1,201 @@ +/* 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/. */ + +"use strict"; + +const { Ci } = require("chrome"); +loader.lazyRequireGetter(this, "getOuterId", "sdk/window/utils", true); +loader.lazyRequireGetter(this, "getBrowserForTab", "sdk/tabs/utils", true); + +var telemetry; +try { + const Telemetry = require("devtools/client/shared/telemetry"); + telemetry = new Telemetry(); +} catch(e) { + // DevTools Telemetry module only available in Firefox +} + +const EventEmitter = require("devtools/shared/event-emitter"); +const eventEmitter = new EventEmitter(); + +const gcli = require("gcli/index"); +const l10n = require("gcli/l10n"); + +const enabledPaintFlashing = new Set(); + +const isCheckedFor = (tab) => + tab ? enabledPaintFlashing.has(getBrowserForTab(tab).outerWindowID) : false; + +/** + * Fire events and telemetry when paintFlashing happens + */ +function onPaintFlashingChanged(target, state) { + const { flashing, id } = state; + + if (flashing) { + enabledPaintFlashing.add(id); + } else { + enabledPaintFlashing.delete(id); + } + + eventEmitter.emit("changed", { target: target }); + function fireChange() { + eventEmitter.emit("changed", { target: target }); + } + + target.off("navigate", fireChange); + target.once("navigate", fireChange); + + if (!telemetry) { + return; + } + if (flashing) { + telemetry.toolOpened("paintflashing"); + } else { + telemetry.toolClosed("paintflashing"); + } +} + +/** + * Alter the paintFlashing state of a window and report on the new value. + * This works with chrome or content windows. + * + * This is a bizarre method that you could argue should be broken up into + * separate getter and setter functions, however keeping it as one helps + * to simplify the commands below. + * + * @param state {string} One of: + * - "on" which does window.paintFlashing = true + * - "off" which does window.paintFlashing = false + * - "toggle" which does window.paintFlashing = !window.paintFlashing + * - "query" which does nothing + * @return The new value of the window.paintFlashing flag + */ +function setPaintFlashing(window, state) { + const winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils); + + if (!["on", "off", "toggle", "query"].includes(state)) { + throw new Error(`Unsupported state: ${state}`); + } + + if (state === "on") { + winUtils.paintFlashing = true; + } else if (state === "off") { + winUtils.paintFlashing = false; + } else if (state === "toggle") { + winUtils.paintFlashing = !winUtils.paintFlashing; + } + + return winUtils.paintFlashing; +} + +exports.items = [ + { + name: "paintflashing", + description: l10n.lookup("paintflashingDesc") + }, + { + item: "command", + runAt: "client", + name: "paintflashing on", + description: l10n.lookup("paintflashingOnDesc"), + manual: l10n.lookup("paintflashingManual"), + params: [{ + group: "options", + params: [ + { + type: "boolean", + name: "chrome", + get hidden() { + return gcli.hiddenByChromePref(); + }, + description: l10n.lookup("paintflashingChromeDesc"), + } + ] + }], + exec: function*(args, context) { + if (!args.chrome) { + const output = yield context.updateExec("paintflashing_server --state on"); + + onPaintFlashingChanged(context.environment.target, output.data); + } else { + setPaintFlashing(context.environment.chromeWindow, "on"); + } + } + }, + { + item: "command", + runAt: "client", + name: "paintflashing off", + description: l10n.lookup("paintflashingOffDesc"), + manual: l10n.lookup("paintflashingManual"), + params: [{ + group: "options", + params: [ + { + type: "boolean", + name: "chrome", + get hidden() { + return gcli.hiddenByChromePref(); + }, + description: l10n.lookup("paintflashingChromeDesc"), + } + ] + }], + exec: function*(args, context) { + if (!args.chrome) { + const output = yield context.updateExec("paintflashing_server --state off"); + + onPaintFlashingChanged(context.environment.target, output.data); + } else { + setPaintFlashing(context.environment.chromeWindow, "off"); + } + } + }, + { + item: "command", + runAt: "client", + name: "paintflashing toggle", + hidden: true, + buttonId: "command-button-paintflashing", + buttonClass: "command-button command-button-invertable", + state: { + isChecked: ({_tab}) => isCheckedFor(_tab), + onChange: (_, handler) => eventEmitter.on("changed", handler), + offChange: (_, handler) => eventEmitter.off("changed", handler), + }, + tooltipText: l10n.lookup("paintflashingTooltip"), + description: l10n.lookup("paintflashingToggleDesc"), + manual: l10n.lookup("paintflashingManual"), + exec: function*(args, context) { + const output = yield context.updateExec("paintflashing_server --state toggle"); + + onPaintFlashingChanged(context.environment.target, output.data); + } + }, + { + item: "command", + runAt: "server", + name: "paintflashing_server", + hidden: true, + params: [ + { + name: "state", + type: { + name: "selection", + data: [ "on", "off", "toggle", "query" ] + } + }, + ], + returnType: "paintFlashingState", + exec: function(args, context) { + let { window } = context.environment; + let id = getOuterId(window); + let flashing = setPaintFlashing(window, args.state); + + return { flashing, id }; + } + } +]; |