1/* 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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. 29 */ 30 31/** 32 * @constructor 33 * @extends {WebInspector.Object} 34 * @param {WebInspector.Setting} breakpointStorage 35 * @param {WebInspector.DebuggerModel} debuggerModel 36 * @param {WebInspector.Workspace} workspace 37 */ 38WebInspector.BreakpointManager = function(breakpointStorage, debuggerModel, workspace) 39{ 40 this._storage = new WebInspector.BreakpointManager.Storage(this, breakpointStorage); 41 this._debuggerModel = debuggerModel; 42 this._workspace = workspace; 43 44 this._breakpoints = new Map(); 45 this._breakpointForDebuggerId = {}; 46 this._breakpointsForUISourceCode = new Map(); 47 this._sourceFilesWithRestoredBreakpoints = {}; 48 49 this._debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this); 50 this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._projectWillReset, this); 51 this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this); 52} 53 54WebInspector.BreakpointManager.Events = { 55 BreakpointAdded: "breakpoint-added", 56 BreakpointRemoved: "breakpoint-removed" 57} 58 59WebInspector.BreakpointManager.sourceFileId = function(uiSourceCode) 60{ 61 if (!uiSourceCode.url) 62 return ""; 63 var deobfuscatedPrefix = uiSourceCode.formatted() ? "deobfuscated:" : ""; 64 return deobfuscatedPrefix + uiSourceCode.uri(); 65} 66 67WebInspector.BreakpointManager.prototype = { 68 /** 69 * @param {WebInspector.UISourceCode} uiSourceCode 70 */ 71 _restoreBreakpoints: function(uiSourceCode) 72 { 73 var sourceFileId = WebInspector.BreakpointManager.sourceFileId(uiSourceCode); 74 if (!sourceFileId || this._sourceFilesWithRestoredBreakpoints[sourceFileId]) 75 return; 76 this._sourceFilesWithRestoredBreakpoints[sourceFileId] = true; 77 78 // Erase provisional breakpoints prior to restoring them. 79 for (var debuggerId in this._breakpointForDebuggerId) { 80 var breakpoint = this._breakpointForDebuggerId[debuggerId]; 81 if (breakpoint._sourceFileId !== sourceFileId) 82 continue; 83 breakpoint.remove(true); 84 } 85 this._storage._restoreBreakpoints(uiSourceCode); 86 }, 87 88 /** 89 * @param {WebInspector.Event} event 90 */ 91 _uiSourceCodeAdded: function(event) 92 { 93 var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data); 94 this._restoreBreakpoints(uiSourceCode); 95 if (uiSourceCode.contentType() === WebInspector.resourceTypes.Script || uiSourceCode.contentType() === WebInspector.resourceTypes.Document) { 96 uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.SourceMappingChanged, this._uiSourceCodeMappingChanged, this); 97 uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.FormattedChanged, this._uiSourceCodeFormatted, this); 98 } 99 }, 100 101 /** 102 * @param {WebInspector.Event} event 103 */ 104 _uiSourceCodeFormatted: function(event) 105 { 106 var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.target); 107 this._restoreBreakpoints(uiSourceCode); 108 }, 109 110 /** 111 * @param {WebInspector.UISourceCode} uiSourceCode 112 */ 113 _resetBreakpoints: function(uiSourceCode) 114 { 115 var sourceFileId = WebInspector.BreakpointManager.sourceFileId(uiSourceCode); 116 var breakpoints = this._breakpoints.keys(); 117 for (var i = 0; i < breakpoints.length; ++i) { 118 var breakpoint = breakpoints[i]; 119 if (breakpoint._sourceFileId !== sourceFileId) 120 return; 121 if (breakpoint.enabled()) { 122 breakpoint._removeFromDebugger(); 123 breakpoint._setInDebugger(); 124 } 125 } 126 }, 127 128 /** 129 * @param {WebInspector.Event} event 130 */ 131 _uiSourceCodeMappingChanged: function(event) 132 { 133 var identityHasChanged = /** @type {boolean} */ (event.data.identityHasChanged); 134 if (!identityHasChanged) 135 return; 136 var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.target); 137 this._resetBreakpoints(uiSourceCode); 138 }, 139 140 /** 141 * @param {WebInspector.UISourceCode} uiSourceCode 142 * @param {number} lineNumber 143 * @param {string} condition 144 * @param {boolean} enabled 145 * @return {WebInspector.BreakpointManager.Breakpoint} 146 */ 147 setBreakpoint: function(uiSourceCode, lineNumber, condition, enabled) 148 { 149 this._debuggerModel.setBreakpointsActive(true); 150 return this._innerSetBreakpoint(uiSourceCode, lineNumber, condition, enabled); 151 }, 152 153 /** 154 * @param {WebInspector.UISourceCode} uiSourceCode 155 * @param {number} lineNumber 156 * @param {string} condition 157 * @param {boolean} enabled 158 * @return {WebInspector.BreakpointManager.Breakpoint} 159 */ 160 _innerSetBreakpoint: function(uiSourceCode, lineNumber, condition, enabled) 161 { 162 var breakpoint = this.findBreakpoint(uiSourceCode, lineNumber); 163 if (breakpoint) { 164 breakpoint._updateBreakpoint(condition, enabled); 165 return breakpoint; 166 } 167 breakpoint = new WebInspector.BreakpointManager.Breakpoint(this, uiSourceCode, lineNumber, condition, enabled); 168 this._breakpoints.put(breakpoint); 169 return breakpoint; 170 }, 171 172 /** 173 * @param {WebInspector.UISourceCode} uiSourceCode 174 * @param {number} lineNumber 175 * @return {?WebInspector.BreakpointManager.Breakpoint} 176 */ 177 findBreakpoint: function(uiSourceCode, lineNumber) 178 { 179 var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); 180 var lineBreakpoints = breakpoints ? breakpoints[lineNumber] : null; 181 return lineBreakpoints ? lineBreakpoints[0] : null; 182 }, 183 184 /** 185 * @param {WebInspector.UISourceCode} uiSourceCode 186 * @return {Array.<WebInspector.BreakpointManager.Breakpoint>} 187 */ 188 breakpointsForUISourceCode: function(uiSourceCode) 189 { 190 var result = []; 191 var breakpoints = /** @type {Array.<WebInspector.BreakpointManager.Breakpoint>} */(this._breakpoints.keys()); 192 for (var i = 0; i < breakpoints.length; ++i) { 193 var breakpoint = breakpoints[i]; 194 var uiLocation = breakpoint._primaryUILocation; 195 if (uiLocation.uiSourceCode === uiSourceCode) 196 result.push(breakpoint); 197 } 198 return result; 199 }, 200 201 /** 202 * @return {Array.<WebInspector.BreakpointManager.Breakpoint>} 203 */ 204 allBreakpoints: function() 205 { 206 var result = []; 207 var breakpoints = /** @type {Array.<WebInspector.BreakpointManager.Breakpoint>} */(this._breakpoints.keys()); 208 return breakpoints; 209 }, 210 211 /** 212 * @param {WebInspector.UISourceCode} uiSourceCode 213 * @return {Array.<{breakpoint: WebInspector.BreakpointManager.Breakpoint, uiLocation: WebInspector.UILocation}>} 214 */ 215 breakpointLocationsForUISourceCode: function(uiSourceCode) 216 { 217 var result = []; 218 var breakpoints = /** @type {Array.<WebInspector.BreakpointManager.Breakpoint>} */(this._breakpoints.keys()); 219 for (var i = 0; i < breakpoints.length; ++i) { 220 var breakpoint = breakpoints[i]; 221 var uiLocations = Object.values(breakpoint._uiLocations); 222 for (var j = 0; j < uiLocations.length; ++j) { 223 var uiLocation = uiLocations[j]; 224 if (uiLocation.uiSourceCode === uiSourceCode) 225 result.push({breakpoint: breakpoint, uiLocation: uiLocations[j]}); 226 } 227 } 228 return result; 229 }, 230 231 /** 232 * @return {Array.<{breakpoint: WebInspector.BreakpointManager.Breakpoint, uiLocation: WebInspector.UILocation}>} 233 */ 234 allBreakpointLocations: function() 235 { 236 var result = []; 237 var breakpoints = /** @type {Array.<WebInspector.BreakpointManager.Breakpoint>} */(this._breakpoints.keys()); 238 for (var i = 0; i < breakpoints.length; ++i) { 239 var breakpoint = breakpoints[i]; 240 var uiLocations = Object.values(breakpoint._uiLocations); 241 for (var j = 0; j < uiLocations.length; ++j) 242 result.push({breakpoint: breakpoint, uiLocation: uiLocations[j]}); 243 } 244 return result; 245 }, 246 247 /** 248 * @param {boolean} toggleState 249 */ 250 toggleAllBreakpoints: function(toggleState) 251 { 252 var breakpoints = /** @type {Array.<WebInspector.BreakpointManager.Breakpoint>} */(this._breakpoints.keys()); 253 for (var i = 0; i < breakpoints.length; ++i) { 254 var breakpoint = breakpoints[i]; 255 if (breakpoint.enabled() != toggleState) 256 breakpoint.setEnabled(toggleState); 257 } 258 }, 259 260 removeAllBreakpoints: function() 261 { 262 var breakpoints = /** @type {Array.<WebInspector.BreakpointManager.Breakpoint>} */(this._breakpoints.keys()); 263 for (var i = 0; i < breakpoints.length; ++i) 264 breakpoints[i].remove(); 265 }, 266 267 reset: function() 268 { 269 // Remove all breakpoints from UI and debugger, do not update storage. 270 this._storage._muted = true; 271 this.removeAllBreakpoints(); 272 delete this._storage._muted; 273 274 // Remove all provisional breakpoints from the debugger. 275 for (var debuggerId in this._breakpointForDebuggerId) 276 this._debuggerModel.removeBreakpoint(debuggerId); 277 this._breakpointForDebuggerId = {}; 278 this._sourceFilesWithRestoredBreakpoints = {}; 279 }, 280 281 _projectWillReset: function(event) 282 { 283 var project = /** @type {WebInspector.Project} */ (event.data); 284 var uiSourceCodes = project.uiSourceCodes(); 285 for (var i = 0; i < uiSourceCodes.length; ++i) { 286 var uiSourceCode = uiSourceCodes[i]; 287 var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode) || []; 288 for (var lineNumber in breakpoints) { 289 var lineBreakpoints = breakpoints[lineNumber]; 290 for (var j = 0; j < lineBreakpoints.length; ++j) { 291 var breakpoint = lineBreakpoints[j]; 292 breakpoint._resetLocations(); 293 } 294 } 295 this._breakpointsForUISourceCode.remove(uiSourceCode); 296 297 breakpoints = this.breakpointsForUISourceCode(uiSourceCode); 298 for (var j = 0; j < breakpoints.length; ++j) { 299 var breakpoint = breakpoints[j]; 300 this._breakpoints.remove(breakpoint); 301 delete breakpoint._primaryUILocation; 302 } 303 304 var sourceFileId = WebInspector.BreakpointManager.sourceFileId(uiSourceCode); 305 delete this._sourceFilesWithRestoredBreakpoints[sourceFileId]; 306 } 307 }, 308 309 _breakpointResolved: function(event) 310 { 311 var breakpointId = /** @type {DebuggerAgent.BreakpointId} */ (event.data.breakpointId); 312 var location = /** @type {WebInspector.DebuggerModel.Location} */ (event.data.location); 313 var breakpoint = this._breakpointForDebuggerId[breakpointId]; 314 if (!breakpoint) 315 return; 316 if (!this._breakpoints.contains(breakpoint)) 317 this._breakpoints.put(breakpoint); 318 breakpoint._addResolvedLocation(location); 319 }, 320 321 /** 322 * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint 323 * @param {boolean} removeFromStorage 324 */ 325 _removeBreakpoint: function(breakpoint, removeFromStorage) 326 { 327 console.assert(!breakpoint._debuggerId) 328 this._breakpoints.remove(breakpoint); 329 if (removeFromStorage) 330 this._storage._removeBreakpoint(breakpoint); 331 }, 332 333 /** 334 * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint 335 * @param {WebInspector.UILocation} uiLocation 336 */ 337 _uiLocationAdded: function(breakpoint, uiLocation) 338 { 339 var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode); 340 if (!breakpoints) { 341 breakpoints = {}; 342 this._breakpointsForUISourceCode.put(uiLocation.uiSourceCode, breakpoints); 343 } 344 345 var lineBreakpoints = breakpoints[uiLocation.lineNumber]; 346 if (!lineBreakpoints) { 347 lineBreakpoints = []; 348 breakpoints[uiLocation.lineNumber] = lineBreakpoints; 349 } 350 351 lineBreakpoints.push(breakpoint); 352 this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointAdded, {breakpoint: breakpoint, uiLocation: uiLocation}); 353 }, 354 355 /** 356 * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint 357 * @param {WebInspector.UILocation} uiLocation 358 */ 359 _uiLocationRemoved: function(breakpoint, uiLocation) 360 { 361 var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode); 362 if (!breakpoints) 363 return; 364 365 var lineBreakpoints = breakpoints[uiLocation.lineNumber]; 366 if (!lineBreakpoints) 367 return; 368 369 lineBreakpoints.remove(breakpoint); 370 if (!lineBreakpoints.length) 371 delete breakpoints[uiLocation.lineNumber]; 372 this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointRemoved, {breakpoint: breakpoint, uiLocation: uiLocation}); 373 }, 374 375 __proto__: WebInspector.Object.prototype 376} 377 378/** 379 * @constructor 380 * @param {WebInspector.BreakpointManager} breakpointManager 381 * @param {WebInspector.UISourceCode} uiSourceCode 382 * @param {number} lineNumber 383 * @param {string} condition 384 * @param {boolean} enabled 385 */ 386WebInspector.BreakpointManager.Breakpoint = function(breakpointManager, uiSourceCode, lineNumber, condition, enabled) 387{ 388 this._breakpointManager = breakpointManager; 389 this._primaryUILocation = new WebInspector.UILocation(uiSourceCode, lineNumber, 0); 390 this._sourceFileId = WebInspector.BreakpointManager.sourceFileId(uiSourceCode); 391 /** @type {Array.<WebInspector.Script.Location>} */ 392 this._liveLocations = []; 393 /** @type {Object.<string, WebInspector.UILocation>} */ 394 this._uiLocations = {}; 395 396 // Force breakpoint update. 397 /** @type {string} */ this._condition; 398 /** @type {boolean} */ this._enabled; 399 this._updateBreakpoint(condition, enabled); 400} 401 402WebInspector.BreakpointManager.Breakpoint.prototype = { 403 /** 404 * @return {WebInspector.UILocation} 405 */ 406 primaryUILocation: function() 407 { 408 return this._primaryUILocation; 409 }, 410 411 /** 412 * @param {WebInspector.DebuggerModel.Location} location 413 */ 414 _addResolvedLocation: function(location) 415 { 416 this._liveLocations.push(this._breakpointManager._debuggerModel.createLiveLocation(location, this._locationUpdated.bind(this, location))); 417 }, 418 419 /** 420 * @param {WebInspector.DebuggerModel.Location} location 421 * @param {WebInspector.UILocation} uiLocation 422 */ 423 _locationUpdated: function(location, uiLocation) 424 { 425 var stringifiedLocation = location.scriptId + ":" + location.lineNumber + ":" + location.columnNumber; 426 var oldUILocation = /** @type {WebInspector.UILocation} */ (this._uiLocations[stringifiedLocation]); 427 if (oldUILocation) 428 this._breakpointManager._uiLocationRemoved(this, oldUILocation); 429 if (this._uiLocations[""]) { 430 delete this._uiLocations[""]; 431 this._breakpointManager._uiLocationRemoved(this, this._primaryUILocation); 432 } 433 this._uiLocations[stringifiedLocation] = uiLocation; 434 this._breakpointManager._uiLocationAdded(this, uiLocation); 435 }, 436 437 /** 438 * @return {boolean} 439 */ 440 enabled: function() 441 { 442 return this._enabled; 443 }, 444 445 /** 446 * @param {boolean} enabled 447 */ 448 setEnabled: function(enabled) 449 { 450 this._updateBreakpoint(this._condition, enabled); 451 }, 452 453 /** 454 * @return {string} 455 */ 456 condition: function() 457 { 458 return this._condition; 459 }, 460 461 /** 462 * @param {string} condition 463 */ 464 setCondition: function(condition) 465 { 466 this._updateBreakpoint(condition, this._enabled); 467 }, 468 469 /** 470 * @param {string} condition 471 * @param {boolean} enabled 472 */ 473 _updateBreakpoint: function(condition, enabled) 474 { 475 if (this._enabled === enabled && this._condition === condition) 476 return; 477 478 if (this._enabled) 479 this._removeFromDebugger(); 480 481 this._enabled = enabled; 482 this._condition = condition; 483 this._breakpointManager._storage._updateBreakpoint(this); 484 485 var scriptFile = this._primaryUILocation.uiSourceCode.scriptFile(); 486 if (this._enabled && !(scriptFile && scriptFile.hasDivergedFromVM())) { 487 this._setInDebugger(); 488 return; 489 } 490 491 this._fakeBreakpointAtPrimaryLocation(); 492 }, 493 494 /** 495 * @param {boolean=} keepInStorage 496 */ 497 remove: function(keepInStorage) 498 { 499 var removeFromStorage = !keepInStorage; 500 this._resetLocations(); 501 this._removeFromDebugger(); 502 this._breakpointManager._removeBreakpoint(this, removeFromStorage); 503 }, 504 505 _setInDebugger: function() 506 { 507 console.assert(!this._debuggerId); 508 var rawLocation = this._primaryUILocation.uiLocationToRawLocation(); 509 var debuggerModelLocation = /** @type {WebInspector.DebuggerModel.Location} */ (rawLocation); 510 if (debuggerModelLocation) 511 this._breakpointManager._debuggerModel.setBreakpointByScriptLocation(debuggerModelLocation, this._condition, didSetBreakpoint.bind(this)); 512 else 513 this._breakpointManager._debuggerModel.setBreakpointByURL(this._primaryUILocation.uiSourceCode.url, this._primaryUILocation.lineNumber, 0, this._condition, didSetBreakpoint.bind(this)); 514 515 /** 516 * @this {WebInspector.BreakpointManager.Breakpoint} 517 * @param {?DebuggerAgent.BreakpointId} breakpointId 518 * @param {Array.<WebInspector.DebuggerModel.Location>} locations 519 */ 520 function didSetBreakpoint(breakpointId, locations) 521 { 522 if (!breakpointId) { 523 this._resetLocations(); 524 this._breakpointManager._removeBreakpoint(this, false); 525 return; 526 } 527 528 this._debuggerId = breakpointId; 529 this._breakpointManager._breakpointForDebuggerId[breakpointId] = this; 530 531 if (!locations.length) { 532 this._fakeBreakpointAtPrimaryLocation(); 533 return; 534 } 535 536 this._resetLocations(); 537 for (var i = 0; i < locations.length; ++i) { 538 var script = this._breakpointManager._debuggerModel.scriptForId(locations[i].scriptId); 539 var uiLocation = script.rawLocationToUILocation(locations[i].lineNumber, locations[i].columnNumber); 540 if (this._breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber)) { 541 // location clash 542 this.remove(); 543 return; 544 } 545 } 546 547 for (var i = 0; i < locations.length; ++i) 548 this._addResolvedLocation(locations[i]); 549 } 550 }, 551 552 _removeFromDebugger: function() 553 { 554 if (this._debuggerId) { 555 this._breakpointManager._debuggerModel.removeBreakpoint(this._debuggerId); 556 delete this._breakpointManager._breakpointForDebuggerId[this._debuggerId]; 557 delete this._debuggerId; 558 } 559 }, 560 561 _resetLocations: function() 562 { 563 for (var stringifiedLocation in this._uiLocations) 564 this._breakpointManager._uiLocationRemoved(this, this._uiLocations[stringifiedLocation]); 565 566 for (var i = 0; i < this._liveLocations.length; ++i) 567 this._liveLocations[i].dispose(); 568 this._liveLocations = []; 569 570 this._uiLocations = {}; 571 }, 572 573 /** 574 * @return {string} 575 */ 576 _breakpointStorageId: function() 577 { 578 if (!this._sourceFileId) 579 return ""; 580 return this._sourceFileId + ":" + this._primaryUILocation.lineNumber; 581 }, 582 583 _fakeBreakpointAtPrimaryLocation: function() 584 { 585 this._resetLocations(); 586 this._uiLocations[""] = this._primaryUILocation; 587 this._breakpointManager._uiLocationAdded(this, this._primaryUILocation); 588 } 589} 590 591/** 592 * @constructor 593 * @param {WebInspector.BreakpointManager} breakpointManager 594 * @param {WebInspector.Setting} setting 595 */ 596WebInspector.BreakpointManager.Storage = function(breakpointManager, setting) 597{ 598 this._breakpointManager = breakpointManager; 599 this._setting = setting; 600 var breakpoints = this._setting.get(); 601 /** @type {Object.<string,WebInspector.BreakpointManager.Storage.Item>} */ 602 this._breakpoints = {}; 603 for (var i = 0; i < breakpoints.length; ++i) { 604 var breakpoint = /** @type {WebInspector.BreakpointManager.Storage.Item} */ (breakpoints[i]); 605 this._breakpoints[breakpoint.sourceFileId + ":" + breakpoint.lineNumber] = breakpoint; 606 } 607} 608 609WebInspector.BreakpointManager.Storage.prototype = { 610 /** 611 * @param {WebInspector.UISourceCode} uiSourceCode 612 */ 613 _restoreBreakpoints: function(uiSourceCode) 614 { 615 this._muted = true; 616 var sourceFileId = WebInspector.BreakpointManager.sourceFileId(uiSourceCode); 617 for (var id in this._breakpoints) { 618 var breakpoint = this._breakpoints[id]; 619 if (breakpoint.sourceFileId === sourceFileId) 620 this._breakpointManager._innerSetBreakpoint(uiSourceCode, breakpoint.lineNumber, breakpoint.condition, breakpoint.enabled); 621 } 622 delete this._muted; 623 }, 624 625 /** 626 * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint 627 */ 628 _updateBreakpoint: function(breakpoint) 629 { 630 if (this._muted || !breakpoint._breakpointStorageId()) 631 return; 632 this._breakpoints[breakpoint._breakpointStorageId()] = new WebInspector.BreakpointManager.Storage.Item(breakpoint); 633 this._save(); 634 }, 635 636 /** 637 * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint 638 */ 639 _removeBreakpoint: function(breakpoint) 640 { 641 if (this._muted) 642 return; 643 delete this._breakpoints[breakpoint._breakpointStorageId()]; 644 this._save(); 645 }, 646 647 _save: function() 648 { 649 var breakpointsArray = []; 650 for (var id in this._breakpoints) 651 breakpointsArray.push(this._breakpoints[id]); 652 this._setting.set(breakpointsArray); 653 } 654} 655 656/** 657 * @constructor 658 * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint 659 */ 660WebInspector.BreakpointManager.Storage.Item = function(breakpoint) 661{ 662 var primaryUILocation = breakpoint.primaryUILocation(); 663 this.sourceFileId = breakpoint._sourceFileId; 664 this.lineNumber = primaryUILocation.lineNumber; 665 this.condition = breakpoint.condition(); 666 this.enabled = breakpoint.enabled(); 667} 668 669/** @type {WebInspector.BreakpointManager} */ 670WebInspector.breakpointManager = null; 671