2011-03-28 Pavel Podivilov <podivilov@chromium.org>

        Reviewed by Yury Semikhatsky.

        Web Inspector: fix breakpoints positions in formatted scripts.
        https://bugs.webkit.org/show_bug.cgi?id=56931

        Add async requestMapping method to SourceFile interface as required for populating
        breakpoints sidebar pane when in "format all scripts" mode.

        * inspector/front-end/DebuggerPresentationModel.js:
        (WebInspector.DebuggerPresentationModel.prototype.continueToLine):
        (WebInspector.DebuggerPresentationModel.prototype.setBreakpoint.didRequestSourceMapping):
        (WebInspector.DebuggerPresentationModel.prototype.setBreakpoint):
        (WebInspector.DebuggerPresentationModel.prototype._breakpointAdded.didRequestSourceMapping):
        (WebInspector.DebuggerPresentationModel.prototype._breakpointAdded):
        (WebInspector.DebuggerPresentationModel.prototype.set selectedCallFrame.didRequestSourceMapping):
        (WebInspector.DebuggerPresentationModel.prototype.set selectedCallFrame):
        (WebInspector.PresentationBreakpoint): Breakpoint wrapper for UI.
        (WebInspector.PresentationBreakpoint.prototype.get sourceFileId):
        (WebInspector.PresentationBreakpoint.prototype.get lineNumber):
        (WebInspector.PresentationBreakpoint.prototype.get condition):
        (WebInspector.PresentationBreakpoint.prototype.get enabled):
        (WebInspector.PresentationBreakpoint.prototype.get url):
        (WebInspector.PresentationBreakpoint.prototype.get resolved):
        (WebInspector.PresentationBreakpoint.prototype.loadSnippet):
        * inspector/front-end/ScriptFormatter.js:
        (WebInspector.ScriptFormatter.prototype.formatContent.didFormatChunks):
        (WebInspector.ScriptFormatter.prototype.formatContent):
        * inspector/front-end/SourceFile.js:
        (WebInspector.SourceFile.prototype.requestSourceMapping):
        (WebInspector.FormattedSourceFile.prototype.requestSourceMapping):
        (WebInspector.FormattedSourceFile.prototype._didRequestContent):
        (WebInspector.SourceMapping):
        (WebInspector.SourceMapping.prototype.scriptLocationToSourceLocation):
        (WebInspector.SourceMapping.prototype.sourceLocationToScriptLocation):
        (WebInspector.FormattedSourceMapping):
        (WebInspector.FormattedSourceMapping.prototype.scriptLocationToSourceLocation):
        (WebInspector.FormattedSourceMapping.prototype.sourceLocationToScriptLocation):
        (WebInspector.FormattedSourceMapping.prototype._convertPosition):

