Changeset 57909 in webkit


Ignore:
Timestamp:
Apr 20, 2010 1:18:34 PM (14 years ago)
Author:
pfeldman@chromium.org
Message:

2010-04-20 Pavel Feldman <pfeldman@chromium.org>

Reviewed by Timothy Hatcher.

Web Inspector: add basic script editing capabilities to the front-end.

https://bugs.webkit.org/show_bug.cgi?id=37875

  • bindings/js/ScriptDebugServer.cpp: (WebCore::ScriptDebugServer::setBreakpoint): (WebCore::ScriptDebugServer::removeBreakpoint):
  • inspector/front-end/ScriptView.js: (WebInspector.ScriptView): (WebInspector.ScriptView.prototype._editLine): (WebInspector.ScriptView.prototype._editLineComplete):
  • inspector/front-end/ScriptsPanel.js: (WebInspector.ScriptsPanel.prototype._resourceLoadingFinished): (WebInspector.ScriptsPanel.prototype.canEditScripts): (WebInspector.ScriptsPanel.prototype.editScriptLine):
  • inspector/front-end/SourceFrame.js: (WebInspector.SourceFrame): (WebInspector.SourceFrame.prototype.updateContent): (WebInspector.SourceFrame.prototype._createViewerIfNeeded):
  • inspector/front-end/TextEditorHighlighter.js: (WebInspector.TextEditorHighlighter): (WebInspector.TextEditorHighlighter.prototype.reset):
  • inspector/front-end/TextEditorModel.js: (WebInspector.TextEditorModel.prototype.copyRange):
  • inspector/front-end/TextViewer.js: (WebInspector.TextViewer): (WebInspector.TextViewer.prototype.set editCallback): (WebInspector.TextViewer.prototype._buildChunks): (WebInspector.TextViewer.prototype._handleKeyDown): (WebInspector.TextViewer.prototype._handleDoubleClick): (WebInspector.TextViewer.prototype._commitEditingLine): (WebInspector.TextViewer.prototype._cancelEditingLine):
  • inspector/front-end/inspector.js: (WebInspector.documentKeyDown): (WebInspector.log.logMessage): (WebInspector.log): (WebInspector.isEditingAnyField): (WebInspector.startEditing.cleanUpAfterEditing):

2010-04-20 Pavel Feldman <pfeldman@chromium.org>

Reviewed by Timothy Hatcher.

Web Inspector: add basic script editing capabilities to the front-end.

