OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google 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 are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
11 * copyright notice, this list of conditions and the following disclaimer | 11 * copyright notice, this list of conditions and the following disclaimer |
12 * in the documentation and/or other materials provided with the | 12 * in the documentation and/or other materials provided with the |
13 * distribution. | 13 * distribution. |
14 * * Neither the name of Google Inc. nor the names of its | 14 * * Neither the name of Google Inc. nor the names of its |
15 * contributors may be used to endorse or promote products derived from | 15 * contributors may be used to endorse or promote products derived from |
16 * this software without specific prior written permission. | 16 * this software without specific prior written permission. |
17 * | 17 * |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | |
31 /** | 30 /** |
32 * @constructor | |
33 * @extends {WebInspector.Object} | |
34 * @implements {WebInspector.TargetManager.Observer} | 31 * @implements {WebInspector.TargetManager.Observer} |
35 * @param {?WebInspector.Setting} breakpointsSetting | 32 * @unrestricted |
36 * @param {!WebInspector.Workspace} workspace | |
37 * @param {!WebInspector.TargetManager} targetManager | |
38 * @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding | |
39 */ | 33 */ |
40 WebInspector.BreakpointManager = function(breakpointsSetting, workspace, targetM
anager, debuggerWorkspaceBinding) | 34 WebInspector.BreakpointManager = class extends WebInspector.Object { |
41 { | 35 /** |
| 36 * @param {?WebInspector.Setting} breakpointsSetting |
| 37 * @param {!WebInspector.Workspace} workspace |
| 38 * @param {!WebInspector.TargetManager} targetManager |
| 39 * @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding |
| 40 */ |
| 41 constructor(breakpointsSetting, workspace, targetManager, debuggerWorkspaceBin
ding) { |
| 42 super(); |
42 this._storage = new WebInspector.BreakpointManager.Storage(this, breakpoints
Setting); | 43 this._storage = new WebInspector.BreakpointManager.Storage(this, breakpoints
Setting); |
43 this._workspace = workspace; | 44 this._workspace = workspace; |
44 this._targetManager = targetManager; | 45 this._targetManager = targetManager; |
45 this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; | 46 this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; |
46 | 47 |
47 this._breakpointsActive = true; | 48 this._breakpointsActive = true; |
48 this._breakpointsForUISourceCode = new Map(); | 49 this._breakpointsForUISourceCode = new Map(); |
49 this._breakpointsForPrimaryUISourceCode = new Map(); | 50 this._breakpointsForPrimaryUISourceCode = new Map(); |
50 /** @type {!Multimap.<string, !WebInspector.BreakpointManager.Breakpoint>} *
/ | 51 /** @type {!Multimap.<string, !WebInspector.BreakpointManager.Breakpoint>} *
/ |
51 this._provisionalBreakpoints = new Multimap(); | 52 this._provisionalBreakpoints = new Multimap(); |
52 | 53 |
53 this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemove
d, this._projectRemoved, this); | 54 this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemove
d, this._projectRemoved, this); |
54 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeA
dded, this._uiSourceCodeAdded, this); | 55 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeA
dded, this._uiSourceCodeAdded, this); |
55 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeR
emoved, this._uiSourceCodeRemoved, this); | 56 this._workspace.addEventListener( |
| 57 WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRem
oved, this); |
| 58 } |
| 59 |
| 60 /** |
| 61 * @param {string} sourceFileId |
| 62 * @param {number} lineNumber |
| 63 * @param {number} columnNumber |
| 64 * @return {string} |
| 65 */ |
| 66 static _breakpointStorageId(sourceFileId, lineNumber, columnNumber) { |
| 67 if (!sourceFileId) |
| 68 return ''; |
| 69 return sourceFileId + ':' + lineNumber + ':' + columnNumber; |
| 70 } |
| 71 |
| 72 /** |
| 73 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 74 * @return {string} |
| 75 */ |
| 76 _sourceFileId(uiSourceCode) { |
| 77 // TODO(lushnikov): _sourceFileId is not needed any more. |
| 78 return uiSourceCode.url(); |
| 79 } |
| 80 |
| 81 /** |
| 82 * @override |
| 83 * @param {!WebInspector.Target} target |
| 84 */ |
| 85 targetAdded(target) { |
| 86 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); |
| 87 if (debuggerModel && !this._breakpointsActive) |
| 88 debuggerModel.setBreakpointsActive(this._breakpointsActive); |
| 89 } |
| 90 |
| 91 /** |
| 92 * @override |
| 93 * @param {!WebInspector.Target} target |
| 94 */ |
| 95 targetRemoved(target) { |
| 96 } |
| 97 |
| 98 /** |
| 99 * @param {string} sourceFileId |
| 100 * @return {!Map.<string, !WebInspector.BreakpointManager.Breakpoint>} |
| 101 */ |
| 102 _provisionalBreakpointsForSourceFileId(sourceFileId) { |
| 103 var result = new Map(); |
| 104 var breakpoints = this._provisionalBreakpoints.get(sourceFileId).valuesArray
(); |
| 105 for (var i = 0; i < breakpoints.length; ++i) |
| 106 result.set(breakpoints[i]._breakpointStorageId(), breakpoints[i]); |
| 107 return result; |
| 108 } |
| 109 |
| 110 removeProvisionalBreakpointsForTest() { |
| 111 var breakpoints = this._provisionalBreakpoints.valuesArray(); |
| 112 for (var i = 0; i < breakpoints.length; ++i) |
| 113 breakpoints[i].remove(); |
| 114 this._provisionalBreakpoints.clear(); |
| 115 } |
| 116 |
| 117 /** |
| 118 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 119 */ |
| 120 _restoreBreakpoints(uiSourceCode) { |
| 121 var sourceFileId = this._sourceFileId(uiSourceCode); |
| 122 if (!sourceFileId) |
| 123 return; |
| 124 |
| 125 this._storage.mute(); |
| 126 var breakpointItems = this._storage.breakpointItems(this._sourceFileId(uiSou
rceCode)); |
| 127 var provisionalBreakpoints = this._provisionalBreakpointsForSourceFileId(sou
rceFileId); |
| 128 for (var i = 0; i < breakpointItems.length; ++i) { |
| 129 var breakpointItem = breakpointItems[i]; |
| 130 var itemStorageId = WebInspector.BreakpointManager._breakpointStorageId( |
| 131 breakpointItem.sourceFileId, breakpointItem.lineNumber, breakpointItem
.columnNumber); |
| 132 var provisionalBreakpoint = provisionalBreakpoints.get(itemStorageId); |
| 133 if (provisionalBreakpoint) { |
| 134 if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode)) |
| 135 this._breakpointsForPrimaryUISourceCode.set(uiSourceCode, []); |
| 136 this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(provision
alBreakpoint); |
| 137 provisionalBreakpoint._updateBreakpoint(); |
| 138 } else { |
| 139 this._innerSetBreakpoint( |
| 140 uiSourceCode, breakpointItem.lineNumber, breakpointItem.columnNumber
, breakpointItem.condition, |
| 141 breakpointItem.enabled); |
| 142 } |
| 143 } |
| 144 this._provisionalBreakpoints.removeAll(sourceFileId); |
| 145 this._storage.unmute(); |
| 146 } |
| 147 |
| 148 /** |
| 149 * @param {!WebInspector.Event} event |
| 150 */ |
| 151 _uiSourceCodeAdded(event) { |
| 152 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data); |
| 153 this._restoreBreakpoints(uiSourceCode); |
| 154 if (uiSourceCode.contentType().hasScripts()) |
| 155 uiSourceCode.addEventListener( |
| 156 WebInspector.UISourceCode.Events.SourceMappingChanged, this._uiSourceC
odeMappingChanged, this); |
| 157 } |
| 158 |
| 159 /** |
| 160 * @param {!WebInspector.Event} event |
| 161 */ |
| 162 _uiSourceCodeRemoved(event) { |
| 163 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data); |
| 164 this._removeUISourceCode(uiSourceCode); |
| 165 } |
| 166 |
| 167 /** |
| 168 * @param {!WebInspector.Event} event |
| 169 */ |
| 170 _uiSourceCodeMappingChanged(event) { |
| 171 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.target); |
| 172 var isIdentity = /** @type {boolean} */ (event.data.isIdentity); |
| 173 var target = /** @type {!WebInspector.Target} */ (event.data.target); |
| 174 if (isIdentity) |
| 175 return; |
| 176 var breakpoints = this._breakpointsForPrimaryUISourceCode.get(uiSourceCode)
|| []; |
| 177 for (var i = 0; i < breakpoints.length; ++i) |
| 178 breakpoints[i]._updateInDebuggerForTarget(target); |
| 179 } |
| 180 |
| 181 /** |
| 182 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 183 */ |
| 184 _removeUISourceCode(uiSourceCode) { |
| 185 var breakpoints = this._breakpointsForPrimaryUISourceCode.get(uiSourceCode)
|| []; |
| 186 var sourceFileId = this._sourceFileId(uiSourceCode); |
| 187 for (var i = 0; i < breakpoints.length; ++i) { |
| 188 breakpoints[i]._resetLocations(); |
| 189 if (breakpoints[i].enabled()) |
| 190 this._provisionalBreakpoints.set(sourceFileId, breakpoints[i]); |
| 191 } |
| 192 uiSourceCode.removeEventListener( |
| 193 WebInspector.UISourceCode.Events.SourceMappingChanged, this._uiSourceCod
eMappingChanged, this); |
| 194 this._breakpointsForPrimaryUISourceCode.remove(uiSourceCode); |
| 195 } |
| 196 |
| 197 /** |
| 198 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 199 * @param {number} lineNumber |
| 200 * @param {number} columnNumber |
| 201 * @param {string} condition |
| 202 * @param {boolean} enabled |
| 203 * @return {!WebInspector.BreakpointManager.Breakpoint} |
| 204 */ |
| 205 setBreakpoint(uiSourceCode, lineNumber, columnNumber, condition, enabled) { |
| 206 var uiLocation = new WebInspector.UILocation(uiSourceCode, lineNumber, colum
nNumber); |
| 207 var normalizedLocation = this._debuggerWorkspaceBinding.normalizeUILocation(
uiLocation); |
| 208 if (normalizedLocation.id() !== uiLocation.id()) { |
| 209 WebInspector.Revealer.reveal(normalizedLocation); |
| 210 uiLocation = normalizedLocation; |
| 211 } |
| 212 this.setBreakpointsActive(true); |
| 213 return this._innerSetBreakpoint( |
| 214 uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber,
condition, enabled); |
| 215 } |
| 216 |
| 217 /** |
| 218 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 219 * @param {number} lineNumber |
| 220 * @param {number} columnNumber |
| 221 * @param {string} condition |
| 222 * @param {boolean} enabled |
| 223 * @return {!WebInspector.BreakpointManager.Breakpoint} |
| 224 */ |
| 225 _innerSetBreakpoint(uiSourceCode, lineNumber, columnNumber, condition, enabled
) { |
| 226 var breakpoint = this.findBreakpoint(uiSourceCode, lineNumber, columnNumber)
; |
| 227 if (breakpoint) { |
| 228 breakpoint._updateState(condition, enabled); |
| 229 return breakpoint; |
| 230 } |
| 231 var projectId = uiSourceCode.project().id(); |
| 232 var path = uiSourceCode.url(); |
| 233 var sourceFileId = this._sourceFileId(uiSourceCode); |
| 234 breakpoint = new WebInspector.BreakpointManager.Breakpoint( |
| 235 this, projectId, path, sourceFileId, lineNumber, columnNumber, condition
, enabled); |
| 236 if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode)) |
| 237 this._breakpointsForPrimaryUISourceCode.set(uiSourceCode, []); |
| 238 this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(breakpoint); |
| 239 return breakpoint; |
| 240 } |
| 241 |
| 242 /** |
| 243 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 244 * @param {number} lineNumber |
| 245 * @param {number} columnNumber |
| 246 * @return {?WebInspector.BreakpointManager.Breakpoint} |
| 247 */ |
| 248 findBreakpoint(uiSourceCode, lineNumber, columnNumber) { |
| 249 var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); |
| 250 var lineBreakpoints = breakpoints ? breakpoints.get(String(lineNumber)) : nu
ll; |
| 251 var columnBreakpoints = lineBreakpoints ? lineBreakpoints.get(String(columnN
umber)) : null; |
| 252 return columnBreakpoints ? columnBreakpoints[0] : null; |
| 253 } |
| 254 |
| 255 /** |
| 256 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 257 * @param {number} lineNumber |
| 258 * @return {?WebInspector.BreakpointManager.Breakpoint} |
| 259 */ |
| 260 findBreakpointOnLine(uiSourceCode, lineNumber) { |
| 261 var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); |
| 262 var lineBreakpoints = breakpoints ? breakpoints.get(String(lineNumber)) : nu
ll; |
| 263 return lineBreakpoints ? lineBreakpoints.valuesArray()[0][0] : null; |
| 264 } |
| 265 |
| 266 /** |
| 267 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 268 * @return {!Array.<!WebInspector.BreakpointManager.Breakpoint>} |
| 269 */ |
| 270 breakpointsForUISourceCode(uiSourceCode) { |
| 271 var result = []; |
| 272 var uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSourceC
ode); |
| 273 var breakpoints = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.valuesAr
ray() : []; |
| 274 for (var i = 0; i < breakpoints.length; ++i) { |
| 275 var lineBreakpoints = breakpoints[i]; |
| 276 var columnBreakpointArrays = lineBreakpoints ? lineBreakpoints.valuesArray
() : []; |
| 277 result = result.concat.apply(result, columnBreakpointArrays); |
| 278 } |
| 279 return result; |
| 280 } |
| 281 |
| 282 /** |
| 283 * @return {!Array.<!WebInspector.BreakpointManager.Breakpoint>} |
| 284 */ |
| 285 allBreakpoints() { |
| 286 var result = []; |
| 287 var uiSourceCodes = this._breakpointsForUISourceCode.keysArray(); |
| 288 for (var i = 0; i < uiSourceCodes.length; ++i) |
| 289 result = result.concat(this.breakpointsForUISourceCode(uiSourceCodes[i])); |
| 290 return result; |
| 291 } |
| 292 |
| 293 /** |
| 294 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 295 * @return {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint,
uiLocation: !WebInspector.UILocation}>} |
| 296 */ |
| 297 breakpointLocationsForUISourceCode(uiSourceCode) { |
| 298 var uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSourceC
ode); |
| 299 var lineNumbers = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.keysArra
y() : []; |
| 300 var result = []; |
| 301 for (var i = 0; i < lineNumbers.length; ++i) { |
| 302 var lineBreakpoints = uiSourceCodeBreakpoints.get(lineNumbers[i]); |
| 303 var columnNumbers = lineBreakpoints.keysArray(); |
| 304 for (var j = 0; j < columnNumbers.length; ++j) { |
| 305 var columnBreakpoints = lineBreakpoints.get(columnNumbers[j]); |
| 306 var lineNumber = parseInt(lineNumbers[i], 10); |
| 307 var columnNumber = parseInt(columnNumbers[j], 10); |
| 308 for (var k = 0; k < columnBreakpoints.length; ++k) { |
| 309 var breakpoint = columnBreakpoints[k]; |
| 310 var uiLocation = uiSourceCode.uiLocation(lineNumber, columnNumber); |
| 311 result.push({breakpoint: breakpoint, uiLocation: uiLocation}); |
| 312 } |
| 313 } |
| 314 } |
| 315 return result; |
| 316 } |
| 317 |
| 318 /** |
| 319 * @return {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint,
uiLocation: !WebInspector.UILocation}>} |
| 320 */ |
| 321 allBreakpointLocations() { |
| 322 var result = []; |
| 323 var uiSourceCodes = this._breakpointsForUISourceCode.keysArray(); |
| 324 for (var i = 0; i < uiSourceCodes.length; ++i) |
| 325 result = result.concat(this.breakpointLocationsForUISourceCode(uiSourceCod
es[i])); |
| 326 return result; |
| 327 } |
| 328 |
| 329 /** |
| 330 * @param {boolean} toggleState |
| 331 */ |
| 332 toggleAllBreakpoints(toggleState) { |
| 333 var breakpoints = this.allBreakpoints(); |
| 334 for (var i = 0; i < breakpoints.length; ++i) |
| 335 breakpoints[i].setEnabled(toggleState); |
| 336 } |
| 337 |
| 338 removeAllBreakpoints() { |
| 339 var breakpoints = this.allBreakpoints(); |
| 340 for (var i = 0; i < breakpoints.length; ++i) |
| 341 breakpoints[i].remove(); |
| 342 } |
| 343 |
| 344 _projectRemoved(event) { |
| 345 var project = /** @type {!WebInspector.Project} */ (event.data); |
| 346 var uiSourceCodes = project.uiSourceCodes(); |
| 347 for (var i = 0; i < uiSourceCodes.length; ++i) |
| 348 this._removeUISourceCode(uiSourceCodes[i]); |
| 349 } |
| 350 |
| 351 /** |
| 352 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint |
| 353 * @param {boolean} removeFromStorage |
| 354 */ |
| 355 _removeBreakpoint(breakpoint, removeFromStorage) { |
| 356 var uiSourceCode = breakpoint.uiSourceCode(); |
| 357 var breakpoints = uiSourceCode ? this._breakpointsForPrimaryUISourceCode.get
(uiSourceCode) || [] : []; |
| 358 breakpoints.remove(breakpoint); |
| 359 if (removeFromStorage) |
| 360 this._storage._removeBreakpoint(breakpoint); |
| 361 this._provisionalBreakpoints.remove(breakpoint._sourceFileId, breakpoint); |
| 362 } |
| 363 |
| 364 /** |
| 365 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint |
| 366 * @param {!WebInspector.UILocation} uiLocation |
| 367 */ |
| 368 _uiLocationAdded(breakpoint, uiLocation) { |
| 369 var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCo
de); |
| 370 if (!breakpoints) { |
| 371 breakpoints = new Map(); |
| 372 this._breakpointsForUISourceCode.set(uiLocation.uiSourceCode, breakpoints)
; |
| 373 } |
| 374 var lineBreakpoints = breakpoints.get(String(uiLocation.lineNumber)); |
| 375 if (!lineBreakpoints) { |
| 376 lineBreakpoints = new Map(); |
| 377 breakpoints.set(String(uiLocation.lineNumber), lineBreakpoints); |
| 378 } |
| 379 var columnBreakpoints = lineBreakpoints.get(String(uiLocation.columnNumber))
; |
| 380 if (!columnBreakpoints) { |
| 381 columnBreakpoints = []; |
| 382 lineBreakpoints.set(String(uiLocation.columnNumber), columnBreakpoints); |
| 383 } |
| 384 columnBreakpoints.push(breakpoint); |
| 385 this.dispatchEventToListeners( |
| 386 WebInspector.BreakpointManager.Events.BreakpointAdded, {breakpoint: brea
kpoint, uiLocation: uiLocation}); |
| 387 } |
| 388 |
| 389 /** |
| 390 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint |
| 391 * @param {!WebInspector.UILocation} uiLocation |
| 392 */ |
| 393 _uiLocationRemoved(breakpoint, uiLocation) { |
| 394 var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCo
de); |
| 395 if (!breakpoints) |
| 396 return; |
| 397 |
| 398 var lineBreakpoints = breakpoints.get(String(uiLocation.lineNumber)); |
| 399 if (!lineBreakpoints) |
| 400 return; |
| 401 var columnBreakpoints = lineBreakpoints.get(String(uiLocation.columnNumber))
; |
| 402 if (!columnBreakpoints) |
| 403 return; |
| 404 columnBreakpoints.remove(breakpoint); |
| 405 if (!columnBreakpoints.length) |
| 406 lineBreakpoints.remove(String(uiLocation.columnNumber)); |
| 407 if (!lineBreakpoints.size) |
| 408 breakpoints.remove(String(uiLocation.lineNumber)); |
| 409 if (!breakpoints.size) |
| 410 this._breakpointsForUISourceCode.remove(uiLocation.uiSourceCode); |
| 411 this.dispatchEventToListeners( |
| 412 WebInspector.BreakpointManager.Events.BreakpointRemoved, {breakpoint: br
eakpoint, uiLocation: uiLocation}); |
| 413 } |
| 414 |
| 415 /** |
| 416 * @param {boolean} active |
| 417 */ |
| 418 setBreakpointsActive(active) { |
| 419 if (this._breakpointsActive === active) |
| 420 return; |
| 421 |
| 422 this._breakpointsActive = active; |
| 423 var debuggerModels = WebInspector.DebuggerModel.instances(); |
| 424 for (var i = 0; i < debuggerModels.length; ++i) |
| 425 debuggerModels[i].setBreakpointsActive(active); |
| 426 |
| 427 this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.Breakpoi
ntsActiveStateChanged, active); |
| 428 } |
| 429 |
| 430 /** |
| 431 * @return {boolean} |
| 432 */ |
| 433 breakpointsActive() { |
| 434 return this._breakpointsActive; |
| 435 } |
56 }; | 436 }; |
57 | 437 |
58 /** @enum {symbol} */ | 438 /** @enum {symbol} */ |
59 WebInspector.BreakpointManager.Events = { | 439 WebInspector.BreakpointManager.Events = { |
60 BreakpointAdded: Symbol("breakpoint-added"), | 440 BreakpointAdded: Symbol('breakpoint-added'), |
61 BreakpointRemoved: Symbol("breakpoint-removed"), | 441 BreakpointRemoved: Symbol('breakpoint-removed'), |
62 BreakpointsActiveStateChanged: Symbol("BreakpointsActiveStateChanged") | 442 BreakpointsActiveStateChanged: Symbol('BreakpointsActiveStateChanged') |
63 }; | 443 }; |
64 | 444 |
| 445 |
65 /** | 446 /** |
66 * @param {string} sourceFileId | 447 * @implements {WebInspector.TargetManager.Observer} |
67 * @param {number} lineNumber | 448 * @unrestricted |
68 * @param {number} columnNumber | |
69 * @return {string} | |
70 */ | 449 */ |
71 WebInspector.BreakpointManager._breakpointStorageId = function(sourceFileId, lin
eNumber, columnNumber) | 450 WebInspector.BreakpointManager.Breakpoint = class { |
72 { | 451 /** |
73 if (!sourceFileId) | 452 * @param {!WebInspector.BreakpointManager} breakpointManager |
74 return ""; | 453 * @param {string} projectId |
75 return sourceFileId + ":" + lineNumber + ":" + columnNumber; | 454 * @param {string} path |
76 }; | 455 * @param {string} sourceFileId |
77 | 456 * @param {number} lineNumber |
78 WebInspector.BreakpointManager.prototype = { | 457 * @param {number} columnNumber |
79 /** | 458 * @param {string} condition |
80 * @param {!WebInspector.UISourceCode} uiSourceCode | 459 * @param {boolean} enabled |
81 * @return {string} | 460 */ |
82 */ | 461 constructor(breakpointManager, projectId, path, sourceFileId, lineNumber, colu
mnNumber, condition, enabled) { |
83 _sourceFileId: function(uiSourceCode) | |
84 { | |
85 // TODO(lushnikov): _sourceFileId is not needed any more. | |
86 return uiSourceCode.url(); | |
87 }, | |
88 | |
89 /** | |
90 * @override | |
91 * @param {!WebInspector.Target} target | |
92 */ | |
93 targetAdded: function(target) | |
94 { | |
95 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); | |
96 if (debuggerModel && !this._breakpointsActive) | |
97 debuggerModel.setBreakpointsActive(this._breakpointsActive); | |
98 }, | |
99 | |
100 /** | |
101 * @override | |
102 * @param {!WebInspector.Target} target | |
103 */ | |
104 targetRemoved: function(target) { }, | |
105 | |
106 /** | |
107 * @param {string} sourceFileId | |
108 * @return {!Map.<string, !WebInspector.BreakpointManager.Breakpoint>} | |
109 */ | |
110 _provisionalBreakpointsForSourceFileId: function(sourceFileId) | |
111 { | |
112 var result = new Map(); | |
113 var breakpoints = this._provisionalBreakpoints.get(sourceFileId).valuesA
rray(); | |
114 for (var i = 0; i < breakpoints.length; ++i) | |
115 result.set(breakpoints[i]._breakpointStorageId(), breakpoints[i]); | |
116 return result; | |
117 }, | |
118 | |
119 removeProvisionalBreakpointsForTest: function() | |
120 { | |
121 var breakpoints = this._provisionalBreakpoints.valuesArray(); | |
122 for (var i = 0; i < breakpoints.length; ++i) | |
123 breakpoints[i].remove(); | |
124 this._provisionalBreakpoints.clear(); | |
125 }, | |
126 | |
127 /** | |
128 * @param {!WebInspector.UISourceCode} uiSourceCode | |
129 */ | |
130 _restoreBreakpoints: function(uiSourceCode) | |
131 { | |
132 var sourceFileId = this._sourceFileId(uiSourceCode); | |
133 if (!sourceFileId) | |
134 return; | |
135 | |
136 this._storage.mute(); | |
137 var breakpointItems = this._storage.breakpointItems(this._sourceFileId(u
iSourceCode)); | |
138 var provisionalBreakpoints = this._provisionalBreakpointsForSourceFileId
(sourceFileId); | |
139 for (var i = 0; i < breakpointItems.length; ++i) { | |
140 var breakpointItem = breakpointItems[i]; | |
141 var itemStorageId = WebInspector.BreakpointManager._breakpointStorag
eId(breakpointItem.sourceFileId, breakpointItem.lineNumber, breakpointItem.colum
nNumber); | |
142 var provisionalBreakpoint = provisionalBreakpoints.get(itemStorageId
); | |
143 if (provisionalBreakpoint) { | |
144 if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode)) | |
145 this._breakpointsForPrimaryUISourceCode.set(uiSourceCode, []
); | |
146 this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(p
rovisionalBreakpoint); | |
147 provisionalBreakpoint._updateBreakpoint(); | |
148 } else { | |
149 this._innerSetBreakpoint(uiSourceCode, breakpointItem.lineNumber
, breakpointItem.columnNumber, breakpointItem.condition, breakpointItem.enabled)
; | |
150 } | |
151 } | |
152 this._provisionalBreakpoints.removeAll(sourceFileId); | |
153 this._storage.unmute(); | |
154 }, | |
155 | |
156 /** | |
157 * @param {!WebInspector.Event} event | |
158 */ | |
159 _uiSourceCodeAdded: function(event) | |
160 { | |
161 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data
); | |
162 this._restoreBreakpoints(uiSourceCode); | |
163 if (uiSourceCode.contentType().hasScripts()) | |
164 uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.Sourc
eMappingChanged, this._uiSourceCodeMappingChanged, this); | |
165 }, | |
166 | |
167 /** | |
168 * @param {!WebInspector.Event} event | |
169 */ | |
170 _uiSourceCodeRemoved: function(event) | |
171 { | |
172 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data
); | |
173 this._removeUISourceCode(uiSourceCode); | |
174 }, | |
175 | |
176 /** | |
177 * @param {!WebInspector.Event} event | |
178 */ | |
179 _uiSourceCodeMappingChanged: function(event) | |
180 { | |
181 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.targ
et); | |
182 var isIdentity = /** @type {boolean} */ (event.data.isIdentity); | |
183 var target = /** @type {!WebInspector.Target} */ (event.data.target); | |
184 if (isIdentity) | |
185 return; | |
186 var breakpoints = this._breakpointsForPrimaryUISourceCode.get(uiSourceCo
de) || []; | |
187 for (var i = 0; i < breakpoints.length; ++i) | |
188 breakpoints[i]._updateInDebuggerForTarget(target); | |
189 }, | |
190 | |
191 /** | |
192 * @param {!WebInspector.UISourceCode} uiSourceCode | |
193 */ | |
194 _removeUISourceCode: function(uiSourceCode) | |
195 { | |
196 var breakpoints = this._breakpointsForPrimaryUISourceCode.get(uiSourceCo
de) || []; | |
197 var sourceFileId = this._sourceFileId(uiSourceCode); | |
198 for (var i = 0; i < breakpoints.length; ++i) { | |
199 breakpoints[i]._resetLocations(); | |
200 if (breakpoints[i].enabled()) | |
201 this._provisionalBreakpoints.set(sourceFileId, breakpoints[i]); | |
202 } | |
203 uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.Source
MappingChanged, this._uiSourceCodeMappingChanged, this); | |
204 this._breakpointsForPrimaryUISourceCode.remove(uiSourceCode); | |
205 }, | |
206 | |
207 /** | |
208 * @param {!WebInspector.UISourceCode} uiSourceCode | |
209 * @param {number} lineNumber | |
210 * @param {number} columnNumber | |
211 * @param {string} condition | |
212 * @param {boolean} enabled | |
213 * @return {!WebInspector.BreakpointManager.Breakpoint} | |
214 */ | |
215 setBreakpoint: function(uiSourceCode, lineNumber, columnNumber, condition, e
nabled) | |
216 { | |
217 var uiLocation = new WebInspector.UILocation(uiSourceCode, lineNumber, c
olumnNumber); | |
218 var normalizedLocation = this._debuggerWorkspaceBinding.normalizeUILocat
ion(uiLocation); | |
219 if (normalizedLocation.id() !== uiLocation.id()) { | |
220 WebInspector.Revealer.reveal(normalizedLocation); | |
221 uiLocation = normalizedLocation; | |
222 } | |
223 this.setBreakpointsActive(true); | |
224 return this._innerSetBreakpoint(uiLocation.uiSourceCode, uiLocation.line
Number, uiLocation.columnNumber, condition, enabled); | |
225 }, | |
226 | |
227 /** | |
228 * @param {!WebInspector.UISourceCode} uiSourceCode | |
229 * @param {number} lineNumber | |
230 * @param {number} columnNumber | |
231 * @param {string} condition | |
232 * @param {boolean} enabled | |
233 * @return {!WebInspector.BreakpointManager.Breakpoint} | |
234 */ | |
235 _innerSetBreakpoint: function(uiSourceCode, lineNumber, columnNumber, condit
ion, enabled) | |
236 { | |
237 var breakpoint = this.findBreakpoint(uiSourceCode, lineNumber, columnNum
ber); | |
238 if (breakpoint) { | |
239 breakpoint._updateState(condition, enabled); | |
240 return breakpoint; | |
241 } | |
242 var projectId = uiSourceCode.project().id(); | |
243 var path = uiSourceCode.url(); | |
244 var sourceFileId = this._sourceFileId(uiSourceCode); | |
245 breakpoint = new WebInspector.BreakpointManager.Breakpoint(this, project
Id, path, sourceFileId, lineNumber, columnNumber, condition, enabled); | |
246 if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode)) | |
247 this._breakpointsForPrimaryUISourceCode.set(uiSourceCode, []); | |
248 this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(breakpoin
t); | |
249 return breakpoint; | |
250 }, | |
251 | |
252 /** | |
253 * @param {!WebInspector.UISourceCode} uiSourceCode | |
254 * @param {number} lineNumber | |
255 * @param {number} columnNumber | |
256 * @return {?WebInspector.BreakpointManager.Breakpoint} | |
257 */ | |
258 findBreakpoint: function(uiSourceCode, lineNumber, columnNumber) | |
259 { | |
260 var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); | |
261 var lineBreakpoints = breakpoints ? breakpoints.get(String(lineNumber))
: null; | |
262 var columnBreakpoints = lineBreakpoints ? lineBreakpoints.get(String(col
umnNumber)) : null; | |
263 return columnBreakpoints ? columnBreakpoints[0] : null; | |
264 }, | |
265 | |
266 /** | |
267 * @param {!WebInspector.UISourceCode} uiSourceCode | |
268 * @param {number} lineNumber | |
269 * @return {?WebInspector.BreakpointManager.Breakpoint} | |
270 */ | |
271 findBreakpointOnLine: function(uiSourceCode, lineNumber) | |
272 { | |
273 var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); | |
274 var lineBreakpoints = breakpoints ? breakpoints.get(String(lineNumber))
: null; | |
275 return lineBreakpoints ? lineBreakpoints.valuesArray()[0][0] : null; | |
276 }, | |
277 | |
278 /** | |
279 * @param {!WebInspector.UISourceCode} uiSourceCode | |
280 * @return {!Array.<!WebInspector.BreakpointManager.Breakpoint>} | |
281 */ | |
282 breakpointsForUISourceCode: function(uiSourceCode) | |
283 { | |
284 var result = []; | |
285 var uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSou
rceCode); | |
286 var breakpoints = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.valu
esArray() : []; | |
287 for (var i = 0; i < breakpoints.length; ++i) { | |
288 var lineBreakpoints = breakpoints[i]; | |
289 var columnBreakpointArrays = lineBreakpoints ? lineBreakpoints.value
sArray() : []; | |
290 result = result.concat.apply(result, columnBreakpointArrays); | |
291 } | |
292 return result; | |
293 }, | |
294 | |
295 /** | |
296 * @return {!Array.<!WebInspector.BreakpointManager.Breakpoint>} | |
297 */ | |
298 allBreakpoints: function() | |
299 { | |
300 var result = []; | |
301 var uiSourceCodes = this._breakpointsForUISourceCode.keysArray(); | |
302 for (var i = 0; i < uiSourceCodes.length; ++i) | |
303 result = result.concat(this.breakpointsForUISourceCode(uiSourceCodes
[i])); | |
304 return result; | |
305 }, | |
306 | |
307 /** | |
308 * @param {!WebInspector.UISourceCode} uiSourceCode | |
309 * @return {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint
, uiLocation: !WebInspector.UILocation}>} | |
310 */ | |
311 breakpointLocationsForUISourceCode: function(uiSourceCode) | |
312 { | |
313 var uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSou
rceCode); | |
314 var lineNumbers = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.keys
Array() : []; | |
315 var result = []; | |
316 for (var i = 0; i < lineNumbers.length; ++i) { | |
317 var lineBreakpoints = uiSourceCodeBreakpoints.get(lineNumbers[i]); | |
318 var columnNumbers = lineBreakpoints.keysArray(); | |
319 for (var j = 0; j < columnNumbers.length; ++j) { | |
320 var columnBreakpoints = lineBreakpoints.get(columnNumbers[j]); | |
321 var lineNumber = parseInt(lineNumbers[i], 10); | |
322 var columnNumber = parseInt(columnNumbers[j], 10); | |
323 for (var k = 0; k < columnBreakpoints.length; ++k) { | |
324 var breakpoint = columnBreakpoints[k]; | |
325 var uiLocation = uiSourceCode.uiLocation(lineNumber, columnN
umber); | |
326 result.push({breakpoint: breakpoint, uiLocation: uiLocation}
); | |
327 } | |
328 } | |
329 } | |
330 return result; | |
331 }, | |
332 | |
333 /** | |
334 * @return {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint
, uiLocation: !WebInspector.UILocation}>} | |
335 */ | |
336 allBreakpointLocations: function() | |
337 { | |
338 var result = []; | |
339 var uiSourceCodes = this._breakpointsForUISourceCode.keysArray(); | |
340 for (var i = 0; i < uiSourceCodes.length; ++i) | |
341 result = result.concat(this.breakpointLocationsForUISourceCode(uiSou
rceCodes[i])); | |
342 return result; | |
343 }, | |
344 | |
345 /** | |
346 * @param {boolean} toggleState | |
347 */ | |
348 toggleAllBreakpoints: function(toggleState) | |
349 { | |
350 var breakpoints = this.allBreakpoints(); | |
351 for (var i = 0; i < breakpoints.length; ++i) | |
352 breakpoints[i].setEnabled(toggleState); | |
353 }, | |
354 | |
355 removeAllBreakpoints: function() | |
356 { | |
357 var breakpoints = this.allBreakpoints(); | |
358 for (var i = 0; i < breakpoints.length; ++i) | |
359 breakpoints[i].remove(); | |
360 }, | |
361 | |
362 _projectRemoved: function(event) | |
363 { | |
364 var project = /** @type {!WebInspector.Project} */ (event.data); | |
365 var uiSourceCodes = project.uiSourceCodes(); | |
366 for (var i = 0; i < uiSourceCodes.length; ++i) | |
367 this._removeUISourceCode(uiSourceCodes[i]); | |
368 }, | |
369 | |
370 /** | |
371 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint | |
372 * @param {boolean} removeFromStorage | |
373 */ | |
374 _removeBreakpoint: function(breakpoint, removeFromStorage) | |
375 { | |
376 var uiSourceCode = breakpoint.uiSourceCode(); | |
377 var breakpoints = uiSourceCode ? this._breakpointsForPrimaryUISourceCode
.get(uiSourceCode) || [] : []; | |
378 breakpoints.remove(breakpoint); | |
379 if (removeFromStorage) | |
380 this._storage._removeBreakpoint(breakpoint); | |
381 this._provisionalBreakpoints.remove(breakpoint._sourceFileId, breakpoint
); | |
382 }, | |
383 | |
384 /** | |
385 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint | |
386 * @param {!WebInspector.UILocation} uiLocation | |
387 */ | |
388 _uiLocationAdded: function(breakpoint, uiLocation) | |
389 { | |
390 var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSour
ceCode); | |
391 if (!breakpoints) { | |
392 breakpoints = new Map(); | |
393 this._breakpointsForUISourceCode.set(uiLocation.uiSourceCode, breakp
oints); | |
394 } | |
395 var lineBreakpoints = breakpoints.get(String(uiLocation.lineNumber)); | |
396 if (!lineBreakpoints) { | |
397 lineBreakpoints = new Map(); | |
398 breakpoints.set(String(uiLocation.lineNumber), lineBreakpoints); | |
399 } | |
400 var columnBreakpoints = lineBreakpoints.get(String(uiLocation.columnNumb
er)); | |
401 if (!columnBreakpoints) { | |
402 columnBreakpoints = []; | |
403 lineBreakpoints.set(String(uiLocation.columnNumber), columnBreakpoin
ts); | |
404 } | |
405 columnBreakpoints.push(breakpoint); | |
406 this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.Brea
kpointAdded, {breakpoint: breakpoint, uiLocation: uiLocation}); | |
407 }, | |
408 | |
409 /** | |
410 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint | |
411 * @param {!WebInspector.UILocation} uiLocation | |
412 */ | |
413 _uiLocationRemoved: function(breakpoint, uiLocation) | |
414 { | |
415 var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSour
ceCode); | |
416 if (!breakpoints) | |
417 return; | |
418 | |
419 var lineBreakpoints = breakpoints.get(String(uiLocation.lineNumber)); | |
420 if (!lineBreakpoints) | |
421 return; | |
422 var columnBreakpoints = lineBreakpoints.get(String(uiLocation.columnNumb
er)); | |
423 if (!columnBreakpoints) | |
424 return; | |
425 columnBreakpoints.remove(breakpoint); | |
426 if (!columnBreakpoints.length) | |
427 lineBreakpoints.remove(String(uiLocation.columnNumber)); | |
428 if (!lineBreakpoints.size) | |
429 breakpoints.remove(String(uiLocation.lineNumber)); | |
430 if (!breakpoints.size) | |
431 this._breakpointsForUISourceCode.remove(uiLocation.uiSourceCode); | |
432 this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.Brea
kpointRemoved, {breakpoint: breakpoint, uiLocation: uiLocation}); | |
433 }, | |
434 | |
435 /** | |
436 * @param {boolean} active | |
437 */ | |
438 setBreakpointsActive: function(active) | |
439 { | |
440 if (this._breakpointsActive === active) | |
441 return; | |
442 | |
443 this._breakpointsActive = active; | |
444 var debuggerModels = WebInspector.DebuggerModel.instances(); | |
445 for (var i = 0; i < debuggerModels.length; ++i) | |
446 debuggerModels[i].setBreakpointsActive(active); | |
447 | |
448 this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.Brea
kpointsActiveStateChanged, active); | |
449 }, | |
450 | |
451 /** | |
452 * @return {boolean} | |
453 */ | |
454 breakpointsActive: function() | |
455 { | |
456 return this._breakpointsActive; | |
457 }, | |
458 | |
459 __proto__: WebInspector.Object.prototype | |
460 }; | |
461 | |
462 /** | |
463 * @constructor | |
464 * @implements {WebInspector.TargetManager.Observer} | |
465 * @param {!WebInspector.BreakpointManager} breakpointManager | |
466 * @param {string} projectId | |
467 * @param {string} path | |
468 * @param {string} sourceFileId | |
469 * @param {number} lineNumber | |
470 * @param {number} columnNumber | |
471 * @param {string} condition | |
472 * @param {boolean} enabled | |
473 */ | |
474 WebInspector.BreakpointManager.Breakpoint = function(breakpointManager, projectI
d, path, sourceFileId, lineNumber, columnNumber, condition, enabled) | |
475 { | |
476 this._breakpointManager = breakpointManager; | 462 this._breakpointManager = breakpointManager; |
477 this._projectId = projectId; | 463 this._projectId = projectId; |
478 this._path = path; | 464 this._path = path; |
479 this._lineNumber = lineNumber; | 465 this._lineNumber = lineNumber; |
480 this._columnNumber = columnNumber; | 466 this._columnNumber = columnNumber; |
481 this._sourceFileId = sourceFileId; | 467 this._sourceFileId = sourceFileId; |
482 | 468 |
483 /** @type {!Map<string, number>} */ | 469 /** @type {!Map<string, number>} */ |
484 this._numberOfDebuggerLocationForUILocation = new Map(); | 470 this._numberOfDebuggerLocationForUILocation = new Map(); |
485 | 471 |
486 // Force breakpoint update. | 472 // Force breakpoint update. |
487 /** @type {string} */ this._condition; | 473 /** @type {string} */ this._condition; |
488 /** @type {boolean} */ this._enabled; | 474 /** @type {boolean} */ this._enabled; |
489 /** @type {boolean} */ this._isRemoved; | 475 /** @type {boolean} */ this._isRemoved; |
490 /** @type {!WebInspector.UILocation|undefined} */ this._fakePrimaryLocation; | 476 /** @type {!WebInspector.UILocation|undefined} */ this._fakePrimaryLocation; |
491 | 477 |
492 this._currentState = null; | 478 this._currentState = null; |
493 /** @type {!Map.<!WebInspector.Target, !WebInspector.BreakpointManager.Targe
tBreakpoint>}*/ | 479 /** @type {!Map.<!WebInspector.Target, !WebInspector.BreakpointManager.Targe
tBreakpoint>}*/ |
494 this._targetBreakpoints = new Map(); | 480 this._targetBreakpoints = new Map(); |
495 this._updateState(condition, enabled); | 481 this._updateState(condition, enabled); |
496 this._breakpointManager._targetManager.observeTargets(this); | 482 this._breakpointManager._targetManager.observeTargets(this); |
| 483 } |
| 484 |
| 485 /** |
| 486 * @override |
| 487 * @param {!WebInspector.Target} target |
| 488 */ |
| 489 targetAdded(target) { |
| 490 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); |
| 491 if (!debuggerModel) |
| 492 return; |
| 493 var debuggerWorkspaceBinding = this._breakpointManager._debuggerWorkspaceBin
ding; |
| 494 this._targetBreakpoints.set( |
| 495 target, new WebInspector.BreakpointManager.TargetBreakpoint(debuggerMode
l, this, debuggerWorkspaceBinding)); |
| 496 } |
| 497 |
| 498 /** |
| 499 * @override |
| 500 * @param {!WebInspector.Target} target |
| 501 */ |
| 502 targetRemoved(target) { |
| 503 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); |
| 504 if (!debuggerModel) |
| 505 return; |
| 506 var targetBreakpoint = this._targetBreakpoints.remove(target); |
| 507 targetBreakpoint._cleanUpAfterDebuggerIsGone(); |
| 508 targetBreakpoint._removeEventListeners(); |
| 509 } |
| 510 |
| 511 /** |
| 512 * @return {string} |
| 513 */ |
| 514 projectId() { |
| 515 return this._projectId; |
| 516 } |
| 517 |
| 518 /** |
| 519 * @return {string} |
| 520 */ |
| 521 path() { |
| 522 return this._path; |
| 523 } |
| 524 |
| 525 /** |
| 526 * @return {number} |
| 527 */ |
| 528 lineNumber() { |
| 529 return this._lineNumber; |
| 530 } |
| 531 |
| 532 /** |
| 533 * @return {number} |
| 534 */ |
| 535 columnNumber() { |
| 536 return this._columnNumber; |
| 537 } |
| 538 |
| 539 /** |
| 540 * @return {?WebInspector.UISourceCode} |
| 541 */ |
| 542 uiSourceCode() { |
| 543 return this._breakpointManager._workspace.uiSourceCode(this._projectId, this
._path); |
| 544 } |
| 545 |
| 546 /** |
| 547 * @param {?WebInspector.UILocation} oldUILocation |
| 548 * @param {!WebInspector.UILocation} newUILocation |
| 549 */ |
| 550 _replaceUILocation(oldUILocation, newUILocation) { |
| 551 if (this._isRemoved) |
| 552 return; |
| 553 |
| 554 this._removeUILocation(oldUILocation, true); |
| 555 this._removeFakeBreakpointAtPrimaryLocation(); |
| 556 |
| 557 var current = (this._numberOfDebuggerLocationForUILocation.get(newUILocation
.id()) || 0) + 1; |
| 558 this._numberOfDebuggerLocationForUILocation.set(newUILocation.id(), current)
; |
| 559 if (current === 1) |
| 560 this._breakpointManager._uiLocationAdded(this, newUILocation); |
| 561 } |
| 562 |
| 563 /** |
| 564 * @param {?WebInspector.UILocation} uiLocation |
| 565 * @param {boolean=} muteCreationFakeBreakpoint |
| 566 */ |
| 567 _removeUILocation(uiLocation, muteCreationFakeBreakpoint) { |
| 568 if (!uiLocation || !this._numberOfDebuggerLocationForUILocation.has(uiLocati
on.id())) |
| 569 return; |
| 570 var current = (this._numberOfDebuggerLocationForUILocation.get(uiLocation.id
()) || 0) - 1; |
| 571 this._numberOfDebuggerLocationForUILocation.set(uiLocation.id(), current); |
| 572 if (current !== 0) |
| 573 return; |
| 574 |
| 575 this._numberOfDebuggerLocationForUILocation.delete(uiLocation.id()); |
| 576 this._breakpointManager._uiLocationRemoved(this, uiLocation); |
| 577 if (!muteCreationFakeBreakpoint) |
| 578 this._fakeBreakpointAtPrimaryLocation(); |
| 579 } |
| 580 |
| 581 /** |
| 582 * @return {boolean} |
| 583 */ |
| 584 enabled() { |
| 585 return this._enabled; |
| 586 } |
| 587 |
| 588 /** |
| 589 * @param {boolean} enabled |
| 590 */ |
| 591 setEnabled(enabled) { |
| 592 this._updateState(this._condition, enabled); |
| 593 } |
| 594 |
| 595 /** |
| 596 * @return {string} |
| 597 */ |
| 598 condition() { |
| 599 return this._condition; |
| 600 } |
| 601 |
| 602 /** |
| 603 * @param {string} condition |
| 604 */ |
| 605 setCondition(condition) { |
| 606 this._updateState(condition, this._enabled); |
| 607 } |
| 608 |
| 609 /** |
| 610 * @param {string} condition |
| 611 * @param {boolean} enabled |
| 612 */ |
| 613 _updateState(condition, enabled) { |
| 614 if (this._enabled === enabled && this._condition === condition) |
| 615 return; |
| 616 this._enabled = enabled; |
| 617 this._condition = condition; |
| 618 this._breakpointManager._storage._updateBreakpoint(this); |
| 619 this._updateBreakpoint(); |
| 620 } |
| 621 |
| 622 _updateBreakpoint() { |
| 623 this._removeFakeBreakpointAtPrimaryLocation(); |
| 624 this._fakeBreakpointAtPrimaryLocation(); |
| 625 var targetBreakpoints = this._targetBreakpoints.valuesArray(); |
| 626 for (var i = 0; i < targetBreakpoints.length; ++i) |
| 627 targetBreakpoints[i]._scheduleUpdateInDebugger(); |
| 628 } |
| 629 |
| 630 /** |
| 631 * @param {boolean=} keepInStorage |
| 632 */ |
| 633 remove(keepInStorage) { |
| 634 this._isRemoved = true; |
| 635 var removeFromStorage = !keepInStorage; |
| 636 this._removeFakeBreakpointAtPrimaryLocation(); |
| 637 var targetBreakpoints = this._targetBreakpoints.valuesArray(); |
| 638 for (var i = 0; i < targetBreakpoints.length; ++i) { |
| 639 targetBreakpoints[i]._scheduleUpdateInDebugger(); |
| 640 targetBreakpoints[i]._removeEventListeners(); |
| 641 } |
| 642 |
| 643 this._breakpointManager._removeBreakpoint(this, removeFromStorage); |
| 644 this._breakpointManager._targetManager.unobserveTargets(this); |
| 645 } |
| 646 |
| 647 /** |
| 648 * @param {!WebInspector.Target} target |
| 649 */ |
| 650 _updateInDebuggerForTarget(target) { |
| 651 this._targetBreakpoints.get(target)._scheduleUpdateInDebugger(); |
| 652 } |
| 653 |
| 654 /** |
| 655 * @return {string} |
| 656 */ |
| 657 _breakpointStorageId() { |
| 658 return WebInspector.BreakpointManager._breakpointStorageId( |
| 659 this._sourceFileId, this._lineNumber, this._columnNumber); |
| 660 } |
| 661 |
| 662 _fakeBreakpointAtPrimaryLocation() { |
| 663 if (this._isRemoved || this._numberOfDebuggerLocationForUILocation.size || t
his._fakePrimaryLocation) |
| 664 return; |
| 665 |
| 666 var uiSourceCode = this._breakpointManager._workspace.uiSourceCode(this._pro
jectId, this._path); |
| 667 if (!uiSourceCode) |
| 668 return; |
| 669 |
| 670 this._fakePrimaryLocation = uiSourceCode.uiLocation(this._lineNumber, this._
columnNumber); |
| 671 if (this._fakePrimaryLocation) |
| 672 this._breakpointManager._uiLocationAdded(this, this._fakePrimaryLocation); |
| 673 } |
| 674 |
| 675 _removeFakeBreakpointAtPrimaryLocation() { |
| 676 if (this._fakePrimaryLocation) { |
| 677 this._breakpointManager._uiLocationRemoved(this, this._fakePrimaryLocation
); |
| 678 delete this._fakePrimaryLocation; |
| 679 } |
| 680 } |
| 681 |
| 682 _resetLocations() { |
| 683 this._removeFakeBreakpointAtPrimaryLocation(); |
| 684 var targetBreakpoints = this._targetBreakpoints.valuesArray(); |
| 685 for (var i = 0; i < targetBreakpoints.length; ++i) |
| 686 targetBreakpoints[i]._resetLocations(); |
| 687 } |
497 }; | 688 }; |
498 | 689 |
499 WebInspector.BreakpointManager.Breakpoint.prototype = { | |
500 /** | |
501 * @override | |
502 * @param {!WebInspector.Target} target | |
503 */ | |
504 targetAdded: function(target) | |
505 { | |
506 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); | |
507 if (!debuggerModel) | |
508 return; | |
509 var debuggerWorkspaceBinding = this._breakpointManager._debuggerWorkspac
eBinding; | |
510 this._targetBreakpoints.set(target, new WebInspector.BreakpointManager.T
argetBreakpoint(debuggerModel, this, debuggerWorkspaceBinding)); | |
511 }, | |
512 | |
513 /** | |
514 * @override | |
515 * @param {!WebInspector.Target} target | |
516 */ | |
517 targetRemoved: function(target) | |
518 { | |
519 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); | |
520 if (!debuggerModel) | |
521 return; | |
522 var targetBreakpoint = this._targetBreakpoints.remove(target); | |
523 targetBreakpoint._cleanUpAfterDebuggerIsGone(); | |
524 targetBreakpoint._removeEventListeners(); | |
525 }, | |
526 | |
527 /** | |
528 * @return {string} | |
529 */ | |
530 projectId: function() | |
531 { | |
532 return this._projectId; | |
533 }, | |
534 | |
535 /** | |
536 * @return {string} | |
537 */ | |
538 path: function() | |
539 { | |
540 return this._path; | |
541 }, | |
542 | |
543 /** | |
544 * @return {number} | |
545 */ | |
546 lineNumber: function() | |
547 { | |
548 return this._lineNumber; | |
549 }, | |
550 | |
551 /** | |
552 * @return {number} | |
553 */ | |
554 columnNumber: function() | |
555 { | |
556 return this._columnNumber; | |
557 }, | |
558 | |
559 /** | |
560 * @return {?WebInspector.UISourceCode} | |
561 */ | |
562 uiSourceCode: function() | |
563 { | |
564 return this._breakpointManager._workspace.uiSourceCode(this._projectId,
this._path); | |
565 }, | |
566 | |
567 /** | |
568 * @param {?WebInspector.UILocation} oldUILocation | |
569 * @param {!WebInspector.UILocation} newUILocation | |
570 */ | |
571 _replaceUILocation: function(oldUILocation, newUILocation) | |
572 { | |
573 if (this._isRemoved) | |
574 return; | |
575 | |
576 this._removeUILocation(oldUILocation, true); | |
577 this._removeFakeBreakpointAtPrimaryLocation(); | |
578 | |
579 var current = (this._numberOfDebuggerLocationForUILocation.get(newUILoca
tion.id()) || 0) + 1; | |
580 this._numberOfDebuggerLocationForUILocation.set(newUILocation.id(), curr
ent); | |
581 if (current === 1) | |
582 this._breakpointManager._uiLocationAdded(this, newUILocation); | |
583 }, | |
584 | |
585 /** | |
586 * @param {?WebInspector.UILocation} uiLocation | |
587 * @param {boolean=} muteCreationFakeBreakpoint | |
588 */ | |
589 _removeUILocation: function(uiLocation, muteCreationFakeBreakpoint) | |
590 { | |
591 if (!uiLocation || !this._numberOfDebuggerLocationForUILocation.has(uiLo
cation.id())) | |
592 return; | |
593 var current = (this._numberOfDebuggerLocationForUILocation.get(uiLocatio
n.id()) || 0) - 1; | |
594 this._numberOfDebuggerLocationForUILocation.set(uiLocation.id(), current
); | |
595 if (current !== 0) | |
596 return; | |
597 | |
598 this._numberOfDebuggerLocationForUILocation.delete(uiLocation.id()); | |
599 this._breakpointManager._uiLocationRemoved(this, uiLocation); | |
600 if (!muteCreationFakeBreakpoint) | |
601 this._fakeBreakpointAtPrimaryLocation(); | |
602 }, | |
603 | |
604 /** | |
605 * @return {boolean} | |
606 */ | |
607 enabled: function() | |
608 { | |
609 return this._enabled; | |
610 }, | |
611 | |
612 /** | |
613 * @param {boolean} enabled | |
614 */ | |
615 setEnabled: function(enabled) | |
616 { | |
617 this._updateState(this._condition, enabled); | |
618 }, | |
619 | |
620 /** | |
621 * @return {string} | |
622 */ | |
623 condition: function() | |
624 { | |
625 return this._condition; | |
626 }, | |
627 | |
628 /** | |
629 * @param {string} condition | |
630 */ | |
631 setCondition: function(condition) | |
632 { | |
633 this._updateState(condition, this._enabled); | |
634 }, | |
635 | |
636 /** | |
637 * @param {string} condition | |
638 * @param {boolean} enabled | |
639 */ | |
640 _updateState: function(condition, enabled) | |
641 { | |
642 if (this._enabled === enabled && this._condition === condition) | |
643 return; | |
644 this._enabled = enabled; | |
645 this._condition = condition; | |
646 this._breakpointManager._storage._updateBreakpoint(this); | |
647 this._updateBreakpoint(); | |
648 }, | |
649 | |
650 _updateBreakpoint: function() | |
651 { | |
652 this._removeFakeBreakpointAtPrimaryLocation(); | |
653 this._fakeBreakpointAtPrimaryLocation(); | |
654 var targetBreakpoints = this._targetBreakpoints.valuesArray(); | |
655 for (var i = 0; i < targetBreakpoints.length; ++i) | |
656 targetBreakpoints[i]._scheduleUpdateInDebugger(); | |
657 }, | |
658 | |
659 /** | |
660 * @param {boolean=} keepInStorage | |
661 */ | |
662 remove: function(keepInStorage) | |
663 { | |
664 | |
665 this._isRemoved = true; | |
666 var removeFromStorage = !keepInStorage; | |
667 this._removeFakeBreakpointAtPrimaryLocation(); | |
668 var targetBreakpoints = this._targetBreakpoints.valuesArray(); | |
669 for (var i = 0; i < targetBreakpoints.length; ++i) { | |
670 targetBreakpoints[i]._scheduleUpdateInDebugger(); | |
671 targetBreakpoints[i]._removeEventListeners(); | |
672 } | |
673 | |
674 this._breakpointManager._removeBreakpoint(this, removeFromStorage); | |
675 this._breakpointManager._targetManager.unobserveTargets(this); | |
676 }, | |
677 | |
678 /** | |
679 * @param {!WebInspector.Target} target | |
680 */ | |
681 _updateInDebuggerForTarget: function(target) | |
682 { | |
683 this._targetBreakpoints.get(target)._scheduleUpdateInDebugger(); | |
684 }, | |
685 | |
686 /** | |
687 * @return {string} | |
688 */ | |
689 _breakpointStorageId: function() | |
690 { | |
691 return WebInspector.BreakpointManager._breakpointStorageId(this._sourceF
ileId, this._lineNumber, this._columnNumber); | |
692 }, | |
693 | |
694 _fakeBreakpointAtPrimaryLocation: function() | |
695 { | |
696 if (this._isRemoved || this._numberOfDebuggerLocationForUILocation.size
|| this._fakePrimaryLocation) | |
697 return; | |
698 | |
699 var uiSourceCode = this._breakpointManager._workspace.uiSourceCode(this.
_projectId, this._path); | |
700 if (!uiSourceCode) | |
701 return; | |
702 | |
703 this._fakePrimaryLocation = uiSourceCode.uiLocation(this._lineNumber, th
is._columnNumber); | |
704 if (this._fakePrimaryLocation) | |
705 this._breakpointManager._uiLocationAdded(this, this._fakePrimaryLoca
tion); | |
706 }, | |
707 | |
708 _removeFakeBreakpointAtPrimaryLocation: function() | |
709 { | |
710 if (this._fakePrimaryLocation) { | |
711 this._breakpointManager._uiLocationRemoved(this, this._fakePrimaryLo
cation); | |
712 delete this._fakePrimaryLocation; | |
713 } | |
714 }, | |
715 | |
716 _resetLocations: function() | |
717 { | |
718 this._removeFakeBreakpointAtPrimaryLocation(); | |
719 var targetBreakpoints = this._targetBreakpoints.valuesArray(); | |
720 for (var i = 0; i < targetBreakpoints.length; ++i) | |
721 targetBreakpoints[i]._resetLocations(); | |
722 } | |
723 }; | |
724 | |
725 /** | 690 /** |
726 * @constructor | 691 * @unrestricted |
727 * @extends {WebInspector.SDKObject} | |
728 * @param {!WebInspector.DebuggerModel} debuggerModel | |
729 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint | |
730 * @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding | |
731 */ | 692 */ |
732 WebInspector.BreakpointManager.TargetBreakpoint = function(debuggerModel, breakp
oint, debuggerWorkspaceBinding) | 693 WebInspector.BreakpointManager.TargetBreakpoint = class extends WebInspector.SDK
Object { |
733 { | 694 /** |
734 WebInspector.SDKObject.call(this, debuggerModel.target()); | 695 * @param {!WebInspector.DebuggerModel} debuggerModel |
| 696 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint |
| 697 * @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding |
| 698 */ |
| 699 constructor(debuggerModel, breakpoint, debuggerWorkspaceBinding) { |
| 700 super(debuggerModel.target()); |
735 this._debuggerModel = debuggerModel; | 701 this._debuggerModel = debuggerModel; |
736 this._breakpoint = breakpoint; | 702 this._breakpoint = breakpoint; |
737 this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; | 703 this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; |
738 | 704 |
739 this._liveLocations = new WebInspector.LiveLocationPool(); | 705 this._liveLocations = new WebInspector.LiveLocationPool(); |
740 | 706 |
741 /** @type {!Map<string, !WebInspector.UILocation>} */ | 707 /** @type {!Map<string, !WebInspector.UILocation>} */ |
742 this._uiLocations = new Map(); | 708 this._uiLocations = new Map(); |
743 this._debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.Debug
gerWasDisabled, this._cleanUpAfterDebuggerIsGone, this); | 709 this._debuggerModel.addEventListener( |
744 this._debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.Debug
gerWasEnabled, this._scheduleUpdateInDebugger, this); | 710 WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._cleanUpAfte
rDebuggerIsGone, this); |
| 711 this._debuggerModel.addEventListener( |
| 712 WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._scheduleUpda
teInDebugger, this); |
745 this._hasPendingUpdate = false; | 713 this._hasPendingUpdate = false; |
746 this._isUpdating = false; | 714 this._isUpdating = false; |
747 this._cancelCallback = false; | 715 this._cancelCallback = false; |
748 this._currentState = null; | 716 this._currentState = null; |
749 if (this._debuggerModel.debuggerEnabled()) | 717 if (this._debuggerModel.debuggerEnabled()) |
750 this._scheduleUpdateInDebugger(); | 718 this._scheduleUpdateInDebugger(); |
| 719 } |
| 720 |
| 721 _resetLocations() { |
| 722 for (var uiLocation of this._uiLocations.values()) |
| 723 this._breakpoint._removeUILocation(uiLocation); |
| 724 |
| 725 this._uiLocations.clear(); |
| 726 this._liveLocations.disposeAll(); |
| 727 } |
| 728 |
| 729 _scheduleUpdateInDebugger() { |
| 730 if (this._isUpdating) { |
| 731 this._hasPendingUpdate = true; |
| 732 return; |
| 733 } |
| 734 |
| 735 this._isUpdating = true; |
| 736 this._updateInDebugger(this._didUpdateInDebugger.bind(this)); |
| 737 } |
| 738 |
| 739 _didUpdateInDebugger() { |
| 740 this._isUpdating = false; |
| 741 if (this._hasPendingUpdate) { |
| 742 this._hasPendingUpdate = false; |
| 743 this._scheduleUpdateInDebugger(); |
| 744 } |
| 745 } |
| 746 |
| 747 /** |
| 748 * @return {boolean} |
| 749 */ |
| 750 _scriptDiverged() { |
| 751 var uiSourceCode = this._breakpoint.uiSourceCode(); |
| 752 if (!uiSourceCode) |
| 753 return false; |
| 754 var scriptFile = this._debuggerWorkspaceBinding.scriptFile(uiSourceCode, thi
s.target()); |
| 755 return !!scriptFile && scriptFile.hasDivergedFromVM(); |
| 756 } |
| 757 |
| 758 /** |
| 759 * @param {function()} callback |
| 760 */ |
| 761 _updateInDebugger(callback) { |
| 762 if (this.target().isDisposed()) { |
| 763 this._cleanUpAfterDebuggerIsGone(); |
| 764 callback(); |
| 765 return; |
| 766 } |
| 767 |
| 768 var uiSourceCode = this._breakpoint.uiSourceCode(); |
| 769 var lineNumber = this._breakpoint._lineNumber; |
| 770 var columnNumber = this._breakpoint._columnNumber; |
| 771 var condition = this._breakpoint.condition(); |
| 772 |
| 773 var debuggerLocation = uiSourceCode ? |
| 774 this._debuggerWorkspaceBinding.uiLocationToRawLocation(this.target(), ui
SourceCode, lineNumber, columnNumber) : |
| 775 null; |
| 776 var newState; |
| 777 if (this._breakpoint._isRemoved || !this._breakpoint.enabled() || this._scri
ptDiverged()) |
| 778 newState = null; |
| 779 else if (debuggerLocation) { |
| 780 var script = debuggerLocation.script(); |
| 781 if (script.sourceURL) |
| 782 newState = new WebInspector.BreakpointManager.Breakpoint.State( |
| 783 script.sourceURL, null, debuggerLocation.lineNumber, debuggerLocatio
n.columnNumber, condition); |
| 784 else |
| 785 newState = new WebInspector.BreakpointManager.Breakpoint.State( |
| 786 null, debuggerLocation.scriptId, debuggerLocation.lineNumber, debugg
erLocation.columnNumber, condition); |
| 787 } else if (this._breakpoint._currentState && this._breakpoint._currentState.
url) { |
| 788 var position = this._breakpoint._currentState; |
| 789 newState = new WebInspector.BreakpointManager.Breakpoint.State( |
| 790 position.url, null, position.lineNumber, position.columnNumber, condit
ion); |
| 791 } else if (uiSourceCode) { |
| 792 newState = new WebInspector.BreakpointManager.Breakpoint.State( |
| 793 uiSourceCode.url(), null, lineNumber, columnNumber, condition); |
| 794 } |
| 795 if (this._debuggerId && WebInspector.BreakpointManager.Breakpoint.State.equa
ls(newState, this._currentState)) { |
| 796 callback(); |
| 797 return; |
| 798 } |
| 799 |
| 800 this._breakpoint._currentState = newState; |
| 801 |
| 802 if (this._debuggerId) { |
| 803 this._resetLocations(); |
| 804 this._debuggerModel.removeBreakpoint(this._debuggerId, this._didRemoveFrom
Debugger.bind(this, callback)); |
| 805 this._scheduleUpdateInDebugger(); |
| 806 this._currentState = null; |
| 807 return; |
| 808 } |
| 809 |
| 810 if (!newState) { |
| 811 callback(); |
| 812 return; |
| 813 } |
| 814 |
| 815 var updateCallback = this._didSetBreakpointInDebugger.bind(this, callback); |
| 816 if (newState.url) |
| 817 this._debuggerModel.setBreakpointByURL( |
| 818 newState.url, newState.lineNumber, newState.columnNumber, this._breakp
oint.condition(), updateCallback); |
| 819 else if (newState.scriptId) |
| 820 this._debuggerModel.setBreakpointBySourceId( |
| 821 /** @type {!WebInspector.DebuggerModel.Location} */ (debuggerLocation)
, condition, updateCallback); |
| 822 |
| 823 this._currentState = newState; |
| 824 } |
| 825 |
| 826 /** |
| 827 * @param {function()} callback |
| 828 * @param {?DebuggerAgent.BreakpointId} breakpointId |
| 829 * @param {!Array.<!WebInspector.DebuggerModel.Location>} locations |
| 830 */ |
| 831 _didSetBreakpointInDebugger(callback, breakpointId, locations) { |
| 832 if (this._cancelCallback) { |
| 833 this._cancelCallback = false; |
| 834 callback(); |
| 835 return; |
| 836 } |
| 837 |
| 838 if (!breakpointId) { |
| 839 this._breakpoint.remove(true); |
| 840 callback(); |
| 841 return; |
| 842 } |
| 843 |
| 844 this._debuggerId = breakpointId; |
| 845 this._debuggerModel.addBreakpointListener(this._debuggerId, this._breakpoint
Resolved, this); |
| 846 for (var i = 0; i < locations.length; ++i) { |
| 847 if (!this._addResolvedLocation(locations[i])) |
| 848 break; |
| 849 } |
| 850 callback(); |
| 851 } |
| 852 |
| 853 /** |
| 854 * @param {function()} callback |
| 855 */ |
| 856 _didRemoveFromDebugger(callback) { |
| 857 if (this._cancelCallback) { |
| 858 this._cancelCallback = false; |
| 859 callback(); |
| 860 return; |
| 861 } |
| 862 |
| 863 this._resetLocations(); |
| 864 this._debuggerModel.removeBreakpointListener(this._debuggerId, this._breakpo
intResolved, this); |
| 865 delete this._debuggerId; |
| 866 callback(); |
| 867 } |
| 868 |
| 869 /** |
| 870 * @param {!WebInspector.Event} event |
| 871 */ |
| 872 _breakpointResolved(event) { |
| 873 this._addResolvedLocation(/** @type {!WebInspector.DebuggerModel.Location}*/
(event.data)); |
| 874 } |
| 875 |
| 876 /** |
| 877 * @param {!WebInspector.DebuggerModel.Location} location |
| 878 * @param {!WebInspector.LiveLocation} liveLocation |
| 879 */ |
| 880 _locationUpdated(location, liveLocation) { |
| 881 var uiLocation = liveLocation.uiLocation(); |
| 882 if (!uiLocation) |
| 883 return; |
| 884 var oldUILocation = this._uiLocations.get(location.id()) || null; |
| 885 this._uiLocations.set(location.id(), uiLocation); |
| 886 this._breakpoint._replaceUILocation(oldUILocation, uiLocation); |
| 887 } |
| 888 |
| 889 /** |
| 890 * @param {!WebInspector.DebuggerModel.Location} location |
| 891 * @return {boolean} |
| 892 */ |
| 893 _addResolvedLocation(location) { |
| 894 var uiLocation = this._debuggerWorkspaceBinding.rawLocationToUILocation(loca
tion); |
| 895 var breakpoint = this._breakpoint._breakpointManager.findBreakpoint( |
| 896 uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber)
; |
| 897 if (breakpoint && breakpoint !== this._breakpoint) { |
| 898 // location clash |
| 899 this._breakpoint.remove(); |
| 900 return false; |
| 901 } |
| 902 this._debuggerWorkspaceBinding.createLiveLocation( |
| 903 location, this._locationUpdated.bind(this, location), this._liveLocation
s); |
| 904 return true; |
| 905 } |
| 906 |
| 907 _cleanUpAfterDebuggerIsGone() { |
| 908 if (this._isUpdating) |
| 909 this._cancelCallback = true; |
| 910 |
| 911 this._resetLocations(); |
| 912 this._currentState = null; |
| 913 if (this._debuggerId) |
| 914 this._didRemoveFromDebugger(function() {}); |
| 915 } |
| 916 |
| 917 _removeEventListeners() { |
| 918 this._debuggerModel.removeEventListener( |
| 919 WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._cleanUpAfte
rDebuggerIsGone, this); |
| 920 this._debuggerModel.removeEventListener( |
| 921 WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._scheduleUpda
teInDebugger, this); |
| 922 } |
751 }; | 923 }; |
752 | 924 |
753 WebInspector.BreakpointManager.TargetBreakpoint.prototype = { | |
754 | |
755 _resetLocations: function() | |
756 { | |
757 for (var uiLocation of this._uiLocations.values()) | |
758 this._breakpoint._removeUILocation(uiLocation); | |
759 | |
760 this._uiLocations.clear(); | |
761 this._liveLocations.disposeAll(); | |
762 }, | |
763 | |
764 _scheduleUpdateInDebugger: function() | |
765 { | |
766 if (this._isUpdating) { | |
767 this._hasPendingUpdate = true; | |
768 return; | |
769 } | |
770 | |
771 this._isUpdating = true; | |
772 this._updateInDebugger(this._didUpdateInDebugger.bind(this)); | |
773 }, | |
774 | |
775 _didUpdateInDebugger: function() | |
776 { | |
777 this._isUpdating = false; | |
778 if (this._hasPendingUpdate) { | |
779 this._hasPendingUpdate = false; | |
780 this._scheduleUpdateInDebugger(); | |
781 } | |
782 }, | |
783 | |
784 /** | |
785 * @return {boolean} | |
786 */ | |
787 _scriptDiverged: function() | |
788 { | |
789 var uiSourceCode = this._breakpoint.uiSourceCode(); | |
790 if (!uiSourceCode) | |
791 return false; | |
792 var scriptFile = this._debuggerWorkspaceBinding.scriptFile(uiSourceCode,
this.target()); | |
793 return !!scriptFile && scriptFile.hasDivergedFromVM(); | |
794 }, | |
795 | |
796 /** | |
797 * @param {function()} callback | |
798 */ | |
799 _updateInDebugger: function(callback) | |
800 { | |
801 if (this.target().isDisposed()) { | |
802 this._cleanUpAfterDebuggerIsGone(); | |
803 callback(); | |
804 return; | |
805 } | |
806 | |
807 var uiSourceCode = this._breakpoint.uiSourceCode(); | |
808 var lineNumber = this._breakpoint._lineNumber; | |
809 var columnNumber = this._breakpoint._columnNumber; | |
810 var condition = this._breakpoint.condition(); | |
811 | |
812 var debuggerLocation = uiSourceCode ? this._debuggerWorkspaceBinding.uiL
ocationToRawLocation(this.target(), uiSourceCode, lineNumber, columnNumber) : nu
ll; | |
813 var newState; | |
814 if (this._breakpoint._isRemoved || !this._breakpoint.enabled() || this._
scriptDiverged()) | |
815 newState = null; | |
816 else if (debuggerLocation) { | |
817 var script = debuggerLocation.script(); | |
818 if (script.sourceURL) | |
819 newState = new WebInspector.BreakpointManager.Breakpoint.State(s
cript.sourceURL, null, debuggerLocation.lineNumber, debuggerLocation.columnNumbe
r, condition); | |
820 else | |
821 newState = new WebInspector.BreakpointManager.Breakpoint.State(n
ull, debuggerLocation.scriptId, debuggerLocation.lineNumber, debuggerLocation.co
lumnNumber, condition); | |
822 } else if (this._breakpoint._currentState && this._breakpoint._currentSt
ate.url) { | |
823 var position = this._breakpoint._currentState; | |
824 newState = new WebInspector.BreakpointManager.Breakpoint.State(posit
ion.url, null, position.lineNumber, position.columnNumber, condition); | |
825 } else if (uiSourceCode) { | |
826 newState = new WebInspector.BreakpointManager.Breakpoint.State(uiSou
rceCode.url(), null, lineNumber, columnNumber, condition); | |
827 } | |
828 if (this._debuggerId && WebInspector.BreakpointManager.Breakpoint.State.
equals(newState, this._currentState)) { | |
829 callback(); | |
830 return; | |
831 } | |
832 | |
833 this._breakpoint._currentState = newState; | |
834 | |
835 if (this._debuggerId) { | |
836 this._resetLocations(); | |
837 this._debuggerModel.removeBreakpoint(this._debuggerId, this._didRemo
veFromDebugger.bind(this, callback)); | |
838 this._scheduleUpdateInDebugger(); | |
839 this._currentState = null; | |
840 return; | |
841 } | |
842 | |
843 if (!newState) { | |
844 callback(); | |
845 return; | |
846 } | |
847 | |
848 var updateCallback = this._didSetBreakpointInDebugger.bind(this, callbac
k); | |
849 if (newState.url) | |
850 this._debuggerModel.setBreakpointByURL(newState.url, newState.lineNu
mber, newState.columnNumber, this._breakpoint.condition(), updateCallback); | |
851 else if (newState.scriptId) | |
852 this._debuggerModel.setBreakpointBySourceId(/** @type {!WebInspector
.DebuggerModel.Location} */ (debuggerLocation), condition, updateCallback); | |
853 | |
854 this._currentState = newState; | |
855 }, | |
856 | |
857 /** | |
858 * @param {function()} callback | |
859 * @param {?DebuggerAgent.BreakpointId} breakpointId | |
860 * @param {!Array.<!WebInspector.DebuggerModel.Location>} locations | |
861 */ | |
862 _didSetBreakpointInDebugger: function(callback, breakpointId, locations) | |
863 { | |
864 if (this._cancelCallback) { | |
865 this._cancelCallback = false; | |
866 callback(); | |
867 return; | |
868 } | |
869 | |
870 if (!breakpointId) { | |
871 this._breakpoint.remove(true); | |
872 callback(); | |
873 return; | |
874 } | |
875 | |
876 this._debuggerId = breakpointId; | |
877 this._debuggerModel.addBreakpointListener(this._debuggerId, this._breakp
ointResolved, this); | |
878 for (var i = 0; i < locations.length; ++i) { | |
879 if (!this._addResolvedLocation(locations[i])) | |
880 break; | |
881 } | |
882 callback(); | |
883 }, | |
884 | |
885 /** | |
886 * @param {function()} callback | |
887 */ | |
888 _didRemoveFromDebugger: function(callback) | |
889 { | |
890 if (this._cancelCallback) { | |
891 this._cancelCallback = false; | |
892 callback(); | |
893 return; | |
894 } | |
895 | |
896 this._resetLocations(); | |
897 this._debuggerModel.removeBreakpointListener(this._debuggerId, this._bre
akpointResolved, this); | |
898 delete this._debuggerId; | |
899 callback(); | |
900 }, | |
901 | |
902 /** | |
903 * @param {!WebInspector.Event} event | |
904 */ | |
905 _breakpointResolved: function(event) | |
906 { | |
907 this._addResolvedLocation(/** @type {!WebInspector.DebuggerModel.Locatio
n}*/ (event.data)); | |
908 }, | |
909 | |
910 /** | |
911 * @param {!WebInspector.DebuggerModel.Location} location | |
912 * @param {!WebInspector.LiveLocation} liveLocation | |
913 */ | |
914 _locationUpdated: function(location, liveLocation) | |
915 { | |
916 var uiLocation = liveLocation.uiLocation(); | |
917 if (!uiLocation) | |
918 return; | |
919 var oldUILocation = this._uiLocations.get(location.id()) || null; | |
920 this._uiLocations.set(location.id(), uiLocation); | |
921 this._breakpoint._replaceUILocation(oldUILocation, uiLocation); | |
922 }, | |
923 | |
924 /** | |
925 * @param {!WebInspector.DebuggerModel.Location} location | |
926 * @return {boolean} | |
927 */ | |
928 _addResolvedLocation: function(location) | |
929 { | |
930 var uiLocation = this._debuggerWorkspaceBinding.rawLocationToUILocation(
location); | |
931 var breakpoint = this._breakpoint._breakpointManager.findBreakpoint(uiLo
cation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber); | |
932 if (breakpoint && breakpoint !== this._breakpoint) { | |
933 // location clash | |
934 this._breakpoint.remove(); | |
935 return false; | |
936 } | |
937 this._debuggerWorkspaceBinding.createLiveLocation(location, this._locati
onUpdated.bind(this, location), this._liveLocations); | |
938 return true; | |
939 }, | |
940 | |
941 _cleanUpAfterDebuggerIsGone: function() | |
942 { | |
943 if (this._isUpdating) | |
944 this._cancelCallback = true; | |
945 | |
946 this._resetLocations(); | |
947 this._currentState = null; | |
948 if (this._debuggerId) | |
949 this._didRemoveFromDebugger(function() {}); | |
950 }, | |
951 | |
952 _removeEventListeners: function() | |
953 { | |
954 this._debuggerModel.removeEventListener(WebInspector.DebuggerModel.Event
s.DebuggerWasDisabled, this._cleanUpAfterDebuggerIsGone, this); | |
955 this._debuggerModel.removeEventListener(WebInspector.DebuggerModel.Event
s.DebuggerWasEnabled, this._scheduleUpdateInDebugger, this); | |
956 }, | |
957 | |
958 __proto__: WebInspector.SDKObject.prototype | |
959 }; | |
960 | |
961 /** | 925 /** |
962 * @constructor | 926 * @unrestricted |
963 * @param {?string} url | |
964 * @param {?string} scriptId | |
965 * @param {number} lineNumber | |
966 * @param {number} columnNumber | |
967 * @param {string} condition | |
968 */ | 927 */ |
969 WebInspector.BreakpointManager.Breakpoint.State = function(url, scriptId, lineNu
mber, columnNumber, condition) | 928 WebInspector.BreakpointManager.Breakpoint.State = class { |
970 { | 929 /** |
| 930 * @param {?string} url |
| 931 * @param {?string} scriptId |
| 932 * @param {number} lineNumber |
| 933 * @param {number} columnNumber |
| 934 * @param {string} condition |
| 935 */ |
| 936 constructor(url, scriptId, lineNumber, columnNumber, condition) { |
971 this.url = url; | 937 this.url = url; |
972 this.scriptId = scriptId; | 938 this.scriptId = scriptId; |
973 this.lineNumber = lineNumber; | 939 this.lineNumber = lineNumber; |
974 this.columnNumber = columnNumber; | 940 this.columnNumber = columnNumber; |
975 this.condition = condition; | 941 this.condition = condition; |
| 942 } |
| 943 |
| 944 /** |
| 945 * @param {?WebInspector.BreakpointManager.Breakpoint.State|undefined} stateA |
| 946 * @param {?WebInspector.BreakpointManager.Breakpoint.State|undefined} stateB |
| 947 * @return {boolean} |
| 948 */ |
| 949 static equals(stateA, stateB) { |
| 950 if (!stateA || !stateB) |
| 951 return false; |
| 952 |
| 953 if (stateA.scriptId || stateB.scriptId) |
| 954 return false; |
| 955 |
| 956 return stateA.url === stateB.url && stateA.lineNumber === stateB.lineNumber
&& |
| 957 stateA.columnNumber === stateB.columnNumber && stateA.condition === stat
eB.condition; |
| 958 } |
976 }; | 959 }; |
977 | 960 |
| 961 |
978 /** | 962 /** |
979 * @param {?WebInspector.BreakpointManager.Breakpoint.State|undefined} stateA | 963 * @unrestricted |
980 * @param {?WebInspector.BreakpointManager.Breakpoint.State|undefined} stateB | |
981 * @return {boolean} | |
982 */ | 964 */ |
983 WebInspector.BreakpointManager.Breakpoint.State.equals = function(stateA, stateB
) | 965 WebInspector.BreakpointManager.Storage = class { |
984 { | 966 /** |
985 if (!stateA || !stateB) | 967 * @param {!WebInspector.BreakpointManager} breakpointManager |
986 return false; | 968 * @param {?WebInspector.Setting} setting |
987 | 969 */ |
988 if (stateA.scriptId || stateB.scriptId) | 970 constructor(breakpointManager, setting) { |
989 return false; | |
990 | |
991 return stateA.url === stateB.url && stateA.lineNumber === stateB.lineNumber
&& stateA.columnNumber === stateB.columnNumber && stateA.condition === stateB.co
ndition; | |
992 }; | |
993 | |
994 /** | |
995 * @constructor | |
996 * @param {!WebInspector.BreakpointManager} breakpointManager | |
997 * @param {?WebInspector.Setting} setting | |
998 */ | |
999 WebInspector.BreakpointManager.Storage = function(breakpointManager, setting) | |
1000 { | |
1001 this._breakpointManager = breakpointManager; | 971 this._breakpointManager = breakpointManager; |
1002 this._setting = setting || WebInspector.settings.createLocalSetting("breakpo
ints", []); | 972 this._setting = setting || WebInspector.settings.createLocalSetting('breakpo
ints', []); |
1003 var breakpoints = this._setting.get(); | 973 var breakpoints = this._setting.get(); |
1004 /** @type {!Object.<string, !WebInspector.BreakpointManager.Storage.Item>} *
/ | 974 /** @type {!Object.<string, !WebInspector.BreakpointManager.Storage.Item>} *
/ |
1005 this._breakpoints = {}; | 975 this._breakpoints = {}; |
1006 for (var i = 0; i < breakpoints.length; ++i) { | 976 for (var i = 0; i < breakpoints.length; ++i) { |
1007 var breakpoint = /** @type {!WebInspector.BreakpointManager.Storage.Item
} */ (breakpoints[i]); | 977 var breakpoint = /** @type {!WebInspector.BreakpointManager.Storage.Item}
*/ (breakpoints[i]); |
1008 breakpoint.columnNumber = breakpoint.columnNumber || 0; | 978 breakpoint.columnNumber = breakpoint.columnNumber || 0; |
1009 this._breakpoints[breakpoint.sourceFileId + ":" + breakpoint.lineNumber
+ ":" + breakpoint.columnNumber] = breakpoint; | 979 this._breakpoints[breakpoint.sourceFileId + ':' + breakpoint.lineNumber +
':' + breakpoint.columnNumber] = |
1010 } | 980 breakpoint; |
| 981 } |
| 982 } |
| 983 |
| 984 mute() { |
| 985 this._muted = true; |
| 986 } |
| 987 |
| 988 unmute() { |
| 989 delete this._muted; |
| 990 } |
| 991 |
| 992 /** |
| 993 * @param {string} sourceFileId |
| 994 * @return {!Array.<!WebInspector.BreakpointManager.Storage.Item>} |
| 995 */ |
| 996 breakpointItems(sourceFileId) { |
| 997 var result = []; |
| 998 for (var id in this._breakpoints) { |
| 999 var breakpoint = this._breakpoints[id]; |
| 1000 if (breakpoint.sourceFileId === sourceFileId) |
| 1001 result.push(breakpoint); |
| 1002 } |
| 1003 return result; |
| 1004 } |
| 1005 |
| 1006 /** |
| 1007 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint |
| 1008 */ |
| 1009 _updateBreakpoint(breakpoint) { |
| 1010 if (this._muted || !breakpoint._breakpointStorageId()) |
| 1011 return; |
| 1012 this._breakpoints[breakpoint._breakpointStorageId()] = new WebInspector.Brea
kpointManager.Storage.Item(breakpoint); |
| 1013 this._save(); |
| 1014 } |
| 1015 |
| 1016 /** |
| 1017 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint |
| 1018 */ |
| 1019 _removeBreakpoint(breakpoint) { |
| 1020 if (this._muted) |
| 1021 return; |
| 1022 delete this._breakpoints[breakpoint._breakpointStorageId()]; |
| 1023 this._save(); |
| 1024 } |
| 1025 |
| 1026 _save() { |
| 1027 var breakpointsArray = []; |
| 1028 for (var id in this._breakpoints) |
| 1029 breakpointsArray.push(this._breakpoints[id]); |
| 1030 this._setting.set(breakpointsArray); |
| 1031 } |
1011 }; | 1032 }; |
1012 | 1033 |
1013 WebInspector.BreakpointManager.Storage.prototype = { | |
1014 mute: function() | |
1015 { | |
1016 this._muted = true; | |
1017 }, | |
1018 | |
1019 unmute: function() | |
1020 { | |
1021 delete this._muted; | |
1022 }, | |
1023 | |
1024 /** | |
1025 * @param {string} sourceFileId | |
1026 * @return {!Array.<!WebInspector.BreakpointManager.Storage.Item>} | |
1027 */ | |
1028 breakpointItems: function(sourceFileId) | |
1029 { | |
1030 var result = []; | |
1031 for (var id in this._breakpoints) { | |
1032 var breakpoint = this._breakpoints[id]; | |
1033 if (breakpoint.sourceFileId === sourceFileId) | |
1034 result.push(breakpoint); | |
1035 } | |
1036 return result; | |
1037 }, | |
1038 | |
1039 /** | |
1040 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint | |
1041 */ | |
1042 _updateBreakpoint: function(breakpoint) | |
1043 { | |
1044 if (this._muted || !breakpoint._breakpointStorageId()) | |
1045 return; | |
1046 this._breakpoints[breakpoint._breakpointStorageId()] = new WebInspector.
BreakpointManager.Storage.Item(breakpoint); | |
1047 this._save(); | |
1048 }, | |
1049 | |
1050 /** | |
1051 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint | |
1052 */ | |
1053 _removeBreakpoint: function(breakpoint) | |
1054 { | |
1055 if (this._muted) | |
1056 return; | |
1057 delete this._breakpoints[breakpoint._breakpointStorageId()]; | |
1058 this._save(); | |
1059 }, | |
1060 | |
1061 _save: function() | |
1062 { | |
1063 var breakpointsArray = []; | |
1064 for (var id in this._breakpoints) | |
1065 breakpointsArray.push(this._breakpoints[id]); | |
1066 this._setting.set(breakpointsArray); | |
1067 } | |
1068 }; | |
1069 | |
1070 /** | 1034 /** |
1071 * @constructor | 1035 * @unrestricted |
1072 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint | |
1073 */ | 1036 */ |
1074 WebInspector.BreakpointManager.Storage.Item = function(breakpoint) | 1037 WebInspector.BreakpointManager.Storage.Item = class { |
1075 { | 1038 /** |
| 1039 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint |
| 1040 */ |
| 1041 constructor(breakpoint) { |
1076 this.sourceFileId = breakpoint._sourceFileId; | 1042 this.sourceFileId = breakpoint._sourceFileId; |
1077 this.lineNumber = breakpoint.lineNumber(); | 1043 this.lineNumber = breakpoint.lineNumber(); |
1078 this.columnNumber = breakpoint.columnNumber(); | 1044 this.columnNumber = breakpoint.columnNumber(); |
1079 this.condition = breakpoint.condition(); | 1045 this.condition = breakpoint.condition(); |
1080 this.enabled = breakpoint.enabled(); | 1046 this.enabled = breakpoint.enabled(); |
| 1047 } |
1081 }; | 1048 }; |
1082 | 1049 |
1083 /** @type {!WebInspector.BreakpointManager} */ | 1050 /** @type {!WebInspector.BreakpointManager} */ |
1084 WebInspector.breakpointManager; | 1051 WebInspector.breakpointManager; |
OLD | NEW |