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 */ 38 WebInspector.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.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this); 52 } 53 54 WebInspector.BreakpointManager.Events = { 55 BreakpointAdded: "breakpoint-added", 56 BreakpointRemoved: "breakpoint-removed" 57 } 58 59 WebInspector.BreakpointManager.sourceFileId = function(uiSourceCode) 60 { 61 if (!uiSourceCode.url) 62 return ""; 63 var deobfuscatedPrefix = uiSourceCode.formatted() ? "deobfuscated:" : ""; 64 return deobfuscatedPrefix + uiSourceCode.uri(); 65 } 66 67 WebInspector.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 } 302 303 var sourceFileId = WebInspector.BreakpointManager.sourceFileId(uiSourceCode); 304 delete this._sourceFilesWithRestoredBreakpoints[sourceFileId]; 305 } 306 }, 307 308 _breakpointResolved: function(event) 309 { 310 var breakpointId = /** @type {DebuggerAgent.BreakpointId} */ (event.data.breakpointId); 311 var location = /** @type {WebInspector.DebuggerModel.Location} */ (event.data.location); 312 var breakpoint = this._breakpointForDebuggerId[breakpointId]; 313 if (!breakpoint) 314 return; 315 if (!this._breakpoints.contains(breakpoint)) 316 this._breakpoints.put(breakpoint); 317 breakpoint._addResolvedLocation(location); 318 }, 319 320 /** 321 * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint 322 * @param {boolean} removeFromStorage 323 */ 324 _removeBreakpoint: function(breakpoint, removeFromStorage) 325 { 326 console.assert(!breakpoint._debuggerId) 327 this._breakpoints.remove(breakpoint); 328 if (removeFromStorage) 329 this._storage._removeBreakpoint(breakpoint); 330 }, 331 332 /** 333 * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint 334 * @param {WebInspector.UILocation} uiLocation 335 */ 336 _uiLocationAdded: function(breakpoint, uiLocation) 337 { 338 var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode); 339 if (!breakpoints) { 340 breakpoints = {}; 341 this._breakpointsForUISourceCode.put(uiLocation.uiSourceCode, breakpoints); 342 } 343 344 var lineBreakpoints = breakpoints[uiLocation.lineNumber]; 345 if (!lineBreakpoints) { 346 lineBreakpoints = []; 347 breakpoints[uiLocation.lineNumber] = lineBreakpoints; 348 } 349 350 lineBreakpoints.push(breakpoint); 351 this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointAdded, {breakpoint: breakpoint, uiLocation: uiLocation}); 352 }, 353 354 /** 355 * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint 356 * @param {WebInspector.UILocation} uiLocation 357 */ 358 _uiLocationRemoved: function(breakpoint, uiLocation) 359 { 360 var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode); 361 if (!breakpoints) 362 return; 363 364 var lineBreakpoints = breakpoints[uiLocation.lineNumber]; 365 if (!lineBreakpoints) 366 return; 367 368 lineBreakpoints.remove(breakpoint); 369 if (!lineBreakpoints.length) 370 delete breakpoints[uiLocation.lineNumber]; 371 this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointRemoved, {breakpoint: breakpoint, uiLocation: uiLocation}); 372 }, 373 374 __proto__: WebInspector.Object.prototype 375 } 376 377 /** 378 * @constructor 379 * @param {WebInspector.BreakpointManager} breakpointManager 380 * @param {WebInspector.UISourceCode} uiSourceCode 381 * @param {number} lineNumber 382 * @param {string} condition 383 * @param {boolean} enabled 384 */ 385 WebInspector.BreakpointManager.Breakpoint = function(breakpointManager, uiSourceCode, lineNumber, condition, enabled) 386 { 387 this._breakpointManager = breakpointManager; 388 this._primaryUILocation = new WebInspector.UILocation(uiSourceCode, lineNumber, 0); 389 this._sourceFileId = WebInspector.BreakpointManager.sourceFileId(uiSourceCode); 390 /** @type {Array.<WebInspector.Script.Location>} */ 391 this._liveLocations = []; 392 /** @type {!Object.<string, WebInspector.UILocation>} */ 393 this._uiLocations = {}; 394 395 // Force breakpoint update. 396 /** @type {string} */ this._condition; 397 /** @type {boolean} */ this._enabled; 398 this._updateBreakpoint(condition, enabled); 399 } 400 401 WebInspector.BreakpointManager.Breakpoint.prototype = { 402 /** 403 * @return {WebInspector.UILocation} 404 */ 405 primaryUILocation: function() 406 { 407 return this._primaryUILocation; 408 }, 409 410 /** 411 * @param {WebInspector.DebuggerModel.Location} location 412 */ 413 _addResolvedLocation: function(location) 414 { 415 this._liveLocations.push(this._breakpointManager._debuggerModel.createLiveLocation(location, this._locationUpdated.bind(this, location))); 416 }, 417 418 /** 419 * @param {WebInspector.DebuggerModel.Location} location 420 * @param {WebInspector.UILocation} uiLocation 421 */ 422 _locationUpdated: function(location, uiLocation) 423 { 424 var stringifiedLocation = location.scriptId + ":" + location.lineNumber + ":" + location.columnNumber; 425 var oldUILocation = /** @type {WebInspector.UILocation} */ (this._uiLocations[stringifiedLocation]); 426 if (oldUILocation) 427 this._breakpointManager._uiLocationRemoved(this, oldUILocation); 428 if (this._uiLocations[""]) { 429 delete this._uiLocations[""]; 430 this._breakpointManager._uiLocationRemoved(this, this._primaryUILocation); 431 } 432 this._uiLocations[stringifiedLocation] = uiLocation; 433 this._breakpointManager._uiLocationAdded(this, uiLocation); 434 }, 435 436 /** 437 * @return {boolean} 438 */ 439 enabled: function() 440 { 441 return this._enabled; 442 }, 443 444 /** 445 * @param {boolean} enabled 446 */ 447 setEnabled: function(enabled) 448 { 449 this._updateBreakpoint(this._condition, enabled); 450 }, 451 452 /** 453 * @return {string} 454 */ 455 condition: function() 456 { 457 return this._condition; 458 }, 459 460 /** 461 * @param {string} condition 462 */ 463 setCondition: function(condition) 464 { 465 this._updateBreakpoint(condition, this._enabled); 466 }, 467 468 /** 469 * @param {string} condition 470 * @param {boolean} enabled 471 */ 472 _updateBreakpoint: function(condition, enabled) 473 { 474 if (this._enabled === enabled && this._condition === condition) 475 return; 476 477 if (this._enabled) 478 this._removeFromDebugger(); 479 480 this._enabled = enabled; 481 this._condition = condition; 482 this._breakpointManager._storage._updateBreakpoint(this); 483 484 var scriptFile = this._primaryUILocation.uiSourceCode.scriptFile(); 485 if (this._enabled && !(scriptFile && scriptFile.hasDivergedFromVM())) { 486 if (this._setInDebugger()) 487 return; 488 } 489 490 this._fakeBreakpointAtPrimaryLocation(); 491 }, 492 493 /** 494 * @param {boolean=} keepInStorage 495 */ 496 remove: function(keepInStorage) 497 { 498 var removeFromStorage = !keepInStorage; 499 this._resetLocations(); 500 this._removeFromDebugger(); 501 this._breakpointManager._removeBreakpoint(this, removeFromStorage); 502 }, 503 504 _setInDebugger: function() 505 { 506 console.assert(!this._debuggerId); 507 var rawLocation = this._primaryUILocation.uiLocationToRawLocation(); 508 var debuggerModelLocation = /** @type {WebInspector.DebuggerModel.Location} */ (rawLocation); 509 if (debuggerModelLocation) { 510 this._breakpointManager._debuggerModel.setBreakpointByScriptLocation(debuggerModelLocation, this._condition, this._didSetBreakpointInDebugger.bind(this)); 511 return true; 512 } 513 if (this._primaryUILocation.uiSourceCode.url) { 514 this._breakpointManager._debuggerModel.setBreakpointByURL(this._primaryUILocation.uiSourceCode.url, this._primaryUILocation.lineNumber, 0, this._condition, this._didSetBreakpointInDebugger.bind(this)); 515 return true; 516 } 517 return false; 518 }, 519 520 /** 521 * @this {WebInspector.BreakpointManager.Breakpoint} 522 * @param {?DebuggerAgent.BreakpointId} breakpointId 523 * @param {Array.<WebInspector.DebuggerModel.Location>} locations 524 */ 525 _didSetBreakpointInDebugger: function(breakpointId, locations) 526 { 527 if (!breakpointId) { 528 this._resetLocations(); 529 this._breakpointManager._removeBreakpoint(this, false); 530 return; 531 } 532 533 this._debuggerId = breakpointId; 534 this._breakpointManager._breakpointForDebuggerId[breakpointId] = this; 535 536 if (!locations.length) { 537 this._fakeBreakpointAtPrimaryLocation(); 538 return; 539 } 540 541 this._resetLocations(); 542 for (var i = 0; i < locations.length; ++i) { 543 var script = this._breakpointManager._debuggerModel.scriptForId(locations[i].scriptId); 544 var uiLocation = script.rawLocationToUILocation(locations[i].lineNumber, locations[i].columnNumber); 545 if (this._breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber)) { 546 // location clash 547 this.remove(); 548 return; 549 } 550 } 551 552 for (var i = 0; i < locations.length; ++i) 553 this._addResolvedLocation(locations[i]); 554 }, 555 556 _removeFromDebugger: function() 557 { 558 if (this._debuggerId) { 559 this._breakpointManager._debuggerModel.removeBreakpoint(this._debuggerId); 560 delete this._breakpointManager._breakpointForDebuggerId[this._debuggerId]; 561 delete this._debuggerId; 562 } 563 }, 564 565 _resetLocations: function() 566 { 567 for (var stringifiedLocation in this._uiLocations) 568 this._breakpointManager._uiLocationRemoved(this, this._uiLocations[stringifiedLocation]); 569 570 for (var i = 0; i < this._liveLocations.length; ++i) 571 this._liveLocations[i].dispose(); 572 this._liveLocations = []; 573 574 this._uiLocations = {}; 575 }, 576 577 /** 578 * @return {string} 579 */ 580 _breakpointStorageId: function() 581 { 582 if (!this._sourceFileId) 583 return ""; 584 return this._sourceFileId + ":" + this._primaryUILocation.lineNumber; 585 }, 586 587 _fakeBreakpointAtPrimaryLocation: function() 588 { 589 this._resetLocations(); 590 this._uiLocations[""] = this._primaryUILocation; 591 this._breakpointManager._uiLocationAdded(this, this._primaryUILocation); 592 } 593 } 594 595 /** 596 * @constructor 597 * @param {WebInspector.BreakpointManager} breakpointManager 598 * @param {WebInspector.Setting} setting 599 */ 600 WebInspector.BreakpointManager.Storage = function(breakpointManager, setting) 601 { 602 this._breakpointManager = breakpointManager; 603 this._setting = setting; 604 var breakpoints = this._setting.get(); 605 /** @type {Object.<string,WebInspector.BreakpointManager.Storage.Item>} */ 606 this._breakpoints = {}; 607 for (var i = 0; i < breakpoints.length; ++i) { 608 var breakpoint = /** @type {WebInspector.BreakpointManager.Storage.Item} */ (breakpoints[i]); 609 this._breakpoints[breakpoint.sourceFileId + ":" + breakpoint.lineNumber] = breakpoint; 610 } 611 } 612 613 WebInspector.BreakpointManager.Storage.prototype = { 614 /** 615 * @param {WebInspector.UISourceCode} uiSourceCode 616 */ 617 _restoreBreakpoints: function(uiSourceCode) 618 { 619 this._muted = true; 620 var sourceFileId = WebInspector.BreakpointManager.sourceFileId(uiSourceCode); 621 for (var id in this._breakpoints) { 622 var breakpoint = this._breakpoints[id]; 623 if (breakpoint.sourceFileId === sourceFileId) 624 this._breakpointManager._innerSetBreakpoint(uiSourceCode, breakpoint.lineNumber, breakpoint.condition, breakpoint.enabled); 625 } 626 delete this._muted; 627 }, 628 629 /** 630 * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint 631 */ 632 _updateBreakpoint: function(breakpoint) 633 { 634 if (this._muted || !breakpoint._breakpointStorageId()) 635 return; 636 this._breakpoints[breakpoint._breakpointStorageId()] = new WebInspector.BreakpointManager.Storage.Item(breakpoint); 637 this._save(); 638 }, 639 640 /** 641 * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint 642 */ 643 _removeBreakpoint: function(breakpoint) 644 { 645 if (this._muted) 646 return; 647 delete this._breakpoints[breakpoint._breakpointStorageId()]; 648 this._save(); 649 }, 650 651 _save: function() 652 { 653 var breakpointsArray = []; 654 for (var id in this._breakpoints) 655 breakpointsArray.push(this._breakpoints[id]); 656 this._setting.set(breakpointsArray); 657 } 658 } 659 660 /** 661 * @constructor 662 * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint 663 */ 664 WebInspector.BreakpointManager.Storage.Item = function(breakpoint) 665 { 666 var primaryUILocation = breakpoint.primaryUILocation(); 667 this.sourceFileId = breakpoint._sourceFileId; 668 this.lineNumber = primaryUILocation.lineNumber; 669 this.condition = breakpoint.condition(); 670 this.enabled = breakpoint.enabled(); 671 } 672 673 /** @type {WebInspector.BreakpointManager} */ 674 WebInspector.breakpointManager = null; 675