Skip to content

Instantly share code, notes, and snippets.

@jdm
Created September 5, 2014 16:58
Show Gist options
  • Save jdm/873de0d028f5acf9bcc5 to your computer and use it in GitHub Desktop.
Save jdm/873de0d028f5acf9bcc5 to your computer and use it in GitHub Desktop.
# HG changeset patch
# Parent 5c15b7c381072db058469b32b5d4fbeaed044c1e
# User Josh Matthews <josh@joshmatthews.net>
diff --git a/browser/devtools/jar.mn b/browser/devtools/jar.mn
--- a/browser/devtools/jar.mn
+++ b/browser/devtools/jar.mn
@@ -21,16 +21,17 @@ browser.jar:
* content/browser/devtools/scratchpad.xul (scratchpad/scratchpad.xul)
content/browser/devtools/scratchpad.js (scratchpad/scratchpad.js)
content/browser/devtools/scratchpad-commands.js (scratchpad/scratchpad-commands.js)
content/browser/devtools/splitview.css (shared/splitview.css)
content/browser/devtools/theme-switching.js (shared/theme-switching.js)
content/browser/devtools/frame-script-utils.js (shared/frame-script-utils.js)
content/browser/devtools/styleeditor.xul (styleeditor/styleeditor.xul)
content/browser/devtools/styleeditor.css (styleeditor/styleeditor.css)
+ content/browser/devtools/power.xul (power/power.xul)
content/browser/devtools/storage.xul (storage/storage.xul)
content/browser/devtools/computedview.xhtml (styleinspector/computedview.xhtml)
content/browser/devtools/cssruleview.xhtml (styleinspector/cssruleview.xhtml)
content/browser/devtools/ruleview.css (styleinspector/ruleview.css)
content/browser/devtools/layoutview/view.js (layoutview/view.js)
content/browser/devtools/layoutview/view.xhtml (layoutview/view.xhtml)
content/browser/devtools/layoutview/view.css (layoutview/view.css)
content/browser/devtools/fontinspector/font-inspector.js (fontinspector/font-inspector.js)
diff --git a/browser/devtools/main.js b/browser/devtools/main.js
--- a/browser/devtools/main.js
+++ b/browser/devtools/main.js
@@ -29,43 +29,46 @@ loader.lazyGetter(this, "DebuggerPanel",
loader.lazyGetter(this, "StyleEditorPanel", () => require("devtools/styleeditor/styleeditor-panel").StyleEditorPanel);
loader.lazyGetter(this, "ShaderEditorPanel", () => require("devtools/shadereditor/panel").ShaderEditorPanel);
loader.lazyGetter(this, "CanvasDebuggerPanel", () => require("devtools/canvasdebugger/panel").CanvasDebuggerPanel);
loader.lazyGetter(this, "WebAudioEditorPanel", () => require("devtools/webaudioeditor/panel").WebAudioEditorPanel);
loader.lazyGetter(this, "ProfilerPanel", () => require("devtools/profiler/panel").ProfilerPanel);
loader.lazyGetter(this, "NetMonitorPanel", () => require("devtools/netmonitor/panel").NetMonitorPanel);
loader.lazyGetter(this, "ScratchpadPanel", () => require("devtools/scratchpad/scratchpad-panel").ScratchpadPanel);
loader.lazyGetter(this, "StoragePanel", () => require("devtools/storage/panel").StoragePanel);
+loader.lazyGetter(this, "PowerPanel", () => require("devtools/power/panel").PowerPanel);
// Strings
const toolboxProps = "chrome://browser/locale/devtools/toolbox.properties";
const inspectorProps = "chrome://browser/locale/devtools/inspector.properties";
const debuggerProps = "chrome://browser/locale/devtools/debugger.properties";
const styleEditorProps = "chrome://browser/locale/devtools/styleeditor.properties";
const shaderEditorProps = "chrome://browser/locale/devtools/shadereditor.properties";
const canvasDebuggerProps = "chrome://browser/locale/devtools/canvasdebugger.properties";
const webAudioEditorProps = "chrome://browser/locale/devtools/webaudioeditor.properties";
const webConsoleProps = "chrome://browser/locale/devtools/webconsole.properties";
const profilerProps = "chrome://browser/locale/devtools/profiler.properties";
const netMonitorProps = "chrome://browser/locale/devtools/netmonitor.properties";
const scratchpadProps = "chrome://browser/locale/devtools/scratchpad.properties";
const storageProps = "chrome://browser/locale/devtools/storage.properties";
+const powerProps = "chrome://browser/locale/devtools/power.properties";
loader.lazyGetter(this, "toolboxStrings", () => Services.strings.createBundle(toolboxProps));
loader.lazyGetter(this, "webConsoleStrings", () => Services.strings.createBundle(webConsoleProps));
loader.lazyGetter(this, "debuggerStrings", () => Services.strings.createBundle(debuggerProps));
loader.lazyGetter(this, "styleEditorStrings", () => Services.strings.createBundle(styleEditorProps));
loader.lazyGetter(this, "shaderEditorStrings", () => Services.strings.createBundle(shaderEditorProps));
loader.lazyGetter(this, "canvasDebuggerStrings", () => Services.strings.createBundle(canvasDebuggerProps));
loader.lazyGetter(this, "webAudioEditorStrings", () => Services.strings.createBundle(webAudioEditorProps));
loader.lazyGetter(this, "inspectorStrings", () => Services.strings.createBundle(inspectorProps));
loader.lazyGetter(this, "profilerStrings",() => Services.strings.createBundle(profilerProps));
loader.lazyGetter(this, "netMonitorStrings", () => Services.strings.createBundle(netMonitorProps));
loader.lazyGetter(this, "scratchpadStrings", () => Services.strings.createBundle(scratchpadProps));
loader.lazyGetter(this, "storageStrings", () => Services.strings.createBundle(storageProps));
+loader.lazyGetter(this, "powerStrings", () => Services.strings.createBundle(powerProps));
let Tools = {};
exports.Tools = Tools;
// Definitions
Tools.options = {
id: "options",
ordinal: 0,
@@ -364,29 +367,56 @@ Tools.scratchpad = {
},
build: function(iframeWindow, toolbox) {
let panel = new ScratchpadPanel(iframeWindow, toolbox);
return panel.open();
}
};
+Tools.power = {
+ id: "power",
+ key: l10n("power.commandkey", powerStrings),
+ ordinal: 9,
+ accesskey: l10n("power.accesskey", powerStrings),
+ modifiers: "shift",
+ visibilityswitch: "devtools.storage.enabled",
+ icon: "chrome://browser/skin/devtools/tool-storage.svg",
+ invertIconForLightTheme: true,
+ url: "chrome://browser/content/devtools/power.xul",
+ label: l10n("power.label", powerStrings),
+ menuLabel: l10n("power.menuLabel", powerStrings),
+ panelLabel: l10n("power.panelLabel", powerStrings),
+ tooltip: l10n("power.tooltip2", powerStrings),
+ inMenu: true,
+
+ isTargetSupported: function(target) {
+ return /*target.client.traits.powerMonitor &&*/ !target.isAddon;
+ },
+
+ build: function(iframeWindow, toolbox) {
+ let panel = new PowerPanel(iframeWindow, toolbox);
+ return panel.open();
+ }
+};
+
let defaultTools = [
Tools.options,
Tools.webConsole,
Tools.inspector,
Tools.jsdebugger,
Tools.styleEditor,
Tools.shaderEditor,
Tools.canvasDebugger,
Tools.webAudioEditor,
Tools.jsprofiler,
Tools.netMonitor,
Tools.storage,
- Tools.scratchpad
+ Tools.scratchpad,
+ Tools.power,
];
exports.defaultTools = defaultTools;
for (let definition of defaultTools) {
gDevTools.registerTool(definition);
}
diff --git a/browser/devtools/moz.build b/browser/devtools/moz.build
--- a/browser/devtools/moz.build
+++ b/browser/devtools/moz.build
@@ -12,16 +12,17 @@ DIRS += [
'eyedropper',
'fontinspector',
'framework',
'inspector',
'projecteditor',
'layoutview',
'markupview',
'netmonitor',
+ 'power',
'profiler',
'responsivedesign',
'scratchpad',
'shadereditor',
'shared',
'sourceeditor',
'storage',
'styleeditor',
diff --git a/browser/devtools/power/moz.build b/browser/devtools/power/moz.build
new file mode 100644
--- /dev/null
+++ b/browser/devtools/power/moz.build
@@ -0,0 +1,4 @@
+EXTRA_JS_MODULES.devtools.power += [
+ 'panel.js',
+ 'ui.js',
+]
diff --git a/browser/devtools/power/panel.js b/browser/devtools/power/panel.js
new file mode 100644
--- /dev/null
+++ b/browser/devtools/power/panel.js
@@ -0,0 +1,83 @@
+/* -*- Mode: Javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* 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/. */
+
+const {Cc, Ci, Cu, Cr} = require("chrome");
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/Promise.jsm");
+
+let EventEmitter = require("devtools/toolkit/event-emitter");
+
+loader.lazyGetter(this, "PowerFront",
+ () => require("devtools/server/actors/power").PowerFront);
+
+loader.lazyGetter(this, "PowerUI",
+ () => require("devtools/power/ui").PowerUI);
+
+this.PowerPanel = function PowerPanel(panelWin, toolbox) {
+ EventEmitter.decorate(this);
+
+ this._toolbox = toolbox;
+ this._target = toolbox.target;
+ this._panelWin = panelWin;
+
+ this.destroy = this.destroy.bind(this);
+}
+
+exports.PowerPanel = PowerPanel;
+
+PowerPanel.prototype = {
+ get target() this._toolbox.target,
+
+ get panelWindow() this._panelWin,
+
+ /**
+ * open is effectively an asynchronous constructor
+ */
+ open: function() {
+ let targetPromise;
+ // We always interact with the target as if it were remote
+ if (!this.target.isRemote) {
+ targetPromise = this.target.makeRemote();
+ } else {
+ targetPromise = Promise.resolve(this.target);
+ }
+
+ return targetPromise.then(() => {
+ this.target.on("close", this.destroy);
+ this._front = new PowerFront(this.target.client, this.target.form);
+
+ this.UI = new PowerUI(this._front, this._target, this._panelWin);
+ this.isReady = true;
+ this.emit("ready");
+ return this;
+ }, console.error);
+ },
+
+ /**
+ * Destroy the style editor.
+ */
+ destroy: function() {
+ if (!this._destroyed) {
+ this.UI.destroy();
+ this._destroyed = true;
+
+ this._target.off("close", this.destroy);
+ this._target = null;
+ this._toolbox = null;
+ this._panelDoc = null;
+ }
+
+ return Promise.resolve(null);
+ },
+}
+
+XPCOMUtils.defineLazyGetter(PowerPanel.prototype, "strings",
+ function () {
+ return Services.strings.createBundle(
+ "chrome://browser/locale/devtools/power.properties");
+ });
diff --git a/browser/devtools/power/power.xul b/browser/devtools/power/power.xul
new file mode 100644
--- /dev/null
+++ b/browser/devtools/power/power.xul
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/content/devtools/widgets.css" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/skin/devtools/common.css" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/skin/devtools/widgets.css" type="text/css"?>
+<!--<?xml-stylesheet href="chrome://browser/skin/devtools/storage.css" type="text/css"?>-->
+
+<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/javascript;version=1.8"
+ src="chrome://browser/content/devtools/theme-switching.js"/>
+ <script type="text/javascript" src="chrome://global/content/globalOverlay.js"/>
+
+ <commandset id="editMenuCommands"/>
+
+ <box flex="1" class="devtools-responsive-container theme-body">
+ <vbox id="power-log"/>
+ </box>
+
+</window>
diff --git a/browser/devtools/power/ui.js b/browser/devtools/power/ui.js
new file mode 100644
--- /dev/null
+++ b/browser/devtools/power/ui.js
@@ -0,0 +1,48 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* 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 {Cu} = require("chrome");
+const POWER_STRINGS = "chrome://browser/locale/devtools/power.properties";
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "EventEmitter",
+ "resource://gre/modules/devtools/event-emitter.js");
+XPCOMUtils.defineLazyGetter(this, "TableWidget",
+ () => require("devtools/shared/widgets/TableWidget").TableWidget);
+XPCOMUtils.defineLazyModuleGetter(this, "ViewHelpers",
+ "resource:///modules/devtools/ViewHelpers.jsm");
+
+let L10N = new ViewHelpers.L10N(POWER_STRINGS);
+
+this.PowerUI = function PowerUI(front, target, panelWin) {
+ EventEmitter.decorate(this);
+
+ this._target = target;
+ this._window = panelWin;
+ this._panelDoc = panelWin.document;
+ this.front = front;
+
+ this.front.attach();
+
+ var curPower = this._panelDoc.getElementById("power-log");
+
+ this._interval = this._window.setInterval(function() {
+ front.currentPower().then(power => {
+ curPower.textContent = power;
+ });
+ }, 1000);
+}
+
+exports.PowerUI = PowerUI;
+
+PowerUI.prototype = {
+ destroy: function() {
+ this.front.detach();
+ this._window.clearInterval(this._interval);
+ },
+}
diff --git a/browser/locales/en-US/chrome/browser/devtools/power.properties b/browser/locales/en-US/chrome/browser/devtools/power.properties
new file mode 100644
--- /dev/null
+++ b/browser/locales/en-US/chrome/browser/devtools/power.properties
@@ -0,0 +1,10 @@
+power.commandkey=VK_F10
+power.accesskey=p
+
+power.label=Power
+power.menuLabel=Power Monitor
+power.panelLabel=Power Panel
+power.tooltip2=Power Monitor
+
+table.emptyText=No power information present
+
diff --git a/browser/locales/jar.mn b/browser/locales/jar.mn
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -39,16 +39,17 @@
locale/browser/devtools/gcli.properties (%chrome/browser/devtools/gcli.properties)
locale/browser/devtools/gclicommands.properties (%chrome/browser/devtools/gclicommands.properties)
locale/browser/devtools/webconsole.properties (%chrome/browser/devtools/webconsole.properties)
locale/browser/devtools/inspector.properties (%chrome/browser/devtools/inspector.properties)
locale/browser/devtools/tilt.properties (%chrome/browser/devtools/tilt.properties)
locale/browser/devtools/scratchpad.properties (%chrome/browser/devtools/scratchpad.properties)
locale/browser/devtools/scratchpad.dtd (%chrome/browser/devtools/scratchpad.dtd)
locale/browser/devtools/storage.properties (%chrome/browser/devtools/storage.properties)
+ locale/browser/devtools/power.properties (%chrome/browser/devtools/power.properties)
locale/browser/devtools/styleeditor.properties (%chrome/browser/devtools/styleeditor.properties)
locale/browser/devtools/styleeditor.dtd (%chrome/browser/devtools/styleeditor.dtd)
locale/browser/devtools/styleinspector.dtd (%chrome/browser/devtools/styleinspector.dtd)
locale/browser/devtools/webConsole.dtd (%chrome/browser/devtools/webConsole.dtd)
locale/browser/devtools/VariablesView.dtd (%chrome/browser/devtools/VariablesView.dtd)
locale/browser/devtools/sourceeditor.properties (%chrome/browser/devtools/sourceeditor.properties)
locale/browser/devtools/sourceeditor.dtd (%chrome/browser/devtools/sourceeditor.dtd)
locale/browser/devtools/profiler.dtd (%chrome/browser/devtools/profiler.dtd)
diff --git a/toolkit/devtools/server/actors/power.js b/toolkit/devtools/server/actors/power.js
new file mode 100644
--- /dev/null
+++ b/toolkit/devtools/server/actors/power.js
@@ -0,0 +1,78 @@
+/* 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 {Cu, Cc, Ci} = require("chrome");
+const events = require("sdk/event/core");
+const protocol = require("devtools/server/protocol");
+const {async} = require("devtools/async-utils");
+const {Arg, Option, method, RetVal, types} = protocol;
+const {LongStringActor, ShortLongString} = require("devtools/server/actors/string");
+
+Cu.import("resource://gre/modules/Promise.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+exports.register = function(handle) {
+ handle.addTabActor(PowerActor, "powerActor");
+};
+
+exports.unregister = function(handle) {
+ handle.removeTabActor(PowerActor);
+};
+
+let PowerActor = exports.PowerActor = protocol.ActorClass({
+ typeName: "power",
+
+ events: {
+ "attach": {
+ type: "attach"
+ },
+ "detach": {
+ type: "detach"
+ },
+ "current-power": {
+ type: "currentPower",
+ data: Arg(0, "number"),
+ }
+ },
+
+ initialize: function (conn, tabActor) {
+ protocol.Actor.prototype.initialize.call(this, null);
+
+ this.conn = conn;
+ this.parentActor = tabActor;
+ },
+
+ destroy: function() {
+ this.destroyed = true;
+ },
+
+ attach: method(function() {
+ return true;
+ }, {
+ response: {attached: RetVal("boolean")}
+ }),
+
+ detach: method(function() {
+ return true;
+ }, {
+ response: {detached: RetVal("boolean")}
+ }),
+
+ currentPower: method(function() {
+ return 0.0;
+ }, {
+ response: {power: RetVal("number")}
+ }),
+});
+
+let PowerFront = exports.PowerFront = protocol.FrontClass(PowerActor, {
+ initialize: function(client, tabForm) {
+ protocol.Front.prototype.initialize.call(this, client);
+ this.actorID = tabForm.powerActor;
+ this.manage(this);
+ }
+});
diff --git a/toolkit/devtools/server/moz.build b/toolkit/devtools/server/moz.build
--- a/toolkit/devtools/server/moz.build
+++ b/toolkit/devtools/server/moz.build
@@ -41,16 +41,17 @@ EXTRA_JS_MODULES.devtools.server.actors
'actors/eventlooplag.js',
'actors/framerate.js',
'actors/gcli.js',
'actors/highlighter.js',
'actors/inspector.js',
'actors/layout.js',
'actors/memory.js',
'actors/monitor.js',
+ 'actors/power.js',
'actors/preference.js',
'actors/pretty-print-worker.js',
'actors/profiler.js',
'actors/root.js',
'actors/script.js',
'actors/storage.js',
'actors/string.js',
'actors/styleeditor.js',
diff --git a/src/components/devtools/actors/tab.rs b/src/components/devtools/actors/tab.rs
index c9cc348..1ae816d 100644
--- a/src/components/devtools/actors/tab.rs
+++ b/src/components/devtools/actors/tab.rs
@@ -11,6 +11,7 @@ use protocol::JsonPacketSender;
use serialize::json;
use std::io::TcpStream;
+use std::rand;
#[deriving(Encodable)]
struct TabTraits;
@@ -26,6 +27,71 @@ struct TabAttachedReply {
}
#[deriving(Encodable)]
+struct AttachReply {
+ attached: bool,
+ from: String,
+}
+
+#[deriving(Encodable)]
+struct DetachReply {
+ detached: bool,
+ from: String,
+}
+
+#[deriving(Encodable)]
+struct CurrentPowerReply {
+ power: f32,
+ from: String,
+}
+
+pub struct PowerActor {
+ pub name: String,
+}
+
+impl Actor for PowerActor {
+ fn name(&self) -> String {
+ self.name.clone()
+ }
+
+ fn handle_message(&self,
+ _registry: &ActorRegistry,
+ msg_type: &String,
+ _msg: &json::Object,
+ stream: &mut TcpStream) -> bool {
+ match msg_type.as_slice() {
+ "attach" => {
+ let msg = AttachReply {
+ attached: true,
+ from: self.name(),
+ };
+ stream.write_json_packet(&msg);
+ true
+ }
+
+ "detach" => {
+ let msg = DetachReply {
+ detached: true,
+ from: self.name(),
+ };
+ stream.write_json_packet(&msg);
+ true
+ }
+
+ "currentPower" => {
+ let msg = CurrentPowerReply {
+ power: rand::random(),
+ from: self.name(),
+ };
+ stream.write_json_packet(&msg);
+ true
+ }
+
+ _ => false,
+ }
+ }
+}
+
+#[deriving(Encodable)]
struct TabDetachedReply {
from: String,
__type__: String,
@@ -58,6 +124,7 @@ pub struct TabActorMsg {
outerWindowID: uint,
consoleActor: String,
inspectorActor: String,
+ powerActor: String,
}
pub struct TabActor {
@@ -66,6 +133,7 @@ pub struct TabActor {
pub url: String,
pub console: String,
pub inspector: String,
+ pub power: String,
}
impl Actor for TabActor {
@@ -131,6 +199,7 @@ impl TabActor {
outerWindowID: 0, //FIXME: this should probably be the pipeline id
consoleActor: self.console.clone(),
inspectorActor: self.inspector.clone(),
+ powerActor: self.power.clone(),
}
}
}
diff --git a/src/components/devtools/devtools.rs b/src/components/devtools/devtools.rs
index 71fd82f..6e05a7d 100644
--- a/src/components/devtools/devtools.rs
+++ b/src/components/devtools/devtools.rs
@@ -31,7 +31,7 @@ use actor::{Actor, ActorRegistry};
use actors::console::ConsoleActor;
use actors::inspector::InspectorActor;
use actors::root::RootActor;
-use actors::tab::TabActor;
+use actors::tab::{PowerActor, TabActor};
use protocol::JsonPacketSender;
use devtools_traits::{ServerExitMsg, DevtoolsControlMsg, NewGlobal, DevtoolScriptControlMsg};
@@ -139,7 +139,10 @@ fn run_server(port: Receiver<DevtoolsControlMsg>) {
let mut actors = actors.lock();
//TODO: move all this actor creation into a constructor method on TabActor
- let (tab, console, inspector) = {
+ let (tab, console, inspector, power) = {
+ let power = PowerActor {
+ name: actors.new_name("power"),
+ };
let console = ConsoleActor {
name: actors.new_name("console"),
script_chan: sender.clone(),
@@ -160,16 +163,18 @@ fn run_server(port: Receiver<DevtoolsControlMsg>) {
url: "about:blank".to_string(),
console: console.name(),
inspector: inspector.name(),
+ power: power.name(),
};
let root = actors.find_mut::<RootActor>("root");
root.tabs.push(tab.name.clone());
- (tab, console, inspector)
+ (tab, console, inspector, power)
};
actors.register(box tab);
actors.register(box console);
actors.register(box inspector);
+ actors.register(box power);
}
//TODO: figure out some system that allows us to watch for new connections,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment