mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1176981 - Part 0: Remove the tracing debugger UI; r=vporof
This commit is contained in:
parent
4144f8d25e
commit
612a7e0254
@ -185,7 +185,6 @@ let DebuggerController = {
|
||||
if (this._target.isTabActor) {
|
||||
this.Workers.disconnect();
|
||||
}
|
||||
this.Tracer.disconnect();
|
||||
this.disconnect();
|
||||
|
||||
this._shutdown = true;
|
||||
@ -204,7 +203,7 @@ let DebuggerController = {
|
||||
}
|
||||
|
||||
let target = this._target;
|
||||
let { client, form: { chromeDebugger, traceActor, actor } } = target;
|
||||
let { client, form: { chromeDebugger, actor } } = target;
|
||||
target.on("close", this._onTabDetached);
|
||||
target.on("navigate", this._onTabNavigated);
|
||||
target.on("will-navigate", this._onTabNavigated);
|
||||
@ -218,10 +217,6 @@ let DebuggerController = {
|
||||
yield this._startChromeDebugging(chromeDebugger);
|
||||
} else {
|
||||
yield this._startDebuggingTab();
|
||||
|
||||
if (Prefs.tracerEnabled && traceActor) {
|
||||
yield this._startTracingTab(traceActor);
|
||||
}
|
||||
}
|
||||
|
||||
this._hideUnsupportedFeatures();
|
||||
@ -390,31 +385,6 @@ let DebuggerController = {
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets up an execution tracing session.
|
||||
*
|
||||
* @param object aTraceActor
|
||||
* The remote protocol grip of the trace actor.
|
||||
* @return object
|
||||
* A promise resolved once the client attaches to the tracer.
|
||||
*/
|
||||
_startTracingTab: function(aTraceActor) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
this.client.attachTracer(aTraceActor, (response, traceClient) => {
|
||||
if (!traceClient) {
|
||||
deferred.reject(new Error("Failed to attach to tracing actor."));
|
||||
return;
|
||||
}
|
||||
this.traceClient = traceClient;
|
||||
this.Tracer.connect();
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Detach and reattach to the thread actor with useSourceMaps true, blow
|
||||
* away old sources and get them again.
|
||||
@ -1301,7 +1271,6 @@ SourceScripts.prototype = {
|
||||
// both in the editor and the breakpoints pane.
|
||||
DebuggerController.Breakpoints.updatePaneBreakpoints();
|
||||
DebuggerController.Breakpoints.updateEditorBreakpoints();
|
||||
DebuggerController.HitCounts.updateEditorHitCounts();
|
||||
|
||||
// Make sure the events listeners are up to date.
|
||||
if (DebuggerView.instrumentsPaneTab == "events-tab") {
|
||||
@ -1354,7 +1323,6 @@ SourceScripts.prototype = {
|
||||
// both in the editor and the breakpoints pane.
|
||||
DebuggerController.Breakpoints.updatePaneBreakpoints();
|
||||
DebuggerController.Breakpoints.updateEditorBreakpoints();
|
||||
DebuggerController.HitCounts.updateEditorHitCounts();
|
||||
|
||||
// Signal that sources have been added.
|
||||
window.emit(EVENTS.SOURCES_ADDED);
|
||||
@ -1566,237 +1534,6 @@ SourceScripts.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Tracer update the UI according to the messages exchanged with the tracer
|
||||
* actor.
|
||||
*/
|
||||
function Tracer() {
|
||||
this._trace = null;
|
||||
this._idCounter = 0;
|
||||
this.onTraces = this.onTraces.bind(this);
|
||||
}
|
||||
|
||||
Tracer.prototype = {
|
||||
get client() {
|
||||
return DebuggerController.client;
|
||||
},
|
||||
|
||||
get traceClient() {
|
||||
return DebuggerController.traceClient;
|
||||
},
|
||||
|
||||
get tracing() {
|
||||
return !!this._trace;
|
||||
},
|
||||
|
||||
/**
|
||||
* Hooks up the debugger controller with the tracer client.
|
||||
*/
|
||||
connect: function() {
|
||||
this._stack = [];
|
||||
this.client.addListener("traces", this.onTraces);
|
||||
},
|
||||
|
||||
/**
|
||||
* Disconnects the debugger controller from the tracer client. Any further
|
||||
* communcation with the tracer actor will not have any effect on the UI.
|
||||
*/
|
||||
disconnect: function() {
|
||||
this._stack = null;
|
||||
this.client.removeListener("traces", this.onTraces);
|
||||
},
|
||||
|
||||
/**
|
||||
* Instructs the tracer actor to start tracing.
|
||||
*/
|
||||
startTracing: function(aCallback = () => {}) {
|
||||
if (this.tracing) {
|
||||
return;
|
||||
}
|
||||
|
||||
DebuggerView.Tracer.selectTab();
|
||||
|
||||
let id = this._trace = "dbg.trace" + Math.random();
|
||||
let fields = [
|
||||
"name",
|
||||
"location",
|
||||
"hitCount",
|
||||
"parameterNames",
|
||||
"depth",
|
||||
"arguments",
|
||||
"return",
|
||||
"throw",
|
||||
"yield"
|
||||
];
|
||||
|
||||
this.traceClient.startTrace(fields, id, aResponse => {
|
||||
const { error } = aResponse;
|
||||
if (error) {
|
||||
DevToolsUtils.reportException("Tracer.prototype.startTracing", error);
|
||||
this._trace = null;
|
||||
}
|
||||
|
||||
aCallback(aResponse);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Instructs the tracer actor to stop tracing.
|
||||
*/
|
||||
stopTracing: function(aCallback = () => {}) {
|
||||
if (!this.tracing) {
|
||||
return;
|
||||
}
|
||||
this.traceClient.stopTrace(this._trace, aResponse => {
|
||||
const { error } = aResponse;
|
||||
if (error) {
|
||||
DevToolsUtils.reportException("Tracer.prototype.stopTracing", error);
|
||||
}
|
||||
|
||||
this._trace = null;
|
||||
DebuggerController.HitCounts.clear();
|
||||
aCallback(aResponse);
|
||||
});
|
||||
},
|
||||
|
||||
onTraces: function (aEvent, { traces }) {
|
||||
const tracesLength = traces.length;
|
||||
let tracesToShow;
|
||||
|
||||
// Update hit counts.
|
||||
for (let t of traces) {
|
||||
if (t.type == "enteredFrame") {
|
||||
DebuggerController.HitCounts.set(t.location, t.hitCount);
|
||||
}
|
||||
}
|
||||
DebuggerController.HitCounts.updateEditorHitCounts();
|
||||
|
||||
// Limit number of traces to be shown in the log.
|
||||
if (tracesLength > TracerView.MAX_TRACES) {
|
||||
tracesToShow = traces.slice(tracesLength - TracerView.MAX_TRACES, tracesLength);
|
||||
this._stack.splice(0, this._stack.length);
|
||||
DebuggerView.Tracer.empty();
|
||||
} else {
|
||||
tracesToShow = traces;
|
||||
}
|
||||
|
||||
// Show traces in the log.
|
||||
for (let t of tracesToShow) {
|
||||
if (t.type == "enteredFrame") {
|
||||
this._onCall(t);
|
||||
} else {
|
||||
this._onReturn(t);
|
||||
}
|
||||
}
|
||||
DebuggerView.Tracer.commit();
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback for handling a new call frame.
|
||||
*/
|
||||
_onCall: function({ name, location, blackBoxed, parameterNames, depth, arguments: args }) {
|
||||
const item = {
|
||||
name: name,
|
||||
location: location,
|
||||
id: this._idCounter++,
|
||||
blackBoxed
|
||||
};
|
||||
|
||||
this._stack.push(item);
|
||||
DebuggerView.Tracer.addTrace({
|
||||
type: "call",
|
||||
name: name,
|
||||
location: location,
|
||||
depth: depth,
|
||||
parameterNames: parameterNames,
|
||||
arguments: args,
|
||||
frameId: item.id,
|
||||
blackBoxed
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback for handling an exited frame.
|
||||
*/
|
||||
_onReturn: function(aPacket) {
|
||||
if (!this._stack.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { name, id, location, blackBoxed } = this._stack.pop();
|
||||
DebuggerView.Tracer.addTrace({
|
||||
type: aPacket.why,
|
||||
name: name,
|
||||
location: location,
|
||||
depth: aPacket.depth,
|
||||
frameId: id,
|
||||
returnVal: aPacket.return || aPacket.throw || aPacket.yield,
|
||||
blackBoxed
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Create an object which has the same interface as a normal object client,
|
||||
* but since we already have all the information for an object that we will
|
||||
* ever get (the server doesn't create actors when tracing, just firehoses
|
||||
* data and forgets about it) just return the data immdiately.
|
||||
*
|
||||
* @param Object aObject
|
||||
* The tracer object "grip" (more like a limited snapshot).
|
||||
* @returns Object
|
||||
* The synchronous client object.
|
||||
*/
|
||||
syncGripClient: function(aObject) {
|
||||
return {
|
||||
get isFrozen() { return aObject.frozen; },
|
||||
get isSealed() { return aObject.sealed; },
|
||||
get isExtensible() { return aObject.extensible; },
|
||||
|
||||
get ownProperties() { return aObject.ownProperties; },
|
||||
get prototype() { return null; },
|
||||
|
||||
getParameterNames: callback => callback(aObject),
|
||||
getPrototypeAndProperties: callback => callback(aObject),
|
||||
getPrototype: callback => callback(aObject),
|
||||
|
||||
getOwnPropertyNames: (callback) => {
|
||||
callback({
|
||||
ownPropertyNames: aObject.ownProperties
|
||||
? Object.keys(aObject.ownProperties)
|
||||
: []
|
||||
});
|
||||
},
|
||||
|
||||
getProperty: (property, callback) => {
|
||||
callback({
|
||||
descriptor: aObject.ownProperties
|
||||
? aObject.ownProperties[property]
|
||||
: null
|
||||
});
|
||||
},
|
||||
|
||||
getDisplayString: callback => callback("[object " + aObject.class + "]"),
|
||||
|
||||
getScope: callback => callback({
|
||||
error: "scopeNotAvailable",
|
||||
message: "Cannot get scopes for traced objects"
|
||||
})
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Wraps object snapshots received from the tracer server so that we can
|
||||
* differentiate them from long living object grips from the debugger server
|
||||
* in the variables view.
|
||||
*
|
||||
* @param Object aObject
|
||||
* The object snapshot from the tracer actor.
|
||||
*/
|
||||
WrappedObject: function(aObject) {
|
||||
this.object = aObject;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles breaking on event listeners in the currently debugged target.
|
||||
*/
|
||||
@ -2167,10 +1904,10 @@ Breakpoints.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
// Preserve information about the breakpoint's line text, to display it
|
||||
// in the sources pane without requiring fetching the source (for example,
|
||||
// after the target navigated). Note that this will get out of sync
|
||||
// if the source text contents change.
|
||||
// Preserve information about the breakpoint's line text, to display it in
|
||||
// the sources pane without requiring fetching the source (for example,
|
||||
// after the target navigated). Note that this will get out of sync if the
|
||||
// source text contents change.
|
||||
let line = aBreakpointClient.location.line - 1;
|
||||
aBreakpointClient.text = DebuggerView.editor.getText(line).trim();
|
||||
|
||||
@ -2427,87 +2164,6 @@ Object.defineProperty(Breakpoints.prototype, "_addedOrDisabled", {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Handles Tracer's hit counts.
|
||||
*/
|
||||
function HitCounts() {
|
||||
/**
|
||||
* Storage of hit counts for every location
|
||||
* hitCount = _locations[url][line][column]
|
||||
*/
|
||||
this._hitCounts = Object.create(null);
|
||||
}
|
||||
|
||||
HitCounts.prototype = {
|
||||
set: function({url, line, column}, aHitCount) {
|
||||
if (url) {
|
||||
if (!this._hitCounts[url]) {
|
||||
this._hitCounts[url] = Object.create(null);
|
||||
}
|
||||
if (!this._hitCounts[url][line]) {
|
||||
this._hitCounts[url][line] = Object.create(null);
|
||||
}
|
||||
this._hitCounts[url][line][column] = aHitCount;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update all the hit counts in the editor view. This is invoked when the
|
||||
* selected script is changed, or when new sources are received via the
|
||||
* _onNewSource and _onSourcesAdded event listeners.
|
||||
*/
|
||||
updateEditorHitCounts: function() {
|
||||
// First, remove all hit counters.
|
||||
DebuggerView.editor.removeAllMarkers("hit-counts");
|
||||
|
||||
// Then, add new hit counts, just for the current source.
|
||||
for (let url in this._hitCounts) {
|
||||
for (let line in this._hitCounts[url]) {
|
||||
for (let column in this._hitCounts[url][line]) {
|
||||
this._updateEditorHitCount({url, line, column});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update a hit counter on a certain line.
|
||||
*/
|
||||
_updateEditorHitCount: function({url, line, column}) {
|
||||
// Editor must be initialized.
|
||||
if (!DebuggerView.editor) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No need to do anything if the counter's source is not being shown in the
|
||||
// editor.
|
||||
if (url &&
|
||||
DebuggerView.Sources.selectedItem.attachment.source.url != url) {
|
||||
return;
|
||||
}
|
||||
|
||||
// There might be more counters on the same line. We need to combine them
|
||||
// into one.
|
||||
let content = Object.keys(this._hitCounts[url][line])
|
||||
.sort() // Sort by key (column).
|
||||
.map(a => this._hitCounts[url][line][a]) // Extract values.
|
||||
.map(a => a + "\u00D7") // Format hit count (e.g. 146×).
|
||||
.join("|");
|
||||
|
||||
// CodeMirror's lines are indexed from 0, while traces start from 1
|
||||
DebuggerView.editor.addContentMarker(line - 1, "hit-counts", "hit-count",
|
||||
content);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all hit couters and clear the storage
|
||||
*/
|
||||
clear: function() {
|
||||
DebuggerView.editor.removeAllMarkers("hit-counts");
|
||||
this._hitCounts = Object.create(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Localization convenience methods.
|
||||
*/
|
||||
@ -2528,7 +2184,6 @@ let Prefs = new ViewHelpers.Prefs("devtools", {
|
||||
sourceMapsEnabled: ["Bool", "debugger.source-maps-enabled"],
|
||||
prettyPrintEnabled: ["Bool", "debugger.pretty-print-enabled"],
|
||||
autoPrettyPrint: ["Bool", "debugger.auto-pretty-print"],
|
||||
tracerEnabled: ["Bool", "debugger.tracer"],
|
||||
workersEnabled: ["Bool", "debugger.workers"],
|
||||
editorTabSize: ["Int", "editor.tabsize"],
|
||||
autoBlackBox: ["Bool", "debugger.auto-black-box"]
|
||||
@ -2550,8 +2205,6 @@ DebuggerController.StackFrames = new StackFrames();
|
||||
DebuggerController.SourceScripts = new SourceScripts();
|
||||
DebuggerController.Breakpoints = new Breakpoints();
|
||||
DebuggerController.Breakpoints.DOM = new EventListeners();
|
||||
DebuggerController.Tracer = new Tracer();
|
||||
DebuggerController.HitCounts = new HitCounts();
|
||||
|
||||
/**
|
||||
* Export some properties to the global scope for easier access.
|
||||
|
@ -58,7 +58,6 @@ let DebuggerView = {
|
||||
this.Workers.initialize();
|
||||
this.Sources.initialize();
|
||||
this.VariableBubble.initialize();
|
||||
this.Tracer.initialize();
|
||||
this.WatchExpressions.initialize();
|
||||
this.EventListeners.initialize();
|
||||
this.GlobalSearch.initialize();
|
||||
@ -91,7 +90,6 @@ let DebuggerView = {
|
||||
this.StackFramesClassicList.destroy();
|
||||
this.Sources.destroy();
|
||||
this.VariableBubble.destroy();
|
||||
this.Tracer.destroy();
|
||||
this.WatchExpressions.destroy();
|
||||
this.EventListeners.destroy();
|
||||
this.GlobalSearch.destroy();
|
||||
@ -174,9 +172,7 @@ let DebuggerView = {
|
||||
VariablesViewController.attach(this.Variables, {
|
||||
getEnvironmentClient: aObject => gThreadClient.environment(aObject),
|
||||
getObjectClient: aObject => {
|
||||
return aObject instanceof DebuggerController.Tracer.WrappedObject
|
||||
? DebuggerController.Tracer.syncGripClient(aObject.object)
|
||||
: gThreadClient.pauseGrip(aObject)
|
||||
return gThreadClient.pauseGrip(aObject)
|
||||
}
|
||||
});
|
||||
|
||||
@ -219,9 +215,6 @@ let DebuggerView = {
|
||||
}
|
||||
|
||||
let gutters = ["breakpoints"];
|
||||
if (Services.prefs.getBoolPref("devtools.debugger.tracer")) {
|
||||
gutters.unshift("hit-counts");
|
||||
}
|
||||
|
||||
this.editor = new Editor({
|
||||
mode: Editor.modes.text,
|
||||
@ -414,7 +407,6 @@ let DebuggerView = {
|
||||
// source.
|
||||
DebuggerView.Sources.selectedValue = aSource.actor;
|
||||
DebuggerController.Breakpoints.updateEditorBreakpoints();
|
||||
DebuggerController.HitCounts.updateEditorHitCounts();
|
||||
|
||||
histogram.add(Date.now() - startTime);
|
||||
|
||||
@ -673,7 +665,6 @@ let DebuggerView = {
|
||||
GlobalSearch: null,
|
||||
StackFrames: null,
|
||||
Sources: null,
|
||||
Tracer: null,
|
||||
Variables: null,
|
||||
VariableBubble: null,
|
||||
WatchExpressions: null,
|
||||
|
@ -31,7 +31,6 @@
|
||||
<script type="text/javascript" src="debugger/workers-view.js"/>
|
||||
<script type="text/javascript" src="debugger/sources-view.js"/>
|
||||
<script type="text/javascript" src="debugger/variable-bubble-view.js"/>
|
||||
<script type="text/javascript" src="debugger/tracer-view.js"/>
|
||||
<script type="text/javascript" src="debugger/watch-expressions-view.js"/>
|
||||
<script type="text/javascript" src="debugger/event-listeners-view.js"/>
|
||||
<script type="text/javascript" src="debugger/global-search-view.js"/>
|
||||
@ -280,13 +279,6 @@
|
||||
class="devtools-toolbarbutton"
|
||||
tabindex="0"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<toolbarbutton id="trace"
|
||||
class="devtools-toolbarbutton"
|
||||
command="toggleTracing"
|
||||
tabindex="0"
|
||||
hidden="true"/>
|
||||
</hbox>
|
||||
<vbox id="stackframes" flex="1"/>
|
||||
<textbox id="searchbox"
|
||||
class="devtools-searchinput" type="search"/>
|
||||
@ -324,7 +316,6 @@
|
||||
<tabs>
|
||||
<tab id="sources-tab" label="&debuggerUI.tabs.sources;"/>
|
||||
<tab id="callstack-tab" label="&debuggerUI.tabs.callstack;"/>
|
||||
<tab id="tracer-tab" label="&debuggerUI.tabs.traces;" hidden="true"/>
|
||||
</tabs>
|
||||
<tabpanels flex="1">
|
||||
<tabpanel id="sources-tabpanel">
|
||||
@ -355,26 +346,6 @@
|
||||
<tabpanel id="callstack-tabpanel">
|
||||
<vbox id="callstack-list" flex="1"/>
|
||||
</tabpanel>
|
||||
<tabpanel id="tracer-tabpanel">
|
||||
<vbox id="tracer-traces" flex="1"/>
|
||||
<hbox class="trace-item-template" hidden="true">
|
||||
<hbox class="trace-item" align="center" flex="1" crop="end">
|
||||
<label class="trace-type plain"/>
|
||||
<label class="trace-name plain" crop="end"/>
|
||||
</hbox>
|
||||
</hbox>
|
||||
<toolbar id="tracer-toolbar" class="devtools-toolbar">
|
||||
<toolbarbutton id="clear-tracer"
|
||||
label="&debuggerUI.clearButton;"
|
||||
tooltiptext="&debuggerUI.clearButton.tooltip;"
|
||||
command="clearTraces"
|
||||
class="devtools-toolbarbutton"/>
|
||||
<textbox id="tracer-search"
|
||||
class="devtools-searchinput"
|
||||
flex="1"
|
||||
type="search"/>
|
||||
</toolbar>
|
||||
</tabpanel>
|
||||
</tabpanels>
|
||||
</tabbox>
|
||||
</vbox>
|
||||
|
@ -33,7 +33,6 @@ support-files =
|
||||
code_script-switching-01.js
|
||||
code_script-switching-02.js
|
||||
code_test-editor-mode
|
||||
code_tracing-01.js
|
||||
code_ugly.js
|
||||
code_ugly-2.js
|
||||
code_ugly-3.js
|
||||
@ -91,7 +90,6 @@ support-files =
|
||||
doc_promise.html
|
||||
doc_random-javascript.html
|
||||
doc_recursion-stack.html
|
||||
doc_same-line-functions.html
|
||||
doc_scope-variable.html
|
||||
doc_scope-variable-2.html
|
||||
doc_scope-variable-3.html
|
||||
@ -103,7 +101,6 @@ support-files =
|
||||
doc_split-console-paused-reload.html
|
||||
doc_step-out.html
|
||||
doc_terminate-on-tab-close.html
|
||||
doc_tracing-01.html
|
||||
doc_watch-expressions.html
|
||||
doc_watch-expression-button.html
|
||||
doc_with-frame.html
|
||||
@ -247,10 +244,6 @@ skip-if = e10s && debug
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_hide-toolbar-buttons.js]
|
||||
skip-if = e10s
|
||||
[browser_dbg_hit-counts-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_hit-counts-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_host-layout.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_iframes.js]
|
||||
@ -453,22 +446,6 @@ skip-if = e10s # TODO
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_terminate-on-tab-close.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-04.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-05.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-06.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-07.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-08.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-02.js]
|
||||
|
@ -1,61 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Evaluating two functions on the same line and checking for correct hit count
|
||||
* for both of them in CodeMirror's gutter.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_same-line-functions.html";
|
||||
const CODE_URL = "code_same-line-functions.js";
|
||||
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gEditor;
|
||||
|
||||
function test() {
|
||||
Task.async(function* () {
|
||||
yield pushPrefs(["devtools.debugger.tracer", true]);
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
|
||||
Task.async(function* () {
|
||||
yield waitForSourceShown(gPanel, CODE_URL);
|
||||
yield startTracing(gPanel);
|
||||
|
||||
clickButton();
|
||||
|
||||
yield waitForClientEvents(aPanel, "traces");
|
||||
|
||||
testHitCounts();
|
||||
|
||||
yield stopTracing(gPanel);
|
||||
yield popPrefs();
|
||||
yield closeDebuggerAndFinish(gPanel);
|
||||
})();
|
||||
});
|
||||
})().catch(e => {
|
||||
ok(false, "Got an error: " + e.message + "\n" + e.stack);
|
||||
});
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
function testHitCounts() {
|
||||
let marker = gEditor.getMarker(0, 'hit-counts');
|
||||
|
||||
is(marker.innerHTML, "1\u00D7|1\u00D7",
|
||||
"Both functions should be hit only once.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
});
|
@ -1,66 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* When tracing is stopped all hit counters should be cleared.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_same-line-functions.html";
|
||||
const CODE_URL = "code_same-line-functions.js";
|
||||
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gEditor;
|
||||
|
||||
function test() {
|
||||
Task.async(function* () {
|
||||
yield pushPrefs(["devtools.debugger.tracer", true]);
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
|
||||
Task.async(function* () {
|
||||
yield waitForSourceShown(gPanel, CODE_URL);
|
||||
yield startTracing(gPanel);
|
||||
|
||||
clickButton();
|
||||
|
||||
yield waitForClientEvents(aPanel, "traces");
|
||||
|
||||
testHitCountsBeforeStopping();
|
||||
|
||||
yield stopTracing(gPanel);
|
||||
|
||||
testHitCountsAfterStopping();
|
||||
|
||||
yield popPrefs();
|
||||
yield closeDebuggerAndFinish(gPanel);
|
||||
})();
|
||||
});
|
||||
})().catch(e => {
|
||||
ok(false, "Got an error: " + e.message + "\n" + e.stack);
|
||||
});
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
function testHitCountsBeforeStopping() {
|
||||
let marker = gEditor.getMarker(0, 'hit-counts');
|
||||
ok(marker, "A counter should exists.");
|
||||
}
|
||||
|
||||
function testHitCountsAfterStopping() {
|
||||
let marker = gEditor.getMarker(0, 'hit-counts');
|
||||
is(marker, undefined, "A counter should be cleared.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
});
|
@ -1,105 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that we get the expected frame enter/exit logs in the tracer view.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
|
||||
|
||||
let gTab, gPanel, gDebugger;
|
||||
|
||||
function test() {
|
||||
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
waitForSourceShown(gPanel, "code_tracing-01.js")
|
||||
.then(() => startTracing(gPanel))
|
||||
.then(clickButton)
|
||||
.then(() => waitForClientEvents(aPanel, "traces"))
|
||||
.then(testTraceLogs)
|
||||
.then(() => stopTracing(gPanel))
|
||||
.then(() => {
|
||||
const deferred = promise.defer();
|
||||
SpecialPowers.popPrefEnv(deferred.resolve);
|
||||
return deferred.promise;
|
||||
})
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
function testTraceLogs() {
|
||||
const onclickLogs = filterTraces(gPanel,
|
||||
t => t.querySelector(".trace-name[value=onclick]"));
|
||||
is(onclickLogs.length, 2, "Should have two logs from 'onclick'");
|
||||
ok(onclickLogs[0].querySelector(".trace-call"),
|
||||
"The first 'onclick' log should be a call.");
|
||||
ok(onclickLogs[1].querySelector(".trace-return"),
|
||||
"The second 'onclick' log should be a return.");
|
||||
for (let t of onclickLogs) {
|
||||
ok(t.querySelector(".trace-item").getAttribute("tooltiptext")
|
||||
.includes("doc_tracing-01.html"));
|
||||
}
|
||||
|
||||
const nonOnclickLogs = filterTraces(gPanel,
|
||||
t => !t.querySelector(".trace-name[value=onclick]"));
|
||||
for (let t of nonOnclickLogs) {
|
||||
ok(t.querySelector(".trace-item").getAttribute("tooltiptext")
|
||||
.includes("code_tracing-01.js"));
|
||||
}
|
||||
|
||||
const mainLogs = filterTraces(gPanel,
|
||||
t => t.querySelector(".trace-name[value=main]"));
|
||||
is(mainLogs.length, 2, "Should have an enter and an exit for 'main'");
|
||||
ok(mainLogs[0].querySelector(".trace-call"),
|
||||
"The first 'main' log should be a call.");
|
||||
ok(mainLogs[1].querySelector(".trace-return"),
|
||||
"The second 'main' log should be a return.");
|
||||
|
||||
const factorialLogs = filterTraces(gPanel,
|
||||
t => t.querySelector(".trace-name[value=factorial]"));
|
||||
is(factorialLogs.length, 10, "Should have 5 enter, and 5 exit frames for 'factorial'");
|
||||
ok(factorialLogs.slice(0, 5).every(t => t.querySelector(".trace-call")),
|
||||
"The first five 'factorial' logs should be calls.");
|
||||
ok(factorialLogs.slice(5).every(t => t.querySelector(".trace-return")),
|
||||
"The second five 'factorial' logs should be returns.")
|
||||
|
||||
// Test that the depth affects padding so that calls are indented properly.
|
||||
let lastDepth = -Infinity;
|
||||
for (let t of factorialLogs.slice(0, 5)) {
|
||||
let depth = parseInt(t.querySelector(".trace-item").style.MozPaddingStart, 10);
|
||||
ok(depth > lastDepth, "The depth should be increasing");
|
||||
lastDepth = depth;
|
||||
}
|
||||
lastDepth = Infinity;
|
||||
for (let t of factorialLogs.slice(5)) {
|
||||
let depth = parseInt(t.querySelector(".trace-item").style.MozPaddingStart, 10);
|
||||
ok(depth < lastDepth, "The depth should be decreasing");
|
||||
lastDepth = depth;
|
||||
}
|
||||
|
||||
const throwerLogs = filterTraces(gPanel,
|
||||
t => t.querySelector(".trace-name[value=thrower]"));
|
||||
is(throwerLogs.length, 2, "Should have an enter and an exit for 'thrower'");
|
||||
ok(throwerLogs[0].querySelector(".trace-call"),
|
||||
"The first 'thrower' log should be a call.");
|
||||
ok(throwerLogs[1].querySelector(".trace-throw",
|
||||
"The second 'thrower' log should be a throw."));
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
@ -1,74 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that we highlight matching calls and returns on hover.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
|
||||
|
||||
let gTab, gPanel, gDebugger;
|
||||
|
||||
function test() {
|
||||
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
waitForSourceShown(gPanel, "code_tracing-01.js")
|
||||
.then(() => startTracing(gPanel))
|
||||
.then(clickButton)
|
||||
.then(() => waitForClientEvents(aPanel, "traces"))
|
||||
.then(highlightCall)
|
||||
.then(testReturnHighlighted)
|
||||
.then(unhighlightCall)
|
||||
.then(testNoneHighlighted)
|
||||
.then(() => stopTracing(gPanel))
|
||||
.then(() => {
|
||||
const deferred = promise.defer();
|
||||
SpecialPowers.popPrefEnv(deferred.resolve);
|
||||
return deferred.promise;
|
||||
})
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
function highlightCall() {
|
||||
const callTrace = filterTraces(gPanel, t => t.querySelector(".trace-name[value=main]"))[0];
|
||||
EventUtils.sendMouseEvent({ type: "mouseover" },
|
||||
callTrace,
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function testReturnHighlighted() {
|
||||
const returnTrace = filterTraces(gPanel, t => t.querySelector(".trace-name[value=main]"))[1];
|
||||
ok(Array.indexOf(returnTrace.querySelector(".trace-item").classList, "selected-matching") >= 0,
|
||||
"The corresponding return log should be highlighted.");
|
||||
}
|
||||
|
||||
function unhighlightCall() {
|
||||
const callTrace = filterTraces(gPanel, t => t.querySelector(".trace-name[value=main]"))[0];
|
||||
EventUtils.sendMouseEvent({ type: "mouseout" },
|
||||
callTrace,
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function testNoneHighlighted() {
|
||||
const highlightedTraces = filterTraces(gPanel, t => t.querySelector(".selected-matching"));
|
||||
is(highlightedTraces.length, 0, "Shouldn't have any highlighted traces");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
@ -1,70 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
SimpleTest.requestCompleteLog();
|
||||
|
||||
/**
|
||||
* Test that we can jump to function definitions by clicking on logs.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
|
||||
|
||||
let gTab, gPanel, gDebugger, gSources;
|
||||
|
||||
function test() {
|
||||
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
waitForSourceShown(gPanel, "code_tracing-01.js")
|
||||
.then(() => startTracing(gPanel))
|
||||
.then(() => clickButton())
|
||||
.then(() => waitForClientEvents(aPanel, "traces"))
|
||||
.then(() => {
|
||||
// Switch away from the JS file so we can make sure that clicking on a
|
||||
// log will switch us back to the correct JS file.
|
||||
gSources.selectedValue = getSourceActor(gSources, TAB_URL);
|
||||
return ensureSourceIs(aPanel, getSourceActor(gSources, TAB_URL), true);
|
||||
})
|
||||
.then(() => {
|
||||
const finished = waitForSourceShown(gPanel, "code_tracing-01.js");
|
||||
clickTraceLog();
|
||||
return finished;
|
||||
})
|
||||
.then(testCorrectLine)
|
||||
.then(() => stopTracing(gPanel))
|
||||
.then(() => {
|
||||
const deferred = promise.defer();
|
||||
SpecialPowers.popPrefEnv(deferred.resolve);
|
||||
return deferred.promise;
|
||||
})
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
function clickTraceLog() {
|
||||
filterTraces(gPanel, t => t.querySelector(".trace-name[value=main]"))[0].click();
|
||||
}
|
||||
|
||||
function testCorrectLine() {
|
||||
is(gDebugger.DebuggerView.editor.getCursor().line, 18,
|
||||
"The editor should have the function definition site's line selected.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gSources = null;
|
||||
});
|
@ -1,80 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that when we click on logs, we get the parameters/return value in the variables view.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
|
||||
|
||||
let gTab, gPanel, gDebugger;
|
||||
|
||||
function test() {
|
||||
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
waitForSourceShown(gPanel, "code_tracing-01.js")
|
||||
.then(() => startTracing(gPanel))
|
||||
.then(clickButton)
|
||||
.then(() => waitForClientEvents(aPanel, "traces"))
|
||||
.then(clickTraceCall)
|
||||
.then(testParams)
|
||||
.then(clickTraceReturn)
|
||||
.then(testReturn)
|
||||
.then(() => stopTracing(gPanel))
|
||||
.then(() => {
|
||||
const deferred = promise.defer();
|
||||
SpecialPowers.popPrefEnv(deferred.resolve);
|
||||
return deferred.promise;
|
||||
})
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
DevToolsUtils.reportException("browser_dbg_tracing-04.js", aError);
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
function clickTraceCall() {
|
||||
filterTraces(gPanel, t => t.querySelector(".trace-name[value=factorial]"))[0]
|
||||
.click();
|
||||
}
|
||||
|
||||
function testParams() {
|
||||
const name = gDebugger.document.querySelector(".variables-view-variable .name");
|
||||
ok(name, "Should have a variable name");
|
||||
is(name.getAttribute("value"), "n", "The variable name should be n");
|
||||
|
||||
const value = gDebugger.document.querySelector(".variables-view-variable .value.token-number");
|
||||
ok(value, "Should have a variable value");
|
||||
is(value.getAttribute("value"), "5", "The variable value should be 5");
|
||||
}
|
||||
|
||||
function clickTraceReturn() {
|
||||
filterTraces(gPanel, t => t.querySelector(".trace-name[value=factorial]"))
|
||||
.pop().click();
|
||||
}
|
||||
|
||||
function testReturn() {
|
||||
const name = gDebugger.document.querySelector(".variables-view-variable .name");
|
||||
ok(name, "Should have a variable name");
|
||||
is(name.getAttribute("value"), "<return>", "The variable name should be <return>");
|
||||
|
||||
const value = gDebugger.document.querySelector(".variables-view-variable .value.token-number");
|
||||
ok(value, "Should have a variable value");
|
||||
is(value.getAttribute("value"), "120", "The variable value should be 120");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
@ -1,81 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that text describing the tracing state is correctly displayed.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
|
||||
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gTracer, gL10N;
|
||||
|
||||
function test() {
|
||||
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gTracer = gDebugger.DebuggerView.Tracer;
|
||||
gL10N = gDebugger.L10N;
|
||||
|
||||
waitForSourceShown(gPanel, "code_tracing-01.js")
|
||||
.then(testTracingNotStartedText)
|
||||
.then(() => gTracer._onStartTracing())
|
||||
.then(testFunctionCallsUnavailableText)
|
||||
.then(clickButton)
|
||||
.then(() => waitForClientEvents(aPanel, "traces"))
|
||||
.then(testNoEmptyText)
|
||||
.then(() => gTracer._onClear())
|
||||
.then(testFunctionCallsUnavailableText)
|
||||
.then(() => gTracer._onStopTracing())
|
||||
.then(testTracingNotStartedText)
|
||||
.then(() => gTracer._onClear())
|
||||
.then(testTracingNotStartedText)
|
||||
.then(() => {
|
||||
const deferred = promise.defer();
|
||||
SpecialPowers.popPrefEnv(deferred.resolve);
|
||||
return deferred.promise;
|
||||
})
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
DevToolsUtils.reportException("browser_dbg_tracing-05.js", aError);
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testTracingNotStartedText() {
|
||||
let label = gDebugger.document.querySelector("#tracer-tabpanel .fast-list-widget-empty-text");
|
||||
ok(label,
|
||||
"A label is displayed in the tracer tabpanel.");
|
||||
is(label.getAttribute("value"), gL10N.getStr("tracingNotStartedText"),
|
||||
"The correct {{tracingNotStartedText}} is displayed in the tracer tabpanel.");
|
||||
}
|
||||
|
||||
function testFunctionCallsUnavailableText() {
|
||||
let label = gDebugger.document.querySelector("#tracer-tabpanel .fast-list-widget-empty-text");
|
||||
ok(label,
|
||||
"A label is displayed in the tracer tabpanel.");
|
||||
is(label.getAttribute("value"), gL10N.getStr("noFunctionCallsText"),
|
||||
"The correct {{noFunctionCallsText}} is displayed in the tracer tabpanel.");
|
||||
}
|
||||
|
||||
function testNoEmptyText() {
|
||||
let label = gDebugger.document.querySelector("#tracer-tabpanel .fast-list-widget-empty-text");
|
||||
ok(!label,
|
||||
"No label should be displayed in the tracer tabpanel.");
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gTracer = null;
|
||||
gL10N = null;
|
||||
});
|
@ -1,37 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that the tracer doesn't connect to the backend when tracing is disabled.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
|
||||
const TRACER_PREF = "devtools.debugger.tracer";
|
||||
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gOriginalPref = Services.prefs.getBoolPref(TRACER_PREF);
|
||||
Services.prefs.setBoolPref(TRACER_PREF, false);
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
waitForSourceShown(gPanel, "code_tracing-01.js")
|
||||
.then(() => {
|
||||
ok(!gDebugger.DebuggerController.traceClient, "Should not have a trace client");
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
})
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
Services.prefs.setBoolPref(TRACER_PREF, gOriginalPref);
|
||||
});
|
@ -1,83 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Execute code both before and after blackboxing and test that we get
|
||||
* appropriately styled traces.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
|
||||
|
||||
let gTab, gPanel;
|
||||
|
||||
function test() {
|
||||
Task.async(function*() {
|
||||
yield pushPref();
|
||||
|
||||
[gTab,, gPanel] = yield initDebugger(TAB_URL);
|
||||
|
||||
yield startTracing(gPanel);
|
||||
yield clickButton();
|
||||
yield waitForClientEvents(gPanel, "traces");
|
||||
|
||||
/**
|
||||
* Test that there are some traces which are not blackboxed.
|
||||
*/
|
||||
const firstBbButton = getBlackBoxButton(gPanel);
|
||||
ok(!firstBbButton.checked, "Should not be black boxed by default");
|
||||
|
||||
const blackBoxedTraces =
|
||||
gPanel.panelWin.document.querySelectorAll(".trace-item.black-boxed");
|
||||
ok(blackBoxedTraces.length === 0, "There should no blackboxed traces.");
|
||||
|
||||
const notBlackBoxedTraces =
|
||||
gPanel.panelWin.document.querySelectorAll(".trace-item:not(.black-boxed)");
|
||||
ok(notBlackBoxedTraces.length > 0,
|
||||
"There should be some traces which are not blackboxed.");
|
||||
|
||||
yield toggleBlackBoxing(gPanel);
|
||||
yield clickButton();
|
||||
yield waitForClientEvents(gPanel, "traces");
|
||||
|
||||
/**
|
||||
* Test that there are some traces which are blackboxed.
|
||||
*/
|
||||
const secondBbButton = getBlackBoxButton(gPanel);
|
||||
ok(secondBbButton.checked, "The checkbox should no longer be checked.");
|
||||
const traces =
|
||||
gPanel.panelWin.document.querySelectorAll(".trace-item.black-boxed");
|
||||
ok(traces.length > 0, "There should be some blackboxed traces.");
|
||||
|
||||
yield stopTracing(gPanel);
|
||||
yield popPref();
|
||||
yield closeDebuggerAndFinish(gPanel);
|
||||
|
||||
finish();
|
||||
})().catch(e => {
|
||||
ok(false, "Got an error: " + e.message + "\n" + e.stack);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
function pushPref() {
|
||||
let deferred = promise.defer();
|
||||
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]},
|
||||
deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function popPref() {
|
||||
let deferred = promise.defer();
|
||||
SpecialPowers.popPrefEnv(deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
});
|
||||
|
@ -1,59 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that tracing about:config doesn't produce errors.
|
||||
*/
|
||||
|
||||
const TAB_URL = "about:config";
|
||||
|
||||
let gPanel, gDoneChecks;
|
||||
|
||||
function test() {
|
||||
gDoneChecks = promise.defer();
|
||||
const tracerPref = promise.defer();
|
||||
const configPref = promise.defer();
|
||||
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, tracerPref.resolve);
|
||||
SpecialPowers.pushPrefEnv({'set': [["general.warnOnAboutConfig", false]]}, configPref.resolve);
|
||||
promise.all([tracerPref.promise, configPref.promise]).then(() => {
|
||||
initDebugger(TAB_URL).then(([,, aPanel]) => {
|
||||
gPanel = aPanel;
|
||||
gPanel.panelWin.gClient.addOneTimeListener("traces", testTraceLogs);
|
||||
}).then(() => startTracing(gPanel))
|
||||
.then(generateTrace)
|
||||
.then(() => waitForClientEvents(gPanel, "traces"))
|
||||
.then(() => gDoneChecks.promise)
|
||||
.then(() => stopTracing(gPanel))
|
||||
.then(resetPreferences)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testTraceLogs(name, packet) {
|
||||
info("Traces: " + packet.traces.length);
|
||||
ok(packet.traces.length > 0, "Got some traces.");
|
||||
ok(packet.traces.every(t => t.type != "enteredFrame" || !!t.location),
|
||||
"All enteredFrame traces contain location.");
|
||||
gDoneChecks.resolve();
|
||||
}
|
||||
|
||||
function generateTrace(name, packet) {
|
||||
// Interact with the page to cause JS execution.
|
||||
let search = content.document.getElementById("textbox");
|
||||
info("Interacting with the page.");
|
||||
search.value = "devtools";
|
||||
}
|
||||
|
||||
function resetPreferences() {
|
||||
const deferred = promise.defer();
|
||||
SpecialPowers.popPrefEnv(() => SpecialPowers.popPrefEnv(deferred.resolve));
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gPanel = null;
|
||||
gDoneChecks = null;
|
||||
});
|
@ -1,29 +0,0 @@
|
||||
function factorial(n) {
|
||||
if (n <= 1) {
|
||||
return 1;
|
||||
} else {
|
||||
return n * factorial(n - 1);
|
||||
}
|
||||
}
|
||||
|
||||
function* yielder(n) {
|
||||
while (n-- >= 0) {
|
||||
yield { value: n, squared: n * n };
|
||||
}
|
||||
}
|
||||
|
||||
function thrower() {
|
||||
throw new Error("Curse your sudden but inevitable betrayal!");
|
||||
}
|
||||
|
||||
function main() {
|
||||
factorial(5);
|
||||
|
||||
// XXX bug 923729: Can't test yielding yet.
|
||||
// for (let x of yielder(5)) {}
|
||||
|
||||
try {
|
||||
thrower();
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Debugger Tracer test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script src="code_same-line-functions.js"></script>
|
||||
<button onclick="first()">Click me!</button>
|
||||
</body>
|
||||
</html>
|
@ -1,20 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Debugger Tracer test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script src="code_tracing-01.js"></script>
|
||||
<button onclick="main()">Click me!</button>
|
||||
|
||||
<script type="text/javascript">
|
||||
// Have an inline script to make sure the HTML file is listed
|
||||
// in the sources. We want to switch between them.
|
||||
function foo() {
|
||||
return 5;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -888,39 +888,6 @@ function reopenVarPopup(...aArgs) {
|
||||
return hideVarPopup.apply(this, aArgs).then(() => openVarPopup.apply(this, aArgs));
|
||||
}
|
||||
|
||||
// Tracing helpers
|
||||
|
||||
function startTracing(aPanel) {
|
||||
const deferred = promise.defer();
|
||||
aPanel.panelWin.DebuggerController.Tracer.startTracing(aResponse => {
|
||||
if (aResponse.error) {
|
||||
deferred.reject(aResponse);
|
||||
} else {
|
||||
deferred.resolve(aResponse);
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function stopTracing(aPanel) {
|
||||
const deferred = promise.defer();
|
||||
aPanel.panelWin.DebuggerController.Tracer.stopTracing(aResponse => {
|
||||
if (aResponse.error) {
|
||||
deferred.reject(aResponse);
|
||||
} else {
|
||||
deferred.resolve(aResponse);
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function filterTraces(aPanel, f) {
|
||||
const traces = aPanel.panelWin.document
|
||||
.getElementById("tracer-traces")
|
||||
.querySelector("scrollbox")
|
||||
.children;
|
||||
return Array.filter(traces, f);
|
||||
}
|
||||
function attachAddonActorForUrl(aClient, aUrl) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
|
@ -1,416 +0,0 @@
|
||||
/* 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";
|
||||
|
||||
/**
|
||||
* Functions handling the traces UI.
|
||||
*/
|
||||
function TracerView(DebuggerController, DebuggerView) {
|
||||
this._selectedItem = null;
|
||||
this._matchingItems = null;
|
||||
this.widget = null;
|
||||
|
||||
this.Tracer = DebuggerController.Tracer;
|
||||
this.DebuggerView = DebuggerView;
|
||||
|
||||
this._highlightItem = this._highlightItem.bind(this);
|
||||
this._isNotSelectedItem = this._isNotSelectedItem.bind(this);
|
||||
|
||||
this._unhighlightMatchingItems =
|
||||
DevToolsUtils.makeInfallible(this._unhighlightMatchingItems.bind(this));
|
||||
this._onToggleTracing =
|
||||
DevToolsUtils.makeInfallible(this._onToggleTracing.bind(this));
|
||||
this._onStartTracing =
|
||||
DevToolsUtils.makeInfallible(this._onStartTracing.bind(this));
|
||||
this._onClear =
|
||||
DevToolsUtils.makeInfallible(this._onClear.bind(this));
|
||||
this._onSelect =
|
||||
DevToolsUtils.makeInfallible(this._onSelect.bind(this));
|
||||
this._onMouseOver =
|
||||
DevToolsUtils.makeInfallible(this._onMouseOver.bind(this));
|
||||
this._onSearch =
|
||||
DevToolsUtils.makeInfallible(this._onSearch.bind(this));
|
||||
}
|
||||
|
||||
TracerView.MAX_TRACES = 200;
|
||||
|
||||
TracerView.prototype = Heritage.extend(WidgetMethods, {
|
||||
/**
|
||||
* Initialization function, called when the debugger is started.
|
||||
*/
|
||||
initialize: function() {
|
||||
dumpn("Initializing the TracerView");
|
||||
|
||||
this._traceButton = document.getElementById("trace");
|
||||
this._tracerTab = document.getElementById("tracer-tab");
|
||||
|
||||
// Remove tracer related elements from the dom and tear everything down if
|
||||
// the tracer isn't enabled.
|
||||
if (!Prefs.tracerEnabled) {
|
||||
this._traceButton.remove();
|
||||
this._traceButton = null;
|
||||
this._tracerTab.remove();
|
||||
this._tracerTab = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this.widget = new FastListWidget(document.getElementById("tracer-traces"));
|
||||
this._traceButton.removeAttribute("hidden");
|
||||
this._tracerTab.removeAttribute("hidden");
|
||||
|
||||
this._search = document.getElementById("tracer-search");
|
||||
this._template = document.getElementsByClassName("trace-item-template")[0];
|
||||
this._templateItem = this._template.getElementsByClassName("trace-item")[0];
|
||||
this._templateTypeIcon = this._template.getElementsByClassName("trace-type")[0];
|
||||
this._templateNameNode = this._template.getElementsByClassName("trace-name")[0];
|
||||
|
||||
this.widget.addEventListener("select", this._onSelect, false);
|
||||
this.widget.addEventListener("mouseover", this._onMouseOver, false);
|
||||
this.widget.addEventListener("mouseout", this._unhighlightMatchingItems, false);
|
||||
this._search.addEventListener("input", this._onSearch, false);
|
||||
|
||||
this._startTooltip = L10N.getStr("startTracingTooltip");
|
||||
this._stopTooltip = L10N.getStr("stopTracingTooltip");
|
||||
this._tracingNotStartedString = L10N.getStr("tracingNotStartedText");
|
||||
this._noFunctionCallsString = L10N.getStr("noFunctionCallsText");
|
||||
|
||||
this._traceButton.setAttribute("tooltiptext", this._startTooltip);
|
||||
this.emptyText = this._tracingNotStartedString;
|
||||
|
||||
this._addCommands();
|
||||
},
|
||||
|
||||
/**
|
||||
* Destruction function, called when the debugger is closed.
|
||||
*/
|
||||
destroy: function() {
|
||||
dumpn("Destroying the TracerView");
|
||||
|
||||
if (!this.widget) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.widget.removeEventListener("select", this._onSelect, false);
|
||||
this.widget.removeEventListener("mouseover", this._onMouseOver, false);
|
||||
this.widget.removeEventListener("mouseout", this._unhighlightMatchingItems, false);
|
||||
this._search.removeEventListener("input", this._onSearch, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add commands that XUL can fire.
|
||||
*/
|
||||
_addCommands: function() {
|
||||
XULUtils.addCommands(document.getElementById('debuggerCommands'), {
|
||||
toggleTracing: () => this._onToggleTracing(),
|
||||
startTracing: () => this._onStartTracing(),
|
||||
clearTraces: () => this._onClear()
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked by the "toggleTracing" command to switch the tracer state.
|
||||
*/
|
||||
_onToggleTracing: function() {
|
||||
if (this.Tracer.tracing) {
|
||||
this._onStopTracing();
|
||||
} else {
|
||||
this._onStartTracing();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked either by the "startTracing" command or by
|
||||
* _onToggleTracing to start execution tracing in the backend.
|
||||
*
|
||||
* @return object
|
||||
* A promise resolved once the tracing has successfully started.
|
||||
*/
|
||||
_onStartTracing: function() {
|
||||
this._traceButton.setAttribute("checked", true);
|
||||
this._traceButton.setAttribute("tooltiptext", this._stopTooltip);
|
||||
|
||||
this.empty();
|
||||
this.emptyText = this._noFunctionCallsString;
|
||||
|
||||
let deferred = promise.defer();
|
||||
this.Tracer.startTracing(deferred.resolve);
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked by _onToggleTracing to stop execution tracing in the
|
||||
* backend.
|
||||
*
|
||||
* @return object
|
||||
* A promise resolved once the tracing has successfully stopped.
|
||||
*/
|
||||
_onStopTracing: function() {
|
||||
this._traceButton.removeAttribute("checked");
|
||||
this._traceButton.setAttribute("tooltiptext", this._startTooltip);
|
||||
|
||||
this.emptyText = this._tracingNotStartedString;
|
||||
|
||||
let deferred = promise.defer();
|
||||
this.Tracer.stopTracing(deferred.resolve);
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked by the "clearTraces" command to empty the traces pane.
|
||||
*/
|
||||
_onClear: function() {
|
||||
this.empty();
|
||||
},
|
||||
|
||||
/**
|
||||
* Populate the given parent scope with the variable with the provided name
|
||||
* and value.
|
||||
*
|
||||
* @param String aName
|
||||
* The name of the variable.
|
||||
* @param Object aParent
|
||||
* The parent scope.
|
||||
* @param Object aValue
|
||||
* The value of the variable.
|
||||
*/
|
||||
_populateVariable: function(aName, aParent, aValue) {
|
||||
let item = aParent.addItem(aName, { value: aValue });
|
||||
|
||||
if (aValue) {
|
||||
let wrappedValue = new this.Tracer.WrappedObject(aValue);
|
||||
this.DebuggerView.Variables.controller.populate(item, wrappedValue);
|
||||
item.expand();
|
||||
item.twisty = false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the widget's "select" event. Displays parameters, exception, or
|
||||
* return value depending on whether the selected trace is a call, throw, or
|
||||
* return respectively.
|
||||
*
|
||||
* @param Object traceItem
|
||||
* The selected trace item.
|
||||
*/
|
||||
_onSelect: function _onSelect({ detail: traceItem }) {
|
||||
if (!traceItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = traceItem.attachment.trace;
|
||||
const { location: { url, line } } = data;
|
||||
this.DebuggerView.setEditorLocation(
|
||||
this.DebuggerView.Sources.getActorForLocation({ url }),
|
||||
line,
|
||||
{ noDebug: true }
|
||||
);
|
||||
|
||||
this.DebuggerView.Variables.empty();
|
||||
const scope = this.DebuggerView.Variables.addScope();
|
||||
|
||||
if (data.type == "call") {
|
||||
const params = DevToolsUtils.zip(data.parameterNames, data.arguments);
|
||||
for (let [name, val] of params) {
|
||||
if (val === undefined) {
|
||||
scope.addItem(name, { value: "<value not available>" });
|
||||
} else {
|
||||
this._populateVariable(name, scope, val);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const varName = "<" + (data.type == "throw" ? "exception" : data.type) + ">";
|
||||
this._populateVariable(varName, scope, data.returnVal);
|
||||
}
|
||||
|
||||
scope.expand();
|
||||
this.DebuggerView.showInstrumentsPane();
|
||||
},
|
||||
|
||||
/**
|
||||
* Add the hover frame enter/exit highlighting to a given item.
|
||||
*/
|
||||
_highlightItem: function(aItem) {
|
||||
if (!aItem || !aItem.target) {
|
||||
return;
|
||||
}
|
||||
const trace = aItem.target.querySelector(".trace-item");
|
||||
trace.classList.add("selected-matching");
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove the hover frame enter/exit highlighting to a given item.
|
||||
*/
|
||||
_unhighlightItem: function(aItem) {
|
||||
if (!aItem || !aItem.target) {
|
||||
return;
|
||||
}
|
||||
const match = aItem.target.querySelector(".selected-matching");
|
||||
if (match) {
|
||||
match.classList.remove("selected-matching");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove the frame enter/exit pair highlighting we do when hovering.
|
||||
*/
|
||||
_unhighlightMatchingItems: function() {
|
||||
if (this._matchingItems) {
|
||||
this._matchingItems.forEach(this._unhighlightItem);
|
||||
this._matchingItems = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given item is not the selected item.
|
||||
*/
|
||||
_isNotSelectedItem: function(aItem) {
|
||||
return aItem !== this.selectedItem;
|
||||
},
|
||||
|
||||
/**
|
||||
* Highlight the frame enter/exit pair of items for the given item.
|
||||
*/
|
||||
_highlightMatchingItems: function(aItem) {
|
||||
const frameId = aItem.attachment.trace.frameId;
|
||||
const predicate = e => e.attachment.trace.frameId == frameId;
|
||||
|
||||
this._unhighlightMatchingItems();
|
||||
this._matchingItems = this.items.filter(predicate);
|
||||
this._matchingItems
|
||||
.filter(this._isNotSelectedItem)
|
||||
.forEach(this._highlightItem);
|
||||
},
|
||||
|
||||
/**
|
||||
* Listener for the mouseover event.
|
||||
*/
|
||||
_onMouseOver: function({ target }) {
|
||||
const traceItem = this.getItemForElement(target);
|
||||
if (traceItem) {
|
||||
this._highlightMatchingItems(traceItem);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Listener for typing in the search box.
|
||||
*/
|
||||
_onSearch: function() {
|
||||
const query = this._search.value.trim().toLowerCase();
|
||||
const predicate = name => name.toLowerCase().includes(query);
|
||||
this.filterContents(item => predicate(item.attachment.trace.name));
|
||||
},
|
||||
|
||||
/**
|
||||
* Select the traces tab in the sidebar.
|
||||
*/
|
||||
selectTab: function() {
|
||||
const tabs = this._tracerTab.parentElement;
|
||||
tabs.selectedIndex = Array.indexOf(tabs.children, this._tracerTab);
|
||||
},
|
||||
|
||||
/**
|
||||
* Commit all staged items to the widget. Overridden so that we can call
|
||||
* |FastListWidget.prototype.flush|.
|
||||
*/
|
||||
commit: function() {
|
||||
WidgetMethods.commit.call(this);
|
||||
// TODO: Accessing non-standard widget properties. Figure out what's the
|
||||
// best way to expose such things. Bug 895514.
|
||||
this.widget.flush();
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the trace record provided as an argument to the view.
|
||||
*
|
||||
* @param object aTrace
|
||||
* The trace record coming from the tracer actor.
|
||||
*/
|
||||
addTrace: function(aTrace) {
|
||||
// Create the element node for the trace item.
|
||||
let view = this._createView(aTrace);
|
||||
|
||||
// Append a source item to this container.
|
||||
this.push([view], {
|
||||
staged: true,
|
||||
attachment: {
|
||||
trace: aTrace
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Customization function for creating an item's UI.
|
||||
*
|
||||
* @return nsIDOMNode
|
||||
* The network request view.
|
||||
*/
|
||||
_createView: function(aTrace) {
|
||||
let { type, name, location, blackBoxed, depth, frameId } = aTrace;
|
||||
let { parameterNames, returnVal, arguments: args } = aTrace;
|
||||
let fragment = document.createDocumentFragment();
|
||||
|
||||
this._templateItem.classList.toggle("black-boxed", blackBoxed);
|
||||
this._templateItem.setAttribute("tooltiptext", SourceUtils.trimUrl(location.url));
|
||||
this._templateItem.style.MozPaddingStart = depth + "em";
|
||||
|
||||
const TYPES = ["call", "yield", "return", "throw"];
|
||||
for (let t of TYPES) {
|
||||
this._templateTypeIcon.classList.toggle("trace-" + t, t == type);
|
||||
}
|
||||
this._templateTypeIcon.setAttribute("value", {
|
||||
call: "\u2192",
|
||||
yield: "Y",
|
||||
return: "\u2190",
|
||||
throw: "E",
|
||||
terminated: "TERMINATED"
|
||||
}[type]);
|
||||
|
||||
this._templateNameNode.setAttribute("value", name);
|
||||
|
||||
// All extra syntax and parameter nodes added.
|
||||
const addedNodes = [];
|
||||
|
||||
if (parameterNames) {
|
||||
const syntax = (p) => {
|
||||
const el = document.createElement("label");
|
||||
el.setAttribute("value", p);
|
||||
el.classList.add("trace-syntax");
|
||||
el.classList.add("plain");
|
||||
addedNodes.push(el);
|
||||
return el;
|
||||
};
|
||||
|
||||
this._templateItem.appendChild(syntax("("));
|
||||
|
||||
for (let i = 0, n = parameterNames.length; i < n; i++) {
|
||||
let param = document.createElement("label");
|
||||
param.setAttribute("value", parameterNames[i]);
|
||||
param.classList.add("trace-param");
|
||||
param.classList.add("plain");
|
||||
addedNodes.push(param);
|
||||
this._templateItem.appendChild(param);
|
||||
|
||||
if (i + 1 !== n) {
|
||||
this._templateItem.appendChild(syntax(", "));
|
||||
}
|
||||
}
|
||||
|
||||
this._templateItem.appendChild(syntax(")"));
|
||||
}
|
||||
|
||||
// Flatten the DOM by removing one redundant box (the template container).
|
||||
for (let node of this._template.childNodes) {
|
||||
fragment.appendChild(node.cloneNode(true));
|
||||
}
|
||||
|
||||
// Remove any added nodes from the template.
|
||||
for (let node of addedNodes) {
|
||||
this._templateItem.removeChild(node);
|
||||
}
|
||||
|
||||
return fragment;
|
||||
}
|
||||
});
|
||||
|
||||
DebuggerView.Tracer = new TracerView(DebuggerController, DebuggerView);
|
@ -71,7 +71,6 @@ browser.jar:
|
||||
content/browser/devtools/debugger/workers-view.js (debugger/views/workers-view.js)
|
||||
content/browser/devtools/debugger/sources-view.js (debugger/views/sources-view.js)
|
||||
content/browser/devtools/debugger/variable-bubble-view.js (debugger/views/variable-bubble-view.js)
|
||||
content/browser/devtools/debugger/tracer-view.js (debugger/views/tracer-view.js)
|
||||
content/browser/devtools/debugger/watch-expressions-view.js (debugger/views/watch-expressions-view.js)
|
||||
content/browser/devtools/debugger/event-listeners-view.js (debugger/views/event-listeners-view.js)
|
||||
content/browser/devtools/debugger/global-search-view.js (debugger/views/global-search-view.js)
|
||||
|
Loading…
Reference in New Issue
Block a user