OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
12 * | 12 * |
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR | 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 */ | 24 */ |
25 | 25 |
26 WebInspector.SourceFrame = function(element, addBreakpointDelegate) | 26 WebInspector.SourceFrame = function(element, addBreakpointDelegate) |
27 { | 27 { |
28 this.messages = []; | 28 this.messages = []; |
29 this.breakpoints = []; | 29 this.breakpoints = []; |
| 30 this._shortcuts = {}; |
30 | 31 |
31 this.addBreakpointDelegate = addBreakpointDelegate; | 32 this.addBreakpointDelegate = addBreakpointDelegate; |
32 | 33 |
33 this.element = element || document.createElement("iframe"); | 34 this.element = element || document.createElement("iframe"); |
34 this.element.addStyleClass("source-view-frame"); | 35 this.element.addStyleClass("source-view-frame"); |
35 this.element.setAttribute("viewsource", "true"); | 36 this.element.setAttribute("viewsource", "true"); |
36 | 37 |
37 this.element.addEventListener("load", this._loaded.bind(this), false); | 38 this.element.addEventListener("load", this._loaded.bind(this), false); |
38 } | 39 } |
39 | 40 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 while (sourceRow) { | 104 while (sourceRow) { |
104 ++lineNumber; | 105 ++lineNumber; |
105 sourceRow = sourceRow.previousSibling; | 106 sourceRow = sourceRow.previousSibling; |
106 } | 107 } |
107 | 108 |
108 return lineNumber; | 109 return lineNumber; |
109 }, | 110 }, |
110 | 111 |
111 revealLine: function(lineNumber) | 112 revealLine: function(lineNumber) |
112 { | 113 { |
| 114 if (!this._isContentLoaded()) { |
| 115 this._lineNumberToReveal = lineNumber; |
| 116 return; |
| 117 } |
| 118 |
113 var row = this.sourceRow(lineNumber); | 119 var row = this.sourceRow(lineNumber); |
114 if (row) | 120 if (row) |
115 row.scrollIntoViewIfNeeded(true); | 121 row.scrollIntoViewIfNeeded(true); |
116 }, | 122 }, |
117 | 123 |
118 addBreakpoint: function(breakpoint) | 124 addBreakpoint: function(breakpoint) |
119 { | 125 { |
120 this.breakpoints.push(breakpoint); | 126 this.breakpoints.push(breakpoint); |
121 breakpoint.addEventListener("enabled", this._breakpointEnableChanged, th
is); | 127 breakpoint.addEventListener("enabled", this._breakpointEnableChanged, th
is); |
122 breakpoint.addEventListener("disabled", this._breakpointEnableChanged, t
his); | 128 breakpoint.addEventListener("disabled", this._breakpointEnableChanged, t
his); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 } | 171 } |
166 }, | 172 }, |
167 | 173 |
168 _highlightLineEnds: function(event) | 174 _highlightLineEnds: function(event) |
169 { | 175 { |
170 event.target.parentNode.removeStyleClass("webkit-highlighted-line"); | 176 event.target.parentNode.removeStyleClass("webkit-highlighted-line"); |
171 }, | 177 }, |
172 | 178 |
173 highlightLine: function(lineNumber) | 179 highlightLine: function(lineNumber) |
174 { | 180 { |
| 181 if (!this._isContentLoaded()) { |
| 182 this._lineNumberToHighlight = lineNumber; |
| 183 return; |
| 184 } |
| 185 |
175 var sourceRow = this.sourceRow(lineNumber); | 186 var sourceRow = this.sourceRow(lineNumber); |
176 if (!sourceRow) | 187 if (!sourceRow) |
177 return; | 188 return; |
178 var line = sourceRow.getElementsByClassName('webkit-line-content')[0]; | 189 var line = sourceRow.getElementsByClassName('webkit-line-content')[0]; |
179 // Trick to reset the animation if the user clicks on the same link | 190 // Trick to reset the animation if the user clicks on the same link |
180 // Using a timeout to avoid coalesced style updates | 191 // Using a timeout to avoid coalesced style updates |
181 line.style.setProperty("-webkit-animation-name", "none"); | 192 line.style.setProperty("-webkit-animation-name", "none"); |
182 setTimeout(function () { | 193 setTimeout(function () { |
183 line.style.removeProperty("-webkit-animation-name"); | 194 line.style.removeProperty("-webkit-animation-name"); |
184 sourceRow.addStyleClass("webkit-highlighted-line"); | 195 sourceRow.addStyleClass("webkit-highlighted-line"); |
185 }, 0); | 196 }, 0); |
186 }, | 197 }, |
187 | 198 |
188 _loaded: function() | 199 _loaded: function() |
189 { | 200 { |
190 WebInspector.addMainEventListeners(this.element.contentDocument); | 201 WebInspector.addMainEventListeners(this.element.contentDocument); |
191 this.element.contentDocument.addEventListener("mousedown", this._documen
tMouseDown.bind(this), true); | 202 this.element.contentDocument.addEventListener("mousedown", this._documen
tMouseDown.bind(this), true); |
| 203 this.element.contentDocument.addEventListener("keydown", this._documentK
eyDown.bind(this), true); |
| 204 this.element.contentDocument.addEventListener("keyup", WebInspector.docu
mentKeyUp.bind(WebInspector), true); |
192 this.element.contentDocument.addEventListener("webkitAnimationEnd", this
._highlightLineEnds.bind(this), false); | 205 this.element.contentDocument.addEventListener("webkitAnimationEnd", this
._highlightLineEnds.bind(this), false); |
193 | 206 |
| 207 // Register 'eval' shortcut. |
| 208 var isMac = InspectorController.platform().indexOf("mac-") === 0; |
| 209 var platformSpecificModifier = isMac ? WebInspector.KeyboardShortcut.Mod
ifiers.Meta : WebInspector.KeyboardShortcut.Modifiers.Ctrl; |
| 210 var shortcut = WebInspector.KeyboardShortcut.makeKey(69 /* 'E' */, platf
ormSpecificModifier | WebInspector.KeyboardShortcut.Modifiers.Shift); |
| 211 this._shortcuts[shortcut] = this._evalSelectionInCallFrame.bind(this); |
| 212 |
194 var headElement = this.element.contentDocument.getElementsByTagName("hea
d")[0]; | 213 var headElement = this.element.contentDocument.getElementsByTagName("hea
d")[0]; |
195 if (!headElement) { | 214 if (!headElement) { |
196 headElement = this.element.contentDocument.createElement("head"); | 215 headElement = this.element.contentDocument.createElement("head"); |
197 this.element.contentDocument.documentElement.insertBefore(headElemen
t, this.element.contentDocument.documentElement.firstChild); | 216 this.element.contentDocument.documentElement.insertBefore(headElemen
t, this.element.contentDocument.documentElement.firstChild); |
198 } | 217 } |
199 | 218 |
200 var styleElement = this.element.contentDocument.createElement("style"); | 219 var styleElement = this.element.contentDocument.createElement("style"); |
201 headElement.appendChild(styleElement); | 220 headElement.appendChild(styleElement); |
202 | 221 |
203 // Add these style rules here since they are specific to the Inspector.
They also behave oddly and not | 222 // Add these style rules here since they are specific to the Inspector.
They also behave oddly and not |
(...skipping 27 matching lines...) Expand all Loading... |
231 this.element.contentWindow.Node.prototype.enclosingNodeOrSelfWithNodeNam
eInArray = Node.prototype.enclosingNodeOrSelfWithNodeNameInArray; | 250 this.element.contentWindow.Node.prototype.enclosingNodeOrSelfWithNodeNam
eInArray = Node.prototype.enclosingNodeOrSelfWithNodeNameInArray; |
232 | 251 |
233 this._addExistingMessagesToSource(); | 252 this._addExistingMessagesToSource(); |
234 this._addExistingBreakpointsToSource(); | 253 this._addExistingBreakpointsToSource(); |
235 this._updateExecutionLine(); | 254 this._updateExecutionLine(); |
236 if (this._executionLine) | 255 if (this._executionLine) |
237 this.revealLine(this._executionLine); | 256 this.revealLine(this._executionLine); |
238 | 257 |
239 if (this.autoSizesToFitContentHeight) | 258 if (this.autoSizesToFitContentHeight) |
240 this.sizeToFitContentHeight(); | 259 this.sizeToFitContentHeight(); |
| 260 |
| 261 if (this._lineNumberToReveal) { |
| 262 this.revealLine(this._lineNumberToReveal); |
| 263 delete this._lineNumberToReveal; |
| 264 } |
| 265 |
| 266 if (this._lineNumberToHighlight) { |
| 267 this.highlightLine(this._lineNumberToHighlight); |
| 268 delete this._lineNumberToHighlight; |
| 269 } |
| 270 |
| 271 this.dispatchEventToListeners("content loaded"); |
| 272 }, |
| 273 |
| 274 _isContentLoaded: function() { |
| 275 var doc = this.element.contentDocument; |
| 276 return doc && doc.getElementsByTagName("table")[0]; |
241 }, | 277 }, |
242 | 278 |
243 _windowResized: function(event) | 279 _windowResized: function(event) |
244 { | 280 { |
245 if (!this._autoSizesToFitContentHeight) | 281 if (!this._autoSizesToFitContentHeight) |
246 return; | 282 return; |
247 this.sizeToFitContentHeight(); | 283 this.sizeToFitContentHeight(); |
248 }, | 284 }, |
249 | 285 |
250 _documentMouseDown: function(event) | 286 _documentMouseDown: function(event) |
251 { | 287 { |
252 if (!event.target.hasStyleClass("webkit-line-number")) | 288 if (!event.target.hasStyleClass("webkit-line-number")) |
253 return; | 289 return; |
254 | 290 |
255 var sourceRow = event.target.enclosingNodeOrSelfWithNodeName("tr"); | 291 var sourceRow = event.target.enclosingNodeOrSelfWithNodeName("tr"); |
256 if (sourceRow._breakpointObject) | 292 if (sourceRow._breakpointObject && sourceRow._breakpointObject.enabled) |
257 sourceRow._breakpointObject.enabled = !sourceRow._breakpointObject.e
nabled; | 293 sourceRow._breakpointObject.enabled = false; |
| 294 else if (sourceRow._breakpointObject) |
| 295 WebInspector.panels.scripts.removeBreakpoint(sourceRow._breakpointOb
ject); |
258 else if (this.addBreakpointDelegate) | 296 else if (this.addBreakpointDelegate) |
259 this.addBreakpointDelegate(this.lineNumberForSourceRow(sourceRow)); | 297 this.addBreakpointDelegate(this.lineNumberForSourceRow(sourceRow)); |
260 }, | 298 }, |
261 | 299 |
| 300 _documentKeyDown: function(event) |
| 301 { |
| 302 var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event); |
| 303 var handler = this._shortcuts[shortcut]; |
| 304 if (handler) { |
| 305 handler(event); |
| 306 event.preventDefault(); |
| 307 } else { |
| 308 WebInspector.documentKeyDown(event); |
| 309 } |
| 310 }, |
| 311 |
| 312 _evalSelectionInCallFrame: function(event) |
| 313 { |
| 314 if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused) |
| 315 return; |
| 316 |
| 317 var selection = this.element.contentWindow.getSelection(); |
| 318 if (!selection.rangeCount) |
| 319 return; |
| 320 |
| 321 var expression = selection.getRangeAt(0).toString().trimWhitespace(); |
| 322 WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, fals
e, function(result, exception) { |
| 323 WebInspector.showConsole(); |
| 324 var commandMessage = new WebInspector.ConsoleCommand(expression); |
| 325 WebInspector.console.addMessage(commandMessage); |
| 326 WebInspector.console.addMessage(new WebInspector.ConsoleCommandResul
t(result, exception, commandMessage)); |
| 327 }); |
| 328 }, |
| 329 |
262 _breakpointEnableChanged: function(event) | 330 _breakpointEnableChanged: function(event) |
263 { | 331 { |
264 var breakpoint = event.target; | 332 var breakpoint = event.target; |
265 var sourceRow = this.sourceRow(breakpoint.line); | 333 var sourceRow = this.sourceRow(breakpoint.line); |
266 if (!sourceRow) | 334 if (!sourceRow) |
267 return; | 335 return; |
268 | 336 |
269 sourceRow.addStyleClass("webkit-breakpoint"); | 337 sourceRow.addStyleClass("webkit-breakpoint"); |
270 | 338 |
271 if (breakpoint.enabled) | 339 if (breakpoint.enabled) |
(...skipping 26 matching lines...) Expand all Loading... |
298 for (var i = 0; i < length; ++i) | 366 for (var i = 0; i < length; ++i) |
299 this._addBreakpointToSource(this.breakpoints[i]); | 367 this._addBreakpointToSource(this.breakpoints[i]); |
300 }, | 368 }, |
301 | 369 |
302 _addBreakpointToSource: function(breakpoint) | 370 _addBreakpointToSource: function(breakpoint) |
303 { | 371 { |
304 var sourceRow = this.sourceRow(breakpoint.line); | 372 var sourceRow = this.sourceRow(breakpoint.line); |
305 if (!sourceRow) | 373 if (!sourceRow) |
306 return; | 374 return; |
307 | 375 |
| 376 breakpoint.sourceText = sourceRow.getElementsByClassName('webkit-line-co
ntent')[0].textContent; |
| 377 |
308 this._drawBreakpointImagesIfNeeded(); | 378 this._drawBreakpointImagesIfNeeded(); |
309 | 379 |
310 sourceRow._breakpointObject = breakpoint; | 380 sourceRow._breakpointObject = breakpoint; |
311 | 381 |
312 sourceRow.addStyleClass("webkit-breakpoint"); | 382 sourceRow.addStyleClass("webkit-breakpoint"); |
313 if (!breakpoint.enabled) | 383 if (!breakpoint.enabled) |
314 sourceRow.addStyleClass("webkit-breakpoint-disabled"); | 384 sourceRow.addStyleClass("webkit-breakpoint-disabled"); |
315 }, | 385 }, |
316 | 386 |
317 _removeBreakpointFromSource: function(breakpoint) | 387 _removeBreakpointFromSource: function(breakpoint) |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 } | 764 } |
695 } | 765 } |
696 | 766 |
697 processChunk(); | 767 processChunk(); |
698 | 768 |
699 var processChunkInterval = setInterval(processChunk, 25); | 769 var processChunkInterval = setInterval(processChunk, 25); |
700 } | 770 } |
701 } | 771 } |
702 | 772 |
703 WebInspector.SourceFrame.prototype.__proto__ = WebInspector.Object.prototype; | 773 WebInspector.SourceFrame.prototype.__proto__ = WebInspector.Object.prototype; |
OLD | NEW |