зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1233927 - Switching between large JS files in debugger is slow. r=jlong
Changes the way that source files are loaded in the editor. Previously, source text and mode were set on the existing editor document. Now, source files are their own CodeMirror Documents, so when it comes time to showing them in the editor, it's just a matter of swapping one document for another. Notes: + The DebuggerView now has a _setEditorDocument method for showing a source document + The Editor now has support for creating documents and replacing documents. MozReview-Commit-ID: HrkiHrsJPOB
This commit is contained in:
Родитель
17f2b6e204
Коммит
80243acca9
|
@ -82,6 +82,7 @@ var DebuggerView = {
|
|||
this._initializeVariablesView();
|
||||
|
||||
this._editorSource = {};
|
||||
this._editorDocuments = {};
|
||||
|
||||
document.title = L10N.getStr("DebuggerWindowTitle");
|
||||
|
||||
|
@ -416,14 +417,28 @@ var DebuggerView = {
|
|||
* Sets the currently displayed text contents in the source editor.
|
||||
* This resets the mode and undo stack.
|
||||
*
|
||||
* @param string documentKey
|
||||
* Key to get the correct editor document
|
||||
*
|
||||
* @param string aTextContent
|
||||
* The source text content.
|
||||
*
|
||||
* @param boolean shouldUpdateText
|
||||
Forces a text and mode reset
|
||||
*/
|
||||
_setEditorText: function(aTextContent = "") {
|
||||
this.editor.setMode(Editor.modes.text);
|
||||
this.editor.setText(aTextContent);
|
||||
_setEditorText: function(documentKey, aTextContent = "", shouldUpdateText = false) {
|
||||
const isNew = this._setEditorDocument(documentKey);
|
||||
|
||||
this.editor.clearDebugLocation();
|
||||
this.editor.clearHistory();
|
||||
this.editor.setCursor({ line: 0, ch: 0});
|
||||
this.editor.removeBreakpoints();
|
||||
|
||||
// Only set editor's text and mode if it is a new document
|
||||
if (isNew || shouldUpdateText) {
|
||||
this.editor.setMode(Editor.modes.text);
|
||||
this.editor.setText(aTextContent);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -453,6 +468,29 @@ var DebuggerView = {
|
|||
this.editor.setMode(Editor.modes.text);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the editor's displayed document.
|
||||
* If there isn't a document for the source, create one
|
||||
*
|
||||
* @param string key - key used to access the editor document cache
|
||||
*
|
||||
* @return boolean isNew - was the document just created
|
||||
*/
|
||||
_setEditorDocument: function(key) {
|
||||
let isNew;
|
||||
|
||||
if (!this._editorDocuments[key]) {
|
||||
isNew = true;
|
||||
this._editorDocuments[key] = this.editor.createDocument();
|
||||
} else {
|
||||
isNew = false;
|
||||
}
|
||||
|
||||
const doc = this._editorDocuments[key];
|
||||
this.editor.replaceDocument(doc);
|
||||
return isNew;
|
||||
},
|
||||
|
||||
renderBlackBoxed: function(source) {
|
||||
this._renderSourceText(
|
||||
source,
|
||||
|
@ -478,6 +516,7 @@ var DebuggerView = {
|
|||
_renderSourceText: function(source, textInfo, opts = {}) {
|
||||
const selectedSource = queries.getSelectedSource(this.controller.getState());
|
||||
|
||||
// Exit early if we're attempting to render an unselected source
|
||||
if (!selectedSource || selectedSource.actor !== source.actor) {
|
||||
return;
|
||||
}
|
||||
|
@ -497,12 +536,12 @@ var DebuggerView = {
|
|||
// TODO: bug 1228866, we need to update `_editorSource` here but
|
||||
// still make the editor be updated when the full text comes
|
||||
// through somehow.
|
||||
this._setEditorText(L10N.getStr("loadingText"));
|
||||
this._setEditorText('loading', L10N.getStr("loadingText"));
|
||||
return;
|
||||
}
|
||||
else if (textInfo.error) {
|
||||
let msg = L10N.getFormatStr("errorLoadingText2", textInfo.error);
|
||||
this._setEditorText(msg);
|
||||
this._setEditorText('error', msg);
|
||||
Cu.reportError(msg);
|
||||
dumpn(msg);
|
||||
|
||||
|
@ -529,14 +568,18 @@ var DebuggerView = {
|
|||
return;
|
||||
}
|
||||
|
||||
let { text, contentType } = textInfo;
|
||||
let shouldUpdateText = this._editorSource.prettyPrinted != source.isPrettyPrinted;
|
||||
this._setEditorText(source.actor, text, shouldUpdateText);
|
||||
|
||||
this._editorSource.actor = source.actor;
|
||||
this._editorSource.prettyPrinted = source.isPrettyPrinted;
|
||||
this._editorSource.blackboxed = source.isBlackBoxed;
|
||||
this._editorSource.prettyPrinted = source.isPrettyPrinted;
|
||||
|
||||
let { text, contentType } = textInfo;
|
||||
this._setEditorText(text);
|
||||
this._setEditorMode(source.url, contentType, text);
|
||||
this.updateEditorBreakpoints(source);
|
||||
|
||||
setTimeout(() => {
|
||||
window.emit(EVENTS.SOURCE_SHOWN, source);
|
||||
}, 0);
|
||||
|
@ -788,7 +831,6 @@ var DebuggerView = {
|
|||
*/
|
||||
handleTabNavigation: function() {
|
||||
dumpn("Handling tab navigation in the DebuggerView");
|
||||
|
||||
this.Filtering.clearSearch();
|
||||
this.GlobalSearch.clearView();
|
||||
this.StackFrames.empty();
|
||||
|
@ -801,6 +843,7 @@ var DebuggerView = {
|
|||
this.editor.setText("");
|
||||
this.editor.clearHistory();
|
||||
this._editorSource = {};
|
||||
this._editorDocuments = {};
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -173,9 +173,29 @@ function addBreakpoint(ctx, line, cond) {
|
|||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helps reset the debugger's breakpoint state
|
||||
* - removes the breakpoints in the editor
|
||||
* - cleares the debugger's breakpoint state
|
||||
*
|
||||
* Note, does not *actually* remove a source's breakpoints.
|
||||
* The canonical state is kept in the app state.
|
||||
*
|
||||
*/
|
||||
function removeBreakpoints(ctx) {
|
||||
let { ed, cm } = ctx;
|
||||
|
||||
let meta = dbginfo.get(ed);
|
||||
if (meta.breakpoints != null) {
|
||||
meta.breakpoints = {};
|
||||
}
|
||||
|
||||
cm.doc.iter((line) => { removeBreakpoint(ctx, line) });
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a visual breakpoint from a specified line and
|
||||
* makes Editor to emit a breakpointRemoved event.
|
||||
* makes Editor emit a breakpointRemoved event.
|
||||
*/
|
||||
function removeBreakpoint(ctx, line) {
|
||||
if (!hasBreakpoint(ctx, line)) {
|
||||
|
@ -303,7 +323,7 @@ function findPrev(ctx, query) {
|
|||
|
||||
[
|
||||
initialize, hasBreakpoint, addBreakpoint, removeBreakpoint, moveBreakpoint,
|
||||
setBreakpointCondition, removeBreakpointCondition, getBreakpoints,
|
||||
setBreakpointCondition, removeBreakpointCondition, getBreakpoints, removeBreakpoints,
|
||||
setDebugLocation, getDebugLocation, clearDebugLocation, find, findNext,
|
||||
findPrev
|
||||
].forEach(func => module.exports[func.name] = func);
|
||||
|
|
|
@ -241,6 +241,7 @@ Editor.prototype = {
|
|||
container: null,
|
||||
version: null,
|
||||
config: null,
|
||||
Doc: null,
|
||||
|
||||
/**
|
||||
* Appends the current Editor instance to the element specified by
|
||||
|
@ -302,6 +303,7 @@ Editor.prototype = {
|
|||
// context menus won't work).
|
||||
|
||||
cm = win.CodeMirror(win.document.body, this.config);
|
||||
this.Doc = win.CodeMirror.Doc;
|
||||
|
||||
// Disable APZ for source editors. It currently causes the line numbers to
|
||||
// "tear off" and swim around on top of the content. Bug 1160601 tracks
|
||||
|
@ -488,6 +490,22 @@ Editor.prototype = {
|
|||
Services.scriptloader.loadSubScript(url, win, "utf8");
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a CodeMirror Document
|
||||
* @returns CodeMirror.Doc
|
||||
*/
|
||||
createDocument: function() {
|
||||
return new this.Doc("");
|
||||
},
|
||||
|
||||
/**
|
||||
* Replaces the current document with a new source document
|
||||
*/
|
||||
replaceDocument: function(doc) {
|
||||
let cm = editors.get(this);
|
||||
cm.swapDoc(doc);
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the value of a currently used highlighting mode.
|
||||
* See Editor.modes for the list of all supported modes.
|
||||
|
|
Загрузка…
Ссылка в новой задаче