Changeset 96588 in webkit


Ignore:
Timestamp:
Oct 4, 2011 6:24:01 AM (13 years ago)
Author:
podivilov@chromium.org
Message:

Web Inspector: update call frame location when source mapping is changed.
https://bugs.webkit.org/show_bug.cgi?id=68997

Currently we use fake "debugger-paused" event hack to update execution line and call stack placards when source mapping is changed.

  • add PresentationCallFrame.createPlacard method to create "live" placards that are updated on source mapping changes.
  • remove PresentationCallFrame functionName, isInternalScript, and url getters.
  • fire execution-line-changed event when selected call frame or source mapping is changed.

Reviewed by Pavel Feldman.

  • inspector/compile-front-end.sh:
  • inspector/front-end/CallStackSidebarPane.js:

(WebInspector.CallStackSidebarPane.prototype.update):

  • inspector/front-end/CompilerSourceMapping.js:

(WebInspector.ClosureCompilerSourceMappingPayload):
(WebInspector.ClosureCompilerSourceMapping):
(WebInspector.ClosureCompilerSourceMapping.prototype._parseMappings):

  • inspector/front-end/ContentProviders.js:

(WebInspector.CompilerSourceMappingContentProvider.prototype.requestContent):
(WebInspector.CompilerSourceMappingContentProvider.prototype.searchInContent):

  • inspector/front-end/DebuggerPresentationModel.js:

(WebInspector.DebuggerPresentationModel):
(WebInspector.DebuggerPresentationModel.prototype.createPlacard.updatePlacard):
(WebInspector.DebuggerPresentationModel.prototype.createPlacard):
(WebInspector.DebuggerPresentationModel.prototype._debuggerPaused):
(WebInspector.DebuggerPresentationModel.prototype._debuggerResumed):
(WebInspector.DebuggerPresentationModel.prototype.set selectedCallFrame):
(WebInspector.DebuggerPresentationModel.prototype.get selectedCallFrame):
(WebInspector.DebuggerPresentationModel.prototype._dispatchExecutionLineChanged):
(WebInspector.DebuggerPresentationModel.prototype._debuggerReset):
(WebInspector.PresentationCallFrame):
(WebInspector.PresentationCallFrame.prototype.get rawSourceCode):
(WebInspector.PresentationCallFrame.prototype.uiLocation):

  • inspector/front-end/ScriptsPanel.js:

(WebInspector.ScriptsPanel.prototype._debuggerPaused.else.didGetUILocation):
(WebInspector.ScriptsPanel.prototype._debuggerPaused):
(WebInspector.ScriptsPanel.prototype._executionLineChanged):
(WebInspector.ScriptsPanel.prototype._callFrameSelected):

  • inspector/front-end/externs.js:

(WebInspector.displayNameForURL):

Location:
trunk/Source/WebCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r96586 r96588  
     12011-10-04  Pavel Podivilov  <podivilov@chromium.org>
     2
     3        Web Inspector: update call frame location when source mapping is changed.
     4        https://bugs.webkit.org/show_bug.cgi?id=68997
     5
     6        Currently we use fake "debugger-paused" event hack to update execution line and call stack placards when source mapping is changed.
     7        - add PresentationCallFrame.createPlacard method to create "live" placards that are updated on source mapping changes.
     8        - remove PresentationCallFrame functionName, isInternalScript, and url getters.
     9        - fire execution-line-changed event when selected call frame or source mapping is changed.
     10
     11        Reviewed by Pavel Feldman.
     12
     13        * inspector/compile-front-end.sh:
     14        * inspector/front-end/CallStackSidebarPane.js:
     15        (WebInspector.CallStackSidebarPane.prototype.update):
     16        * inspector/front-end/CompilerSourceMapping.js:
     17        (WebInspector.ClosureCompilerSourceMappingPayload):
     18        (WebInspector.ClosureCompilerSourceMapping):
     19        (WebInspector.ClosureCompilerSourceMapping.prototype._parseMappings):
     20        * inspector/front-end/ContentProviders.js:
     21        (WebInspector.CompilerSourceMappingContentProvider.prototype.requestContent):
     22        (WebInspector.CompilerSourceMappingContentProvider.prototype.searchInContent):
     23        * inspector/front-end/DebuggerPresentationModel.js:
     24        (WebInspector.DebuggerPresentationModel):
     25        (WebInspector.DebuggerPresentationModel.prototype.createPlacard.updatePlacard):
     26        (WebInspector.DebuggerPresentationModel.prototype.createPlacard):
     27        (WebInspector.DebuggerPresentationModel.prototype._debuggerPaused):
     28        (WebInspector.DebuggerPresentationModel.prototype._debuggerResumed):
     29        (WebInspector.DebuggerPresentationModel.prototype.set selectedCallFrame):
     30        (WebInspector.DebuggerPresentationModel.prototype.get selectedCallFrame):
     31        (WebInspector.DebuggerPresentationModel.prototype._dispatchExecutionLineChanged):
     32        (WebInspector.DebuggerPresentationModel.prototype._debuggerReset):
     33        (WebInspector.PresentationCallFrame):
     34        (WebInspector.PresentationCallFrame.prototype.get rawSourceCode):
     35        (WebInspector.PresentationCallFrame.prototype.uiLocation):
     36        * inspector/front-end/ScriptsPanel.js:
     37        (WebInspector.ScriptsPanel.prototype._debuggerPaused.else.didGetUILocation):
     38        (WebInspector.ScriptsPanel.prototype._debuggerPaused):
     39        (WebInspector.ScriptsPanel.prototype._executionLineChanged):
     40        (WebInspector.ScriptsPanel.prototype._callFrameSelected):
     41        * inspector/front-end/externs.js:
     42        (WebInspector.displayNameForURL):
     43
    1442011-10-04  Pavel Feldman  <pfeldman@chromium.org>
    245
  • trunk/Source/WebCore/inspector/compile-front-end.sh

    r96584 r96588  
    4545        --js Source/WebCore/inspector/front-end/Settings.js \
    4646        --js Source/WebCore/inspector/front-end/UserMetrics.js \
    47     --module jsmodule_sdk:16:jsmodule_common \
     47    --module jsmodule_sdk:18:jsmodule_common \
     48        --js Source/WebCore/inspector/front-end/CompilerSourceMapping.js \
     49        --js Source/WebCore/inspector/front-end/CompilerSourceMappingProvider.js \
    4850        --js Source/WebCore/inspector/front-end/ConsoleModel.js \
    4951        --js Source/WebCore/inspector/front-end/ContentProviders.js \
  • trunk/Source/WebCore/inspector/front-end/CallStackSidebarPane.js

    r95554 r96588  
    4949        for (var i = 0; i < callFrames.length; ++i) {
    5050            var callFrame = callFrames[i];
    51             var title = callFrame.functionName || WebInspector.UIString("(anonymous function)");
    52 
    53             var subtitle;
    54             if (!callFrame.isInternalScript)
    55                 subtitle = WebInspector.displayNameForURL(callFrame.url);
    56             else
    57                 subtitle = WebInspector.UIString("(internal script)");
    58 
    59             var placard = new WebInspector.Placard(title, subtitle);
     51            var placard = this._model.createPlacard(callFrame);
    6052            placard.callFrame = callFrame;
    6153            placard.element.addEventListener("click", this._placardSelected.bind(this, placard), false);
    62 
    63             function didGetSourceLine(placard, uiSourceCode, lineNumber)
    64             {
    65                 if (placard.subtitle)
    66                     placard.subtitle += ":" + (lineNumber + 1);
    67                 else
    68                     placard.subtitle = WebInspector.UIString("line %d", lineNumber + 1);
    69                 placard._text = WebInspector.UIString("%s() at %s", placard.title, placard.subtitle);
    70             }
    71             callFrame.sourceLine(didGetSourceLine.bind(this, placard));
    72 
    7354            this.placards.push(placard);
    7455            this.bodyElement.appendChild(placard.element);
  • trunk/Source/WebCore/inspector/front-end/CompilerSourceMapping.js

    r95524 r96588  
    5454
    5555/**
     56 * @constructor
     57 */
     58WebInspector.ClosureCompilerSourceMappingPayload = function()
     59{
     60    this.mappings = "";
     61    this.sources = [];
     62}
     63
     64/**
    5665 * Implements Source Map V3 consumer. See http://code.google.com/p/closure-compiler/wiki/SourceMaps
    5766 * for format description.
    5867 * @extends {WebInspector.CompilerSourceMapping}
    5968 * @constructor
    60  */
    61 WebInspector.ClosureCompilerSourceMapping = function(payload)
     69 * @param {WebInspector.ClosureCompilerSourceMappingPayload} mappingPayload
     70 */
     71WebInspector.ClosureCompilerSourceMapping = function(mappingPayload)
    6272{
    6373    if (!WebInspector.ClosureCompilerSourceMapping.prototype._base64Map) {
    64         base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     74        const base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    6575        WebInspector.ClosureCompilerSourceMapping.prototype._base64Map = {};
    6676        for (var i = 0; i < base64Digits.length; ++i)
     
    6878    }
    6979
    70     this._sources = payload.sources;
     80    this._sources = mappingPayload.sources;
    7181    this._mappings = [];
    7282    this._reverseMappingsBySourceURL = {};
    7383    for (var i = 0; i < this._sources.length; ++i)
    7484        this._reverseMappingsBySourceURL[this._sources[i]] = [];
    75     this._parseMappings(payload.mappings);
     85    this._parseMappings(mappingPayload);
    7686}
    7787
     
    116126    },
    117127
    118     _parseMappings: function(mappingsPayload)
    119     {
    120         var stringCharIterator = new WebInspector.ClosureCompilerSourceMapping.StringCharIterator(mappingsPayload);
     128    _parseMappings: function(mappingPayload)
     129    {
     130        var stringCharIterator = new WebInspector.ClosureCompilerSourceMapping.StringCharIterator(mappingPayload.mappings);
    121131
    122132        var lineNumber = 0;
  • trunk/Source/WebCore/inspector/front-end/ContentProviders.js

    r96585 r96588  
    178178        }
    179179        this._compilerSourceMappingProvider.loadSourceCode(this._sourceURL, didLoadSourceCode.bind(this));
     180    },
     181
     182    searchInContent: function(query, callback)
     183    {
     184        callback([]);
    180185    }
    181186}
  • trunk/Source/WebCore/inspector/front-end/DebuggerPresentationModel.js

    r96585 r96588  
    3939    this._rawSourceCode = {};
    4040    this._presentationCallFrames = [];
    41     this._selectedCallFrameIndex = 0;
    4241
    4342    this._breakpointManager = new WebInspector.BreakpointManager(WebInspector.settings.breakpoints, this._breakpointAdded.bind(this), this._breakpointRemoved.bind(this), WebInspector.debuggerModel);
     
    6463    DebuggerPaused: "debugger-paused",
    6564    DebuggerResumed: "debugger-resumed",
    66     CallFrameSelected: "call-frame-selected"
     65    CallFrameSelected: "call-frame-selected",
     66    ExecutionLineChanged: "execution-line-changed"
    6767}
    6868
     
    9292        rawSourceCode.addEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, updateAnchor, this);
    9393        return anchor;
     94    },
     95
     96    createPlacard: function(callFrame)
     97    {
     98        var title = callFrame._callFrame.functionName || WebInspector.UIString("(anonymous function)");
     99        var placard = new WebInspector.Placard(title, "");
     100
     101        var rawSourceCode = callFrame._rawSourceCode;
     102        function updatePlacard()
     103        {
     104            var uiLocation = rawSourceCode.sourceMapping.rawLocationToUILocation(callFrame._callFrame.location);
     105            placard.subtitle = WebInspector.displayNameForURL(uiLocation.uiSourceCode.url) + ":" + (uiLocation.lineNumber + 1);
     106            placard._text = WebInspector.UIString("%s() at %s", placard.title, placard.subtitle);
     107        }
     108        if (rawSourceCode.sourceMapping)
     109            updatePlacard.call(this);
     110        rawSourceCode.addEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, updatePlacard, this);
     111        return placard;
    94112    },
    95113
     
    355373        for (var i = 0; i < callFrames.length; ++i) {
    356374            var callFrame = callFrames[i];
    357             var rawSourceCode;
    358375            var script = WebInspector.debuggerModel.scriptForSourceID(callFrame.location.scriptId);
    359             if (script)
    360                 rawSourceCode = this._rawSourceCodeForScript(script);
     376            if (!script)
     377                continue;
     378            var rawSourceCode = this._rawSourceCodeForScript(script);
    361379            this._presentationCallFrames.push(new WebInspector.PresentationCallFrame(callFrame, i, this, rawSourceCode));
    362380        }
     
    364382        this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.DebuggerPaused, { callFrames: this._presentationCallFrames, details: details });
    365383
    366         this.selectedCallFrame = this._presentationCallFrames[this._selectedCallFrameIndex];
     384        this.selectedCallFrame = this._presentationCallFrames[0];
    367385    },
    368386
     
    370388    {
    371389        this._presentationCallFrames = [];
    372         this._selectedCallFrameIndex = 0;
     390        this.selectedCallFrame = null;
    373391        this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.DebuggerResumed);
    374392    },
     
    376394    set selectedCallFrame(callFrame)
    377395    {
    378         this._selectedCallFrameIndex = callFrame.index;
    379         callFrame.select();
     396        if (this._selectedCallFrame)
     397            this._selectedCallFrame.rawSourceCode.removeEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, this._dispatchExecutionLineChanged, this);
     398        this._selectedCallFrame = callFrame;
     399        if (!this._selectedCallFrame)
     400            return;
     401
     402        this._selectedCallFrame.rawSourceCode.forceUpdateSourceMapping();
    380403        this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.CallFrameSelected, callFrame);
     404
     405        if (this._selectedCallFrame.rawSourceCode.sourceMapping)
     406            this._dispatchExecutionLineChanged(null);
     407        this._selectedCallFrame.rawSourceCode.addEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, this._dispatchExecutionLineChanged, this);
    381408    },
    382409
    383410    get selectedCallFrame()
    384411    {
    385         return this._presentationCallFrames[this._selectedCallFrameIndex];
     412        return this._selectedCallFrame;
     413    },
     414
     415    _dispatchExecutionLineChanged: function(event)
     416    {
     417        var rawLocation = this._selectedCallFrame._callFrame.location;
     418        var uiLocation = this._selectedCallFrame.rawSourceCode.sourceMapping.rawLocationToUILocation(rawLocation);
     419        this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.ExecutionLineChanged, uiLocation);
    386420    },
    387421
     
    418452    _debuggerReset: function()
    419453    {
     454        for (var id in this._rawSourceCode)
     455            this._rawSourceCode[id].removeAllListeners();
    420456        this._rawSourceCode = {};
    421457        this._presentationCallFrames = [];
    422         this._selectedCallFrameIndex = 0;
     458        this._selectedCallFrame = null;
    423459        this._breakpointManager.debuggerReset();
    424460    }
     
    436472    this._model = model;
    437473    this._rawSourceCode = rawSourceCode;
    438     this._script = WebInspector.debuggerModel.scriptForSourceID(callFrame.location.scriptId);
    439474}
    440475
    441476WebInspector.PresentationCallFrame.prototype = {
    442     get functionName()
    443     {
    444         return this._callFrame.functionName;
    445     },
    446 
    447477    get type()
    448478    {
     
    450480    },
    451481
    452     get isInternalScript()
    453     {
    454         return !this._script;
    455     },
    456 
    457     get url()
    458     {
    459         if (this._rawSourceCode && this._rawSourceCode.sourceMapping)
    460             return this._rawSourceCode.sourceMapping.uiSourceCode.url;
    461     },
    462 
    463482    get scopeChain()
    464483    {
     
    476495    },
    477496
    478     select: function()
    479     {
    480         if (this._rawSourceCode)
    481             this._rawSourceCode.forceUpdateSourceMapping();
     497    get rawSourceCode()
     498    {
     499        return this._rawSourceCode;
    482500    },
    483501
     
    500518    },
    501519
    502     sourceLine: function(callback)
    503     {
    504         var rawLocation = this._callFrame.location;
    505         if (!this._rawSourceCode) {
    506             callback(undefined, rawLocation.lineNumber);
    507             return;
    508         }
    509 
    510         if (this._rawSourceCode.sourceMapping) {
    511             var uiLocation = this._rawSourceCode.sourceMapping.rawLocationToUILocation(rawLocation);
    512             callback(uiLocation.uiSourceCode, uiLocation.lineNumber);
    513             return;
    514         }
    515 
    516         function sourceMappingUpdated()
    517         {
    518             this._rawSourceCode.removeEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, sourceMappingUpdated, this);
    519             var uiLocation = this._rawSourceCode.sourceMapping.rawLocationToUILocation(rawLocation);
    520             callback(uiLocation.uiSourceCode, uiLocation.lineNumber);
    521         }
    522         this._rawSourceCode.addEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, sourceMappingUpdated, this);
     520    uiLocation: function(callback)
     521    {
     522        function sourceMappingReady()
     523        {
     524            this._rawSourceCode.removeEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, sourceMappingReady, this);
     525            callback(this._rawSourceCode.sourceMapping.rawLocationToUILocation(this._callFrame.location));
     526        }
     527        if (this._rawSourceCode.sourceMapping)
     528            sourceMappingReady.call(this);
     529        else
     530            this._rawSourceCode.addEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, sourceMappingReady, this);
    523531    }
    524532}
  • trunk/Source/WebCore/inspector/front-end/ScriptsPanel.js

    r96577 r96588  
    175175    this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.DebuggerResumed, this._debuggerResumed, this);
    176176    this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.CallFrameSelected, this._callFrameSelected, this);
     177    this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.ExecutionLineChanged, this._executionLineChanged, this);
    177178
    178179    var enableDebugger = Preferences.debuggerAlwaysEnabled || WebInspector.settings.debuggerEnabled.get();
     
    513514            this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on exception: '%s'.", details.auxData.description));
    514515        } else {
    515             function didGetSourceLocation(uiSourceCode, lineNumber)
     516            function didGetUILocation(uiLocation)
    516517            {
    517                 if (!uiSourceCode || !this._presentationModel.findBreakpoint(uiSourceCode, lineNumber))
     518                if (!this._presentationModel.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber))
    518519                    return;
    519                 this.sidebarPanes.jsBreakpoints.highlightBreakpoint(uiSourceCode, lineNumber);
     520                this.sidebarPanes.jsBreakpoints.highlightBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber);
    520521                this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a JavaScript breakpoint."));
    521522            }
    522             callFrames[0].sourceLine(didGetSourceLocation.bind(this));
     523            callFrames[0].uiLocation(didGetUILocation.bind(this));
    523524        }
    524525
     
    731732    },
    732733
     734    _executionLineChanged: function(event)
     735    {
     736        var uiLocation = event.data;
     737
     738        this._clearCurrentExecutionLine();
     739        if (!uiLocation)
     740            return;
     741
     742        if (!uiLocation.uiSourceCode._option) {
     743            // Anonymous scripts are not added to files select by default.
     744            this._addOptionToFilesSelect(uiLocation.uiSourceCode);
     745        }
     746        var sourceFrame = this._showSourceFrameAndAddToHistory(uiLocation.uiSourceCode);
     747        sourceFrame.setExecutionLine(uiLocation.lineNumber);
     748        this._executionSourceFrame = sourceFrame;
     749    },
     750
    733751    _callFrameSelected: function(event)
    734752    {
    735753        var callFrame = event.data;
    736 
    737         this._clearCurrentExecutionLine();
    738754
    739755        if (!callFrame)
     
    743759        this.sidebarPanes.watchExpressions.refreshExpressions();
    744760        this.sidebarPanes.callstack.selectedCallFrame = this._presentationModel.selectedCallFrame;
    745 
    746         function didGetSourceLocation(uiSourceCode, lineNumber)
    747         {
    748             if (!uiSourceCode)
    749                 return;
    750 
    751             if (!uiSourceCode._option) {
    752                 // Anonymous scripts are not added to files select by default.
    753                 this._addOptionToFilesSelect(uiSourceCode);
    754             }
    755             var sourceFrame = this._showSourceFrameAndAddToHistory(uiSourceCode);
    756             sourceFrame.setExecutionLine(lineNumber);
    757             this._executionSourceFrame = sourceFrame;
    758         }
    759         callFrame.sourceLine(didGetSourceLocation.bind(this));
    760761    },
    761762
  • trunk/Source/WebCore/inspector/front-end/externs.js

    r96584 r96588  
    5555 */
    5656WebInspector.formatLinkText = function(url, lineNumber) {}
     57
     58/**
     59 * @param {string} url
     60 */
     61WebInspector.displayNameForURL = function(url) {}
    5762
    5863/**
Note: See TracChangeset for help on using the changeset viewer.