зеркало из https://github.com/mozilla/gecko-dev.git
Bug 850145 - Use SideMenuWidget in the Profiler; r=vporof
This commit is contained in:
Родитель
f68b453f7a
Коммит
3cfd9dc53d
|
@ -10,6 +10,8 @@ Cu.import("resource:///modules/devtools/gDevTools.jsm");
|
||||||
Cu.import("resource:///modules/devtools/ProfilerController.jsm");
|
Cu.import("resource:///modules/devtools/ProfilerController.jsm");
|
||||||
Cu.import("resource:///modules/devtools/ProfilerHelpers.jsm");
|
Cu.import("resource:///modules/devtools/ProfilerHelpers.jsm");
|
||||||
Cu.import("resource:///modules/devtools/shared/event-emitter.js");
|
Cu.import("resource:///modules/devtools/shared/event-emitter.js");
|
||||||
|
Cu.import("resource:///modules/devtools/SideMenuWidget.jsm");
|
||||||
|
Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
Cu.import("resource://gre/modules/devtools/Console.jsm");
|
Cu.import("resource://gre/modules/devtools/Console.jsm");
|
||||||
|
|
||||||
|
@ -24,6 +26,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "DebuggerServer",
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||||
"resource://gre/modules/Services.jsm");
|
"resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
|
const PROFILE_IDLE = 0;
|
||||||
|
const PROFILE_RUNNING = 1;
|
||||||
|
const PROFILE_COMPLETED = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An instance of a profile UI. Profile UI consists of
|
* An instance of a profile UI. Profile UI consists of
|
||||||
* an iframe with Cleopatra loaded in it and some
|
* an iframe with Cleopatra loaded in it and some
|
||||||
|
@ -159,18 +165,6 @@ ProfileUI.prototype = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Update profile's label in the sidebar.
|
|
||||||
*
|
|
||||||
* @param string text
|
|
||||||
* New text for the label.
|
|
||||||
*/
|
|
||||||
updateLabel: function PUI_udpateLabel(text) {
|
|
||||||
let doc = this.panel.document;
|
|
||||||
let label = doc.querySelector("li#profile-" + this.uid + "> h1");
|
|
||||||
label.textContent = text;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start profiling and, once started, notify the underlying page
|
* Start profiling and, once started, notify the underlying page
|
||||||
* so that it could update the UI. Also, once started, we add a
|
* so that it could update the UI. Also, once started, we add a
|
||||||
|
@ -192,7 +186,7 @@ ProfileUI.prototype = {
|
||||||
startFn = startFn || this.panel.startProfiling.bind(this.panel);
|
startFn = startFn || this.panel.startProfiling.bind(this.panel);
|
||||||
startFn(this.name, () => {
|
startFn(this.name, () => {
|
||||||
this.isStarted = true;
|
this.isStarted = true;
|
||||||
this.updateLabel(this.name + " *");
|
this.panel.sidebar.setProfileState(this, PROFILE_RUNNING);
|
||||||
this.panel.broadcast(this.uid, {task: "onStarted"}); // Do we really need this?
|
this.panel.broadcast(this.uid, {task: "onStarted"}); // Do we really need this?
|
||||||
this.emit("started");
|
this.emit("started");
|
||||||
});
|
});
|
||||||
|
@ -219,7 +213,7 @@ ProfileUI.prototype = {
|
||||||
stopFn(this.name, () => {
|
stopFn(this.name, () => {
|
||||||
this.isStarted = false;
|
this.isStarted = false;
|
||||||
this.isFinished = true;
|
this.isFinished = true;
|
||||||
this.updateLabel(this.name);
|
this.panel.sidebar.setProfileState(this, PROFILE_COMPLETED);
|
||||||
this.panel.broadcast(this.uid, {task: "onStopped"});
|
this.panel.broadcast(this.uid, {task: "onStopped"});
|
||||||
this.emit("stopped");
|
this.emit("stopped");
|
||||||
});
|
});
|
||||||
|
@ -274,6 +268,39 @@ ProfileUI.prototype = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function SidebarView(el) {
|
||||||
|
EventEmitter.decorate(this);
|
||||||
|
this.node = new SideMenuWidget(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewHelpers.create({ constructor: SidebarView, proto: MenuContainer.prototype }, {
|
||||||
|
getItemByProfile: function (profile) {
|
||||||
|
return this.orderedItems.filter((item) => item.attachment.uid === profile.uid)[0];
|
||||||
|
},
|
||||||
|
|
||||||
|
setProfileState: function (profile, state) {
|
||||||
|
let item = this.getItemByProfile(profile);
|
||||||
|
let label = item.target.querySelector(".profiler-sidebar-item > span");
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case PROFILE_IDLE:
|
||||||
|
label.textContent = L10N.getStr("profiler.stateIdle");
|
||||||
|
break;
|
||||||
|
case PROFILE_RUNNING:
|
||||||
|
label.textContent = L10N.getStr("profiler.stateRunning");
|
||||||
|
break;
|
||||||
|
case PROFILE_COMPLETED:
|
||||||
|
label.textContent = L10N.getStr("profiler.stateCompleted");
|
||||||
|
break;
|
||||||
|
default: // Wrong state, do nothing.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.attachment.state = state;
|
||||||
|
this.emit("stateChanged", item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Profiler panel. It is responsible for creating and managing
|
* Profiler panel. It is responsible for creating and managing
|
||||||
* different profile instances (see ProfileUI).
|
* different profile instances (see ProfileUI).
|
||||||
|
@ -320,6 +347,7 @@ ProfilerPanel.prototype = {
|
||||||
target: null,
|
target: null,
|
||||||
controller: null,
|
controller: null,
|
||||||
profiles: null,
|
profiles: null,
|
||||||
|
sidebar: null,
|
||||||
|
|
||||||
_uid: null,
|
_uid: null,
|
||||||
_activeUid: null,
|
_activeUid: null,
|
||||||
|
@ -332,7 +360,14 @@ ProfilerPanel.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
set activeProfile(profile) {
|
set activeProfile(profile) {
|
||||||
|
if (this._activeUid === profile.uid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this.activeProfile)
|
||||||
|
this.activeProfile.hide();
|
||||||
|
|
||||||
this._activeUid = profile.uid;
|
this._activeUid = profile.uid;
|
||||||
|
profile.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
get browserWindow() {
|
get browserWindow() {
|
||||||
|
@ -357,42 +392,59 @@ ProfilerPanel.prototype = {
|
||||||
* @return Promise
|
* @return Promise
|
||||||
*/
|
*/
|
||||||
open: function PP_open() {
|
open: function PP_open() {
|
||||||
let promise;
|
|
||||||
|
|
||||||
// Local profiling needs to make the target remote.
|
// Local profiling needs to make the target remote.
|
||||||
if (!this.target.isRemote) {
|
let target = this.target;
|
||||||
promise = this.target.makeRemote();
|
let promise = !target.isRemote ? target.makeRemote() : Promise.resolve(target);
|
||||||
} else {
|
|
||||||
promise = Promise.resolve(this.target);
|
|
||||||
}
|
|
||||||
|
|
||||||
return promise
|
return promise
|
||||||
.then(function(target) {
|
.then((target) => {
|
||||||
let deferred = Promise.defer();
|
let deferred = Promise.defer();
|
||||||
this.controller = new ProfilerController(this.target);
|
|
||||||
|
|
||||||
this.controller.connect(function onConnect() {
|
this.controller = new ProfilerController(this.target);
|
||||||
|
this.sidebar = new SidebarView(this.document.querySelector("#profiles-list"));
|
||||||
|
this.sidebar.node.addEventListener("select", (ev) => {
|
||||||
|
if (!ev.detail)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let profile = this.profiles.get(ev.detail.attachment.uid);
|
||||||
|
this.activeProfile = profile;
|
||||||
|
|
||||||
|
if (profile.isReady) {
|
||||||
|
profile.flushMessages();
|
||||||
|
return void this.emit("profileSwitched", profile.uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
profile.once("ready", () => {
|
||||||
|
profile.flushMessages();
|
||||||
|
this.emit("profileSwitched", profile.uid);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.controller.connect(() => {
|
||||||
let create = this.document.getElementById("profiler-create");
|
let create = this.document.getElementById("profiler-create");
|
||||||
create.addEventListener("click", function (ev) {
|
create.addEventListener("click", () => this.createProfile(), false);
|
||||||
this.createProfile()
|
|
||||||
}.bind(this), false);
|
|
||||||
create.removeAttribute("disabled");
|
create.removeAttribute("disabled");
|
||||||
|
|
||||||
let profile = this.createProfile();
|
let profile = this.createProfile();
|
||||||
this.switchToProfile(profile, function () {
|
let onSwitch = (_, uid) => {
|
||||||
|
if (profile.uid !== uid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.off("profileSwitched", onSwitch);
|
||||||
this.isReady = true;
|
this.isReady = true;
|
||||||
this.emit("ready");
|
this.emit("ready");
|
||||||
|
|
||||||
deferred.resolve(this);
|
deferred.resolve(this);
|
||||||
}.bind(this))
|
};
|
||||||
}.bind(this));
|
|
||||||
|
this.on("profileSwitched", onSwitch);
|
||||||
|
this.sidebar.selectedItem = this.sidebar.getItemByProfile(profile);
|
||||||
|
});
|
||||||
|
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}.bind(this))
|
})
|
||||||
.then(null, function onError(reason) {
|
.then(null, (reason) =>
|
||||||
Cu.reportError("ProfilerPanel open failed. " +
|
Cu.reportError("ProfilePanel open failed: " + reason.message));
|
||||||
reason.error + ": " + reason.message);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -427,22 +479,17 @@ ProfilerPanel.prototype = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let list = this.document.getElementById("profiles-list");
|
let box = this.document.createElement("vbox");
|
||||||
let item = this.document.createElement("li");
|
box.className = "profiler-sidebar-item";
|
||||||
let wrap = this.document.createElement("h1");
|
box.id = "profile-" + uid;
|
||||||
name = name || L10N.getFormatStr("profiler.profileName", [uid]);
|
let h3 = this.document.createElement("h3");
|
||||||
|
h3.textContent = name;
|
||||||
|
let span = this.document.createElement("span");
|
||||||
|
span.textContent = L10N.getStr("profiler.stateIdle");
|
||||||
|
box.appendChild(h3);
|
||||||
|
box.appendChild(span);
|
||||||
|
|
||||||
item.setAttribute("id", "profile-" + uid);
|
this.sidebar.push(box, { attachment: { uid: uid, name: name, state: PROFILE_IDLE } });
|
||||||
item.setAttribute("data-uid", uid);
|
|
||||||
item.addEventListener("click", function (ev) {
|
|
||||||
this.switchToProfile(this.profiles.get(uid));
|
|
||||||
}.bind(this), false);
|
|
||||||
|
|
||||||
wrap.className = "profile-name";
|
|
||||||
wrap.textContent = name;
|
|
||||||
|
|
||||||
item.appendChild(wrap);
|
|
||||||
list.appendChild(item);
|
|
||||||
|
|
||||||
let profile = new ProfileUI(uid, name, this);
|
let profile = new ProfileUI(uid, name, this);
|
||||||
this.profiles.set(uid, profile);
|
this.profiles.set(uid, profile);
|
||||||
|
@ -451,47 +498,6 @@ ProfilerPanel.prototype = {
|
||||||
return profile;
|
return profile;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Switches to a different profile by making its instance an
|
|
||||||
* active one.
|
|
||||||
*
|
|
||||||
* @param ProfileUI profile
|
|
||||||
* A profile instance to switch to.
|
|
||||||
* @param function onLoad
|
|
||||||
* A function to call when profile instance is ready.
|
|
||||||
* If the instance is already loaded, onLoad will be
|
|
||||||
* called synchronously.
|
|
||||||
*/
|
|
||||||
switchToProfile: function PP_switchToProfile(profile, onLoad=function() {}) {
|
|
||||||
let doc = this.document;
|
|
||||||
|
|
||||||
if (this.activeProfile) {
|
|
||||||
this.activeProfile.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
let active = doc.querySelector("#profiles-list > li.splitview-active");
|
|
||||||
if (active) {
|
|
||||||
active.className = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
doc.getElementById("profile-" + profile.uid).className = "splitview-active";
|
|
||||||
profile.show();
|
|
||||||
this.activeProfile = profile;
|
|
||||||
|
|
||||||
if (profile.isReady) {
|
|
||||||
profile.flushMessages();
|
|
||||||
this.emit("profileSwitched", profile.uid);
|
|
||||||
onLoad();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
profile.once("ready", () => {
|
|
||||||
profile.flushMessages();
|
|
||||||
this.emit("profileSwitched", profile.uid);
|
|
||||||
onLoad();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start collecting profile data.
|
* Start collecting profile data.
|
||||||
*
|
*
|
||||||
|
|
|
@ -83,7 +83,15 @@ gcli.addCommand({
|
||||||
throw gcli.lookup("profilerAlreadyFinished");
|
throw gcli.lookup("profilerAlreadyFinished");
|
||||||
}
|
}
|
||||||
|
|
||||||
panel.switchToProfile(profile, function () profile.start());
|
let item = panel.sidebar.getItemByProfile(profile);
|
||||||
|
|
||||||
|
if (panel.sidebar.selectedItem === item) {
|
||||||
|
profile.start();
|
||||||
|
} else {
|
||||||
|
panel.on("profileSwitched", () => profile.start());
|
||||||
|
panel.sidebar.selectedItem = item;
|
||||||
|
}
|
||||||
|
|
||||||
return gcli.lookup("profilerStarting2");
|
return gcli.lookup("profilerStarting2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +132,15 @@ gcli.addCommand({
|
||||||
throw gcli.lookup("profilerNotStarted2");
|
throw gcli.lookup("profilerNotStarted2");
|
||||||
}
|
}
|
||||||
|
|
||||||
panel.switchToProfile(profile, function () profile.stop());
|
let item = panel.sidebar.getItemByProfile(profile);
|
||||||
|
|
||||||
|
if (panel.sidebar.selectedItem === item) {
|
||||||
|
profile.stop();
|
||||||
|
} else {
|
||||||
|
panel.on("profileSwitched", () => profile.stop());
|
||||||
|
panel.sidebar.selectedItem = item;
|
||||||
|
}
|
||||||
|
|
||||||
return gcli.lookup("profilerStopping2");
|
return gcli.lookup("profilerStopping2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +209,7 @@ gcli.addCommand({
|
||||||
throw gcli.lookup("profilerNotFound");
|
throw gcli.lookup("profilerNotFound");
|
||||||
}
|
}
|
||||||
|
|
||||||
panel.switchToProfile(profile);
|
panel.sidebar.selectedItem = panel.sidebar.getItemByProfile(profile);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
|
|
||||||
<?xml-stylesheet href="chrome://global/skin/global.css"?>
|
<?xml-stylesheet href="chrome://global/skin/global.css"?>
|
||||||
<?xml-stylesheet href="chrome://browser/skin/devtools/common.css"?>
|
<?xml-stylesheet href="chrome://browser/skin/devtools/common.css"?>
|
||||||
<?xml-stylesheet href="chrome://browser/skin/devtools/splitview.css"?>
|
<?xml-stylesheet href="chrome://browser/skin/devtools/widgets.css"?>
|
||||||
<?xml-stylesheet href="chrome://browser/skin/devtools/profiler.css"?>
|
<?xml-stylesheet href="chrome://browser/skin/devtools/profiler.css"?>
|
||||||
<?xml-stylesheet href="chrome://browser/content/devtools/splitview.css"?>
|
<?xml-stylesheet href="chrome://browser/content/devtools/widgets.css"?>
|
||||||
|
|
||||||
<!DOCTYPE window [
|
<!DOCTYPE window [
|
||||||
<!ENTITY % profilerDTD SYSTEM "chrome://browser/locale/devtools/profiler.dtd">
|
<!ENTITY % profilerDTD SYSTEM "chrome://browser/locale/devtools/profiler.dtd">
|
||||||
|
@ -16,37 +16,31 @@
|
||||||
]>
|
]>
|
||||||
|
|
||||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
<box flex="1" id="profiler-chrome" class="splitview-root">
|
<box flex="1" id="profiler-chrome" class="devtools-responsive-container">
|
||||||
<box class="splitview-controller" width="180px">
|
<vbox class="profiler-sidebar">
|
||||||
<box class="splitview-main"></box>
|
<toolbar class="devtools-toolbar">
|
||||||
|
<toolbarbutton id="profiler-create"
|
||||||
|
class="devtools-toolbarbutton"
|
||||||
|
label="&profilerNew.label;"
|
||||||
|
disabled="true"/>
|
||||||
|
</toolbar>
|
||||||
|
|
||||||
<box class="splitview-nav-container">
|
<vbox id="profiles-list" flex="1">
|
||||||
<ol class="splitview-nav" id="profiles-list">
|
</vbox>
|
||||||
<!-- Example:
|
</vbox>
|
||||||
<li class="splitview-active" id="profile-1" data-uid="1">
|
|
||||||
<h1 class="profile-name">Profile 1</h1>
|
|
||||||
</li>
|
|
||||||
-->
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<spacer flex="1"/>
|
<splitter class="devtools-side-splitter"/>
|
||||||
|
|
||||||
<toolbar class="devtools-toolbar" mode="full">
|
<vbox flex="1">
|
||||||
<toolbarbutton id="profiler-create"
|
<toolbar class="devtools-toolbar">
|
||||||
class="devtools-toolbarbutton"
|
</toolbar>
|
||||||
label="&profilerNew.label;"
|
|
||||||
disabled="true"/>
|
|
||||||
</toolbar>
|
|
||||||
</box> <!-- splitview-nav-container -->
|
|
||||||
</box> <!-- splitview-controller -->
|
|
||||||
|
|
||||||
<box flex="1">
|
|
||||||
<vbox flex="1" id="profiler-report">
|
<vbox flex="1" id="profiler-report">
|
||||||
<!-- Example:
|
<!-- Example:
|
||||||
<iframe id="profiler-cleo-1"
|
<iframe id="profiler-cleo-1"
|
||||||
src="devtools/cleopatra.html" flex="1"></iframe>
|
src="devtools/cleopatra.html" flex="1"></iframe>
|
||||||
-->
|
-->
|
||||||
</vbox>
|
</vbox>
|
||||||
</box>
|
</vbox>
|
||||||
</box>
|
</box>
|
||||||
</window>
|
</window>
|
||||||
|
|
|
@ -26,13 +26,6 @@ function test() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCleoControls(doc) {
|
|
||||||
return [
|
|
||||||
doc.querySelector("#startWrapper button"),
|
|
||||||
doc.querySelector("#profilerMessage")
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
function startProfiling() {
|
function startProfiling() {
|
||||||
gPanel.profiles.get(gPanel.activeProfile.uid).once("started", function () {
|
gPanel.profiles.get(gPanel.activeProfile.uid).once("started", function () {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
|
@ -40,36 +33,27 @@ function startProfiling() {
|
||||||
gPanel.profiles.get(2).once("started", function () setTimeout(stopProfiling, 50));
|
gPanel.profiles.get(2).once("started", function () setTimeout(stopProfiling, 50));
|
||||||
}, 50);
|
}, 50);
|
||||||
});
|
});
|
||||||
|
|
||||||
sendFromProfile(gPanel.activeProfile.uid, "start");
|
sendFromProfile(gPanel.activeProfile.uid, "start");
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopProfiling() {
|
function stopProfiling() {
|
||||||
let [win, doc] = getProfileInternals(gUid);
|
is(getSidebarItem(1).attachment.state, PROFILE_RUNNING);
|
||||||
let [btn, msg] = getCleoControls(doc);
|
is(getSidebarItem(2).attachment.state, PROFILE_RUNNING);
|
||||||
|
|
||||||
is(gPanel.document.querySelector("li#profile-1 > h1").textContent,
|
|
||||||
"Profile 1 *", "Profile 1 has a star next to it.");
|
|
||||||
is(gPanel.document.querySelector("li#profile-2 > h1").textContent,
|
|
||||||
"Profile 2 *", "Profile 2 has a star next to it.");
|
|
||||||
|
|
||||||
gPanel.profiles.get(gPanel.activeProfile.uid).once("stopped", function () {
|
gPanel.profiles.get(gPanel.activeProfile.uid).once("stopped", function () {
|
||||||
is(gPanel.document.querySelector("li#profile-1 > h1").textContent,
|
is(getSidebarItem(1).attachment.state, PROFILE_COMPLETED);
|
||||||
"Profile 1", "Profile 1 doesn't have a star next to it anymore.");
|
|
||||||
|
|
||||||
sendFromProfile(2, "stop");
|
sendFromProfile(2, "stop");
|
||||||
gPanel.profiles.get(2).once("stopped", confirmAndFinish);
|
gPanel.profiles.get(2).once("stopped", confirmAndFinish);
|
||||||
});
|
});
|
||||||
|
|
||||||
sendFromProfile(gPanel.activeProfile.uid, "stop");
|
sendFromProfile(gPanel.activeProfile.uid, "stop");
|
||||||
}
|
}
|
||||||
|
|
||||||
function confirmAndFinish(ev, data) {
|
function confirmAndFinish(ev, data) {
|
||||||
let [win, doc] = getProfileInternals(gUid);
|
is(getSidebarItem(1).attachment.state, PROFILE_COMPLETED);
|
||||||
let [btn, msg] = getCleoControls(doc);
|
is(getSidebarItem(2).attachment.state, PROFILE_COMPLETED);
|
||||||
|
|
||||||
is(gPanel.document.querySelector("li#profile-1 > h1").textContent,
|
|
||||||
"Profile 1", "Profile 1 doesn't have a star next to it.");
|
|
||||||
is(gPanel.document.querySelector("li#profile-2 > h1").textContent,
|
|
||||||
"Profile 2", "Profile 2 doesn't have a star next to it.");
|
|
||||||
|
|
||||||
tearDown(gTab, function onTearDown() {
|
tearDown(gTab, function onTearDown() {
|
||||||
gPanel = null;
|
gPanel = null;
|
||||||
|
|
|
@ -48,17 +48,15 @@ function testConsoleProfile(hud) {
|
||||||
|
|
||||||
function checkProfiles(toolbox) {
|
function checkProfiles(toolbox) {
|
||||||
let panel = toolbox.getPanel("jsprofiler");
|
let panel = toolbox.getPanel("jsprofiler");
|
||||||
let getTitle = (uid) =>
|
|
||||||
panel.document.querySelector("li#profile-" + uid + " > h1").textContent;
|
|
||||||
|
|
||||||
is(getTitle(1), "Profile 1", "Profile 1 doesn't have a star next to it.");
|
is(getSidebarItem(1, panel).attachment.state, PROFILE_IDLE);
|
||||||
is(getTitle(2), "Profile 2 *", "Profile 2 doesn't have a star next to it.");
|
is(getSidebarItem(2, panel).attachment.state, PROFILE_RUNNING);
|
||||||
is(getTitle(3), "Profile 3", "Profile 3 doesn't have a star next to it.");
|
is(getSidebarItem(3, panel).attachment.state, PROFILE_COMPLETED);
|
||||||
|
|
||||||
// Make sure we can still stop profiles via the UI.
|
// Make sure we can still stop profiles via the UI.
|
||||||
|
|
||||||
gPanel.profiles.get(2).once("stopped", () => {
|
gPanel.profiles.get(2).once("stopped", () => {
|
||||||
is(getTitle(2), "Profile 2", "Profile 2 doesn't have a star next to it.");
|
is(getSidebarItem(2, panel).attachment.state, PROFILE_COMPLETED);
|
||||||
tearDown(gTab, () => gTab = gPanel = null);
|
tearDown(gTab, () => gTab = gPanel = null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -17,18 +17,20 @@ function test() {
|
||||||
openProfiler(tab, (toolbox) => {
|
openProfiler(tab, (toolbox) => {
|
||||||
gToolbox = toolbox;
|
gToolbox = toolbox;
|
||||||
loadUrl(PAGE, tab, () => {
|
loadUrl(PAGE, tab, () => {
|
||||||
gPanel.on("profileCreated", runTests);
|
gPanel.sidebar.on("stateChanged", (_, item) => {
|
||||||
|
if (item.attachment.state !== PROFILE_COMPLETED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
runTests();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function runTests() {
|
function runTests() {
|
||||||
let getTitle = (uid) =>
|
is(getSidebarItem(1).attachment.state, PROFILE_IDLE);
|
||||||
gPanel.document.querySelector("li#profile-" + uid + " > h1").textContent;
|
is(getSidebarItem(2).attachment.state, PROFILE_COMPLETED);
|
||||||
|
|
||||||
is(getTitle(1), "Profile 1", "Profile 1 doesn't have a star next to it.");
|
|
||||||
is(getTitle(2), "Profile 2", "Profile 2 doesn't have a star next to it.");
|
|
||||||
|
|
||||||
gPanel.once("parsed", () => {
|
gPanel.once("parsed", () => {
|
||||||
function assertSampleAndFinish() {
|
function assertSampleAndFinish() {
|
||||||
|
@ -49,5 +51,6 @@ function runTests() {
|
||||||
assertSampleAndFinish();
|
assertSampleAndFinish();
|
||||||
});
|
});
|
||||||
|
|
||||||
gPanel.switchToProfile(gPanel.profiles.get(2));
|
let profile = gPanel.profiles.get(2);
|
||||||
|
gPanel.sidebar.selectedItem = gPanel.sidebar.getItemByProfile(profile);
|
||||||
}
|
}
|
|
@ -18,15 +18,13 @@ function test() {
|
||||||
|
|
||||||
function runTests(toolbox) {
|
function runTests(toolbox) {
|
||||||
let panel = toolbox.getPanel("jsprofiler");
|
let panel = toolbox.getPanel("jsprofiler");
|
||||||
let getTitle = (uid) =>
|
|
||||||
panel.document.querySelector("li#profile-" + uid + " > h1").textContent;
|
|
||||||
|
|
||||||
panel.profiles.get(1).once("started", () => {
|
panel.profiles.get(1).once("started", () => {
|
||||||
is(getTitle(1), "Profile 1 *", "Profile 1 has a start next to it.");
|
is(getSidebarItem(1, panel).attachment.state, PROFILE_RUNNING);
|
||||||
|
|
||||||
openConsole(gTab, (hud) => {
|
openConsole(gTab, (hud) => {
|
||||||
panel.profiles.get(1).once("stopped", () => {
|
panel.profiles.get(1).once("stopped", () => {
|
||||||
is(getTitle(1), "Profile 1", "Profile 1 doesn't have a star next to it.");
|
is(getSidebarItem(1, panel).attachment.state, PROFILE_COMPLETED);
|
||||||
tearDown(gTab, () => gTab = gPanel = null);
|
tearDown(gTab, () => gTab = gPanel = null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -46,18 +46,18 @@ function testConsoleProfile(hud) {
|
||||||
|
|
||||||
function checkProfiles(toolbox) {
|
function checkProfiles(toolbox) {
|
||||||
let panel = toolbox.getPanel("jsprofiler");
|
let panel = toolbox.getPanel("jsprofiler");
|
||||||
let getTitle = (uid) =>
|
|
||||||
panel.document.querySelector("li#profile-" + uid + " > h1").textContent;
|
|
||||||
|
|
||||||
is(getTitle(1), "Profile 1", "Profile 1 doesn't have a star next to it.");
|
is(getSidebarItem(1, panel).attachment.state, PROFILE_IDLE);
|
||||||
is(getTitle(2), "Second", "Second doesn't have a star next to it.");
|
is(getSidebarItem(2, panel).attachment.name, "Second");
|
||||||
is(getTitle(3), "Third *", "Third does have a star next to it.");
|
is(getSidebarItem(2, panel).attachment.state, PROFILE_COMPLETED);
|
||||||
|
is(getSidebarItem(3, panel).attachment.name, "Third");
|
||||||
|
is(getSidebarItem(3, panel).attachment.state, PROFILE_RUNNING);
|
||||||
|
|
||||||
// Make sure we can still stop profiles via the queue pop.
|
// Make sure we can still stop profiles via the queue pop.
|
||||||
|
|
||||||
gPanel.profiles.get(3).once("stopped", () => {
|
gPanel.profiles.get(3).once("stopped", () => {
|
||||||
openProfiler(gTab, () => {
|
openProfiler(gTab, () => {
|
||||||
is(getTitle(3), "Third", "Third doesn't have a star next to it.");
|
is(getSidebarItem(3, panel).attachment.state, PROFILE_COMPLETED);
|
||||||
tearDown(gTab, () => gTab = gPanel = null);
|
tearDown(gTab, () => gTab = gPanel = null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -48,8 +48,11 @@ function onNamedProfileCreated(name, uid) {
|
||||||
is(gPanel.profiles.size, 3, "There are three profiles now");
|
is(gPanel.profiles.size, 3, "There are three profiles now");
|
||||||
is(gPanel.getProfileByUID(uid).name, "Custom Profile", "Name is correct");
|
is(gPanel.getProfileByUID(uid).name, "Custom Profile", "Name is correct");
|
||||||
|
|
||||||
let label = gPanel.document.querySelector("li#profile-" + uid + "> h1");
|
let profile = gPanel.profiles.get(uid);
|
||||||
is(label.textContent, "Custom Profile", "Name is correct on the label");
|
let data = gPanel.sidebar.getItemByProfile(profile).attachment;
|
||||||
|
|
||||||
|
is(data.uid, uid, "UID is correct");
|
||||||
|
is(data.name, "Custom Profile", "Name is correct on the label");
|
||||||
|
|
||||||
let btn = gPanel.document.getElementById("profile-" + uid);
|
let btn = gPanel.document.getElementById("profile-" + uid);
|
||||||
ok(btn, "Profile item has been added to the sidebar");
|
ok(btn, "Profile item has been added to the sidebar");
|
||||||
|
|
|
@ -2,8 +2,12 @@
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
let temp = {};
|
let temp = {};
|
||||||
|
|
||||||
const PROFILER_ENABLED = "devtools.profiler.enabled";
|
const PROFILER_ENABLED = "devtools.profiler.enabled";
|
||||||
const REMOTE_ENABLED = "devtools.debugger.remote-enabled";
|
const REMOTE_ENABLED = "devtools.debugger.remote-enabled";
|
||||||
|
const PROFILE_IDLE = 0;
|
||||||
|
const PROFILE_RUNNING = 1;
|
||||||
|
const PROFILE_COMPLETED = 2;
|
||||||
|
|
||||||
Cu.import("resource:///modules/devtools/gDevTools.jsm", temp);
|
Cu.import("resource:///modules/devtools/gDevTools.jsm", temp);
|
||||||
let gDevTools = temp.gDevTools;
|
let gDevTools = temp.gDevTools;
|
||||||
|
@ -36,6 +40,11 @@ function getProfileInternals(uid) {
|
||||||
return [win, doc];
|
return [win, doc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSidebarItem(uid, panel=gPanel) {
|
||||||
|
let profile = panel.profiles.get(uid);
|
||||||
|
return panel.sidebar.getItemByProfile(profile);
|
||||||
|
}
|
||||||
|
|
||||||
function sendFromProfile(uid, msg) {
|
function sendFromProfile(uid, msg) {
|
||||||
let [win, doc] = getProfileInternals(uid);
|
let [win, doc] = getProfileInternals(uid);
|
||||||
win.parent.postMessage({ uid: uid, status: msg }, "*");
|
win.parent.postMessage({ uid: uid, status: msg }, "*");
|
||||||
|
|
|
@ -82,3 +82,18 @@ profiler.loading=Loading profile…
|
||||||
# This string is displayed in the profiler whenever there is already
|
# This string is displayed in the profiler whenever there is already
|
||||||
# another running profile. Users can run only one profile at a time.
|
# another running profile. Users can run only one profile at a time.
|
||||||
profiler.alreadyRunning=Profiler is already running. If you want to run this profile stop Profile %S first.
|
profiler.alreadyRunning=Profiler is already running. If you want to run this profile stop Profile %S first.
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (profiler.stateIdle)
|
||||||
|
# This string is used to show that the profile in question is in IDLE
|
||||||
|
# state meaning that it hasn't been started yet.
|
||||||
|
profiler.stateIdle=Idle
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (profiler.stateRunning)
|
||||||
|
# This string is used to show that the profile in question is in RUNNING
|
||||||
|
# state meaning that it has been started and currently gathering profile data.
|
||||||
|
profiler.stateRunning=Running
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (profiler.stateCompleted)
|
||||||
|
# This string is used to show that the profile in question is in COMPLETED
|
||||||
|
# state meaning that it has been started and stopped already.
|
||||||
|
profiler.stateCompleted=Completed
|
||||||
|
|
|
@ -4,21 +4,40 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
.profile-name {
|
.profiler-sidebar {
|
||||||
|
min-width: 196px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profiler-sidebar + .devtools-side-splitter {
|
||||||
|
-moz-border-start-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profiler-sidebar-item {
|
||||||
|
padding: 3px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profiler-sidebar-item > h3 {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
padding: 8px;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
#profiles-list > li {
|
.profiler-sidebar-item > span {
|
||||||
width: 180px;
|
margin-top: 2px;
|
||||||
cursor: pointer;
|
color: rgb(140, 152, 165);
|
||||||
}
|
}
|
||||||
|
|
||||||
.splitview-nav-container button {
|
.selected .profiler-sidebar-item > span {
|
||||||
color: white;
|
color: rgb(128, 195, 228);
|
||||||
background-clip: padding-box;
|
}
|
||||||
border-bottom: 1px solid hsla(210,16%,76%,.1);
|
|
||||||
box-shadow: inset 0 -1px 0 hsla(210,8%,5%,.25);
|
.devtools-toolbar {
|
||||||
-moz-padding-end: 8px;
|
height: 26px;
|
||||||
-moz-box-align: center;
|
padding: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.devtools-toolbar .devtools-toolbarbutton {
|
||||||
|
min-width: 48px;
|
||||||
|
min-height: 0;
|
||||||
|
font-size: 11px;
|
||||||
|
padding: 0px 8px;
|
||||||
}
|
}
|
Загрузка…
Ссылка в новой задаче