зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central and fx-team
This commit is contained in:
Коммит
21ec7a4239
|
@ -213,7 +213,6 @@ let DebuggerController = {
|
|||
DebuggerView._handleTabNavigation();
|
||||
|
||||
// Discard all the old sources.
|
||||
DebuggerController.SourceScripts.clearCache();
|
||||
DebuggerController.Parser.clearCache();
|
||||
SourceUtils.clearCache();
|
||||
return;
|
||||
|
@ -821,11 +820,11 @@ StackFrames.prototype = {
|
|||
// having the whole watch expressions array throw because of a single
|
||||
// faulty expression, simply convert it to a string describing the error.
|
||||
// There's no other information necessary to be offered in such cases.
|
||||
let sanitizedExpressions = list.map(function(str) {
|
||||
let sanitizedExpressions = list.map((aString) => {
|
||||
// Reflect.parse throws when it encounters a syntax error.
|
||||
try {
|
||||
Parser.reflectionAPI.parse(str);
|
||||
return str; // Watch expression can be executed safely.
|
||||
Parser.reflectionAPI.parse(aString);
|
||||
return aString; // Watch expression can be executed safely.
|
||||
} catch (e) {
|
||||
return "\"" + e.name + ": " + e.message + "\""; // Syntax error.
|
||||
}
|
||||
|
@ -835,13 +834,13 @@ StackFrames.prototype = {
|
|||
this.syncedWatchExpressions =
|
||||
this.currentWatchExpressions =
|
||||
"[" +
|
||||
sanitizedExpressions.map(function(str)
|
||||
sanitizedExpressions.map((aString) =>
|
||||
"eval(\"" +
|
||||
"try {" +
|
||||
// Make sure all quotes are escaped in the expression's syntax,
|
||||
// and add a newline after the statement to avoid comments
|
||||
// breaking the code integrity inside the eval block.
|
||||
str.replace(/"/g, "\\$&") + "\" + " + "'\\n'" + " + \"" +
|
||||
aString.replace(/"/g, "\\$&") + "\" + " + "'\\n'" + " + \"" +
|
||||
"} catch (e) {" +
|
||||
"e.name + ': ' + e.message;" + // TODO: Bug 812765, 812764.
|
||||
"}" +
|
||||
|
@ -862,13 +861,9 @@ StackFrames.prototype = {
|
|||
* source script cache.
|
||||
*/
|
||||
function SourceScripts() {
|
||||
this._cache = new Map(); // Can't use a WeakMap because keys are strings.
|
||||
this._onNewGlobal = this._onNewGlobal.bind(this);
|
||||
this._onNewSource = this._onNewSource.bind(this);
|
||||
this._onSourcesAdded = this._onSourcesAdded.bind(this);
|
||||
this._onFetch = this._onFetch.bind(this);
|
||||
this._onTimeout = this._onTimeout.bind(this);
|
||||
this._onFinished = this._onFinished.bind(this);
|
||||
}
|
||||
|
||||
SourceScripts.prototype = {
|
||||
|
@ -944,7 +939,7 @@ SourceScripts.prototype = {
|
|||
// ..or the first entry if there's none selected yet after a while
|
||||
else {
|
||||
window.clearTimeout(this._newSourceTimeout);
|
||||
this._newSourceTimeout = window.setTimeout(function() {
|
||||
this._newSourceTimeout = window.setTimeout(() => {
|
||||
// If after a certain delay the preferred source still wasn't received,
|
||||
// just give up on waiting and display the first entry.
|
||||
if (!container.selectedValue) {
|
||||
|
@ -1009,163 +1004,102 @@ SourceScripts.prototype = {
|
|||
*
|
||||
* @param object aSource
|
||||
* The source object coming from the active thread.
|
||||
* @param function aCallback
|
||||
* Function called after the source text has been loaded.
|
||||
* @param function aTimeout
|
||||
* Function called when the source text takes too long to fetch.
|
||||
* @param function aOnTimeout [optional]
|
||||
* Function called when the source text takes a long time to fetch,
|
||||
* but not necessarily failing. Long fetch times don't cause the
|
||||
* rejection of the returned promise.
|
||||
* @param number aDelay [optional]
|
||||
* The amount of time it takes to consider a source slow to fetch.
|
||||
* If unspecified, it defaults to a predefined value.
|
||||
* @return object
|
||||
* A promise that is resolved after the source text has been fetched.
|
||||
*/
|
||||
getText: function(aSource, aCallback, aTimeout) {
|
||||
// If already loaded, return the source text immediately.
|
||||
if (aSource.loaded) {
|
||||
aCallback(aSource);
|
||||
return;
|
||||
getTextForSource: function(aSource, aOnTimeout, aDelay = FETCH_SOURCE_RESPONSE_DELAY) {
|
||||
// Fetch the source text only once.
|
||||
if (aSource._fetched) {
|
||||
return aSource._fetched;
|
||||
}
|
||||
|
||||
// If the source text takes too long to fetch, invoke a timeout to
|
||||
// avoid blocking any operations.
|
||||
if (aTimeout) {
|
||||
var fetchTimeout = window.setTimeout(() => {
|
||||
aSource._fetchingTimedOut = true;
|
||||
aTimeout(aSource);
|
||||
}, FETCH_SOURCE_RESPONSE_DELAY);
|
||||
let deferred = Promise.defer();
|
||||
aSource._fetched = deferred.promise;
|
||||
|
||||
// If the source text takes a long time to fetch, invoke a callback.
|
||||
if (aOnTimeout) {
|
||||
var fetchTimeout = window.setTimeout(() => aOnTimeout(aSource), aDelay);
|
||||
}
|
||||
|
||||
// Get the source text from the active thread.
|
||||
this.activeThread.source(aSource).source((aResponse) => {
|
||||
if (aTimeout) {
|
||||
if (aOnTimeout) {
|
||||
window.clearTimeout(fetchTimeout);
|
||||
}
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("Error loading: " + aSource.url + "\n" + aResponse.message);
|
||||
return void aCallback(aSource);
|
||||
deferred.reject([aSource, aResponse.message]);
|
||||
} else {
|
||||
deferred.resolve([aSource, aResponse.source]);
|
||||
}
|
||||
aSource.loaded = true;
|
||||
aSource.text = aResponse.source;
|
||||
aCallback(aSource);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets all the fetched sources.
|
||||
*
|
||||
* @return array
|
||||
* An array containing [url, text] entries for the fetched sources.
|
||||
*/
|
||||
getCache: function() {
|
||||
let sources = [];
|
||||
for (let source of this._cache) {
|
||||
sources.push(source);
|
||||
}
|
||||
return sources.sort(([first], [second]) => first > second);
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears all the fetched sources from cache.
|
||||
*/
|
||||
clearCache: function() {
|
||||
this._cache.clear();
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts fetching all the sources, silently.
|
||||
*
|
||||
* @param array aUrls
|
||||
* The urls for the sources to fetch.
|
||||
* @param object aCallbacks [optional]
|
||||
* An object containing the callback functions to invoke:
|
||||
* - onFetch: optional, called after each source is fetched
|
||||
* - onTimeout: optional, called when a source takes too long to fetch
|
||||
* - onFinished: called when all the sources are fetched
|
||||
* The urls for the sources to fetch. If fetching a source's text
|
||||
* takes too long, it will be discarded.
|
||||
* @return object
|
||||
* A promise that is resolved after source texts have been fetched.
|
||||
*/
|
||||
fetchSources: function(aUrls, aCallbacks = {}) {
|
||||
this._fetchQueue = new Set();
|
||||
this._fetchCallbacks = aCallbacks;
|
||||
getTextForSources: function(aUrls) {
|
||||
let deferred = Promise.defer();
|
||||
let pending = new Set(aUrls);
|
||||
let fetched = [];
|
||||
|
||||
// Add each new source which needs to be fetched in a queue.
|
||||
// Can't use Promise.all, because if one fetch operation is rejected, then
|
||||
// everything is considered rejected, thus no other subsequent source will
|
||||
// be getting fetched. We don't want that. Something like Q's allSettled
|
||||
// would work like a charm here.
|
||||
|
||||
// Try to fetch as many sources as possible.
|
||||
for (let url of aUrls) {
|
||||
if (!this._cache.has(url)) {
|
||||
this._fetchQueue.add(url);
|
||||
let sourceItem = DebuggerView.Sources.getItemByValue(url);
|
||||
let sourceClient = sourceItem.attachment.source;
|
||||
this.getTextForSource(sourceClient, onTimeout).then(onFetch, onError);
|
||||
}
|
||||
|
||||
/* Called if fetching a source takes too long. */
|
||||
function onTimeout(aSource) {
|
||||
onError([aSource]);
|
||||
}
|
||||
|
||||
/* Called if fetching a source finishes successfully. */
|
||||
function onFetch([aSource, aText]) {
|
||||
// If fetching the source has previously timed out, discard it this time.
|
||||
if (!pending.has(aSource.url)) {
|
||||
return;
|
||||
}
|
||||
pending.delete(aSource.url);
|
||||
fetched.push([aSource.url, aText]);
|
||||
maybeFinish();
|
||||
}
|
||||
|
||||
/* Called if fetching a source failed because of an error. */
|
||||
function onError([aSource, aError]) {
|
||||
pending.delete(aSource.url);
|
||||
maybeFinish();
|
||||
}
|
||||
|
||||
/* Called every time something interesting happens while fetching sources. */
|
||||
function maybeFinish() {
|
||||
if (pending.size == 0) {
|
||||
deferred.resolve(fetched.sort(([aFirst], [aSecond]) => aFirst > aSecond));
|
||||
}
|
||||
}
|
||||
|
||||
// If all the sources were already fetched, don't do anything special.
|
||||
if (this._fetchQueue.size == 0) {
|
||||
this._onFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
// Start fetching each new source.
|
||||
for (let url of this._fetchQueue) {
|
||||
let sourceItem = DebuggerView.Sources.getItemByValue(url);
|
||||
let sourceObject = sourceItem.attachment.source;
|
||||
this.getText(sourceObject, this._onFetch, this._onTimeout);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when a source has been fetched via fetchSources().
|
||||
*
|
||||
* @param object aSource
|
||||
* The source object coming from the active thread.
|
||||
*/
|
||||
_onFetch: function(aSource) {
|
||||
// Remember the source in a cache so we don't have to fetch it again.
|
||||
this._cache.set(aSource.url, aSource.text);
|
||||
|
||||
// Fetch completed before timeout, remove the source from the fetch queue.
|
||||
this._fetchQueue.delete(aSource.url);
|
||||
|
||||
// If this fetch was eventually completed at some point after a timeout,
|
||||
// don't call any subsequent event listeners.
|
||||
if (aSource._fetchingTimedOut) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Invoke the source fetch callback if provided via fetchSources();
|
||||
if (this._fetchCallbacks.onFetch) {
|
||||
this._fetchCallbacks.onFetch(aSource);
|
||||
}
|
||||
|
||||
// Check if all sources were fetched and stored in the cache.
|
||||
if (this._fetchQueue.size == 0) {
|
||||
this._onFinished();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when a source's text takes too long to fetch via fetchSources().
|
||||
*
|
||||
* @param object aSource
|
||||
* The source object coming from the active thread.
|
||||
*/
|
||||
_onTimeout: function(aSource) {
|
||||
// Remove the source from the fetch queue.
|
||||
this._fetchQueue.delete(aSource.url);
|
||||
|
||||
// Invoke the source timeout callback if provided via fetchSources();
|
||||
if (this._fetchCallbacks.onTimeout) {
|
||||
this._fetchCallbacks.onTimeout(aSource);
|
||||
}
|
||||
|
||||
// Check if the remaining sources were fetched and stored in the cache.
|
||||
if (this._fetchQueue.size == 0) {
|
||||
this._onFinished();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when all the sources have been fetched.
|
||||
*/
|
||||
_onFinished: function() {
|
||||
// Invoke the finish callback if provided via fetchSources();
|
||||
if (this._fetchCallbacks.onFinished) {
|
||||
this._fetchCallbacks.onFinished();
|
||||
}
|
||||
},
|
||||
|
||||
_cache: null,
|
||||
_fetchQueue: null,
|
||||
_fetchCallbacks: null
|
||||
return deferred.promise;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1636,16 +1636,17 @@ GlobalSearchView.prototype = Heritage.extend(WidgetMethods, {
|
|||
_startSearch: function(aQuery) {
|
||||
this._searchedToken = aQuery;
|
||||
|
||||
DebuggerController.SourceScripts.fetchSources(DebuggerView.Sources.values, {
|
||||
onFinished: this._performGlobalSearch
|
||||
});
|
||||
// Start fetching as many sources as possible, then perform the search.
|
||||
DebuggerController.SourceScripts
|
||||
.getTextForSources(DebuggerView.Sources.values)
|
||||
.then(this._performGlobalSearch);
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds string matches in all the sources stored in the controller's cache,
|
||||
* and groups them by location and line number.
|
||||
*/
|
||||
_performGlobalSearch: function() {
|
||||
_performGlobalSearch: function(aSources) {
|
||||
// Get the currently searched token from the filtering input.
|
||||
let token = this._searchedToken;
|
||||
|
||||
|
@ -1662,9 +1663,8 @@ GlobalSearchView.prototype = Heritage.extend(WidgetMethods, {
|
|||
|
||||
// Prepare the results map, containing search details for each line.
|
||||
let globalResults = new GlobalResults();
|
||||
let sourcesCache = DebuggerController.SourceScripts.getCache();
|
||||
|
||||
for (let [location, contents] of sourcesCache) {
|
||||
for (let [location, contents] of aSources) {
|
||||
// Verify that the search token is found anywhere in the source.
|
||||
if (!contents.toLowerCase().contains(lowerCaseToken)) {
|
||||
continue;
|
||||
|
@ -1684,7 +1684,7 @@ GlobalSearchView.prototype = Heritage.extend(WidgetMethods, {
|
|||
let lineNumber = i;
|
||||
let lineResults = new LineResults();
|
||||
|
||||
lowerCaseLine.split(lowerCaseToken).reduce(function(prev, curr, index, {length}) {
|
||||
lowerCaseLine.split(lowerCaseToken).reduce((prev, curr, index, { length }) => {
|
||||
let prevLength = prev.length;
|
||||
let currLength = curr.length;
|
||||
let unmatched = line.substr(prevLength, currLength);
|
||||
|
|
|
@ -292,7 +292,7 @@ OptionsView.prototype = {
|
|||
window.removeEventListener("Debugger:OptionsPopupHidden", reconfigure, false);
|
||||
|
||||
// The popup panel needs more time to hide after triggering onpopuphidden.
|
||||
window.setTimeout(function() {
|
||||
window.setTimeout(() => {
|
||||
DebuggerController.reconfigureThread(pref);
|
||||
}, POPUP_HIDDEN_DELAY);
|
||||
}
|
||||
|
@ -1446,16 +1446,17 @@ FilteredFunctionsView.prototype = Heritage.extend(ResultsPanelContainer.prototyp
|
|||
_startSearch: function(aQuery) {
|
||||
this._searchedToken = aQuery;
|
||||
|
||||
DebuggerController.SourceScripts.fetchSources(DebuggerView.Sources.values, {
|
||||
onFinished: this._performFunctionSearch
|
||||
});
|
||||
// Start fetching as many sources as possible, then perform the search.
|
||||
DebuggerController.SourceScripts
|
||||
.getTextForSources(DebuggerView.Sources.values)
|
||||
.then(this._performFunctionSearch);
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds function matches in all the sources stored in the cache, and groups
|
||||
* them by location and line number.
|
||||
*/
|
||||
_performFunctionSearch: function() {
|
||||
_performFunctionSearch: function(aSources) {
|
||||
// Get the currently searched token from the filtering input.
|
||||
// Continue parsing even if the searched token is an empty string, to
|
||||
// cache the syntax tree nodes generated by the reflection API.
|
||||
|
@ -1463,19 +1464,18 @@ FilteredFunctionsView.prototype = Heritage.extend(ResultsPanelContainer.prototyp
|
|||
|
||||
// Make sure the currently displayed source is parsed first. Once the
|
||||
// maximum allowed number of resutls are found, parsing will be halted.
|
||||
let sourcesCache = DebuggerController.SourceScripts.getCache();
|
||||
let currentUrl = DebuggerView.Sources.selectedValue;
|
||||
sourcesCache.sort(function([sourceUrl]) sourceUrl == currentUrl ? -1 : 1);
|
||||
aSources.sort(([sourceUrl]) => sourceUrl == currentUrl ? -1 : 1);
|
||||
|
||||
// If not searching for a specific function, only parse the displayed source.
|
||||
if (!token) {
|
||||
sourcesCache.splice(1);
|
||||
aSources.splice(1);
|
||||
}
|
||||
|
||||
// Prepare the results array, containing search details for each source.
|
||||
let searchResults = [];
|
||||
|
||||
for (let [location, contents] of sourcesCache) {
|
||||
for (let [location, contents] of aSources) {
|
||||
let parserMethods = DebuggerController.Parser.get(location, contents);
|
||||
let sourceResults = parserMethods.getNamedFunctionDefinitions(token);
|
||||
|
||||
|
|
|
@ -208,6 +208,12 @@ let DebuggerView = {
|
|||
* The source text content.
|
||||
*/
|
||||
setEditorMode: function(aUrl, aContentType = "", aTextContent = "") {
|
||||
// Avoid setting the editor mode for very large files.
|
||||
if (aTextContent.length >= SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE) {
|
||||
this.editor.setMode(SourceEditor.MODES.TEXT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aContentType) {
|
||||
if (/javascript/.test(aContentType)) {
|
||||
this.editor.setMode(SourceEditor.MODES.JAVASCRIPT);
|
||||
|
@ -243,39 +249,23 @@ let DebuggerView = {
|
|||
}
|
||||
|
||||
dumpn("Setting the DebuggerView editor source: " + aSource.url +
|
||||
", loaded: " + aSource.loaded);
|
||||
", fetched: " + !!aSource._fetched);
|
||||
|
||||
this.editor.setMode(SourceEditor.MODES.TEXT);
|
||||
this.editor.setText(L10N.getStr("loadingText"));
|
||||
this.editor.resetUndo();
|
||||
this._editorSource = aSource;
|
||||
|
||||
// If the source is not loaded, display a placeholder text.
|
||||
if (!aSource.loaded) {
|
||||
DebuggerController.SourceScripts.getText(aSource, set.bind(this));
|
||||
}
|
||||
// If the source is already loaded, display it immediately.
|
||||
else {
|
||||
set.call(this, aSource);
|
||||
}
|
||||
|
||||
// Updates the source editor's displayed text.
|
||||
// @param object aSource
|
||||
function set(aSource) {
|
||||
DebuggerController.SourceScripts.getTextForSource(aSource).then(([, aText]) => {
|
||||
// Avoid setting an unexpected source. This may happen when fast switching
|
||||
// between sources that haven't been fetched yet.
|
||||
if (this._editorSource != aSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Avoid setting the editor mode for very large files.
|
||||
if (aSource.text.length < SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE) {
|
||||
this.setEditorMode(aSource.url, aSource.contentType, aSource.text);
|
||||
} else {
|
||||
this.editor.setMode(SourceEditor.MODES.TEXT);
|
||||
}
|
||||
this.editor.setText(aSource.text);
|
||||
this.editor.setText(aText);
|
||||
this.editor.resetUndo();
|
||||
this.setEditorMode(aSource.url, aSource.contentType, aText);
|
||||
|
||||
// Update the editor's current caret and debug locations given by the
|
||||
// currently active frame in the stack, if there's one available.
|
||||
|
@ -287,7 +277,13 @@ let DebuggerView = {
|
|||
|
||||
// Notify that we've shown a source file.
|
||||
window.dispatchEvent(document, "Debugger:SourceShown", aSource);
|
||||
}
|
||||
},
|
||||
([, aError]) => {
|
||||
// Rejected. TODO: Bug 884484.
|
||||
let msg = "Error loading: " + aSource.url + "\n" + aError;
|
||||
dumpn(msg);
|
||||
Cu.reportError(msg);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,7 +26,10 @@ function test()
|
|||
gSources.preferredSource = EXAMPLE_URL + "test-script-switching-02.js";
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
let url = aEvent.detail.url;
|
||||
let { url, loaded, text } = aEvent.detail;
|
||||
info("Shown source: " + url + ", loaded: " + loaded + ", text:\n" + text);
|
||||
info("Shown label: " + gSources.selectedLabel);
|
||||
info("All labels:" + gSources.labels);
|
||||
if (url.indexOf("-02") != -1) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
performTestWhileNotPaused();
|
||||
|
@ -35,11 +38,11 @@ function test()
|
|||
});
|
||||
|
||||
function addBreakpoints(callback) {
|
||||
gPane.addBreakpoint({url: gSources.values[0], line: 5}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.values[1], line: 6}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.values[1], line: 7}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.values[1], line: 8}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.values[1], line: 9}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[0].value, line: 5}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 6}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 7}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 8}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 9}, function(cl, err) {
|
||||
callback();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -26,7 +26,10 @@ function test()
|
|||
gSources.preferredSource = EXAMPLE_URL + "test-script-switching-02.js";
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
let url = aEvent.detail.url;
|
||||
let { url, loaded, text } = aEvent.detail;
|
||||
info("Shown source: " + url + ", loaded: " + loaded + ", text:\n" + text);
|
||||
info("Shown label: " + gSources.selectedLabel);
|
||||
info("All labels:" + gSources.labels);
|
||||
if (url.indexOf("-02") != -1) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
performTest();
|
||||
|
@ -37,15 +40,15 @@ function test()
|
|||
function performTest()
|
||||
{
|
||||
initialChecks();
|
||||
gPane.addBreakpoint({url: gSources.values[0], line: 5}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[0].value, line: 5}, function(cl, err) {
|
||||
initialChecks();
|
||||
gPane.addBreakpoint({url: gSources.values[1], line: 6}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 6}, function(cl, err) {
|
||||
initialChecks();
|
||||
gPane.addBreakpoint({url: gSources.values[1], line: 7}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 7}, function(cl, err) {
|
||||
initialChecks();
|
||||
gPane.addBreakpoint({url: gSources.values[1], line: 8}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 8}, function(cl, err) {
|
||||
initialChecks();
|
||||
gPane.addBreakpoint({url: gSources.values[1], line: 9}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 9}, function(cl, err) {
|
||||
initialChecks();
|
||||
testHighlight1();
|
||||
});
|
||||
|
@ -56,7 +59,7 @@ function test()
|
|||
}
|
||||
|
||||
function initialChecks() {
|
||||
is(gSources.selectedValue, gSources.values[1],
|
||||
is(gSources.selectedValue, gSources.orderedItems[1].value,
|
||||
"The currently selected source is incorrect (0).");
|
||||
is(gEditor.getCaretPosition().line, 0,
|
||||
"The editor caret line was incorrect (0).");
|
||||
|
@ -65,10 +68,10 @@ function test()
|
|||
}
|
||||
|
||||
function testHighlight1() {
|
||||
gSources.highlightBreakpoint(gSources.values[0], 5);
|
||||
checkHighlight(gSources.values[0], 5);
|
||||
gSources.highlightBreakpoint(gSources.orderedItems[0].value, 5);
|
||||
checkHighlight(gSources.orderedItems[0].value, 5);
|
||||
|
||||
is(gSources.selectedValue, gSources.values[1],
|
||||
is(gSources.selectedValue, gSources.orderedItems[1].value,
|
||||
"The currently selected source is incorrect (1).");
|
||||
|
||||
is(gEditor.getCaretPosition().line, 0,
|
||||
|
@ -87,10 +90,10 @@ function test()
|
|||
}
|
||||
|
||||
function testHighlight2() {
|
||||
gSources.highlightBreakpoint(gSources.values[1], 6);
|
||||
checkHighlight(gSources.values[1], 6);
|
||||
gSources.highlightBreakpoint(gSources.orderedItems[1].value, 6);
|
||||
checkHighlight(gSources.orderedItems[1].value, 6);
|
||||
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
is(gSources.selectedValue, gSources.orderedItems[0].value,
|
||||
"The currently selected source is incorrect (2).");
|
||||
|
||||
is(gEditor.getCaretPosition().line, 4,
|
||||
|
@ -109,10 +112,10 @@ function test()
|
|||
}
|
||||
|
||||
function testHighlight3() {
|
||||
gSources.highlightBreakpoint(gSources.values[1], 7);
|
||||
checkHighlight(gSources.values[1], 7);
|
||||
gSources.highlightBreakpoint(gSources.orderedItems[1].value, 7);
|
||||
checkHighlight(gSources.orderedItems[1].value, 7);
|
||||
|
||||
is(gSources.selectedValue, gSources.values[1],
|
||||
is(gSources.selectedValue, gSources.orderedItems[1].value,
|
||||
"The currently selected source is incorrect (3).");
|
||||
|
||||
is(gEditor.getCaretPosition().line, 5,
|
||||
|
@ -131,10 +134,10 @@ function test()
|
|||
}
|
||||
|
||||
function testHighlight4() {
|
||||
gSources.highlightBreakpoint(gSources.values[1], 8);
|
||||
checkHighlight(gSources.values[1], 8);
|
||||
gSources.highlightBreakpoint(gSources.orderedItems[1].value, 8);
|
||||
checkHighlight(gSources.orderedItems[1].value, 8);
|
||||
|
||||
is(gSources.selectedValue, gSources.values[1],
|
||||
is(gSources.selectedValue, gSources.orderedItems[1].value,
|
||||
"The currently selected source is incorrect (4).");
|
||||
|
||||
is(gEditor.getCaretPosition().line, 6,
|
||||
|
@ -153,10 +156,10 @@ function test()
|
|||
}
|
||||
|
||||
function testHighlight5() {
|
||||
gSources.highlightBreakpoint(gSources.values[1], 9);
|
||||
checkHighlight(gSources.values[1], 9);
|
||||
gSources.highlightBreakpoint(gSources.orderedItems[1].value, 9);
|
||||
checkHighlight(gSources.orderedItems[1].value, 9);
|
||||
|
||||
is(gSources.selectedValue, gSources.values[1],
|
||||
is(gSources.selectedValue, gSources.orderedItems[1].value,
|
||||
"The currently selected source is incorrect (5).");
|
||||
|
||||
is(gEditor.getCaretPosition().line, 7,
|
||||
|
|
|
@ -123,9 +123,6 @@ function testLocationChange()
|
|||
is(gSearchView._splitter.hidden, true,
|
||||
"The global search pane splitter shouldn't be visible after a page navigation.");
|
||||
|
||||
is(gDebugger.DebuggerController.SourceScripts.getCache().length, 0,
|
||||
"The scripts sources cache for global searching should be cleared after a page navigation.")
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -76,8 +76,6 @@ function testSourcesCache()
|
|||
ok(gSources.values.sort()[2].contains("test-function-search-03.js"),
|
||||
"The third source value appears to be correct.");
|
||||
|
||||
is(gControllerSources.getCache().length, 0,
|
||||
"The sources cache should be empty when debugger starts.");
|
||||
is(gDebugger.SourceUtils._labelsCache.size, TOTAL_SOURCES,
|
||||
"There should be " + TOTAL_SOURCES + " labels cached");
|
||||
is(gDebugger.SourceUtils._groupsCache.size, TOTAL_SOURCES,
|
||||
|
@ -97,30 +95,9 @@ function fetchSources(callback) {
|
|||
let fetches = 0;
|
||||
let timeouts = 0;
|
||||
|
||||
gControllerSources.fetchSources(gSources.values, {
|
||||
onFetch: function(aSource) {
|
||||
info("Fetched: " + aSource.url);
|
||||
fetches++;
|
||||
},
|
||||
onTimeout: function(aSource) {
|
||||
info("Timed out: " + aSource.url);
|
||||
timeouts++;
|
||||
},
|
||||
onFinished: function() {
|
||||
info("Finished...");
|
||||
|
||||
ok(fetches > 0,
|
||||
"At least one source should have been fetched.");
|
||||
is(fetches + timeouts, TOTAL_SOURCES,
|
||||
"The correct number of sources have been either fetched or timed out.");
|
||||
|
||||
let cache = gControllerSources.getCache();
|
||||
is(cache.length, fetches,
|
||||
"The sources cache should have exactly " + fetches + " sources cached.");
|
||||
|
||||
testCacheIntegrity();
|
||||
callback();
|
||||
}
|
||||
gControllerSources.getTextForSources(gSources.values).then((aSources) => {
|
||||
testCacheIntegrity(aSources);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -161,17 +138,14 @@ function testStateAfterReload() {
|
|||
"There should be " + TOTAL_SOURCES + " groups cached after reload.");
|
||||
}
|
||||
|
||||
function testCacheIntegrity() {
|
||||
let cache = gControllerSources.getCache();
|
||||
isnot(cache.length, 0,
|
||||
"The sources cache should not be empty at this point.");
|
||||
function testCacheIntegrity(aCache) {
|
||||
for (let source of aCache) {
|
||||
let [url, contents] = source;
|
||||
let index = aCache.indexOf(source);
|
||||
|
||||
for (let source of cache) {
|
||||
let index = cache.indexOf(source);
|
||||
|
||||
ok(source[0].contains("test-function-search-0" + (index + 1)),
|
||||
ok(url.contains("test-function-search-0" + (index + 1)),
|
||||
"Found a source url cached correctly (" + index + ")");
|
||||
ok(source[1].contains(
|
||||
ok(contents.contains(
|
||||
["First source!", "Second source!", "Third source!"][index]),
|
||||
"Found a source's text contents cached correctly (" + index + ")");
|
||||
|
||||
|
|
|
@ -278,6 +278,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
this.widget = new SideMenuWidget($("#requests-menu-contents"), false);
|
||||
this._summary = $("#request-menu-network-summary");
|
||||
|
||||
this.allowFocusOnRightClick = true;
|
||||
this.widget.maintainSelectionVisible = false;
|
||||
this.widget.autoscrollWithAppendedItems = true;
|
||||
|
||||
|
@ -336,7 +337,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
this._registerLastRequestEnd(unixTime);
|
||||
|
||||
// Append a network request item to this container.
|
||||
let requestItem = this.push([menuView, aId], {
|
||||
let requestItem = this.push([menuView, aId, ""], {
|
||||
attachment: {
|
||||
startedDeltaMillis: unixTime - this._firstRequestStartedMillis,
|
||||
startedMillis: unixTime,
|
||||
|
@ -367,7 +368,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
// Create the element node for the network request item.
|
||||
let menuView = this._createMenuView(selected.method, selected.url);
|
||||
|
||||
let newItem = this.push([menuView], {
|
||||
let newItem = this.push([menuView,, ""], {
|
||||
attachment: Object.create(selected, {
|
||||
isCustom: { value: true }
|
||||
})
|
||||
|
|
|
@ -43,6 +43,7 @@ MOCHITEST_BROWSER_TESTS = \
|
|||
browser_net_accessibility-02.js \
|
||||
browser_net_footer-summary.js \
|
||||
browser_net_resend.js \
|
||||
browser_net_req-resp-bodies.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -57,6 +57,6 @@ function test() {
|
|||
teardown(aMonitor).then(finish);
|
||||
});
|
||||
|
||||
aDebuggee.performRequest();
|
||||
aDebuggee.performRequests();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if request and response body logging stays on after opening the console.
|
||||
*/
|
||||
|
||||
function test() {
|
||||
initNetMonitor(JSON_LONG_URL).then(([aTab, aDebuggee, aMonitor]) => {
|
||||
info("Starting test... ");
|
||||
|
||||
let { L10N, NetMonitorView } = aMonitor.panelWin;
|
||||
let { RequestsMenu } = NetMonitorView;
|
||||
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
function verifyRequest(aOffset) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOffset),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=json-long", {
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "json",
|
||||
fullMimeType: "text/json; charset=utf-8",
|
||||
size: L10N.getFormatStr("networkMenu.sizeKB", L10N.numberWithDecimals(85975/1024, 2)),
|
||||
time: true
|
||||
});
|
||||
}
|
||||
|
||||
waitForNetworkEvents(aMonitor, 1).then(() => {
|
||||
verifyRequest(0);
|
||||
|
||||
aMonitor._toolbox.once("webconsole-selected", () => {
|
||||
aMonitor._toolbox.once("netmonitor-selected", () => {
|
||||
|
||||
waitForNetworkEvents(aMonitor, 1).then(() => {
|
||||
waitForNetworkEvents(aMonitor, 1).then(() => {
|
||||
verifyRequest(1);
|
||||
teardown(aMonitor).then(finish);
|
||||
});
|
||||
|
||||
// Perform another batch of requests.
|
||||
aDebuggee.performRequests();
|
||||
});
|
||||
|
||||
// Reload debugee.
|
||||
aDebuggee.location.reload();
|
||||
});
|
||||
|
||||
// Switch back to the netmonitor.
|
||||
aMonitor._toolbox.selectTool("netmonitor");
|
||||
});
|
||||
|
||||
// Switch to the webconsole.
|
||||
aMonitor._toolbox.selectTool("webconsole");
|
||||
});
|
||||
|
||||
// Perform first batch of requests.
|
||||
aDebuggee.performRequests();
|
||||
});
|
||||
}
|
|
@ -22,7 +22,7 @@
|
|||
xhr.send(aMessage);
|
||||
}
|
||||
|
||||
function performRequest() {
|
||||
function performRequests() {
|
||||
var rawData = "Content-Type: application/x-www-form-urlencoded\r\n\r\nfoo=bar&baz=123";
|
||||
post("sjs_simple-test-server.sjs", rawData, function() {
|
||||
// Done.
|
||||
|
|
|
@ -377,9 +377,13 @@ function Item(aOwnerView, aAttachment, aContents = []) {
|
|||
this.attachment = aAttachment;
|
||||
|
||||
let [aLabel, aValue, aDescription] = aContents;
|
||||
// Make sure the label and the value are always strings.
|
||||
this._label = aLabel + "";
|
||||
this._value = aValue + "";
|
||||
this._description = (aDescription || "") + "";
|
||||
// Make sure the description is also a string, but only if it's available.
|
||||
if (aDescription !== undefined) {
|
||||
this._description = aDescription + "";
|
||||
}
|
||||
|
||||
// Allow the insertion of prebuilt nodes, otherwise delegate the item view
|
||||
// creation to a widget.
|
||||
|
@ -499,7 +503,7 @@ Item.prototype = {
|
|||
|
||||
_label: "",
|
||||
_value: "",
|
||||
_description: "",
|
||||
_description: undefined,
|
||||
_prebuiltTarget: null,
|
||||
_target: null,
|
||||
finalize: null,
|
||||
|
@ -663,9 +667,12 @@ this.WidgetMethods = {
|
|||
if (!selectedItem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let { _label: label, _value: value, _description: desc } = selectedItem;
|
||||
this._widget.removeAttribute("notice");
|
||||
this._widget.setAttribute("label", selectedItem._label);
|
||||
this._widget.setAttribute("tooltiptext", selectedItem._value);
|
||||
this._widget.setAttribute("label", label);
|
||||
this._widget.setAttribute("tooltiptext", desc !== undefined ? desc : value);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
@ -1025,6 +1032,12 @@ this.WidgetMethods = {
|
|||
*/
|
||||
autoFocusOnInput: true,
|
||||
|
||||
/**
|
||||
* When focusing on input, allow right clicks?
|
||||
* @see WidgetMethods.autoFocusOnInput
|
||||
*/
|
||||
allowFocusOnRightClick: false,
|
||||
|
||||
/**
|
||||
* The number of elements in this container to jump when Page Up or Page Down
|
||||
* keys are pressed. If falsy, then the page size will be based on the
|
||||
|
@ -1541,12 +1554,12 @@ this.WidgetMethods = {
|
|||
},
|
||||
|
||||
/**
|
||||
* The keyPress event listener for this container.
|
||||
* The mousePress event listener for this container.
|
||||
* @param string aName
|
||||
* @param MouseEvent aEvent
|
||||
*/
|
||||
_onWidgetMousePress: function(aName, aEvent) {
|
||||
if (aEvent.button != 0) {
|
||||
if (aEvent.button != 0 && !this.allowFocusOnRightClick) {
|
||||
// Only allow left-click to trigger this event.
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -41,20 +41,12 @@ function test()
|
|||
browser.removeEventListener("load", onLoad, true);
|
||||
|
||||
openConsole(null, function(hud) {
|
||||
hud.ui.saveRequestAndResponseBodies = true;
|
||||
hud.ui.setSaveRequestAndResponseBodies(true).then(() => {
|
||||
ok(hud.ui._saveRequestAndResponseBodies,
|
||||
"The saveRequestAndResponseBodies property was successfully set.");
|
||||
|
||||
waitForSuccess({
|
||||
name: "saveRequestAndResponseBodies update",
|
||||
validatorFn: function()
|
||||
{
|
||||
return hud.ui.saveRequestAndResponseBodies;
|
||||
},
|
||||
successFn: function()
|
||||
{
|
||||
HUDService.lastFinishedRequestCallback = performTest;
|
||||
content.location = TEST_URI;
|
||||
},
|
||||
failureFn: finishTest,
|
||||
HUDService.lastFinishedRequestCallback = performTest;
|
||||
content.location = TEST_URI;
|
||||
});
|
||||
});
|
||||
}, true);
|
||||
|
|
|
@ -70,10 +70,12 @@ function onpopupshown2(aEvent)
|
|||
isnot(menuitems[1].getAttribute("checked"), "true",
|
||||
"menuitems[1] is not checked");
|
||||
|
||||
ok(!huds[1].ui.saveRequestAndResponseBodies, "bodies are not logged");
|
||||
ok(!huds[1].ui._saveRequestAndResponseBodies, "bodies are not logged");
|
||||
|
||||
// Enable body logging.
|
||||
huds[1].ui.saveRequestAndResponseBodies = true;
|
||||
huds[1].ui.setSaveRequestAndResponseBodies(true).then(() => {
|
||||
menupopups[1].hidePopup();
|
||||
});
|
||||
|
||||
menupopups[1].addEventListener("popuphidden", function _onhidden(aEvent) {
|
||||
menupopups[1].removeEventListener(aEvent.type, _onhidden, false);
|
||||
|
@ -81,29 +83,12 @@ function onpopupshown2(aEvent)
|
|||
info("menupopups[1] hidden");
|
||||
|
||||
// Reopen the context menu.
|
||||
menupopups[1].addEventListener("popupshown", onpopupshown2b, false);
|
||||
executeSoon(function() {
|
||||
menupopups[1].openPopup();
|
||||
});
|
||||
huds[1].ui.once("save-bodies-ui-toggled", () => testpopup2b(aEvent));
|
||||
menupopups[1].openPopup();
|
||||
}, false);
|
||||
|
||||
waitForSuccess({
|
||||
name: "saveRequestAndResponseBodies update",
|
||||
validatorFn: function()
|
||||
{
|
||||
return huds[1].ui.saveRequestAndResponseBodies;
|
||||
},
|
||||
successFn: function()
|
||||
{
|
||||
menupopups[1].hidePopup();
|
||||
},
|
||||
failureFn: finishTest,
|
||||
});
|
||||
}
|
||||
|
||||
function onpopupshown2b(aEvent)
|
||||
{
|
||||
menupopups[1].removeEventListener(aEvent.type, onpopupshown2b, false);
|
||||
function testpopup2b(aEvent) {
|
||||
is(menuitems[1].getAttribute("checked"), "true", "menuitems[1] is checked");
|
||||
|
||||
menupopups[1].addEventListener("popuphidden", function _onhidden(aEvent) {
|
||||
|
@ -143,7 +128,9 @@ function onpopupshown1(aEvent)
|
|||
"menuitems[0] is not checked");
|
||||
|
||||
// Enable body logging for tab 1 as well.
|
||||
huds[0].ui.saveRequestAndResponseBodies = true;
|
||||
huds[0].ui.setSaveRequestAndResponseBodies(true).then(() => {
|
||||
menupopups[0].hidePopup();
|
||||
});
|
||||
|
||||
// Close the menu, and switch back to tab 2.
|
||||
menupopups[0].addEventListener("popuphidden", function _onhidden(aEvent) {
|
||||
|
@ -154,29 +141,13 @@ function onpopupshown1(aEvent)
|
|||
gBrowser.selectedTab = tabs[runCount*2 + 1];
|
||||
waitForFocus(function() {
|
||||
// Reopen the context menu from tab 2.
|
||||
menupopups[1].addEventListener("popupshown", onpopupshown2c, false);
|
||||
huds[1].ui.once("save-bodies-ui-toggled", () => testpopup2c(aEvent));
|
||||
menupopups[1].openPopup();
|
||||
}, tabs[runCount*2 + 1].linkedBrowser.contentWindow);
|
||||
}, false);
|
||||
|
||||
waitForSuccess({
|
||||
name: "saveRequestAndResponseBodies update",
|
||||
validatorFn: function()
|
||||
{
|
||||
return huds[0].ui.saveRequestAndResponseBodies;
|
||||
},
|
||||
successFn: function()
|
||||
{
|
||||
menupopups[0].hidePopup();
|
||||
},
|
||||
failureFn: finishTest,
|
||||
});
|
||||
}
|
||||
|
||||
function onpopupshown2c(aEvent)
|
||||
{
|
||||
menupopups[1].removeEventListener(aEvent.type, onpopupshown2c, false);
|
||||
|
||||
function testpopup2c(aEvent) {
|
||||
is(menuitems[1].getAttribute("checked"), "true", "menuitems[1] is checked");
|
||||
|
||||
menupopups[1].addEventListener("popuphidden", function _onhidden(aEvent) {
|
||||
|
@ -203,7 +174,6 @@ function onpopupshown2c(aEvent)
|
|||
executeSoon(finishTest);
|
||||
}
|
||||
});
|
||||
|
||||
}, false);
|
||||
|
||||
executeSoon(function() {
|
||||
|
|
|
@ -21,21 +21,13 @@ function requestDoneCallback(aHttpRequest )
|
|||
function consoleOpened(hud)
|
||||
{
|
||||
webConsoleClient = hud.ui.webConsoleClient;
|
||||
hud.ui.saveRequestAndResponseBodies = true;
|
||||
hud.ui.setSaveRequestAndResponseBodies(true).then(() => {
|
||||
ok(hud.ui._saveRequestAndResponseBodies,
|
||||
"The saveRequestAndResponseBodies property was successfully set.");
|
||||
|
||||
waitForSuccess({
|
||||
name: "saveRequestAndResponseBodies update",
|
||||
validatorFn: function()
|
||||
{
|
||||
return hud.ui.saveRequestAndResponseBodies;
|
||||
},
|
||||
successFn: function()
|
||||
{
|
||||
HUDService.lastFinishedRequestCallback = requestDoneCallback;
|
||||
waitForSuccess(waitForResponses);
|
||||
content.location = TEST_URI;
|
||||
},
|
||||
failureFn: finishTest,
|
||||
HUDService.lastFinishedRequestCallback = requestDoneCallback;
|
||||
waitForSuccess(waitForResponses);
|
||||
content.location = TEST_URI;
|
||||
});
|
||||
|
||||
let waitForResponses = {
|
||||
|
|
|
@ -85,16 +85,11 @@ function testPageLoad()
|
|||
function testPageLoadBody()
|
||||
{
|
||||
// Turn on logging of request bodies and check again.
|
||||
hud.ui.saveRequestAndResponseBodies = true;
|
||||
hud.ui.setSaveRequestAndResponseBodies(true).then(() => {
|
||||
ok(hud.ui._saveRequestAndResponseBodies,
|
||||
"The saveRequestAndResponseBodies property was successfully set.");
|
||||
|
||||
waitForSuccess({
|
||||
name: "saveRequestAndResponseBodies update",
|
||||
validatorFn: function()
|
||||
{
|
||||
return hud.ui.saveRequestAndResponseBodies;
|
||||
},
|
||||
successFn: testPageLoadBodyAfterSettingUpdate,
|
||||
failureFn: finishTest,
|
||||
testPageLoadBodyAfterSettingUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -355,14 +355,36 @@ WebConsoleFrame.prototype = {
|
|||
|
||||
_destroyer: null,
|
||||
|
||||
// Used in tests.
|
||||
_saveRequestAndResponseBodies: false,
|
||||
|
||||
/**
|
||||
* Tells whether to save the bodies of network requests and responses.
|
||||
* Disabled by default to save memory.
|
||||
* @type boolean
|
||||
*
|
||||
* @return boolean
|
||||
* The saveRequestAndResponseBodies pref value.
|
||||
*/
|
||||
get saveRequestAndResponseBodies() this._saveRequestAndResponseBodies,
|
||||
getSaveRequestAndResponseBodies:
|
||||
function WCF_getSaveRequestAndResponseBodies() {
|
||||
let deferred = Promise.defer();
|
||||
let toGet = [
|
||||
"NetworkMonitor.saveRequestAndResponseBodies"
|
||||
];
|
||||
|
||||
// Make sure the web console client connection is established first.
|
||||
this.webConsoleClient.getPreferences(toGet, aResponse => {
|
||||
if (!aResponse.error) {
|
||||
this._saveRequestAndResponseBodies = aResponse.preferences[toGet[0]];
|
||||
deferred.resolve(this._saveRequestAndResponseBodies);
|
||||
}
|
||||
else {
|
||||
deferred.reject(aResponse.error);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Setter for saving of network request and response bodies.
|
||||
|
@ -370,17 +392,26 @@ WebConsoleFrame.prototype = {
|
|||
* @param boolean aValue
|
||||
* The new value you want to set.
|
||||
*/
|
||||
set saveRequestAndResponseBodies(aValue) {
|
||||
setSaveRequestAndResponseBodies:
|
||||
function WCF_setSaveRequestAndResponseBodies(aValue) {
|
||||
let deferred = Promise.defer();
|
||||
let newValue = !!aValue;
|
||||
let preferences = {
|
||||
let toSet = {
|
||||
"NetworkMonitor.saveRequestAndResponseBodies": newValue,
|
||||
};
|
||||
|
||||
this.webConsoleClient.setPreferences(preferences, function(aResponse) {
|
||||
// Make sure the web console client connection is established first.
|
||||
this.webConsoleClient.setPreferences(toSet, aResponse => {
|
||||
if (!aResponse.error) {
|
||||
this._saveRequestAndResponseBodies = newValue;
|
||||
deferred.resolve(aResponse);
|
||||
}
|
||||
}.bind(this));
|
||||
else {
|
||||
deferred.reject(aResponse.error);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -420,7 +451,6 @@ WebConsoleFrame.prototype = {
|
|||
this.proxy = new WebConsoleConnectionProxy(this, this.owner.target);
|
||||
|
||||
this.proxy.connect().then(() => { // on success
|
||||
this.saveRequestAndResponseBodies = this._saveRequestAndResponseBodies;
|
||||
this._initDefer.resolve(this);
|
||||
}, (aReason) => { // on failure
|
||||
let node = this.createMessageNode(CATEGORY_JS, SEVERITY_ERROR,
|
||||
|
@ -473,42 +503,48 @@ WebConsoleFrame.prototype = {
|
|||
this.inputNode.style.fontSize = fontSize + "px";
|
||||
}
|
||||
|
||||
let updateSaveBodiesPrefUI = (aElement) => {
|
||||
this.getSaveRequestAndResponseBodies().then(aValue => {
|
||||
aElement.setAttribute("checked", aValue);
|
||||
this.emit("save-bodies-ui-toggled");
|
||||
});
|
||||
}
|
||||
|
||||
let reverseSaveBodiesPref = ({ target: aElement }) => {
|
||||
this.getSaveRequestAndResponseBodies().then(aValue => {
|
||||
this.setSaveRequestAndResponseBodies(!aValue);
|
||||
aElement.setAttribute("checked", aValue);
|
||||
this.emit("save-bodies-pref-reversed");
|
||||
});
|
||||
}
|
||||
|
||||
let saveBodies = doc.getElementById("saveBodies");
|
||||
saveBodies.addEventListener("command", function() {
|
||||
this.saveRequestAndResponseBodies = !this.saveRequestAndResponseBodies;
|
||||
}.bind(this));
|
||||
saveBodies.setAttribute("checked", this.saveRequestAndResponseBodies);
|
||||
saveBodies.addEventListener("click", reverseSaveBodiesPref);
|
||||
saveBodies.disabled = !this.getFilterState("networkinfo") &&
|
||||
!this.getFilterState("network");
|
||||
|
||||
saveBodies.parentNode.addEventListener("popupshowing", function() {
|
||||
saveBodies.setAttribute("checked", this.saveRequestAndResponseBodies);
|
||||
saveBodies.disabled = !this.getFilterState("networkinfo") &&
|
||||
!this.getFilterState("network");
|
||||
}.bind(this));
|
||||
|
||||
// Remove this part when context menu entry is removed.
|
||||
let saveBodiesContextMenu = doc.getElementById("saveBodiesContextMenu");
|
||||
saveBodiesContextMenu.addEventListener("command", function() {
|
||||
this.saveRequestAndResponseBodies = !this.saveRequestAndResponseBodies;
|
||||
}.bind(this));
|
||||
saveBodiesContextMenu.setAttribute("checked",
|
||||
this.saveRequestAndResponseBodies);
|
||||
saveBodiesContextMenu.addEventListener("click", reverseSaveBodiesPref);
|
||||
saveBodiesContextMenu.disabled = !this.getFilterState("networkinfo") &&
|
||||
!this.getFilterState("network");
|
||||
|
||||
saveBodiesContextMenu.parentNode.addEventListener("popupshowing", function() {
|
||||
saveBodiesContextMenu.setAttribute("checked",
|
||||
this.saveRequestAndResponseBodies);
|
||||
saveBodies.parentNode.addEventListener("popupshowing", () => {
|
||||
updateSaveBodiesPrefUI(saveBodies);
|
||||
saveBodies.disabled = !this.getFilterState("networkinfo") &&
|
||||
!this.getFilterState("network");
|
||||
});
|
||||
|
||||
saveBodiesContextMenu.parentNode.addEventListener("popupshowing", () => {
|
||||
updateSaveBodiesPrefUI(saveBodiesContextMenu);
|
||||
saveBodiesContextMenu.disabled = !this.getFilterState("networkinfo") &&
|
||||
!this.getFilterState("network");
|
||||
}.bind(this));
|
||||
});
|
||||
|
||||
let clearButton = doc.getElementsByClassName("webconsole-clear-console-button")[0];
|
||||
clearButton.addEventListener("command", function WCF__onClearButton() {
|
||||
clearButton.addEventListener("command", () => {
|
||||
this.owner._onClearButton();
|
||||
this.jsterm.clearOutput(true);
|
||||
}.bind(this));
|
||||
});
|
||||
|
||||
this.jsterm = new JSTerm(this);
|
||||
this.jsterm.init();
|
||||
|
|
|
@ -669,6 +669,23 @@ WebConsoleActor.prototype =
|
|||
return {};
|
||||
},
|
||||
|
||||
/**
|
||||
* The "getPreferences" request handler.
|
||||
*
|
||||
* @param object aRequest
|
||||
* The request message - which preferences need to be retrieved.
|
||||
* @return object
|
||||
* The response message - a { key: value } object map.
|
||||
*/
|
||||
onGetPreferences: function WCA_onGetPreferences(aRequest)
|
||||
{
|
||||
let prefs = Object.create(null);
|
||||
for (let key of aRequest.preferences) {
|
||||
prefs[key] = !!this._prefs[key];
|
||||
}
|
||||
return { preferences: prefs };
|
||||
},
|
||||
|
||||
/**
|
||||
* The "setPreferences" request handler.
|
||||
*
|
||||
|
@ -1187,6 +1204,7 @@ WebConsoleActor.prototype.requestTypes =
|
|||
evaluateJS: WebConsoleActor.prototype.onEvaluateJS,
|
||||
autocomplete: WebConsoleActor.prototype.onAutocomplete,
|
||||
clearMessagesCache: WebConsoleActor.prototype.onClearMessagesCache,
|
||||
getPreferences: WebConsoleActor.prototype.onGetPreferences,
|
||||
setPreferences: WebConsoleActor.prototype.onSetPreferences,
|
||||
sendHTTPRequest: WebConsoleActor.prototype.onSendHTTPRequest
|
||||
};
|
||||
|
|
|
@ -147,6 +147,24 @@ WebConsoleClient.prototype = {
|
|||
this._client.request(packet);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get Web Console-related preferences on the server.
|
||||
*
|
||||
* @param object aPreferences
|
||||
* An object with the preferences you want to retrieve.
|
||||
* @param function [aOnResponse]
|
||||
* Optional function to invoke when the response is received.
|
||||
*/
|
||||
getPreferences: function WCC_getPreferences(aPreferences, aOnResponse)
|
||||
{
|
||||
let packet = {
|
||||
to: this._actor,
|
||||
type: "getPreferences",
|
||||
preferences: aPreferences,
|
||||
};
|
||||
this._client.request(packet, aOnResponse);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set Web Console-related preferences on the server.
|
||||
*
|
||||
|
|
Загрузка…
Ссылка в новой задаче