diff options
Diffstat (limited to 'devtools/shared/gcli/commands/measure.js')
-rw-r--r-- | devtools/shared/gcli/commands/measure.js | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/devtools/shared/gcli/commands/measure.js b/devtools/shared/gcli/commands/measure.js new file mode 100644 index 000000000..7f6233a95 --- /dev/null +++ b/devtools/shared/gcli/commands/measure.js @@ -0,0 +1,112 @@ +/* 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 getOuterId, getBrowserForTab */ + +"use strict"; + +const EventEmitter = require("devtools/shared/event-emitter"); +const eventEmitter = new EventEmitter(); +const events = require("sdk/event/core"); + +loader.lazyRequireGetter(this, "getOuterId", "sdk/window/utils", true); +loader.lazyRequireGetter(this, "getBrowserForTab", "sdk/tabs/utils", true); + +const l10n = require("gcli/l10n"); +require("devtools/server/actors/inspector"); +const { MeasuringToolHighlighter, HighlighterEnvironment } = + require("devtools/server/actors/highlighters"); + +const highlighters = new WeakMap(); +const visibleHighlighters = new Set(); + +const isCheckedFor = (tab) => + tab ? visibleHighlighters.has(getBrowserForTab(tab).outerWindowID) : false; + +exports.items = [ + // The client measure command is used to maintain the toolbar button state + // only and redirects to the server command to actually toggle the measuring + // tool (see `measure_server` below). + { + name: "measure", + runAt: "client", + description: l10n.lookup("measureDesc"), + manual: l10n.lookup("measureManual"), + buttonId: "command-button-measure", + buttonClass: "command-button command-button-invertable", + tooltipText: l10n.lookup("measureTooltip"), + state: { + isChecked: ({_tab}) => isCheckedFor(_tab), + onChange: (target, handler) => eventEmitter.on("changed", handler), + offChange: (target, handler) => eventEmitter.off("changed", handler) + }, + exec: function*(args, context) { + let { target } = context.environment; + + // Pipe the call to the server command. + let response = yield context.updateExec("measure_server"); + let { visible, id } = response.data; + + if (visible) { + visibleHighlighters.add(id); + } else { + visibleHighlighters.delete(id); + } + + eventEmitter.emit("changed", { target }); + + // Toggle off the button when the page navigates because the measuring + // tool is removed automatically by the MeasuringToolHighlighter on the + // server then. + let onNavigate = () => { + visibleHighlighters.delete(id); + eventEmitter.emit("changed", { target }); + }; + target.off("will-navigate", onNavigate); + target.once("will-navigate", onNavigate); + } + }, + // The server measure command is hidden by default, it's just used by the + // client command. + { + name: "measure_server", + runAt: "server", + hidden: true, + returnType: "highlighterVisibility", + exec: function(args, context) { + let env = context.environment; + let { document } = env; + let id = getOuterId(env.window); + + // Calling the command again after the measuring tool has been shown once, + // hides it. + if (highlighters.has(document)) { + let { highlighter } = highlighters.get(document); + highlighter.destroy(); + return {visible: false, id}; + } + + // Otherwise, display the measuring tool. + let environment = new HighlighterEnvironment(); + environment.initFromWindow(env.window); + let highlighter = new MeasuringToolHighlighter(environment); + + // Store the instance of the measuring tool highlighter for this document + // so we can hide it later. + highlighters.set(document, { highlighter, environment }); + + // Listen to the highlighter's destroy event which may happen if the + // window is refreshed or closed with the measuring tool shown. + events.once(highlighter, "destroy", () => { + if (highlighters.has(document)) { + let { environment } = highlighters.get(document); + environment.destroy(); + highlighters.delete(document); + } + }); + + highlighter.show(); + return {visible: true, id}; + } + } +]; |