summaryrefslogtreecommitdiffstats
path: root/devtools/shared/gcli/commands/measure.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/gcli/commands/measure.js')
-rw-r--r--devtools/shared/gcli/commands/measure.js112
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};
+ }
+ }
+];