Revert "Bug 1167006 - Refactor marker details to not handle stack traces explicitly, and move logic into marker utils. Separate out some source link styles. r=vp"

This reverts commit 411adbfe0ea2
This commit is contained in:
Jordan Santell 2015-05-22 13:47:18 -07:00
Родитель 531ac71b86
Коммит 2912d55a1d
5 изменённых файлов: 116 добавлений и 188 удалений

Просмотреть файл

@ -181,95 +181,4 @@ const DOM = exports.DOM = {
hbox.appendChild(labelValue);
return hbox;
},
/**
* Builds a stack trace in an element.
*
* @param {Document} doc
* @param object params
* An options object with the following members:
* string type - String identifier for type of stack ("stack", "startStack" or "endStack")
* integer frameIndex - The index of the topmost stack frame.
* array frames - Array of stack frames.
* @return {Element}
*/
buildStackTrace: function (doc, { type, frameIndex, frames }) {
let container = doc.createElement("vbox");
let labelName = doc.createElement("label");
labelName.className = "plain marker-details-labelname";
labelName.setAttribute("value", L10N.getStr(`timeline.markerDetail.${type}`));
container.appendChild(labelName);
let wasAsyncParent = false;
while (frameIndex > 0) {
let frame = frames[frameIndex];
let url = frame.source;
let displayName = frame.functionDisplayName;
let line = frame.line;
// If the previous frame had an async parent, then the async
// cause is in this frame and should be displayed.
if (wasAsyncParent) {
let asyncBox = doc.createElement("hbox");
let asyncLabel = doc.createElement("label");
asyncLabel.className = "devtools-monospace";
asyncLabel.setAttribute("value", L10N.getFormatStr("timeline.markerDetail.asyncStack",
frame.asyncCause));
asyncBox.appendChild(asyncLabel);
container.appendChild(asyncBox);
wasAsyncParent = false;
}
let hbox = doc.createElement("hbox");
if (displayName) {
let functionLabel = doc.createElement("label");
functionLabel.className = "devtools-monospace";
functionLabel.setAttribute("value", displayName);
hbox.appendChild(functionLabel);
}
if (url) {
let aNode = doc.createElement("a");
aNode.className = "waterfall-marker-location devtools-source-link";
aNode.href = url;
aNode.draggable = false;
aNode.setAttribute("title", url);
let urlNode = doc.createElement("label");
urlNode.className = "filename";
urlNode.setAttribute("value", WebConsoleUtils.Utils.abbreviateSourceURL(url));
let lineNode = doc.createElement("label");
lineNode.className = "line-number";
lineNode.setAttribute("value", `:${line}`);
aNode.appendChild(urlNode);
aNode.appendChild(lineNode);
hbox.appendChild(aNode);
// Clicking here will bubble up to the parent,
// which handles the view source
aNode.setAttribute("data-action", JSON.stringify({
url, line, action: "view-source"
}));
}
if (!displayName && !url) {
let label = doc.createElement("label");
label.setAttribute("value", L10N.getStr("timeline.markerDetail.unknownFrame"));
hbox.appendChild(label);
}
container.appendChild(hbox);
if (frame.asyncParent) {
frameIndex = frame.asyncParent;
wasAsyncParent = true;
} else {
frameIndex = frame.parent;
}
}
return container;
},
};

Просмотреть файл

@ -3,6 +3,9 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
let { Ci } = require("chrome");
let WebConsoleUtils = require("devtools/toolkit/webconsole/utils").Utils;
/**
* This file contains the rendering code for the marker sidebar.
*/
@ -29,12 +32,10 @@ loader.lazyRequireGetter(this, "MarkerUtils",
*/
function MarkerDetails(parent, splitter) {
EventEmitter.decorate(this);
this._onClick = this._onClick.bind(this);
this._document = parent.ownerDocument;
this._parent = parent;
this._splitter = splitter;
this._splitter.addEventListener("mouseup", () => this.emit("resize"));
this._parent.addEventListener("click", this._onClick);
}
MarkerDetails.prototype = {
@ -59,72 +60,121 @@ MarkerDetails.prototype = {
*
* @param object params
* An options object holding:
* toolbox - The toolbox.
* marker - The marker to display.
* frames - Array of stack frame information; see stack.js.
*/
render: function({ marker, frames }) {
render: function({toolbox: toolbox, marker: marker, frames: frames}) {
this.empty();
let elements = [];
elements.push(MarkerUtils.DOM.buildTitle(this._document, marker));
elements.push(MarkerUtils.DOM.buildDuration(this._document, marker));
MarkerUtils.DOM.buildFields(this._document, marker).forEach(field => elements.push(field));
// UI for any marker
let title = MarkerUtils.DOM.buildTitle(this._document, marker);
let duration = MarkerUtils.DOM.buildDuration(this._document, marker);
let fields = MarkerUtils.DOM.buildFields(this._document, marker);
this._parent.appendChild(title);
this._parent.appendChild(duration);
fields.forEach(field => this._parent.appendChild(field));
// Build a stack element -- and use the "startStack" label if
// we have both a start and endStack.
if (marker.stack) {
let type = marker.endStack ? "startStack" : "stack";
elements.push(MarkerUtils.DOM.buildStackTrace(this._document, {
frameIndex: marker.stack, frames, type
}));
let property = "timeline.markerDetail.stack";
if (marker.endStack) {
property = "timeline.markerDetail.startStack";
}
this.renderStackTrace({toolbox: toolbox, parent: this._parent, property: property,
frameIndex: marker.stack, frames: frames});
}
if (marker.endStack) {
elements.push(MarkerUtils.DOM.buildStackTrace(this._document, {
frameIndex: marker.endStack, frames, type: "endStack"
}));
this.renderStackTrace({toolbox: toolbox, parent: this._parent, property: "timeline.markerDetail.endStack",
frameIndex: marker.endStack, frames: frames});
}
elements.forEach(el => this._parent.appendChild(el));
},
/**
* Handles clicking in the marker details view. Based on the target,
* can handle different actions -- only supporting view source links
* for the moment.
* Render a stack trace.
*
* @param object params
* An options object with the following members:
* object toolbox - The toolbox.
* nsIDOMNode parent - The parent node holding the view.
* string property - String identifier for label's name.
* integer frameIndex - The index of the topmost stack frame.
* array frames - Array of stack frames.
*/
_onClick: function (e) {
let data = findActionFromEvent(e.target);
if (!data) {
return;
}
renderStackTrace: function({toolbox: toolbox, parent: parent,
property: property, frameIndex: frameIndex,
frames: frames}) {
let labelName = this._document.createElement("label");
labelName.className = "plain marker-details-labelname";
labelName.setAttribute("value", L10N.getStr(property));
parent.appendChild(labelName);
if (data.action === "view-source") {
this.emit("view-source", data.url, data.line);
let wasAsyncParent = false;
while (frameIndex > 0) {
let frame = frames[frameIndex];
let url = frame.source;
let displayName = frame.functionDisplayName;
let line = frame.line;
// If the previous frame had an async parent, then the async
// cause is in this frame and should be displayed.
if (wasAsyncParent) {
let asyncBox = this._document.createElement("hbox");
let asyncLabel = this._document.createElement("label");
asyncLabel.className = "devtools-monospace";
asyncLabel.setAttribute("value", L10N.getFormatStr("timeline.markerDetail.asyncStack",
frame.asyncCause));
asyncBox.appendChild(asyncLabel);
parent.appendChild(asyncBox);
wasAsyncParent = false;
}
let hbox = this._document.createElement("hbox");
if (displayName) {
let functionLabel = this._document.createElement("label");
functionLabel.className = "devtools-monospace";
functionLabel.setAttribute("value", displayName);
hbox.appendChild(functionLabel);
}
if (url) {
let aNode = this._document.createElement("a");
aNode.className = "waterfall-marker-location theme-link devtools-monospace";
aNode.href = url;
aNode.draggable = false;
aNode.setAttribute("title", url);
let text = WebConsoleUtils.abbreviateSourceURL(url) + ":" + line;
let label = this._document.createElement("label");
label.setAttribute("value", text);
aNode.appendChild(label);
hbox.appendChild(aNode);
aNode.addEventListener("click", (event) => {
event.preventDefault();
this.emit("view-source", url, line);
});
}
if (!displayName && !url) {
let label = this._document.createElement("label");
label.setAttribute("value", L10N.getStr("timeline.markerDetail.unknownFrame"));
hbox.appendChild(label);
}
parent.appendChild(hbox);
if (frame.asyncParent) {
frameIndex = frame.asyncParent;
wasAsyncParent = true;
} else {
frameIndex = frame.parent;
}
}
},
};
/**
* Take an element from an event `target`, and ascend through
* the DOM, looking for an element with a `data-action` attribute. Return
* the parsed `data-action` value found, or null if none found before
* reaching the parent `container`.
*
* @param {Element} target
* @param {Element} container
* @return {object?}
*/
function findActionFromEvent (target, container) {
let el = target;
let action;
while (el !== container) {
if (action = el.getAttribute("data-action")) {
return JSON.parse(action);
}
el = el.parentNode;
}
return null;
}
exports.MarkerDetails = MarkerDetails;

Просмотреть файл

@ -3,8 +3,6 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const MARKER_DETAILS_WIDTH = 300;
/**
* Waterfall view containing the timeline markers, controlled by DetailsView.
*/
@ -26,9 +24,6 @@ let WaterfallView = Heritage.extend(DetailsSubview, {
initialize: function () {
DetailsSubview.initialize.call(this);
// TODO bug 1167093 save the previously set width, and ensure minimum width
$("#waterfall-details").setAttribute("width", MARKER_DETAILS_WIDTH);
this.waterfall = new Waterfall($("#waterfall-breakdown"), $("#waterfall-view"));
this.details = new MarkerDetails($("#waterfall-details"), $("#waterfall-view > splitter"));

Просмотреть файл

@ -6,17 +6,16 @@
:root {
font: message-box;
%ifdef XP_MACOSX
--monospace-font-family: Menlo, monospace;
%elifdef XP_WIN
--monospace-font-family: Consolas, monospace;
%else
--monospace-font-family: monospace;
%endif
}
.devtools-monospace {
font-family: var(--monospace-font-family);
%ifdef XP_MACOSX
font-family: Menlo, monospace;
%elifdef XP_WIN
font-family: Consolas, monospace;
%else
font-family: monospace;
%endif
%if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
font-size: 80%;
%endif
@ -248,37 +247,3 @@
background-color: transparent;
border: none;
}
/* Links to source code, like displaying `myfile.js:45` */
.devtools-source-link {
font-family: var(--monospace-font-family);
color: var(--theme-highlight-blue);
cursor: pointer;
white-space: nowrap;
display: flex;
align-self: flex-start;
text-decoration: none;
font-size: 11px;
width: 12em; /* probably should be changed for each tool */
}
.devtools-source-link:hover {
text-decoration: underline;
}
.devtools-source-link > .filename {
text-overflow: ellipsis;
text-align: end;
overflow: hidden;
margin: 2px 0px;
cursor: pointer;
}
.devtools-source-link > .line-number {
flex: none;
margin: 2px 0px;
cursor: pointer;
}
%include toolbars.inc.css

Просмотреть файл

@ -457,6 +457,15 @@
color: var(--theme-selection-color);
}
.waterfall-marker-location {
color: -moz-nativehyperlinktext;
}
.waterfall-marker-location:hover,
.waterfall-marker-location:focus {
text-decoration: underline;
}
#waterfall-details {
-moz-padding-start: 8px;
-moz-padding-end: 8px;