https://bugs.webkit.org/show_bug.cgi?id=37875

  • src/js/DebuggerAgent.js: (devtools.DebuggerAgent.prototype.resolveScriptSource.this.requestSeqToCallback_.cmd.getSequenceNumber): (devtools.DebuggerAgent.prototype.resolveScriptSource): (devtools.DebuggerAgent.prototype.editScriptLine.this.requestSeqToCallback_.cmd.getSequenceNumber): (devtools.DebuggerAgent.prototype.editScriptLine): (devtools.DebuggerAgent.prototype.handleDebuggerOutput_):
  • src/js/DevTools.js:
  • src/js/InspectorControllerImpl.js: (.devtools.InspectorBackendImpl.prototype.editScriptLine):
Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r57904 r57909  
     12010-04-20  Pavel Feldman  <pfeldman@chromium.org>
     2
     3        Reviewed by Timothy Hatcher.
     4
     5        Web Inspector: add basic script editing capabilities to the front-end.
     6
     7        https://bugs.webkit.org/show_bug.cgi?id=37875
     8
     9        * bindings/js/ScriptDebugServer.cpp:
     10        (WebCore::ScriptDebugServer::setBreakpoint):
     11        (WebCore::ScriptDebugServer::removeBreakpoint):
     12        * inspector/front-end/ScriptView.js:
     13        (WebInspector.ScriptView):
     14        (WebInspector.ScriptView.prototype._editLine):
     15        (WebInspector.ScriptView.prototype._editLineComplete):
     16        * inspector/front-end/ScriptsPanel.js:
     17        (WebInspector.ScriptsPanel.prototype._resourceLoadingFinished):
     18        (WebInspector.ScriptsPanel.prototype.canEditScripts):
     19        (WebInspector.ScriptsPanel.prototype.editScriptLine):
     20        * inspector/front-end/SourceFrame.js:
     21        (WebInspector.SourceFrame):
     22        (WebInspector.SourceFrame.prototype.updateContent):
     23        (WebInspector.SourceFrame.prototype._createViewerIfNeeded):
     24        * inspector/front-end/TextEditorHighlighter.js:
     25        (WebInspector.TextEditorHighlighter):
     26        (WebInspector.TextEditorHighlighter.prototype.reset):
     27        * inspector/front-end/TextEditorModel.js:
     28        (WebInspector.TextEditorModel.prototype.copyRange):
     29        * inspector/front-end/TextViewer.js:
     30        (WebInspector.TextViewer):
     31        (WebInspector.TextViewer.prototype.set editCallback):
     32        (WebInspector.TextViewer.prototype._buildChunks):
     33        (WebInspector.TextViewer.prototype._handleKeyDown):
     34        (WebInspector.TextViewer.prototype._handleDoubleClick):
     35        (WebInspector.TextViewer.prototype._commitEditingLine):
     36        (WebInspector.TextViewer.prototype._cancelEditingLine):
     37        * inspector/front-end/inspector.js:
     38        (WebInspector.documentKeyDown):
     39        (WebInspector.log.logMessage):
     40        (WebInspector.log):
     41        (WebInspector.isEditingAnyField):
     42        (WebInspector.startEditing.cleanUpAfterEditing):
     43
    1442010-04-20  Gavin Barraclough  <barraclough@apple.com>
    245
  • trunk/WebCore/bindings/js/ScriptDebugServer.cpp

    r57738 r57909  
    140140{
    141141    intptr_t sourceIDValue = sourceID.toIntPtr();
     142    if (!sourceIDValue)
     143        return;
    142144    BreakpointsMap::iterator it = m_breakpoints.find(sourceIDValue);
    143145    if (it == m_breakpoints.end())
     
    149151{
    150152    intptr_t sourceIDValue = sourceID.toIntPtr();
     153    if (!sourceIDValue)
     154        return;
    151155    BreakpointsMap::iterator it = m_breakpoints.find(sourceIDValue);
    152156    if (it != m_breakpoints.end())
  • trunk/WebCore/inspector/front-end/ScriptView.js

    r55231 r57909  
    3434    this._frameNeedsSetup = true;
    3535    this._sourceFrameSetup = false;
    36     this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this));
     36    var canEditScripts = WebInspector.panels.scripts.canEditScripts();
     37    this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null);
    3738}
    3839
     
    5354        this.attach();
    5455
     56        this.sourceFrame.setContent("text/javascript", this._prependWhitespace(this.script.source));
     57        this._sourceFrameSetup = true;
     58        delete this._frameNeedsSetup;
     59    },
     60
     61    _prependWhitespace: function(content) {
    5562        var prefix = "";
    5663        for (var i = 0; i < this.script.startingLine - 1; ++i)
    5764            prefix += "\n";
    58 
    59         this.sourceFrame.setContent("text/javascript", prefix + this.script.source);
    60         this._sourceFrameSetup = true;
    61         delete this._frameNeedsSetup;
     65        return prefix + content;
    6266    },
    6367
     
    7276        var breakpoint = new WebInspector.Breakpoint(this.script.sourceURL, line, this.script.sourceID);
    7377        WebInspector.panels.scripts.addBreakpoint(breakpoint);
     78    },
     79
     80    _editLine: function(line, newContent)
     81    {
     82        WebInspector.panels.scripts.editScriptLine(this.script.sourceID, line, newContent, this._editLineComplete.bind(this));
     83    },
     84
     85    _editLineComplete: function(newBody)
     86    {
     87        this.script.source = newBody;
     88        this.sourceFrame.updateContent(this._prependWhitespace(newBody));
    7489    },
    7590
  • trunk/WebCore/inspector/front-end/ScriptsPanel.js

    r57701 r57909  
    298298            if (script._scriptView) {
    299299                var sourceFrame = script._scriptView.sourceFrame;
    300                 for (var j = 0; j < sourceFrame.breakpoints; ++j) {
    301                     var resourceFrame = this._sourceFrameForScriptOrResource(resource);
     300                var resourceFrame = this._sourceFrameForScriptOrResource(resource);
     301                for (var j = 0; j < sourceFrame.breakpoints; ++j)
    302302                    resourceFrame.addBreakpoint(sourceFrame.breakpoints[j]);
    303                 }
    304303            }
    305304        }
     
    350349        if (sourceFrame)
    351350            sourceFrame.removeBreakpoint(breakpoint);
     351    },
     352
     353    canEditScripts: function()
     354    {
     355        return !!InspectorBackend.editScriptLine;
     356    },
     357
     358    editScriptLine: function(sourceID, line, newContent, callback)
     359    {
     360        if (!this.canEditScripts())
     361            return;
     362        var callbackId = WebInspector.Callback.wrap(callback)
     363        InspectorBackend.editScriptLine(callbackId, sourceID, line, newContent);
    352364    },
    353365
     
    577589        view.setupSourceFrameIfNeeded();
    578590        return view.sourceFrame;
    579     },
    580 
    581     _sourceViewForScriptOrResource: function(scriptOrResource)
    582     {
    583         if (scriptOrResource instanceof WebInspector.Resource) {
    584             if (!WebInspector.panels.resources)
    585                 return null;
    586             return WebInspector.panels.resources.resourceViewForResource(scriptOrResource);
    587         }
    588         if (scriptOrResource instanceof WebInspector.Script)
    589             return this.scriptViewForScript(scriptOrResource);
    590591    },
    591592
     
    975976
    976977WebInspector.ScriptsPanel.prototype.__proto__ = WebInspector.Panel.prototype;
     978
     979WebInspector.didEditScriptLine = WebInspector.Callback.processCallback;
  • trunk/WebCore/inspector/front-end/SourceFrame.js

    r55407 r57909  
    2929 */
    3030
    31 WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, removeBreakpointDelegate)
     31WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, removeBreakpointDelegate, editDelegate)
    3232{
    3333    this._parentElement = parentElement;
     
    4646    this._addBreakpointDelegate = addBreakpointDelegate;
    4747    this._removeBreakpointDelegate = removeBreakpointDelegate;
     48    this._editDelegate = editDelegate;
    4849    this._popoverObjectGroup = "popover";
    4950}
     
    142143        this._url = url;
    143144        this._createViewerIfNeeded();
     145    },
     146
     147    updateContent: function(content)
     148    {
     149        this._textModel.setText(null, content);
    144150    },
    145151
     
    193199        }
    194200        this._textViewer.endUpdates();
     201        if (this._editDelegate)
     202            this._textViewer.editCallback = this._editDelegate;
    195203    },
    196204
  • trunk/WebCore/inspector/front-end/TextEditorHighlighter.js

    r56444 r57909  
    3434    this._textModel = textModel;
    3535    this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/html");
    36     this._tokenizerCondition = this._tokenizer.initialCondition;
    3736    this._damageCallback = damageCallback;
    38     this._lastHighlightedLine = 0;
    39     this._lastHighlightedColumn = 0;
     37    this.reset();
    4038}
    4139
     
    4846            this._tokenizerCondition = this._tokenizer.initialCondition;
    4947        }
     48    },
     49
     50    reset: function()
     51    {
     52        this._lastHighlightedLine = 0;
     53        this._lastHighlightedColumn = 0;
     54        this._tokenizerCondition = this._tokenizer.initialCondition;
    5055    },
    5156
  • trunk/WebCore/inspector/front-end/TextEditorModel.js

    r54415 r57909  
    201201    copyRange: function(range)
    202202    {
     203        if (!range)
     204            range = new WebInspector.TextRange(0, 0, this._lines.length - 1, this._lines[this._lines.length - 1].length);
     205
    203206        var clip = [];
    204207        if (range.startLine === range.endLine) {
  • trunk/WebCore/inspector/front-end/TextViewer.js

    r56799 r57909  
    4444    this.element.addEventListener("beforecopy", this._beforeCopy.bind(this), false);
    4545    this.element.addEventListener("copy", this._copy.bind(this), false);
     46    this.element.addEventListener("dblclick", this._handleDoubleClick.bind(this), false);
    4647
    4748    this._url = url;
     
    7879        var chunk = this._makeLineAChunk(lineNumber);
    7980        chunk.element.scrollIntoViewIfNeeded();
     81    },
     82
     83    set editCallback(editCallback)
     84    {
     85        this._editCallback = editCallback;
    8086    },
    8187
     
    139145            this._linesContainerElement.appendChild(chunk.element);
    140146        }
     147
    141148        this._indexChunks();
     149        this._highlighter.reset();
    142150        this._repaintAll();
    143151    },
     
    207215        }.bind(this), 50);
    208216    },
    209    
     217
    210218    _handleKeyDown: function()
    211219    {
    212         if (event.metaKey || event.shiftKey || event.ctrlKey || event.altKey)
    213             return;
    214        
     220        if (this._editingLine || event.metaKey || event.shiftKey || event.ctrlKey || event.altKey)
     221            return;
     222
    215223        var scrollValue = 0;
    216224        if (event.keyCode === WebInspector.KeyboardShortcut.KeyCodes.Up)
     
    237245            this.element.scrollLeft += scrollValue;
    238246        }
     247    },
     248
     249    _handleDoubleClick: function(e)
     250    {
     251        if (!this._editCallback)
     252            return;
     253
     254        var lineRow = e.target.enclosingNodeOrSelfWithNodeName("TR");
     255        if (!lineRow)
     256            return;
     257        var oldContent = lineRow.lastChild.textContent;
     258        this._editingLine = WebInspector.startEditing(lineRow.lastChild, this._commitEditingLine.bind(this, lineRow.lineNumber, lineRow.lastChild), this._cancelEditingLine.bind(this), null, true);
     259    },
     260
     261    _commitEditingLine: function(lineNumber, element)
     262    {
     263        this._editCallback(lineNumber, element.textContent)
     264        delete this._editingLine;
     265    },
     266
     267    _cancelEditingLine: function(e)
     268    {
     269        this._textModel.setText(null, this._textModel.copyRange());
     270        delete this._editingLine;
    239271    },
    240272
  • trunk/WebCore/inspector/front-end/inspector.js

    r57146 r57909  
    678678WebInspector.documentKeyDown = function(event)
    679679{
     680    if (WebInspector.isEditingAnyField())
     681        return;
     682
    680683    if (this.currentFocusElement && this.currentFocusElement.handleKeyEvent) {
    681684        this.currentFocusElement.handleKeyEvent(event);
     
    13631366}
    13641367
    1365 WebInspector.log = function(message)
     1368WebInspector.log = function(message, messageLevel)
    13661369{
    13671370    // remember 'this' for setInterval() callback
     
    14171420            WebInspector.ConsoleMessage.MessageSource.Other,
    14181421            WebInspector.ConsoleMessage.MessageType.Log,
    1419             WebInspector.ConsoleMessage.MessageLevel.Debug,
     1422            messageLevel || WebInspector.ConsoleMessage.MessageLevel.Debug,
    14201423            -1,
    14211424            null,
     
    18141817}
    18151818
     1819WebInspector.isEditingAnyField = function()
     1820{
     1821    return this.__editing;
     1822}
     1823
    18161824WebInspector.startEditing = function(element, committedCallback, cancelledCallback, context, multiline)
    18171825{
     
    18191827        return;
    18201828    element.__editing = true;
     1829    WebInspector.__editing = true;
    18211830
    18221831    var oldText = getContent(element);
     
    18421851    function cleanUpAfterEditing() {
    18431852        delete this.__editing;
     1853        delete WebInspector.__editing;
    18441854
    18451855        this.removeStyleClass("editing");
  • trunk/WebKit/chromium/ChangeLog

    r57903 r57909  
     12010-04-20  Pavel Feldman  <pfeldman@chromium.org>
     2
     3        Reviewed by Timothy Hatcher.
     4
     5        Web Inspector: add basic script editing capabilities to the front-end.
     6
     7        https://bugs.webkit.org/show_bug.cgi?id=37875
     8
     9        * src/js/DebuggerAgent.js:
     10        (devtools.DebuggerAgent.prototype.resolveScriptSource.this.requestSeqToCallback_.cmd.getSequenceNumber):
     11        (devtools.DebuggerAgent.prototype.resolveScriptSource):
     12        (devtools.DebuggerAgent.prototype.editScriptLine.this.requestSeqToCallback_.cmd.getSequenceNumber):
     13        (devtools.DebuggerAgent.prototype.editScriptLine):
     14        (devtools.DebuggerAgent.prototype.handleDebuggerOutput_):
     15        * src/js/DevTools.js:
     16        * src/js/InspectorControllerImpl.js:
     17        (.devtools.InspectorBackendImpl.prototype.editScriptLine):
     18
    1192010-04-20  Kent Tamura  <tkent@chromium.org>
    220
  • trunk/WebKit/chromium/src/js/DebuggerAgent.js

    r56999 r57909  
    216216    RemoteDebuggerAgent.processDebugCommands();
    217217
     218    var self = this;
    218219    this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) {
    219220        if (msg.isSuccess()) {
    220221            var scriptJson = msg.getBody()[0];
    221             if (scriptJson)
     222            if (scriptJson) {
     223                script.source = scriptJson.source;
    222224                callback(scriptJson.source);
     225            }
    223226            else
    224227                callback(null);
     
    296299    // It is necessary for being able to change a breakpoint just after it
    297300    // has been created (since we need an existing breakpoint id for that).
     301    RemoteDebuggerAgent.processDebugCommands();
     302};
     303
     304
     305/**
     306 * Changes given line of the script.
     307 */
     308devtools.DebuggerAgent.prototype.editScriptLine = function(sourceId, line, newContent, callback)
     309{
     310    var script = this.parsedScripts_[sourceId];
     311    if (!script || !script.source)
     312        return;
     313
     314    var lines = script.source.split("\n");
     315    lines[line] = newContent;
     316
     317    var commandArguments = {
     318        "script_id": sourceId,
     319        "new_source": lines.join("\n")
     320    };
     321
     322    var cmd = new devtools.DebugCommand("changelive", commandArguments);
     323    devtools.DebuggerAgent.sendCommand_(cmd);
     324    this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) {
     325        if (!msg.isSuccess())
     326            WebInspector.log("Unable to modify source code within given scope. Only function bodies are editable at the moment.", WebInspector.ConsoleMessage.MessageLevel.Warning);
     327        this.resolveScriptSource(sourceId, callback);
     328        if (WebInspector.panels.scripts.paused)
     329            this.requestBacktrace_();
     330    }.bind(this);
    298331    RemoteDebuggerAgent.processDebugCommands();
    299332};
     
    766799        else if (msg.getCommand() === "setbreakpoint")
    767800            this.handleSetBreakpointResponse_(msg);
     801        else if (msg.getCommand() === "changelive")
     802            this.invokeCallbackForResponse_(msg);
    768803        else if (msg.getCommand() === "clearbreakpoint")
    769804            this.handleClearBreakpointResponse_(msg);
  • trunk/WebKit/chromium/src/js/DevTools.js

    r57701 r57909  
    224224WebInspector.ScriptView.prototype.didResolveScriptSource_ = function()
    225225{
    226     this.sourceFrame.setContent("text/javascript", this.script.source);
     226    this.sourceFrame.setContent("text/javascript", this._prependWhitespace(this.script.source));
    227227    this._sourceFrameSetup = true;
    228228    delete this._frameNeedsSetup;
     
    408408})();
    409409
    410 WebInspector.pausedScript = function(callFrames)
    411 {
    412     this.panels.scripts.debuggerPaused(callFrames);
    413 };
    414 
    415410// Chromium theme support.
    416411WebInspector.setToolbarColors = function(backgroundColor, color)
  • trunk/WebKit/chromium/src/js/InspectorControllerImpl.js

    r57701 r57909  
    140140
    141141
     142devtools.InspectorBackendImpl.prototype.editScriptLine = function(callID, sourceID, line, newContent)
     143{
     144    devtools.tools.getDebuggerAgent().editScriptLine(sourceID, line, newContent, function(newFullBody) {
     145        WebInspector.didEditScriptLine(callID, newFullBody);
     146    });
     147};
     148
     149
    142150devtools.InspectorBackendImpl.prototype.activateBreakpoints = function()
    143151{
Note: See TracChangeset for help on using the changeset viewer.