Changeset 76341 in webkit
- Timestamp:
- Jan 21, 2011 3:59:29 AM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r76340 r76341 1 2011-01-12 Pavel Podivilov <podivilov@chromium.org> 2 3 Reviewed by Pavel Feldman. 4 5 Web Inspector: breakpoints are restored incorrectly when reverting live edit. 6 https://bugs.webkit.org/show_bug.cgi?id=52300 7 8 Fix breakpoints restoring when reverting to old revision by using text diff. 9 Move live edit logic from ScriptsPanel to DebuggerModel. 10 Eliminate unnecessary editLine delegate in TextViewer. 11 12 * inspector/front-end/DebuggerModel.js: 13 (WebInspector.DebuggerModel): 14 (WebInspector.DebuggerModel.prototype.reset): 15 (WebInspector.DebuggerModel.prototype.editScriptSource): 16 (WebInspector.DebuggerModel.prototype._updateScriptSource): 17 (WebInspector.DebuggerModel.prototype.get callFrames): 18 (WebInspector.DebuggerModel.prototype.pausedScript): 19 (WebInspector.DebuggerModel.prototype.resumedScript): 20 * inspector/front-end/Script.js: 21 (WebInspector.Script.prototype.get source): 22 * inspector/front-end/ScriptView.js: 23 (WebInspector.ScriptView): 24 * inspector/front-end/ScriptsPanel.js: 25 (WebInspector.ScriptsPanel): 26 (WebInspector.ScriptsPanel.prototype._scriptSourceChanged): 27 * inspector/front-end/SourceFrame.js: 28 (WebInspector.SourceFrame): 29 (WebInspector.SourceFrame.prototype._createViewerIfNeeded): 30 (WebInspector.SourceFrame.prototype._doubleClick.didEditLine): 31 (WebInspector.SourceFrame.prototype._doubleClick): 32 * inspector/front-end/SourceView.js: 33 (WebInspector.SourceView): 34 * inspector/front-end/TextViewer.js: 35 (WebInspector.TextViewer): 36 (WebInspector.TextViewer.prototype._handleKeyDown): 37 (WebInspector.TextViewer.prototype.editLine.finishEditing): 38 (WebInspector.TextViewer.prototype.editLine): 39 (WebInspector.TextChunk.prototype._createRow): 40 1 41 2011-01-21 Adam Klein <adamk@chromium.org> 2 42 -
trunk/Source/WebCore/inspector/front-end/DebuggerModel.js
r76239 r76341 32 32 { 33 33 this._paused = false; 34 this._callFrames = []; 34 35 this._breakpoints = {}; 35 36 this._sourceIDAndLineToBreakpointId = {}; … … 44 45 ParsedScriptSource: "parsed-script-source", 45 46 FailedToParseScriptSource: "failed-to-parse-script-source", 47 ScriptSourceChanged: "script-source-changed", 46 48 BreakpointAdded: "breakpoint-added", 47 49 BreakpointRemoved: "breakpoint-removed" … … 136 138 { 137 139 this._paused = false; 140 this._callFrames = []; 138 141 this._breakpoints = {}; 139 142 delete this._oneTimeBreakpoint; … … 163 166 }, 164 167 168 editScriptSource: function(sourceID, scriptSource) 169 { 170 function didEditScriptSource(success, newBodyOrErrorMessage, callFrames) 171 { 172 if (success) { 173 if (callFrames && callFrames.length) 174 this._callFrames = callFrames; 175 this._updateScriptSource(sourceID, newBodyOrErrorMessage); 176 } else 177 WebInspector.log(newBodyOrErrorMessage, WebInspector.ConsoleMessage.MessageLevel.Warning); 178 } 179 InspectorBackend.editScriptSource(sourceID, scriptSource, didEditScriptSource.bind(this)); 180 }, 181 182 _updateScriptSource: function(sourceID, scriptSource) 183 { 184 var script = this._scripts[sourceID]; 185 var oldSource = script.source; 186 script.source = scriptSource; 187 188 // Clear and re-create breakpoints according to text diff. 189 var diff = Array.diff(oldSource.split("\n"), script.source.split("\n")); 190 for (var id in this._breakpoints) { 191 var breakpoint = this._breakpoints[id]; 192 if (breakpoint.sourceID !== sourceID) 193 continue; 194 breakpoint.remove(); 195 var lineNumber = breakpoint.line - 1; 196 var newLineNumber = diff.left[lineNumber].row; 197 if (newLineNumber === undefined) { 198 for (var i = lineNumber - 1; i >= 0; --i) { 199 if (diff.left[i].row === undefined) 200 continue; 201 var shiftedLineNumber = diff.left[i].row + lineNumber - i; 202 if (shiftedLineNumber < diff.right.length) { 203 var originalLineNumber = diff.right[shiftedLineNumber].row; 204 if (originalLineNumber === lineNumber || originalLineNumber === undefined) 205 newLineNumber = shiftedLineNumber; 206 } 207 break; 208 } 209 } 210 if (newLineNumber !== undefined) 211 this.setBreakpoint(sourceID, newLineNumber + 1, breakpoint.enabled, breakpoint.condition); 212 } 213 214 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ScriptSourceChanged, { sourceID: sourceID, oldSource: oldSource }); 215 }, 216 217 get callFrames() 218 { 219 return this._callFrames; 220 }, 221 165 222 _pausedScript: function(details) 166 223 { 167 224 this._paused = true; 225 this._callFrames = details.callFrames; 168 226 if ("_continueToLineBreakpointId" in this) { 169 227 InspectorBackend.removeBreakpoint(this._continueToLineBreakpointId); … … 176 234 { 177 235 this._paused = false; 236 this._callFrames = []; 178 237 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerResumed); 179 238 }, -
trunk/Source/WebCore/inspector/front-end/Script.js
r76026 r76341 98 98 get source() 99 99 { 100 if (!this._source && this.resource) 101 this._source = this.resource.content; 100 102 return this._source; 101 103 }, … … 104 106 { 105 107 this._source = source; 108 delete this._lineEndings; 106 109 }, 107 110 -
trunk/Source/WebCore/inspector/front-end/ScriptView.js
r75937 r76341 31 31 32 32 var contentProvider = new WebInspector.SourceFrameContentProviderForScript(script); 33 this.sourceFrame = new WebInspector.SourceFrame(this.element, contentProvider, "", WebInspector.panels.scripts.canEditScripts());33 this.sourceFrame = new WebInspector.SourceFrame(this.element, contentProvider, "", true); 34 34 } 35 35 -
trunk/Source/WebCore/inspector/front-end/ScriptsPanel.js
r76239 r76341 187 187 WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this); 188 188 WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._failedToParseScriptSource, this); 189 WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ScriptSourceChanged, this._scriptSourceChanged, this); 189 190 WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this); 190 191 WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this); … … 250 251 { 251 252 this._addScript(event.data); 253 }, 254 255 _scriptSourceChanged: function(event) 256 { 257 var sourceID = event.data.sourceID; 258 var oldSource = event.data.oldSource; 259 260 var script = WebInspector.debuggerModel.scriptForSourceID(sourceID); 261 var oldView = script._scriptView; 262 if (oldView) { 263 script._scriptView = new WebInspector.ScriptView(script); 264 this.viewRecreated(oldView, script._scriptView); 265 } 266 if (script.resource) { 267 var revertHandle = WebInspector.debuggerModel.editScriptSource.bind(WebInspector.debuggerModel, sourceID, oldSource); 268 script.resource.setContent(script.source, revertHandle); 269 } 270 271 var callFrames = WebInspector.debuggerModel.callFrames; 272 if (callFrames.length) 273 this._debuggerPaused({ data: { callFrames: callFrames } }); 252 274 }, 253 275 … … 285 307 this._addScriptToFilesMenu(resource._scriptsPendingResourceLoad[0]); 286 308 delete resource._scriptsPendingResourceLoad; 287 },288 289 canEditScripts: function()290 {291 return Preferences.canEditScriptSource;292 },293 294 editScriptSource: function(editData, revertEditingCallback, cancelEditingCallback)295 {296 if (!this.canEditScripts())297 return;298 299 // Need to clear breakpoints and re-create them later when editing source.300 var breakpoints = WebInspector.debuggerModel.queryBreakpoints(function(b) { return b.sourceID === editData.sourceID });301 for (var i = 0; i < breakpoints.length; ++i)302 breakpoints[i].remove();303 304 function mycallback(success, newBodyOrErrorMessage, callFrames)305 {306 if (success) {307 var script = WebInspector.debuggerModel.scriptForSourceID(editData.sourceID);308 script.source = newBodyOrErrorMessage;309 var oldView = script._scriptView310 if (oldView) {311 script._scriptView = new WebInspector.ScriptView(script);312 this.viewRecreated(oldView, script._scriptView);313 }314 if (script.resource)315 script.resource.setContent(newBodyOrErrorMessage, revertEditingCallback);316 317 if (callFrames && callFrames.length)318 this._debuggerPaused({ data: { callFrames: callFrames } });319 } else {320 if (cancelEditingCallback)321 cancelEditingCallback();322 WebInspector.log(newBodyOrErrorMessage, WebInspector.ConsoleMessage.MessageLevel.Warning);323 }324 for (var i = 0; i < breakpoints.length; ++i) {325 var breakpoint = breakpoints[i];326 var newLine = breakpoint.line;327 if (success && breakpoint.line >= editData.line)328 newLine += editData.linesCountToShift;329 WebInspector.debuggerModel.setBreakpoint(editData.sourceID, newLine, breakpoint.enabled, breakpoint.condition);330 }331 };332 InspectorBackend.editScriptSource(editData.sourceID, editData.content, mycallback.bind(this));333 309 }, 334 310 -
trunk/Source/WebCore/inspector/front-end/SourceFrame.js
r76132 r76341 29 29 */ 30 30 31 WebInspector.SourceFrame = function(parentElement, contentProvider, url, canEditScripts)31 WebInspector.SourceFrame = function(parentElement, contentProvider, url, isScript) 32 32 { 33 33 this._parentElement = parentElement; 34 34 this._contentProvider = contentProvider; 35 35 this._url = url; 36 this._canEditScripts = canEditScripts; 36 this._isScript = isScript; 37 37 38 38 39 this._textModel = new WebInspector.TextEditorModel(); … … 164 165 element.addEventListener("mousemove", this._mouseMove.bind(this), true); 165 166 element.addEventListener("scroll", this._scroll.bind(this), true); 167 element.addEventListener("dblclick", this._doubleClick.bind(this), true); 166 168 this._parentElement.appendChild(element); 167 169 … … 803 805 }, 804 806 805 _editLine: function(lineNumber, newContent, cancelEditingCallback) 806 { 807 var lines = []; 808 var oldLines = this._content.split('\n'); 809 for (var i = 0; i < oldLines.length; ++i) { 810 if (i === lineNumber) 811 lines.push(newContent); 812 else 813 lines.push(oldLines[i]); 814 } 815 816 var editData = {}; 817 editData.sourceID = this._sourceIDForLine(lineNumber); 818 editData.content = lines.join("\n"); 819 editData.line = lineNumber + 1; 820 editData.linesCountToShift = newContent.split("\n").length - 1; 821 this._doEditLine(editData, cancelEditingCallback); 822 }, 823 824 _revertEditLine: function(editData, contentToRevertTo) 825 { 826 var newEditData = {}; 827 newEditData.sourceID = editData.sourceID; 828 newEditData.content = contentToRevertTo; 829 newEditData.line = editData.line; 830 newEditData.linesCountToShift = -editData.linesCountToShift; 831 this._doEditLine(newEditData); 832 }, 833 834 _doEditLine: function(editData, cancelEditingCallback) 835 { 836 var revertEditingCallback = this._revertEditLine.bind(this, editData); 837 WebInspector.panels.scripts.editScriptSource(editData, revertEditingCallback, cancelEditingCallback); 807 _doubleClick: function(event) 808 { 809 if (!Preferences.canEditScriptSource || !this._isScript) 810 return; 811 812 var target = event.target.enclosingNodeOrSelfWithNodeName("TD"); 813 if (!target || target.parentElement.firstChild === target) 814 return; // Do not trigger editing from line numbers. 815 816 var lineRow = target.parentElement; 817 var lineNumber = lineRow.lineNumber; 818 var sourceID = this._sourceIDForLine(lineNumber); 819 if (!sourceID) 820 return; 821 822 function didEditLine(newContent) 823 { 824 var lines = []; 825 var oldLines = this._content.split('\n'); 826 for (var i = 0; i < oldLines.length; ++i) { 827 if (i === lineNumber) 828 lines.push(newContent); 829 else 830 lines.push(oldLines[i]); 831 } 832 WebInspector.debuggerModel.editScriptSource(sourceID, lines.join("\n")); 833 } 834 this._textViewer.editLine(lineRow, didEditLine.bind(this)); 838 835 }, 839 836 -
trunk/Source/WebCore/inspector/front-end/SourceView.js
r75937 r76341 34 34 35 35 var contentProvider = new WebInspector.SourceFrameContentProviderForResource(resource); 36 var canEditScripts = WebInspector.panels.scripts.canEditScripts() &&resource.type === WebInspector.Resource.Type.Script;37 this.sourceFrame = new WebInspector.SourceFrame(this.element, contentProvider, resource.url, canEditScripts);36 var isScript = resource.type === WebInspector.Resource.Type.Script; 37 this.sourceFrame = new WebInspector.SourceFrame(this.element, contentProvider, resource.url, isScript); 38 38 } 39 39 -
trunk/Source/WebCore/inspector/front-end/TextViewer.js
r73913 r76341 44 44 this.element.addEventListener("beforecopy", this._beforeCopy.bind(this), false); 45 45 this.element.addEventListener("copy", this._copy.bind(this), false); 46 this.element.addEventListener("dblclick", this._handleDoubleClick.bind(this), false);47 46 48 47 this._url = url; … … 79 78 var chunk = this._makeLineAChunk(lineNumber); 80 79 chunk.element.scrollIntoViewIfNeeded(); 81 },82 83 set editCallback(editCallback)84 {85 this._editCallback = editCallback;86 80 }, 87 81 … … 232 226 else if (event.keyCode == WebInspector.KeyboardShortcut.Keys.Down.code) 233 227 scrollValue = 1; 234 228 235 229 if (scrollValue) { 236 230 event.preventDefault(); … … 239 233 return; 240 234 } 241 235 242 236 scrollValue = 0; 243 237 if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Left.code) … … 245 239 else if (event.keyCode == WebInspector.KeyboardShortcut.Keys.Right.code) 246 240 scrollValue = 40; 247 241 248 242 if (scrollValue) { 249 243 event.preventDefault(); … … 253 247 }, 254 248 255 _handleDoubleClick: function(e) 256 { 257 if (!this._editCallback) 258 return; 259 260 var cell = e.target.enclosingNodeOrSelfWithNodeName("TD"); 261 if (!cell) 262 return; 263 264 var lineRow = cell.parentElement; 265 if (lineRow.firstChild === cell) 266 return; // Do not trigger editing from line numbers. 267 268 var oldContent = lineRow.lastChild.innerHTML; 269 var cancelEditingCallback = this._cancelEditingLine.bind(this, lineRow.lastChild, oldContent); 270 var commitEditingCallback = this._commitEditingLine.bind(this, lineRow.lineNumber, lineRow.lastChild, cancelEditingCallback); 271 this._editingLine = WebInspector.startEditing(lineRow.lastChild, { 249 editLine: function(lineRow, callback) 250 { 251 var element = lineRow.lastChild; 252 var oldContent = element.innerHTML; 253 function finishEditing(committed, e, newContent) 254 { 255 if (committed) 256 callback(newContent); 257 element.innerHTML = oldContent; 258 delete this._editingLine; 259 } 260 this._editingLine = WebInspector.startEditing(element, { 272 261 context: null, 273 commitHandler: commitEditingCallback,274 cancelHandler: cancelEditingCallback,262 commitHandler: finishEditing.bind(this, true), 263 cancelHandler: finishEditing.bind(this, false), 275 264 multiline: true 276 265 }); 277 },278 279 _commitEditingLine: function(lineNumber, element, cancelEditingCallback)280 {281 this._editCallback(lineNumber, element.textContent, cancelEditingCallback);282 delete this._editingLine;283 },284 285 _cancelEditingLine: function(element, oldContent, e)286 {287 element.innerHTML = oldContent;288 delete this._editingLine;289 266 }, 290 267 … … 787 764 var lineContentElement = document.createElement("td"); 788 765 lineContentElement.className = "webkit-line-content"; 789 lineRow.appendChild(lineContentElement); 766 lineRow.appendChild(lineContentElement); 790 767 } 791 768 lineRow.lineNumber = lineNumber;
Note: See TracChangeset
for help on using the changeset viewer.