Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: Source/devtools/front_end/sdk/BreakpointManager.js

Issue 471433004: DevTools: Split out the "workspace" and "bindings" modules from "sdk" (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Remove marker interfaces and WI.SourceMapping Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 * @implements {WebInspector.TargetManager.Observer}
35 * @param {!WebInspector.Setting} breakpointStorage
36 * @param {!WebInspector.Workspace} workspace
37 * @param {!WebInspector.TargetManager} targetManager
38 * @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
39 */
40 WebInspector.BreakpointManager = function(breakpointStorage, workspace, targetMa nager, debuggerWorkspaceBinding)
41 {
42 this._storage = new WebInspector.BreakpointManager.Storage(this, breakpointS torage);
43 this._workspace = workspace;
44 this._targetManager = targetManager;
45 this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
46
47 this._breakpointsActive = true;
48 this._breakpointsForUISourceCode = new Map();
49 this._breakpointsForPrimaryUISourceCode = new Map();
50 /** @type {!StringMultimap.<!WebInspector.BreakpointManager.Breakpoint>} */
51 this._provisionalBreakpoints = new StringMultimap();
52
53 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.UISourceCodeR emoved, this._uiSourceCodeRemoved, this);
56 }
57
58 WebInspector.BreakpointManager.Events = {
59 BreakpointAdded: "breakpoint-added",
60 BreakpointRemoved: "breakpoint-removed",
61 BreakpointsActiveStateChanged: "BreakpointsActiveStateChanged"
62 }
63
64 WebInspector.BreakpointManager._sourceFileId = function(uiSourceCode)
65 {
66 if (!uiSourceCode.url)
67 return "";
68 return uiSourceCode.uri();
69 }
70
71 /**
72 * @param {string} sourceFileId
73 * @param {number} lineNumber
74 * @param {number} columnNumber
75 * @return {string}
76 */
77 WebInspector.BreakpointManager._breakpointStorageId = function(sourceFileId, lin eNumber, columnNumber)
78 {
79 if (!sourceFileId)
80 return "";
81 return sourceFileId + ":" + lineNumber + ":" + columnNumber;
82 }
83
84 WebInspector.BreakpointManager.prototype = {
85 /**
86 * @param {!WebInspector.Target} target
87 */
88 targetAdded: function(target) {
89 if (!this._breakpointsActive)
90 target.debuggerAgent().setBreakpointsActive(this._breakpointsActive) ;
91 },
92
93 /**
94 * @param {!WebInspector.Target} target
95 */
96 targetRemoved: function(target) { },
97
98 /**
99 * @param {string} sourceFileId
100 * @return {!StringMap.<!WebInspector.BreakpointManager.Breakpoint>}
101 */
102 _provisionalBreakpointsForSourceFileId: function(sourceFileId)
103 {
104 var result = new StringMap();
105 var breakpoints = this._provisionalBreakpoints.get(sourceFileId).values( );
106 for (var i = 0; i < breakpoints.length; ++i)
107 result.put(breakpoints[i]._breakpointStorageId(), breakpoints[i]);
108 return result;
109 },
110
111 removeProvisionalBreakpointsForTest: function()
112 {
113 var breakpoints = this._provisionalBreakpoints.values();
114 for (var i = 0; i < breakpoints.length; ++i)
115 breakpoints[i].remove();
116 this._provisionalBreakpoints.clear();
117 },
118
119 /**
120 * @param {!WebInspector.UISourceCode} uiSourceCode
121 */
122 _restoreBreakpoints: function(uiSourceCode)
123 {
124 var sourceFileId = WebInspector.BreakpointManager._sourceFileId(uiSource Code);
125 if (!sourceFileId)
126 return;
127
128 this._storage.mute();
129 var breakpointItems = this._storage.breakpointItems(uiSourceCode);
130 var provisionalBreakpoints = this._provisionalBreakpointsForSourceFileId (sourceFileId);
131 for (var i = 0; i < breakpointItems.length; ++i) {
132 var breakpointItem = breakpointItems[i];
133 var itemStorageId = WebInspector.BreakpointManager._breakpointStorag eId(breakpointItem.sourceFileId, breakpointItem.lineNumber, breakpointItem.colum nNumber);
134 var provisionalBreakpoint = provisionalBreakpoints.get(itemStorageId );
135 if (provisionalBreakpoint) {
136 if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode))
137 this._breakpointsForPrimaryUISourceCode.put(uiSourceCode, [] );
138 this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(p rovisionalBreakpoint);
139 provisionalBreakpoint._updateBreakpoint();
140 } else {
141 this._innerSetBreakpoint(uiSourceCode, breakpointItem.lineNumber , breakpointItem.columnNumber, breakpointItem.condition, breakpointItem.enabled) ;
142 }
143 }
144 this._provisionalBreakpoints.removeAll(sourceFileId);
145 this._storage.unmute();
146 },
147
148 /**
149 * @param {!WebInspector.Event} event
150 */
151 _uiSourceCodeAdded: function(event)
152 {
153 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data );
154 this._restoreBreakpoints(uiSourceCode);
155 if (uiSourceCode.contentType() === WebInspector.resourceTypes.Script || uiSourceCode.contentType() === WebInspector.resourceTypes.Document)
156 uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.Sourc eMappingChanged, this._uiSourceCodeMappingChanged, this);
157 },
158
159 /**
160 * @param {!WebInspector.Event} event
161 */
162 _uiSourceCodeRemoved: function(event)
163 {
164 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data );
165 this._removeUISourceCode(uiSourceCode);
166 },
167
168 /**
169 * @param {!WebInspector.Event} event
170 */
171 _uiSourceCodeMappingChanged: function(event)
172 {
173 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.targ et);
174 var isIdentity = /** @type {boolean} */ (event.data.isIdentity);
175 var target = /** @type {!WebInspector.Target} */ (event.data.target);
176 if (isIdentity)
177 return;
178 var breakpoints = this._breakpointsForPrimaryUISourceCode.get(uiSourceCo de) || [];
179 for (var i = 0; i < breakpoints.length; ++i)
180 breakpoints[i]._updateInDebuggerForTarget(target);
181 },
182
183 /**
184 * @param {!WebInspector.UISourceCode} uiSourceCode
185 */
186 _removeUISourceCode: function(uiSourceCode)
187 {
188 var breakpoints = this._breakpointsForPrimaryUISourceCode.get(uiSourceCo de) || [];
189 var sourceFileId = WebInspector.BreakpointManager._sourceFileId(uiSource Code);
190 for (var i = 0; i < breakpoints.length; ++i) {
191 breakpoints[i]._resetLocations();
192 if (breakpoints[i].enabled())
193 this._provisionalBreakpoints.put(sourceFileId, breakpoints[i]);
194 }
195 uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.Source MappingChanged, this._uiSourceCodeMappingChanged, this);
196 this._breakpointsForPrimaryUISourceCode.remove(uiSourceCode);
197 },
198
199 /**
200 * @param {!WebInspector.UISourceCode} uiSourceCode
201 * @param {number} lineNumber
202 * @param {number} columnNumber
203 * @param {string} condition
204 * @param {boolean} enabled
205 * @return {!WebInspector.BreakpointManager.Breakpoint}
206 */
207 setBreakpoint: function(uiSourceCode, lineNumber, columnNumber, condition, e nabled)
208 {
209 this.setBreakpointsActive(true);
210 return this._innerSetBreakpoint(uiSourceCode, lineNumber, columnNumber, condition, enabled);
211 },
212
213 /**
214 * @param {!WebInspector.UISourceCode} uiSourceCode
215 * @param {number} lineNumber
216 * @param {number} columnNumber
217 * @param {string} condition
218 * @param {boolean} enabled
219 * @return {!WebInspector.BreakpointManager.Breakpoint}
220 */
221 _innerSetBreakpoint: function(uiSourceCode, lineNumber, columnNumber, condit ion, enabled)
222 {
223 var breakpoint = this.findBreakpoint(uiSourceCode, lineNumber, columnNum ber);
224 if (breakpoint) {
225 breakpoint._updateState(condition, enabled);
226 return breakpoint;
227 }
228 var projectId = uiSourceCode.project().id();
229 var path = uiSourceCode.path();
230 var sourceFileId = WebInspector.BreakpointManager._sourceFileId(uiSource Code);
231 breakpoint = new WebInspector.BreakpointManager.Breakpoint(this, project Id, path, sourceFileId, lineNumber, columnNumber, condition, enabled);
232 if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode))
233 this._breakpointsForPrimaryUISourceCode.put(uiSourceCode, []);
234 this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(breakpoin t);
235 return breakpoint;
236 },
237
238 /**
239 * @param {!WebInspector.UISourceCode} uiSourceCode
240 * @param {number} lineNumber
241 * @param {number} columnNumber
242 * @return {?WebInspector.BreakpointManager.Breakpoint}
243 */
244 findBreakpoint: function(uiSourceCode, lineNumber, columnNumber)
245 {
246 var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
247 var lineBreakpoints = breakpoints ? breakpoints.get(String(lineNumber)) : null;
248 var columnBreakpoints = lineBreakpoints ? lineBreakpoints.get(String(col umnNumber)) : null;
249 return columnBreakpoints ? columnBreakpoints[0] : null;
250 },
251
252 /**
253 * @param {!WebInspector.UISourceCode} uiSourceCode
254 * @param {number} lineNumber
255 * @return {?WebInspector.BreakpointManager.Breakpoint}
256 */
257 findBreakpointOnLine: function(uiSourceCode, lineNumber)
258 {
259 var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
260 var lineBreakpoints = breakpoints ? breakpoints.get(String(lineNumber)) : null;
261 return lineBreakpoints ? lineBreakpoints.values()[0][0] : null;
262 },
263
264 /**
265 * @param {!WebInspector.UISourceCode} uiSourceCode
266 * @return {!Array.<!WebInspector.BreakpointManager.Breakpoint>}
267 */
268 breakpointsForUISourceCode: function(uiSourceCode)
269 {
270 var result = [];
271 var uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSou rceCode);
272 var breakpoints = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.valu es() : [];
273 for (var i = 0; i < breakpoints.length; ++i) {
274 var lineBreakpoints = breakpoints[i];
275 var columnBreakpointArrays = lineBreakpoints ? lineBreakpoints.value s() : [];
276 result = result.concat.apply(result, columnBreakpointArrays);
277 }
278 return result;
279 },
280
281 /**
282 * @return {!Array.<!WebInspector.BreakpointManager.Breakpoint>}
283 */
284 allBreakpoints: function()
285 {
286 var result = [];
287 var uiSourceCodes = this._breakpointsForUISourceCode.keys();
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: function(uiSourceCode)
298 {
299 var uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSou rceCode);
300 var lineNumbers = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.keys () : [];
301 var result = [];
302 for (var i = 0; i < lineNumbers.length; ++i) {
303 var lineBreakpoints = uiSourceCodeBreakpoints.get(lineNumbers[i]);
304 var columnNumbers = lineBreakpoints.keys();
305 for (var j = 0; j < columnNumbers.length; ++j) {
306 var columnBreakpoints = lineBreakpoints.get(columnNumbers[j]);
307 var lineNumber = parseInt(lineNumbers[i], 10);
308 var columnNumber = parseInt(columnNumbers[j], 10);
309 for (var k = 0; k < columnBreakpoints.length; ++k) {
310 var breakpoint = columnBreakpoints[k];
311 var uiLocation = uiSourceCode.uiLocation(lineNumber, columnN umber);
312 result.push({breakpoint: breakpoint, uiLocation: uiLocation} );
313 }
314 }
315 }
316 return result;
317 },
318
319 /**
320 * @return {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint , uiLocation: !WebInspector.UILocation}>}
321 */
322 allBreakpointLocations: function()
323 {
324 var result = [];
325 var uiSourceCodes = this._breakpointsForUISourceCode.keys();
326 for (var i = 0; i < uiSourceCodes.length; ++i)
327 result = result.concat(this.breakpointLocationsForUISourceCode(uiSou rceCodes[i]));
328 return result;
329 },
330
331 /**
332 * @param {boolean} toggleState
333 */
334 toggleAllBreakpoints: function(toggleState)
335 {
336 var breakpoints = this.allBreakpoints();
337 for (var i = 0; i < breakpoints.length; ++i)
338 breakpoints[i].setEnabled(toggleState);
339 },
340
341 removeAllBreakpoints: function()
342 {
343 var breakpoints = this.allBreakpoints();
344 for (var i = 0; i < breakpoints.length; ++i)
345 breakpoints[i].remove();
346 },
347
348 _projectRemoved: function(event)
349 {
350 var project = /** @type {!WebInspector.Project} */ (event.data);
351 var uiSourceCodes = project.uiSourceCodes();
352 for (var i = 0; i < uiSourceCodes.length; ++i)
353 this._removeUISourceCode(uiSourceCodes[i]);
354 },
355
356 /**
357 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
358 * @param {boolean} removeFromStorage
359 */
360 _removeBreakpoint: function(breakpoint, removeFromStorage)
361 {
362 var uiSourceCode = breakpoint.uiSourceCode();
363 var breakpoints = uiSourceCode ? this._breakpointsForPrimaryUISourceCode .get(uiSourceCode) || [] : [];
364 breakpoints.remove(breakpoint);
365 if (removeFromStorage)
366 this._storage._removeBreakpoint(breakpoint);
367 this._provisionalBreakpoints.remove(breakpoint._sourceFileId, breakpoint );
368 },
369
370 /**
371 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
372 * @param {!WebInspector.UILocation} uiLocation
373 */
374 _uiLocationAdded: function(breakpoint, uiLocation)
375 {
376 var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSour ceCode);
377 if (!breakpoints) {
378 breakpoints = new StringMap();
379 this._breakpointsForUISourceCode.put(uiLocation.uiSourceCode, breakp oints);
380 }
381 var lineBreakpoints = breakpoints.get(String(uiLocation.lineNumber));
382 if (!lineBreakpoints) {
383 lineBreakpoints = new StringMap();
384 breakpoints.put(String(uiLocation.lineNumber), lineBreakpoints);
385 }
386 var columnBreakpoints = lineBreakpoints.get(String(uiLocation.columnNumb er));
387 if (!columnBreakpoints) {
388 columnBreakpoints = [];
389 lineBreakpoints.put(String(uiLocation.columnNumber), columnBreakpoin ts);
390 }
391 columnBreakpoints.push(breakpoint);
392 this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.Brea kpointAdded, {breakpoint: breakpoint, uiLocation: uiLocation});
393 },
394
395 /**
396 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
397 * @param {!WebInspector.UILocation} uiLocation
398 */
399 _uiLocationRemoved: function(breakpoint, uiLocation)
400 {
401 var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSour ceCode);
402 if (!breakpoints)
403 return;
404
405 var lineBreakpoints = breakpoints.get(String(uiLocation.lineNumber));
406 if (!lineBreakpoints)
407 return;
408 var columnBreakpoints = lineBreakpoints.get(String(uiLocation.columnNumb er));
409 if (!columnBreakpoints)
410 return;
411 columnBreakpoints.remove(breakpoint);
412 if (!columnBreakpoints.length)
413 lineBreakpoints.remove(String(uiLocation.columnNumber));
414 if (!lineBreakpoints.size())
415 breakpoints.remove(String(uiLocation.lineNumber));
416 if (!breakpoints.size())
417 this._breakpointsForUISourceCode.remove(uiLocation.uiSourceCode);
418 this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.Brea kpointRemoved, {breakpoint: breakpoint, uiLocation: uiLocation});
419 },
420
421 /**
422 * @param {boolean} active
423 */
424 setBreakpointsActive: function(active)
425 {
426 if (this._breakpointsActive === active)
427 return;
428
429 this._breakpointsActive = active;
430 var targets = WebInspector.targetManager.targets();
431 for (var i = 0; i < targets.length; ++i)
432 targets[i].debuggerAgent().setBreakpointsActive(active);
433
434 this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.Brea kpointsActiveStateChanged, active);
435 },
436
437 /**
438 * @return {boolean}
439 */
440 breakpointsActive: function()
441 {
442 return this._breakpointsActive;
443 },
444
445 __proto__: WebInspector.Object.prototype
446 }
447
448 /**
449 * @constructor
450 * @implements {WebInspector.TargetManager.Observer}
451 * @param {!WebInspector.BreakpointManager} breakpointManager
452 * @param {string} projectId
453 * @param {string} path
454 * @param {string} sourceFileId
455 * @param {number} lineNumber
456 * @param {number} columnNumber
457 * @param {string} condition
458 * @param {boolean} enabled
459 */
460 WebInspector.BreakpointManager.Breakpoint = function(breakpointManager, projectI d, path, sourceFileId, lineNumber, columnNumber, condition, enabled)
461 {
462 this._breakpointManager = breakpointManager;
463 this._projectId = projectId;
464 this._path = path;
465 this._lineNumber = lineNumber;
466 this._columnNumber = columnNumber;
467 this._sourceFileId = sourceFileId;
468
469 /** @type {!Object.<string, number>} */
470 this._numberOfDebuggerLocationForUILocation = {};
471
472 // Force breakpoint update.
473 /** @type {string} */ this._condition;
474 /** @type {boolean} */ this._enabled;
475 /** @type {boolean} */ this._isRemoved;
476 /** @type {!WebInspector.UILocation|undefined} */ this._fakePrimaryLocation;
477
478 this._currentState = null;
479 /** @type {!Map.<!WebInspector.Target, !WebInspector.BreakpointManager.Targe tBreakpoint>}*/
480 this._targetBreakpoints = new Map();
481 this._updateState(condition, enabled);
482 this._breakpointManager._targetManager.observeTargets(this);
483 }
484
485 WebInspector.BreakpointManager.Breakpoint.prototype = {
486 /**
487 * @param {!WebInspector.Target} target
488 */
489 targetAdded: function(target)
490 {
491 this._targetBreakpoints.put(target, new WebInspector.BreakpointManager.T argetBreakpoint(target, this, this._breakpointManager._debuggerWorkspaceBinding) );
492 },
493
494 /**
495 * @param {!WebInspector.Target} target
496 */
497 targetRemoved: function(target)
498 {
499 var targetBreakpoint = this._targetBreakpoints.remove(target);
500 targetBreakpoint._cleanUpAfterDebuggerIsGone();
501 targetBreakpoint._removeEventListeners();
502 },
503
504 /**
505 * @return {string}
506 */
507 projectId: function()
508 {
509 return this._projectId;
510 },
511
512 /**
513 * @return {string}
514 */
515 path: function()
516 {
517 return this._path;
518 },
519
520 /**
521 * @return {number}
522 */
523 lineNumber: function()
524 {
525 return this._lineNumber;
526 },
527
528 /**
529 * @return {number}
530 */
531 columnNumber: function()
532 {
533 return this._columnNumber;
534 },
535
536 /**
537 * @return {?WebInspector.UISourceCode}
538 */
539 uiSourceCode: function()
540 {
541 return this._breakpointManager._workspace.uiSourceCode(this._projectId, this._path);
542 },
543
544 /**
545 * @param {?WebInspector.UILocation} oldUILocation
546 * @param {!WebInspector.UILocation} newUILocation
547 */
548 _replaceUILocation: function(oldUILocation, newUILocation)
549 {
550 if (this._isRemoved)
551 return;
552
553 this._removeUILocation(oldUILocation, true);
554 this._removeFakeBreakpointAtPrimaryLocation();
555
556 if (!this._numberOfDebuggerLocationForUILocation[newUILocation.id()])
557 this._numberOfDebuggerLocationForUILocation[newUILocation.id()] = 0;
558
559 if (++this._numberOfDebuggerLocationForUILocation[newUILocation.id()] == = 1)
560 this._breakpointManager._uiLocationAdded(this, newUILocation);
561 },
562
563 /**
564 * @param {?WebInspector.UILocation} uiLocation
565 * @param {boolean=} muteCreationFakeBreakpoint
566 */
567 _removeUILocation: function(uiLocation, muteCreationFakeBreakpoint)
568 {
569 if (!uiLocation || --this._numberOfDebuggerLocationForUILocation[uiLocat ion.id()] !== 0)
570 return;
571
572 delete this._numberOfDebuggerLocationForUILocation[uiLocation.id()];
573 this._breakpointManager._uiLocationRemoved(this, uiLocation);
574 if (!muteCreationFakeBreakpoint)
575 this._fakeBreakpointAtPrimaryLocation();
576 },
577
578 /**
579 * @return {boolean}
580 */
581 enabled: function()
582 {
583 return this._enabled;
584 },
585
586 /**
587 * @param {boolean} enabled
588 */
589 setEnabled: function(enabled)
590 {
591 this._updateState(this._condition, enabled);
592 },
593
594 /**
595 * @return {string}
596 */
597 condition: function()
598 {
599 return this._condition;
600 },
601
602 /**
603 * @param {string} condition
604 */
605 setCondition: function(condition)
606 {
607 this._updateState(condition, this._enabled);
608 },
609
610 /**
611 * @param {string} condition
612 * @param {boolean} enabled
613 */
614 _updateState: function(condition, enabled)
615 {
616 if (this._enabled === enabled && this._condition === condition)
617 return;
618 this._enabled = enabled;
619 this._condition = condition;
620 this._breakpointManager._storage._updateBreakpoint(this);
621 this._updateBreakpoint();
622 },
623
624 _updateBreakpoint: function()
625 {
626 this._removeFakeBreakpointAtPrimaryLocation();
627 this._fakeBreakpointAtPrimaryLocation();
628 var targetBreakpoints = this._targetBreakpoints.values();
629 for (var i = 0; i < targetBreakpoints.length; ++i)
630 targetBreakpoints[i]._scheduleUpdateInDebugger();
631 },
632
633 /**
634 * @param {boolean=} keepInStorage
635 */
636 remove: function(keepInStorage)
637 {
638
639 this._isRemoved = true;
640 var removeFromStorage = !keepInStorage;
641 this._removeFakeBreakpointAtPrimaryLocation();
642 var targetBreakpoints = this._targetBreakpoints.values();
643 for (var i = 0; i < targetBreakpoints.length; ++i) {
644 targetBreakpoints[i]._scheduleUpdateInDebugger();
645 targetBreakpoints[i]._removeEventListeners();
646 }
647
648 this._breakpointManager._removeBreakpoint(this, removeFromStorage);
649 this._breakpointManager._targetManager.unobserveTargets(this);
650 },
651
652 /**
653 * @param {!WebInspector.Target} target
654 */
655 _updateInDebuggerForTarget: function(target)
656 {
657 this._targetBreakpoints.get(target)._scheduleUpdateInDebugger();
658 },
659
660 /**
661 * @return {string}
662 */
663 _breakpointStorageId: function()
664 {
665 return WebInspector.BreakpointManager._breakpointStorageId(this._sourceF ileId, this._lineNumber, this._columnNumber);
666 },
667
668 _fakeBreakpointAtPrimaryLocation: function()
669 {
670 if (this._isRemoved || !Object.isEmpty(this._numberOfDebuggerLocationFor UILocation) || this._fakePrimaryLocation)
671 return;
672
673 var uiSourceCode = this._breakpointManager._workspace.uiSourceCode(this. _projectId, this._path);
674 if (!uiSourceCode)
675 return;
676
677 this._fakePrimaryLocation = uiSourceCode.uiLocation(this._lineNumber, th is._columnNumber);
678 this._breakpointManager._uiLocationAdded(this, this._fakePrimaryLocation );
679 },
680
681 _removeFakeBreakpointAtPrimaryLocation: function()
682 {
683 if (this._fakePrimaryLocation) {
684 this._breakpointManager._uiLocationRemoved(this, this._fakePrimaryLo cation);
685 delete this._fakePrimaryLocation;
686 }
687 },
688
689 _resetLocations: function()
690 {
691 this._removeFakeBreakpointAtPrimaryLocation();
692 var targetBreakpoints = this._targetBreakpoints.values();
693 for (var i = 0; i < targetBreakpoints.length; ++i)
694 targetBreakpoints[i]._resetLocations();
695 }
696 }
697
698 /**
699 * @constructor
700 * @extends {WebInspector.SDKObject}
701 * @param {!WebInspector.Target} target
702 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
703 * @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
704 */
705 WebInspector.BreakpointManager.TargetBreakpoint = function(target, breakpoint, d ebuggerWorkspaceBinding)
706 {
707 WebInspector.SDKObject.call(this, target);
708 this._breakpoint = breakpoint;
709 this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
710
711 /** @type {!Array.<!WebInspector.DebuggerWorkspaceBinding.Location>} */
712 this._liveLocations = [];
713
714 /** @type {!Object.<string, !WebInspector.UILocation>} */
715 this._uiLocations = {};
716 target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.Debu ggerWasDisabled, this._cleanUpAfterDebuggerIsGone, this);
717 target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.Debu ggerWasEnabled, this._scheduleUpdateInDebugger, this);
718 this._hasPendingUpdate = false;
719 this._isUpdating = false;
720 this._cancelCallback = false;
721 this._currentState = null;
722 if (target.debuggerModel.debuggerEnabled())
723 this._scheduleUpdateInDebugger();
724 }
725
726 WebInspector.BreakpointManager.TargetBreakpoint.prototype = {
727
728 /**
729 * @return {!WebInspector.DebuggerModel}
730 */
731 _debuggerModel: function()
732 {
733 return this.target().debuggerModel;
734 },
735
736 _resetLocations: function()
737 {
738 var uiLocations = Object.values(this._uiLocations);
739 for (var i = 0; i < uiLocations.length; ++i)
740 this._breakpoint._removeUILocation(uiLocations[i]);
741
742 this._uiLocations = {};
743
744 for (var i = 0; i < this._liveLocations.length; ++i)
745 this._liveLocations[i].dispose();
746 this._liveLocations = [];
747 },
748
749 _scheduleUpdateInDebugger: function()
750 {
751 if (this._isUpdating) {
752 this._hasPendingUpdate = true;
753 return;
754 }
755
756 this._isUpdating = true;
757 this._updateInDebugger(this._didUpdateInDebugger.bind(this));
758 },
759
760 _didUpdateInDebugger: function()
761 {
762 this._isUpdating = false;
763 if (this._hasPendingUpdate) {
764 this._hasPendingUpdate = false;
765 this._scheduleUpdateInDebugger();
766 }
767 },
768
769 /**
770 * @return {boolean}
771 */
772 _scriptDiverged: function()
773 {
774 var uiSourceCode = this._breakpoint.uiSourceCode();
775 if (!uiSourceCode)
776 return false;
777 var scriptFile = this._debuggerWorkspaceBinding.scriptFile(uiSourceCode, this.target());
778 return !!scriptFile && scriptFile.hasDivergedFromVM();
779
780 },
781
782 /**
783 * @param {function()} callback
784 */
785 _updateInDebugger: function(callback)
786 {
787 if (this.target().isDetached()) {
788 this._cleanUpAfterDebuggerIsGone();
789 callback();
790 return;
791 }
792
793 var uiSourceCode = this._breakpoint.uiSourceCode();
794 var lineNumber = this._breakpoint._lineNumber;
795 var columnNumber = this._breakpoint._columnNumber;
796 var condition = this._breakpoint.condition();
797
798 var debuggerLocation = uiSourceCode ? this._debuggerWorkspaceBinding.uiL ocationToRawLocation(this.target(), uiSourceCode, lineNumber, columnNumber) : nu ll;
799 var newState;
800 if (this._breakpoint._isRemoved || !this._breakpoint.enabled() || this._ scriptDiverged())
801 newState = null;
802 else if (debuggerLocation) {
803 var script = debuggerLocation.script();
804 if (script.sourceURL)
805 newState = new WebInspector.BreakpointManager.Breakpoint.State(s cript.sourceURL, null, debuggerLocation.lineNumber, debuggerLocation.columnNumbe r, condition);
806 else
807 newState = new WebInspector.BreakpointManager.Breakpoint.State(n ull, debuggerLocation.scriptId, debuggerLocation.lineNumber, debuggerLocation.co lumnNumber, condition)
808 } else if (this._breakpoint._currentState && this._breakpoint._currentSt ate.url) {
809 var position = this._breakpoint._currentState;
810 newState = new WebInspector.BreakpointManager.Breakpoint.State(posit ion.url, null, position.lineNumber, position.columnNumber, condition);
811 } else if (uiSourceCode && uiSourceCode.url)
812 newState = new WebInspector.BreakpointManager.Breakpoint.State(uiSou rceCode.url, null, lineNumber, columnNumber, condition);
813
814 if (this._debuggerId && WebInspector.BreakpointManager.Breakpoint.State. equals(newState, this._currentState)) {
815 callback();
816 return;
817 }
818
819 this._breakpoint._currentState = newState;
820
821 if (this._debuggerId) {
822 this._resetLocations();
823 this._debuggerModel().removeBreakpoint(this._debuggerId, this._didRe moveFromDebugger.bind(this, callback));
824 this._scheduleUpdateInDebugger();
825 this._currentState = null;
826 return;
827 }
828
829 if (!newState) {
830 callback();
831 return;
832 }
833
834 var updateCallback = this._didSetBreakpointInDebugger.bind(this, callbac k);
835 if (newState.url)
836 this._debuggerModel().setBreakpointByURL(newState.url, newState.line Number, newState.columnNumber, this._breakpoint.condition(), updateCallback);
837 else if (newState.scriptId)
838 this._debuggerModel().setBreakpointBySourceId(/** @type {!WebInspect or.DebuggerModel.Location} */ (debuggerLocation), condition, updateCallback);
839
840 this._currentState = newState;
841 },
842
843 /**
844 * @param {function()} callback
845 * @param {?DebuggerAgent.BreakpointId} breakpointId
846 * @param {!Array.<!WebInspector.DebuggerModel.Location>} locations
847 */
848 _didSetBreakpointInDebugger: function(callback, breakpointId, locations)
849 {
850 if (this._cancelCallback) {
851 this._cancelCallback = false;
852 callback();
853 return;
854 }
855
856 if (!breakpointId) {
857 this._breakpoint.remove(true);
858 callback();
859 return;
860 }
861
862 this._debuggerId = breakpointId;
863 this.target().debuggerModel.addBreakpointListener(this._debuggerId, this ._breakpointResolved, this);
864 for (var i = 0; i < locations.length; ++i) {
865 if (!this._addResolvedLocation(locations[i]))
866 break;
867 }
868 callback();
869 },
870
871 /**
872 * @param {function()} callback
873 */
874 _didRemoveFromDebugger: function(callback)
875 {
876 if (this._cancelCallback) {
877 this._cancelCallback = false;
878 callback();
879 return;
880 }
881
882 this._resetLocations();
883 this.target().debuggerModel.removeBreakpointListener(this._debuggerId, t his._breakpointResolved, this);
884 delete this._debuggerId;
885 callback();
886 },
887
888 /**
889 * @param {!WebInspector.Event} event
890 */
891 _breakpointResolved: function(event)
892 {
893 this._addResolvedLocation(/** @type {!WebInspector.DebuggerModel.Locatio n}*/ (event.data));
894 },
895
896 /**
897 * @param {!WebInspector.DebuggerModel.Location} location
898 * @param {!WebInspector.UILocation} uiLocation
899 */
900 _locationUpdated: function(location, uiLocation)
901 {
902 var oldUILocation = this._uiLocations[location.id()] || null;
903 this._uiLocations[location.id()] = uiLocation;
904 this._breakpoint._replaceUILocation(oldUILocation, uiLocation);
905 },
906
907 /**
908 * @param {!WebInspector.DebuggerModel.Location} location
909 * @return {boolean}
910 */
911 _addResolvedLocation: function(location)
912 {
913 var uiLocation = this._debuggerWorkspaceBinding.rawLocationToUILocation( location);
914 var breakpoint = this._breakpoint._breakpointManager.findBreakpoint(uiLo cation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
915 if (breakpoint && breakpoint !== this._breakpoint) {
916 // location clash
917 this._breakpoint.remove();
918 return false;
919 }
920 this._liveLocations.push(this._debuggerWorkspaceBinding.createLiveLocati on(location, this._locationUpdated.bind(this, location)));
921 return true;
922 },
923
924 _cleanUpAfterDebuggerIsGone: function()
925 {
926 if (this._isUpdating)
927 this._cancelCallback = true;
928
929 this._resetLocations();
930 this._currentState = null;
931 if (this._debuggerId)
932 this._didRemoveFromDebugger(function() {});
933 },
934
935 _removeEventListeners: function()
936 {
937 this.target().debuggerModel.removeEventListener(WebInspector.DebuggerMod el.Events.DebuggerWasDisabled, this._cleanUpAfterDebuggerIsGone, this);
938 this.target().debuggerModel.removeEventListener(WebInspector.DebuggerMod el.Events.DebuggerWasEnabled, this._scheduleUpdateInDebugger, this);
939 },
940
941 __proto__: WebInspector.SDKObject.prototype
942 }
943
944 /**
945 * @constructor
946 * @param {?string} url
947 * @param {?string} scriptId
948 * @param {number} lineNumber
949 * @param {number} columnNumber
950 * @param {string} condition
951 */
952 WebInspector.BreakpointManager.Breakpoint.State = function(url, scriptId, lineNu mber, columnNumber, condition)
953 {
954 this.url = url;
955 this.scriptId = scriptId;
956 this.lineNumber = lineNumber;
957 this.columnNumber = columnNumber;
958 this.condition = condition;
959 }
960
961 /**
962 * @param {?WebInspector.BreakpointManager.Breakpoint.State|undefined} stateA
963 * @param {?WebInspector.BreakpointManager.Breakpoint.State|undefined} stateB
964 * @return {boolean}
965 */
966 WebInspector.BreakpointManager.Breakpoint.State.equals = function(stateA, stateB )
967 {
968 if (!stateA || !stateB)
969 return false;
970
971 if (stateA.scriptId || stateB.scriptId)
972 return false;
973
974 return stateA.url === stateB.url && stateA.lineNumber === stateB.lineNumber && stateA.columnNumber === stateB.columnNumber && stateA.condition === stateB.co ndition;
975 }
976
977 /**
978 * @constructor
979 * @param {!WebInspector.BreakpointManager} breakpointManager
980 * @param {!WebInspector.Setting} setting
981 */
982 WebInspector.BreakpointManager.Storage = function(breakpointManager, setting)
983 {
984 this._breakpointManager = breakpointManager;
985 this._setting = setting;
986 var breakpoints = this._setting.get();
987 /** @type {!Object.<string, !WebInspector.BreakpointManager.Storage.Item>} * /
988 this._breakpoints = {};
989 for (var i = 0; i < breakpoints.length; ++i) {
990 var breakpoint = /** @type {!WebInspector.BreakpointManager.Storage.Item } */ (breakpoints[i]);
991 breakpoint.columnNumber = breakpoint.columnNumber || 0;
992 this._breakpoints[breakpoint.sourceFileId + ":" + breakpoint.lineNumber + ":" + breakpoint.columnNumber] = breakpoint;
993 }
994 }
995
996 WebInspector.BreakpointManager.Storage.prototype = {
997 mute: function()
998 {
999 this._muted = true;
1000 },
1001
1002 unmute: function()
1003 {
1004 delete this._muted;
1005 },
1006
1007 /**
1008 * @param {!WebInspector.UISourceCode} uiSourceCode
1009 * @return {!Array.<!WebInspector.BreakpointManager.Storage.Item>}
1010 */
1011 breakpointItems: function(uiSourceCode)
1012 {
1013 var result = [];
1014 var sourceFileId = WebInspector.BreakpointManager._sourceFileId(uiSource Code);
1015 for (var id in this._breakpoints) {
1016 var breakpoint = this._breakpoints[id];
1017 if (breakpoint.sourceFileId === sourceFileId)
1018 result.push(breakpoint);
1019 }
1020 return result;
1021 },
1022
1023 /**
1024 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
1025 */
1026 _updateBreakpoint: function(breakpoint)
1027 {
1028 if (this._muted || !breakpoint._breakpointStorageId())
1029 return;
1030 this._breakpoints[breakpoint._breakpointStorageId()] = new WebInspector. BreakpointManager.Storage.Item(breakpoint);
1031 this._save();
1032 },
1033
1034 /**
1035 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
1036 */
1037 _removeBreakpoint: function(breakpoint)
1038 {
1039 if (this._muted)
1040 return;
1041 delete this._breakpoints[breakpoint._breakpointStorageId()];
1042 this._save();
1043 },
1044
1045 _save: function()
1046 {
1047 var breakpointsArray = [];
1048 for (var id in this._breakpoints)
1049 breakpointsArray.push(this._breakpoints[id]);
1050 this._setting.set(breakpointsArray);
1051 }
1052 }
1053
1054 /**
1055 * @constructor
1056 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
1057 */
1058 WebInspector.BreakpointManager.Storage.Item = function(breakpoint)
1059 {
1060 this.sourceFileId = breakpoint._sourceFileId;
1061 this.lineNumber = breakpoint.lineNumber();
1062 this.columnNumber = breakpoint.columnNumber();
1063 this.condition = breakpoint.condition();
1064 this.enabled = breakpoint.enabled();
1065 }
1066
1067 /** @type {!WebInspector.BreakpointManager} */
1068 WebInspector.breakpointManager;
OLDNEW
« no previous file with comments | « Source/devtools/front_end/inspector.html ('k') | Source/devtools/front_end/sdk/CSSStyleModel.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698