git-svn-id: svn://svn.chromium.org/blink/trunk@82103 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 1fe3f5da
2011-03-28 Pavel Podivilov <podivilov@chromium.org>
Reviewed by Yury Semikhatsky.
Web Inspector: fix breakpoints positions in formatted scripts.
https://bugs.webkit.org/show_bug.cgi?id=56931
Add async requestMapping method to SourceFile interface as required for populating
breakpoints sidebar pane when in "format all scripts" mode.
* inspector/front-end/DebuggerPresentationModel.js:
(WebInspector.DebuggerPresentationModel.prototype.continueToLine):
(WebInspector.DebuggerPresentationModel.prototype.setBreakpoint.didRequestSourceMapping):
(WebInspector.DebuggerPresentationModel.prototype.setBreakpoint):
(WebInspector.DebuggerPresentationModel.prototype._breakpointAdded.didRequestSourceMapping):
(WebInspector.DebuggerPresentationModel.prototype._breakpointAdded):
(WebInspector.DebuggerPresentationModel.prototype.set selectedCallFrame.didRequestSourceMapping):
(WebInspector.DebuggerPresentationModel.prototype.set selectedCallFrame):
(WebInspector.PresentationBreakpoint): Breakpoint wrapper for UI.
(WebInspector.PresentationBreakpoint.prototype.get sourceFileId):
(WebInspector.PresentationBreakpoint.prototype.get lineNumber):
(WebInspector.PresentationBreakpoint.prototype.get condition):
(WebInspector.PresentationBreakpoint.prototype.get enabled):
(WebInspector.PresentationBreakpoint.prototype.get url):
(WebInspector.PresentationBreakpoint.prototype.get resolved):
(WebInspector.PresentationBreakpoint.prototype.loadSnippet):
* inspector/front-end/ScriptFormatter.js:
(WebInspector.ScriptFormatter.prototype.formatContent.didFormatChunks):
(WebInspector.ScriptFormatter.prototype.formatContent):
* inspector/front-end/SourceFile.js:
(WebInspector.SourceFile.prototype.requestSourceMapping):
(WebInspector.FormattedSourceFile.prototype.requestSourceMapping):
(WebInspector.FormattedSourceFile.prototype._didRequestContent):
(WebInspector.SourceMapping):
(WebInspector.SourceMapping.prototype.scriptLocationToSourceLocation):
(WebInspector.SourceMapping.prototype.sourceLocationToScriptLocation):
(WebInspector.FormattedSourceMapping):
(WebInspector.FormattedSourceMapping.prototype.scriptLocationToSourceLocation):
(WebInspector.FormattedSourceMapping.prototype.sourceLocationToScriptLocation):
(WebInspector.FormattedSourceMapping.prototype._convertPosition):
2011-03-28 Nancy Piedra <nancy.piedra@nokia.com>
Reviewed by Csaba Osztrogonác.
......@@ -185,9 +185,12 @@ WebInspector.DebuggerPresentationModel.prototype = {
continueToLine: function(sourceFileId, lineNumber)
{
var location = this._sourceFiles[sourceFileId].sourceLocationToScriptLocation(lineNumber, 0);
if (location)
function didRequestSourceMapping(mapping)
{
var location = mapping.sourceLocationToScriptLocation(lineNumber, 0);
WebInspector.debuggerModel.continueToLocation(location.scriptId, location.lineNumber, location.columnNumber);
}
this._sourceFiles[sourceFileId].requestSourceMapping(didRequestSourceMapping.bind(this));
},
breakpointsForSourceFileId: function(sourceFileId)
......@@ -211,14 +214,16 @@ WebInspector.DebuggerPresentationModel.prototype = {
}
}
var location = this._sourceFiles[sourceFileId].sourceLocationToScriptLocation(lineNumber, 0);
if (!location)
return;
var script = WebInspector.debuggerModel.scriptForSourceID(location.scriptId);
if (script.sourceURL)
WebInspector.debuggerModel.setBreakpoint(script.sourceURL, location.lineNumber, location.columnNumber, condition, enabled, didSetBreakpoint.bind(this));
else
WebInspector.debuggerModel.setBreakpointBySourceId(script.sourceID, location.lineNumber, location.columnNumber, condition, enabled, didSetBreakpoint.bind(this));
function didRequestSourceMapping(mapping)
{
var location = mapping.sourceLocationToScriptLocation(lineNumber, 0);
var script = WebInspector.debuggerModel.scriptForSourceID(location.scriptId);
if (script.sourceURL)
WebInspector.debuggerModel.setBreakpoint(script.sourceURL, location.lineNumber, location.columnNumber, condition, enabled, didSetBreakpoint.bind(this));
else
WebInspector.debuggerModel.setBreakpointBySourceId(script.sourceID, location.lineNumber, location.columnNumber, condition, enabled, didSetBreakpoint.bind(this));
}
this._sourceFiles[sourceFileId].requestSourceMapping(didRequestSourceMapping.bind(this));
},
setBreakpointEnabled: function(sourceFileId, lineNumber, enabled)
......@@ -259,32 +264,26 @@ WebInspector.DebuggerPresentationModel.prototype = {
if (!script)
return;
var sourceFile = this._sourceFileForScript(script);
var location = breakpoint.locations.length ? breakpoint.locations[0] : breakpoint;
var sourceLocation = sourceFile.scriptLocationToSourceLocation(location.lineNumber, location.columnNumber);
if (this.findBreakpoint(sourceFile.id, sourceLocation.lineNumber)) {
// We can't show more than one breakpoint on a single source file line.
WebInspector.debuggerModel.removeBreakpoint(breakpoint.id);
return;
}
function didRequestSourceMapping(mapping)
{
var scriptLocation = breakpoint.locations.length ? breakpoint.locations[0] : breakpoint;
var sourceLocation = mapping.scriptLocationToSourceLocation(scriptLocation.lineNumber, scriptLocation.columnNumber);
var lineNumber = sourceLocation.lineNumber;
var presentationBreakpoint = {
sourceFileId: sourceFile.id,
lineNumber: sourceLocation.lineNumber,
url: breakpoint.url,
resolved: !!breakpoint.locations.length,
condition: breakpoint.condition,
enabled: breakpoint.enabled,
_id: breakpoint.id
};
if (location.sourceID) {
var script = WebInspector.debuggerModel.scriptForSourceID(location.sourceID);
presentationBreakpoint.loadSnippet = script.sourceLine.bind(script, location.lineNumber);
}
if (this.findBreakpoint(sourceFile.id, lineNumber)) {
// We can't show more than one breakpoint on a single source file line.
WebInspector.debuggerModel.removeBreakpoint(breakpoint.id);
return;
}
this._presentationBreakpoints[breakpoint.id] = presentationBreakpoint;
sourceFile.breakpoints[sourceLocation.lineNumber] = presentationBreakpoint;
this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointAdded, presentationBreakpoint);
var presentationBreakpoint = new WebInspector.PresentationBreakpoint(breakpoint, sourceFile, lineNumber);
presentationBreakpoint._id = breakpoint.id;
this._presentationBreakpoints[breakpoint.id] = presentationBreakpoint;
sourceFile.breakpoints[lineNumber] = presentationBreakpoint;
this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointAdded, presentationBreakpoint);
}
var sourceFile = this._sourceFileForScript(script);
sourceFile.requestSourceMapping(didRequestSourceMapping.bind(this));
},
_breakpointRemoved: function(breakpointId)
......@@ -344,14 +343,16 @@ WebInspector.DebuggerPresentationModel.prototype = {
if (!callFrame)
return;
var script = WebInspector.debuggerModel.scriptForSourceID(callFrame.sourceID);
var sourceFile = this._sourceFileForScript(script);
if (sourceFile) {
sourceFile.forceLoadContent(script);
callFrame.sourceLocation = sourceFile.scriptLocationToSourceLocation(callFrame.line, callFrame.column);
function didRequestSourceMapping(mapping)
{
callFrame.sourceLocation = mapping.scriptLocationToSourceLocation(callFrame.line, callFrame.column);
callFrame.sourceLocation.sourceFileId = sourceFile.id;
this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.CallFrameSelected, callFrame);
}
this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.CallFrameSelected, callFrame);
var script = WebInspector.debuggerModel.scriptForSourceID(callFrame.sourceID);
var sourceFile = this._sourceFileForScript(script);
sourceFile.requestSourceMapping(didRequestSourceMapping.bind(this));
sourceFile.forceLoadContent(script);
},
get selectedCallFrame()
......@@ -381,3 +382,55 @@ WebInspector.DebuggerPresentationModel.prototype = {
}
WebInspector.DebuggerPresentationModel.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.PresentationBreakpoint = function(breakpoint, sourceFile, lineNumber)
{
this._breakpoint = breakpoint;
this._sourceFile = sourceFile;
this._lineNumber = lineNumber;
}
WebInspector.PresentationBreakpoint.prototype = {
get sourceFileId()
{
return this._sourceFile.id;
},
get lineNumber()
{
return this._lineNumber;
},
get condition()
{
return this._breakpoint.condition;
},
get enabled()
{
return this._breakpoint.enabled;
},
get url()
{
return this._sourceFile.url;
},
get resolved()
{
return !!this._breakpoint.locations.length
},
loadSnippet: function(callback)
{
function didRequestContent(mimeType, content)
{
var lineEndings = content.lineEndings();
var snippet = "";
if (this.lineNumber < lineEndings.length)
snippet = content.substring(lineEndings[this.lineNumber - 1], lineEndings[this.lineNumber]);
callback(snippet);
}
this._sourceFile.requestContent(didRequestContent.bind(this));
}
}
......@@ -77,10 +77,7 @@ WebInspector.ScriptFormatter.prototype = {
function didFormatChunks()
{
var result = this._buildContentFromChunks(chunks);
var sourceMapping = new WebInspector.SourceMappingForFormattedScript(text.lineEndings(), result.text.lineEndings(), result.mapping);
var originalToFormatted = sourceMapping.actualLocationToSourceLocation.bind(sourceMapping);
var formattedToOriginal = sourceMapping.sourceLocationToActualLocation.bind(sourceMapping);
callback(result.text, originalToFormatted, formattedToOriginal);
callback(result.text, result.mapping);
}
this._formatChunks(chunks, 0, didFormatChunks.bind(this));
},
......@@ -179,48 +176,3 @@ WebInspector.ScriptFormatter.prototype = {
task.callback(task.source, { original: [], formatted: [] });
}
}
WebInspector.SourceMappingForFormattedScript = function(originalLineEndings, formattedLineEndings, mapping)
{
WebInspector.SourceMapping.call(this);
this._originalLineEndings = originalLineEndings;
this._formattedLineEndings = formattedLineEndings;
this._mapping = mapping;
}
WebInspector.SourceMappingForFormattedScript.prototype = {
actualLocationToSourceLocation: function(lineNumber, columnNumber)
{
var position = WebInspector.ScriptFormatter.locationToPosition(this._originalLineEndings, lineNumber, columnNumber);
return this.originalPositionToFormattedLocation(position);
},
sourceLocationToActualLocation: function(lineNumber, columnNumber)
{
var formattedPosition = WebInspector.ScriptFormatter.locationToPosition(this._formattedLineEndings, lineNumber, columnNumber);
var position = this._convertPosition(this._mapping.formatted, this._mapping.original, formattedPosition);
return WebInspector.ScriptFormatter.positionToLocation(this._originalLineEndings, position);
},
originalPositionToFormattedLocation: function(position)
{
var formattedPosition = this._convertPosition(this._mapping.original, this._mapping.formatted, position);
var location = WebInspector.ScriptFormatter.positionToLocation(this._formattedLineEndings, formattedPosition);
location.position = formattedPosition;
return location;
},
_convertPosition: function(positions1, positions2, position)
{
var index = positions1.upperBound(position);
var range1 = positions1[index] - positions1[index - 1];
var range2 = positions2[index] - positions2[index - 1];
var position2 = positions2[index - 1];
if (range1)
position2 += Math.round((position - positions1[index - 1]) * range2 / range1);
return position2;
}
}
WebInspector.SourceMappingForFormattedScript.prototype.__proto__ = WebInspector.SourceMapping.prototype;
......@@ -62,6 +62,13 @@ WebInspector.SourceFile.prototype = {
this._requestContent();
},
requestSourceMapping: function(callback)
{
if (!this._mapping)
this._mapping = new WebInspector.SourceMapping(this._scripts);
callback(this._mapping);
},
forceLoadContent: function(script)
{
if (!this._hasPendingResource())
......@@ -93,23 +100,6 @@ WebInspector.SourceFile.prototype = {
this._requestContent();
},
scriptLocationToSourceLocation: function(lineNumber, columnNumber)
{
return { lineNumber: lineNumber, columnNumber: columnNumber };
},
sourceLocationToScriptLocation: function(lineNumber, columnNumber)
{
var closestScript = this._scripts[0];
for (var i = 1; i < this._scripts.length; ++i) {
script = this._scripts[i];
if (script.lineOffset > lineNumber || (script.lineOffset === lineNumber && script.columnOffset > columnNumber))
break;
closestScript = script;
}
return { scriptId: closestScript.sourceID, lineNumber: lineNumber, columnNumber: columnNumber };
},
_requestContent: function()
{
if (this._contentRequested)
......@@ -230,33 +220,86 @@ WebInspector.FormattedSourceFile = function(sourceFileId, script, contentChanged
}
WebInspector.FormattedSourceFile.prototype = {
scriptLocationToSourceLocation: function(lineNumber, columnNumber)
{
// FIXME: this method should force content formatting to obtain the mapping.
if (!this._originalToFormatted)
return WebInspector.SourceFile.prototype.scriptLocationToSourceLocation.call(this, lineNumber, columnNumber);
return this._originalToFormatted(lineNumber, columnNumber);
},
sourceLocationToScriptLocation: function(lineNumber, columnNumber)
requestSourceMapping: function(callback)
{
// FIXME: this method should force content formatting to obtain the mapping.
if (!this._formattedToOriginal)
return WebInspector.SourceFile.prototype.sourceLocationToScriptLocation.call(this, lineNumber, columnNumber);
var location = this._formattedToOriginal(lineNumber, columnNumber);
return WebInspector.SourceFile.prototype.sourceLocationToScriptLocation.call(this, location.lineNumber, location.columnNumber);
function didRequestContent()
{
callback(this._mapping);
}
this.requestContent(didRequestContent.bind(this));
},
_didRequestContent: function(mimeType, text)
{
function didFormatContent(text, originalToFormatted, formattedToOriginal)
function didFormatContent(formattedText, mapping)
{
this._originalToFormatted = originalToFormatted;
this._formattedToOriginal = formattedToOriginal;
WebInspector.SourceFile.prototype._didRequestContent.call(this, mimeType, text);
this._mapping = new WebInspector.FormattedSourceMapping(this._scripts, text, formattedText, mapping);
WebInspector.SourceFile.prototype._didRequestContent.call(this, mimeType, formattedText);
}
this._formatter.formatContent(text, this._scripts, didFormatContent.bind(this));
}
}
WebInspector.FormattedSourceFile.prototype.__proto__ = WebInspector.SourceFile.prototype;
WebInspector.SourceMapping = function(sortedScripts)
{
this._sortedScripts = sortedScripts;
}
WebInspector.SourceMapping.prototype = {
scriptLocationToSourceLocation: function(lineNumber, columnNumber)
{
return { lineNumber: lineNumber, columnNumber: columnNumber };
},
sourceLocationToScriptLocation: function(lineNumber, columnNumber)
{
var closestScript = this._sortedScripts[0];
for (var i = 1; i < this._sortedScripts.length; ++i) {
script = this._sortedScripts[i];
if (script.lineOffset > lineNumber || (script.lineOffset === lineNumber && script.columnOffset > columnNumber))
break;
closestScript = script;
}
return { scriptId: closestScript.sourceID, lineNumber: lineNumber, columnNumber: columnNumber };
}
}
WebInspector.FormattedSourceMapping = function(sortedScripts, originalText, formattedText, mapping)
{
WebInspector.SourceMapping.call(this, sortedScripts);
this._originalLineEndings = originalText.lineEndings();
this._formattedLineEndings = formattedText.lineEndings();
this._mapping = mapping;
}
WebInspector.FormattedSourceMapping.prototype = {
scriptLocationToSourceLocation: function(lineNumber, columnNumber)
{
var originalPosition = WebInspector.ScriptFormatter.locationToPosition(this._originalLineEndings, lineNumber, columnNumber);
var formattedPosition = this._convertPosition(this._mapping.original, this._mapping.formatted, originalPosition);
return WebInspector.ScriptFormatter.positionToLocation(this._formattedLineEndings, formattedPosition);
},
sourceLocationToScriptLocation: function(lineNumber, columnNumber)
{
var formattedPosition = WebInspector.ScriptFormatter.locationToPosition(this._formattedLineEndings, lineNumber, columnNumber);
var originalPosition = this._convertPosition(this._mapping.formatted, this._mapping.original, formattedPosition);
var originalLocation = WebInspector.ScriptFormatter.positionToLocation(this._originalLineEndings, originalPosition);
return WebInspector.SourceMapping.prototype.sourceLocationToScriptLocation.call(this, originalLocation.lineNumber, originalLocation.columnNumber);
},
_convertPosition: function(positions1, positions2, position)
{
var index = positions1.upperBound(position);
var range1 = positions1[index] - positions1[index - 1];
var range2 = positions2[index] - positions2[index - 1];
var position2 = positions2[index - 1];
if (range1)
position2 += Math.round((position - positions1[index - 1]) * range2 / range1);
return position2;
}
}
WebInspector.FormattedSourceMapping.prototype.__proto__ = WebInspector.SourceMapping.prototype;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment