Changeset 94560 in webkit
- Timestamp:
- Sep 6, 2011 2:34:02 AM (13 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r94558 r94560 1 2011-09-05 Pavel Podivilov <podivilov@chromium.org> 2 3 Web Inspector: re-implement RawSourceCode. 4 https://bugs.webkit.org/show_bug.cgi?id=67609 5 6 Reviewed by Yury Semikhatsky. 7 8 * inspector/debugger/content-providers-expected.txt: 9 * inspector/debugger/content-providers.html: 10 * inspector/debugger/scripts-panel.html: 11 * inspector/debugger/source-frame-count.html: 12 1 13 2011-09-06 Dirk Schulze <krit@webkit.org> 2 14 -
trunk/LayoutTests/inspector/debugger/content-providers-expected.txt
r93972 r94560 22 22 Request resource content. 23 23 24 Running: testFormattedContentProvider25 -
trunk/LayoutTests/inspector/debugger/content-providers.html
r93972 r94560 70 70 } 71 71 contentProvider.requestContent(didRequestContent); 72 },73 74 function testFormattedContentProvider(next)75 {76 var mapping = {};77 var formatter = {78 formatContent: function(mimeType, content, callback)79 {80 setTimeout(callback.bind(null, "<formatted> " + content, mapping), 0);81 }82 };83 var resource = { type: WebInspector.Resource.Type.Document, requestContent: function(callback) { callback("<resource content>"); } };84 var contentProvider = new WebInspector.ResourceContentProvider(resource);85 var formattedContentProvider = new WebInspector.FormattedContentProvider(contentProvider, formatter);86 function didRequestContent(mimeType, content)87 {88 InspectorTest.assertEquals("text/html", mimeType);89 InspectorTest.assertEquals("<formatted> <resource content>", content);90 InspectorTest.assertEquals(mapping, formattedContentProvider.mapping);91 next();92 }93 formattedContentProvider.requestContent(didRequestContent);94 72 } 95 73 ]); -
trunk/LayoutTests/inspector/debugger/scripts-panel.html
r94530 r94560 11 11 var model = new WebInspector.Object(); 12 12 model.breakpointsForUISourceCode = function() { return []; }; 13 model.messagesForUISourceCode = function() { return []; }; 13 14 return model; 14 15 } … … 162 163 addUISouceCode(model, "foo.js"); 163 164 var uiSourceCode = addUISouceCode(model, "bar.js"); 164 panel._uiSourceCodeReplaced({ data: { old SourceCode: uiSourceCode, sourceCode: uiSourceCode }});165 panel._uiSourceCodeReplaced({ data: { oldUISourceCode: uiSourceCode, uiSourceCode: uiSourceCode }}); 165 166 showSourceFrame(panel, "bar.js"); 166 167 next(); -
trunk/LayoutTests/inspector/debugger/source-frame-count.html
r92838 r94560 32 32 function didReload() 33 33 { 34 InspectorTest.showScriptSource("source-frame-count.html", didShowScriptSourceAgain); 35 } 36 37 function didShowScriptSourceAgain() 38 { 34 39 InspectorTest.assertTrue(select[select.selectedIndex].text.indexOf("source-frame-count.html") !== -1); 35 // There should be maximum 2 source frames: first one is the first shown, second one is the last viewed ("s cripts-panel.html").40 // There should be maximum 2 source frames: first one is the first shown, second one is the last viewed ("source-frame-count.html"). 36 41 InspectorTest.assertEquals(true, sourceFrameCount <= 2, "too many source frames created after page reload"); 37 42 next(); -
trunk/Source/WebCore/ChangeLog
r94558 r94560 1 2011-09-05 Pavel Podivilov <podivilov@chromium.org> 2 3 Web Inspector: re-implement RawSourceCode. 4 https://bugs.webkit.org/show_bug.cgi?id=67609 5 6 RawSourceCode content and source mapping loading logic is too complex, re-implement it using simpler semantics: 7 1) Initially, RawSourceCode doesn't have any content or mapping because content loading and 8 formatting operations are asynchronous, it only has scripts metadata. We don't update UI right 9 after RawSourceCode creation until full RawSourceCode representation is ready (content + mapping). 10 2) When RawSourceCode representation is ready (e.g. resource is finished, or content is formatted 11 if in pretty-print mode) we dispatch SourceMappingUpdated event to notify the listeners that 12 source code should be shown to user and raw locations should be converted to ui locations 13 (to show breakpoins, messages, call frames etc in UI). At this moment, all source file's content 14 is ready for loading and source mapping is available. 15 3) Later, RawSourceCode representation may change again, e.g. if pretty-print mode is toggled, or 16 blocked resource is finished etc., in that case SourceMappingUpdated is dispatched again to update 17 source code, links and decorations in UI. 18 19 Reviewed by Yury Semikhatsky. 20 21 * inspector/front-end/DebuggerPresentationModel.js: 22 (WebInspector.DebuggerPresentationModel.prototype.linkifyLocation): 23 (WebInspector.DebuggerPresentationModel.prototype._addScript): 24 (WebInspector.DebuggerPresentationModel.prototype._sourceMappingUpdated): 25 (WebInspector.DebuggerPresentationModel.prototype._restoreBreakpoints): 26 (WebInspector.DebuggerPresentationModel.prototype._addConsoleMessage.didGetUILocation): 27 (WebInspector.DebuggerPresentationModel.prototype._addConsoleMessage): 28 (WebInspector.DebuggerPresentationModel.prototype.messagesForUISourceCode): 29 * inspector/front-end/ScriptsPanel.js: 30 (WebInspector.ScriptsPanel.prototype._uiSourceCodeReplaced): 31 (WebInspector.ScriptsPanel.prototype._sourceFrameLoaded): 32 * inspector/front-end/SourceFile.js: 33 (WebInspector.RawSourceCode): 34 (WebInspector.RawSourceCode.prototype.addScript): 35 (WebInspector.RawSourceCode.prototype.contentEdited): 36 (WebInspector.RawSourceCode.prototype._resourceFinished): 37 (WebInspector.RawSourceCode.prototype.requestContent): 38 (WebInspector.RawSourceCode.prototype.createSourceMappingIfNeeded.sourceMappingUpdated): 39 (WebInspector.RawSourceCode.prototype.createSourceMappingIfNeeded): 40 (WebInspector.RawSourceCode.prototype.forceLoadContent): 41 (WebInspector.RawSourceCode.prototype._updateSourceMapping.didCreateSourceMapping): 42 (WebInspector.RawSourceCode.prototype._updateSourceMapping): 43 (WebInspector.RawSourceCode.prototype._createContentProvider): 44 (WebInspector.RawSourceCode.prototype._createSourceMapping.didRequestContent.didFormatContent): 45 (WebInspector.RawSourceCode.prototype._createSourceMapping.didRequestContent): 46 (WebInspector.RawSourceCode.prototype._createSourceMapping): 47 (WebInspector.RawSourceCode.prototype._saveSourceMapping): 48 (WebInspector.StaticContentProvider): 49 (WebInspector.StaticContentProvider.prototype.requestContent): 50 1 51 2011-09-06 Dirk Schulze <krit@webkit.org> 2 52 -
trunk/Source/WebCore/inspector/front-end/BreakpointManager.js
r94294 r94560 215 215 function resetBreakpoint(breakpoint) 216 216 { 217 delete breakpoint.uiSourceCode;218 217 this._removeBreakpointFromDebugger(breakpoint); 219 218 } -
trunk/Source/WebCore/inspector/front-end/DebuggerPresentationModel.js
r94532 r94560 158 158 rawSourceCode = new WebInspector.RawSourceCode(rawSourceCodeId, script, this._formatter, this._formatSource); 159 159 this._rawSourceCode[rawSourceCodeId] = rawSourceCode; 160 rawSourceCode.addEventListener(WebInspector.RawSourceCode.Events.UISourceCodeReplaced, this._uiSourceCodeReplaced, this); 161 162 function didCreateSourceMapping() 163 { 164 this._breakpointManager.uiSourceCodeAdded(rawSourceCode.uiSourceCode); 165 var breakpoints = this._breakpointManager.breakpointsForUISourceCode(rawSourceCode.uiSourceCode); 166 for (var lineNumber in breakpoints) 167 this._breakpointAdded(breakpoints[lineNumber]); 168 } 169 // FIXME: force source formatting if needed. This will go away once formatting 170 // is fully encapsulated in RawSourceCode class. 171 rawSourceCode.createSourceMappingIfNeeded(didCreateSourceMapping.bind(this)); 172 160 rawSourceCode.addEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, this._sourceMappingUpdated, this); 161 }, 162 163 _sourceMappingUpdated: function(event) 164 { 165 for (var i = 0; i < this._sourceMappingListeners.length; ++i) 166 this._sourceMappingListeners[i](); 167 168 var rawSourceCode = event.target; 169 var oldUISourceCode = event.data.oldUISourceCode; 173 170 var uiSourceCode = rawSourceCode.uiSourceCode; 174 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.UISourceCodeAdded, uiSourceCode); 175 }, 176 177 _uiSourceCodeReplaced: function(event) 178 { 179 // FIXME: restore breakpoints in new source code (currently we just recreate everything when switching to pretty-print mode). 180 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.UISourceCodeReplaced, event.data); 171 172 if (!oldUISourceCode) 173 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.UISourceCodeAdded, uiSourceCode); 174 else { 175 var breakpoints = this._breakpointManager.breakpointsForUISourceCode(oldUISourceCode); 176 for (var lineNumber in breakpoints) { 177 var breakpoint = breakpoints[lineNumber]; 178 this._breakpointRemoved(breakpoint); 179 delete breakpoint.uiSourceCode; 180 } 181 var eventData = { uiSourceCode: uiSourceCode, oldUISourceCode: oldUISourceCode }; 182 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.UISourceCodeReplaced, eventData); 183 } 184 this._restoreBreakpoints(uiSourceCode); 185 }, 186 187 _restoreBreakpoints: function(uiSourceCode) 188 { 189 this._breakpointManager.uiSourceCodeAdded(uiSourceCode); 190 var breakpoints = this._breakpointManager.breakpointsForUISourceCode(uiSourceCode); 191 for (var lineNumber in breakpoints) 192 this._breakpointAdded(breakpoints[lineNumber]); 181 193 }, 182 194 … … 251 263 252 264 this._breakpointManager.reset(); 265 for (var id in this._rawSourceCode) 266 this._rawSourceCode[id].removeEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, this._sourceMappingUpdated, this); 253 267 this._rawSourceCode = {}; 254 268 var messages = this._messages; … … 291 305 presentationMessage.lineNumber = lineNumber; 292 306 presentationMessage.originalMessage = message; 293 uiSourceCode.messages.push(presentationMessage);307 rawSourceCode.messages.push(presentationMessage); 294 308 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.ConsoleMessageAdded, presentationMessage); 295 309 } … … 324 338 breakpointsList.push(breakpointsMap[lineNumber]); 325 339 return breakpointsList; 340 }, 341 342 messagesForUISourceCode: function(uiSourceCode) 343 { 344 var rawSourceCode = uiSourceCode.rawSourceCode; 345 return rawSourceCode.messages; 326 346 }, 327 347 … … 496 516 { 497 517 if (this._uiSourceCode) 498 this._uiSourceCode. forceLoadContent(this._script);518 this._uiSourceCode.rawSourceCode.forceUpdateSourceMapping(); 499 519 }, 500 520 -
trunk/Source/WebCore/inspector/front-end/ScriptsPanel.js
r94167 r94560 672 672 _uiSourceCodeReplaced: function(event) 673 673 { 674 var oldUISourceCode = event.data.old SourceCode;675 var uiSourceCode = event.data. sourceCode;674 var oldUISourceCode = event.data.oldUISourceCode; 675 var uiSourceCode = event.data.uiSourceCode; 676 676 677 677 // Re-bind file select option from old source file to new one. 678 678 var option = oldUISourceCode._option; 679 if (!option) 680 return; 679 681 delete oldUISourceCode._option; 680 682 option._uiSourceCode = uiSourceCode; … … 692 694 var uiSourceCode = sourceFrame._uiSourceCode; 693 695 694 var messages = uiSourceCode.messages;696 var messages = this._presentationModel.messagesForUISourceCode(uiSourceCode); 695 697 for (var i = 0; i < messages.length; ++i) { 696 698 var message = messages[i]; -
trunk/Source/WebCore/inspector/front-end/SourceFile.js
r94532 r94560 44 44 if (script.sourceURL) 45 45 this._resource = WebInspector.networkManager.inflightResourceForURL(script.sourceURL) || WebInspector.resourceForURL(script.sourceURL); 46 this._requestContentCallbacks = [];47 46 48 47 this.id = id; … … 51 50 this.messages = []; 52 51 53 if (this._hasPendingResource()) 54 this._resource.addEventListener("finished", this._reload.bind(this)); 52 this._useTemporaryContent = this._resource && !this._resource.finished; 53 this._hasNewScripts = true; 54 if (!this._useTemporaryContent) 55 this._updateSourceMapping(); 56 else if (this._resource) 57 this._resource.addEventListener("finished", this._resourceFinished.bind(this)); 55 58 } 56 59 57 60 WebInspector.RawSourceCode.Events = { 58 UISourceCodeReplaced: "ui-source-code-replaced"61 SourceMappingUpdated: "source-mapping-updated" 59 62 } 60 63 … … 63 66 { 64 67 this._scripts.push(script); 68 this._hasNewScripts = true; 65 69 }, 66 70 … … 79 83 contentEdited: function() 80 84 { 81 this._reload(); 85 this._updateSourceMapping(); 86 }, 87 88 _resourceFinished: function() 89 { 90 this._useTemporaryContent = false; 91 this._updateSourceMapping(); 82 92 }, 83 93 … … 113 123 requestContent: function(callback) 114 124 { 115 if (this._contentLoaded) { 116 callback(this._mimeType, this._content); 117 return; 118 } 119 120 this._requestContentCallbacks.push(callback); 121 this._requestContent(); 125 // FIXME: remove this. 126 this._uiSourceCode.requestContent(callback); 122 127 }, 123 128 124 129 createSourceMappingIfNeeded: function(callback) 125 130 { 126 if (!this._formatted) { 131 // FIXME: remove createSourceMappingIfNeeded, client should listen to SourceMappingUpdated event instead. 132 if (this._uiSourceCode && !this._updatingSourceMapping) { 127 133 callback(); 128 134 return; 129 135 } 130 136 131 function didRequestContent() 132 { 137 function sourceMappingUpdated() 138 { 139 this.removeEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, sourceMappingUpdated, this); 133 140 callback(); 134 141 } 135 // Force content formatting to obtain the mapping. 136 this.requestContent(didRequestContent.bind(this)); 137 }, 138 139 _setContentProvider: function(contentProvider) 140 { 141 if (this._formatted) 142 this._contentProvider = new WebInspector.FormattedContentProvider(contentProvider, this._formatter); 143 else 144 this._contentProvider = contentProvider; 145 }, 146 147 forceLoadContent: function(script) 148 { 149 if (!this._hasPendingResource()) 142 this.addEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, sourceMappingUpdated, this); 143 }, 144 145 forceUpdateSourceMapping: function(script) 146 { 147 if (!this._useTemporaryContent || !this._hasNewScripts) 150 148 return; 151 152 if (!this._concatenatedScripts) 153 this._concatenatedScripts = {}; 154 if (this._concatenatedScripts[script.scriptId]) 149 this._hasNewScripts = false; 150 this._updateSourceMapping(); 151 }, 152 153 _updateSourceMapping: function() 154 { 155 if (this._updatingSourceMapping) { 156 this._updateNeeded = true; 155 157 return; 156 for (var i = 0; i < this._scripts.length; ++i) 157 this._concatenatedScripts[this._scripts[i].scriptId] = true; 158 159 this._reload(); 160 161 if (!this._contentRequested) { 162 this._contentRequested = true; 163 this._loadAndConcatenateScriptsContent(); 164 } 165 }, 166 167 _reload: function() 168 { 169 if (this._contentLoaded) { 170 this._contentLoaded = false; 171 // FIXME: create another UISourceCode instance here, UISourceCode should be immutable. 172 this.dispatchEventToListeners(WebInspector.RawSourceCode.Events.UISourceCodeReplaced, { oldSourceCode: this, sourceCode: this }); 173 } else if (this._contentRequested) 174 this._reloadContent = true; 175 else if (this._requestContentCallbacks.length) 176 this._requestContent(); 177 }, 178 179 _requestContent: function() 180 { 181 if (this._contentRequested) 158 } 159 this._updatingSourceMapping = true; 160 this._updateNeeded = false; 161 162 var originalContentProvider = this._createContentProvider(); 163 this._createSourceMapping(originalContentProvider, didCreateSourceMapping.bind(this)); 164 165 function didCreateSourceMapping(contentProvider, mapping) 166 { 167 this._updatingSourceMapping = false; 168 if (!this._updateNeeded) 169 this._saveSourceMapping(contentProvider, mapping); 170 else 171 this._updateSourceMapping(); 172 } 173 }, 174 175 _createContentProvider: function() 176 { 177 if (this._resource && this._resource.finished) 178 return new WebInspector.ResourceContentProvider(this._resource); 179 if (this._scripts.length === 1 && !this._scripts[0].lineOffset && !this._scripts[0].columnOffset) 180 return new WebInspector.ScriptContentProvider(this._scripts[0]); 181 return new WebInspector.ConcatenatedScriptsContentProvider(this._scripts); 182 }, 183 184 _createSourceMapping: function(originalContentProvider, callback) 185 { 186 if (!this._formatted) { 187 setTimeout(callback.bind(null, originalContentProvider, null), 0); 182 188 return; 183 184 this._contentRequested = true; 185 if (this._resource && this._resource.finished) 186 this._loadResourceContent(this._resource); 187 else if (!this._resource) 188 this._loadScriptContent(); 189 else if (this._concatenatedScripts) 190 this._loadAndConcatenateScriptsContent(); 191 else 192 this._contentRequested = false; 193 }, 194 195 _loadResourceContent: function(resource) 196 { 197 this._setContentProvider(new WebInspector.ResourceContentProvider(resource)); 198 this._contentProvider.requestContent(this._didRequestContent.bind(this)); 199 }, 200 201 _loadScriptContent: function() 202 { 203 this._setContentProvider(new WebInspector.ScriptContentProvider(this._scripts[0])); 204 this._contentProvider.requestContent(this._didRequestContent.bind(this)); 205 }, 206 207 _loadAndConcatenateScriptsContent: function() 208 { 209 if (this._scripts.length === 1 && !this._scripts[0].lineOffset && !this._scripts[0].columnOffset) 210 this._setContentProvider(new WebInspector.ScriptContentProvider(this._scripts[0])); 211 else 212 this._setContentProvider(new WebInspector.ConcatenatedScriptsContentProvider(this._scripts)); 213 this._contentProvider.requestContent(this._didRequestContent.bind(this)); 214 }, 215 216 _didRequestContent: function(mimeType, content) 217 { 218 this._contentLoaded = true; 219 this._contentRequested = false; 220 this._mimeType = mimeType; 221 this._content = content; 222 this._mapping = this._contentProvider.mapping; 223 224 for (var i = 0; i < this._requestContentCallbacks.length; ++i) 225 this._requestContentCallbacks[i](mimeType, content); 226 this._requestContentCallbacks = []; 227 228 if (this._reloadContent) 229 this._reload(); 230 }, 231 232 _hasPendingResource: function() 233 { 234 return this._resource && !this._resource.finished; 189 } 190 191 function didRequestContent(mimeType, content) 192 { 193 function didFormatContent(formattedContent, mapping) 194 { 195 var contentProvider = new WebInspector.StaticContentProvider(mimeType, formattedContent) 196 callback(contentProvider, mapping); 197 } 198 this._formatter.formatContent(mimeType, content, didFormatContent.bind(this)); 199 } 200 originalContentProvider.requestContent(didRequestContent.bind(this)); 201 }, 202 203 _saveSourceMapping: function(contentProvider, mapping) 204 { 205 var oldUISourceCode; 206 if (this._uiSourceCode) 207 oldUISourceCode = this; 208 var uiSourceCodeId = (this._formatted ? "deobfuscated:" : "") + (this._scripts[0].sourceURL || this._scripts[0].scriptId); 209 this._uiSourceCode = new WebInspector.UISourceCode(uiSourceCodeId, this.url, this.isContentScript, this, contentProvider); 210 this._mapping = mapping; 211 this.dispatchEventToListeners(WebInspector.RawSourceCode.Events.SourceMappingUpdated, { oldUISourceCode: oldUISourceCode }); 235 212 } 236 213 } … … 365 342 366 343 367 WebInspector. FormattedContentProvider = function(contentProvider, formatter)368 { 369 this._ contentProvider = contentProvider;370 this._ formatter = formatter;344 WebInspector.StaticContentProvider = function(mimeType, content) 345 { 346 this._mimeType = mimeType; 347 this._content = content; 371 348 }; 372 349 373 WebInspector. FormattedContentProvider.prototype = {350 WebInspector.StaticContentProvider.prototype = { 374 351 requestContent: function(callback) 375 352 { 376 function didRequestContent(mimeType, content) 377 { 378 function didFormatContent(formattedContent, mapping) 379 { 380 this.mapping = mapping; 381 callback(mimeType, formattedContent); 382 } 383 this._formatter.formatContent(mimeType, content, didFormatContent.bind(this)); 384 } 385 this._contentProvider.requestContent(didRequestContent.bind(this)); 353 callback(this._mimeType, this._content); 386 354 } 387 355 } 388 356 389 WebInspector. FormattedContentProvider.prototype.__proto__ = WebInspector.ContentProvider.prototype;357 WebInspector.StaticContentProvider.prototype.__proto__ = WebInspector.ContentProvider.prototype;
Note: See TracChangeset
for help on using the changeset viewer.