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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js

Issue 2500493003: [DevTools] make breakpoints better (Closed)
Patch Set: Created 4 years, 1 month 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
OLDNEW
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
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 this._scriptsPanel.element, this._getPopoverAnchor.bind(this), this._res olveObjectForPopover.bind(this), 47 this._scriptsPanel.element, this._getPopoverAnchor.bind(this), this._res olveObjectForPopover.bind(this),
48 this._onHidePopover.bind(this), true); 48 this._onHidePopover.bind(this), true);
49 this._popoverHelper.setTimeout(250, 250); 49 this._popoverHelper.setTimeout(250, 250);
50 50
51 this.textEditor.element.addEventListener('keydown', this._onKeyDown.bind(thi s), true); 51 this.textEditor.element.addEventListener('keydown', this._onKeyDown.bind(thi s), true);
52 52
53 this.textEditor.addEventListener( 53 this.textEditor.addEventListener(
54 WebInspector.SourcesTextEditor.Events.GutterClick, this._handleGutterCli ck.bind(this), this); 54 WebInspector.SourcesTextEditor.Events.GutterClick, this._handleGutterCli ck.bind(this), this);
55 55
56 this._breakpointManager.addEventListener( 56 this._breakpointManager.addEventListener(
57 WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointA dded, this); 57 WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointC hanged, this);
58 this._breakpointManager.addEventListener( 58 this._breakpointManager.addEventListener(
59 WebInspector.BreakpointManager.Events.BreakpointRemoved, this._breakpoin tRemoved, this); 59 WebInspector.BreakpointManager.Events.BreakpointRemoved, this._breakpoin tChanged, this);
60 60
61 this.uiSourceCode().addEventListener( 61 this.uiSourceCode().addEventListener(
62 WebInspector.UISourceCode.Events.SourceMappingChanged, this._onSourceMap pingChanged, this); 62 WebInspector.UISourceCode.Events.SourceMappingChanged, this._onSourceMap pingChanged, this);
63 this.uiSourceCode().addEventListener( 63 this.uiSourceCode().addEventListener(
64 WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyCh anged, this); 64 WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyCh anged, this);
65 this.uiSourceCode().addEventListener( 65 this.uiSourceCode().addEventListener(
66 WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopy Committed, this); 66 WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopy Committed, this);
67 this.uiSourceCode().addEventListener( 67 this.uiSourceCode().addEventListener(
68 WebInspector.UISourceCode.Events.TitleChanged, this._showBlackboxInfobar IfNeeded, this); 68 WebInspector.UISourceCode.Events.TitleChanged, this._showBlackboxInfobar IfNeeded, this);
69 69
70 /** @type {!Set<number>} */
71 this._scheduledBreakpointDecorationsUpdates = new Set();
72 this._inlineBreakpointSymbol = Symbol('inline-breakpoint');
73
70 /** @type {!Map.<!WebInspector.Target, !WebInspector.ResourceScriptFile>}*/ 74 /** @type {!Map.<!WebInspector.Target, !WebInspector.ResourceScriptFile>}*/
71 this._scriptFileForTarget = new Map(); 75 this._scriptFileForTarget = new Map();
72 var targets = WebInspector.targetManager.targets(); 76 var targets = WebInspector.targetManager.targets();
73 for (var i = 0; i < targets.length; ++i) { 77 for (var i = 0; i < targets.length; ++i) {
74 var scriptFile = WebInspector.debuggerWorkspaceBinding.scriptFile(uiSource Code, targets[i]); 78 var scriptFile = WebInspector.debuggerWorkspaceBinding.scriptFile(uiSource Code, targets[i]);
75 if (scriptFile) 79 if (scriptFile)
76 this._updateScriptFile(targets[i]); 80 this._updateScriptFile(targets[i]);
77 } 81 }
78 82
79 if (this._scriptFileForTarget.size || uiSourceCode.extension() === 'js' || 83 if (this._scriptFileForTarget.size || uiSourceCode.extension() === 'js' ||
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 if (!breakpoints.length) { 263 if (!breakpoints.length) {
260 // This row doesn't have a breakpoint: We want to show Add Breakpoint an d Add and Edit Breakpoint. 264 // This row doesn't have a breakpoint: We want to show Add Breakpoint an d Add and Edit Breakpoint.
261 contextMenu.appendItem( 265 contextMenu.appendItem(
262 WebInspector.UIString('Add breakpoint'), this._createNewBreakpoint.b ind(this, lineNumber, '', true)); 266 WebInspector.UIString('Add breakpoint'), this._createNewBreakpoint.b ind(this, lineNumber, '', true));
263 contextMenu.appendItem( 267 contextMenu.appendItem(
264 WebInspector.UIString('Add conditional breakpoint…'), this._editBrea kpointCondition.bind(this, lineNumber)); 268 WebInspector.UIString('Add conditional breakpoint…'), this._editBrea kpointCondition.bind(this, lineNumber));
265 contextMenu.appendItem( 269 contextMenu.appendItem(
266 WebInspector.UIString('Never pause here'), 270 WebInspector.UIString('Never pause here'),
267 this._createNewBreakpoint.bind(this, lineNumber, 'false', true)); 271 this._createNewBreakpoint.bind(this, lineNumber, 'false', true));
268 } else { 272 } else {
269 var breakpoint = breakpoints[0]; 273 if (breakpoints.length === 1) {
lushnikov 2016/11/11 19:56:00 nit: can we make it non-nested?
274 var breakpoint = breakpoints[0];
275 // This row has a breakpoint, we want to show edit and remove breakpoi nt, and either disable or enable.
276 contextMenu.appendItem(WebInspector.UIString('Remove breakpoint'), bre akpoint.remove.bind(breakpoint));
277 contextMenu.appendItem(
278 WebInspector.UIString('Edit breakpoint…'),
lushnikov 2016/11/11 19:56:00 nit: use \u.. for unicode
279 this._editBreakpointCondition.bind(this, lineNumber, breakpoint));
280 if (breakpoint.enabled())
281 contextMenu.appendItem(
282 WebInspector.UIString('Disable breakpoint'), breakpoint.setEnabl ed.bind(breakpoint, false));
283 else
284 contextMenu.appendItem(
285 WebInspector.UIString('Enable breakpoint'), breakpoint.setEnable d.bind(breakpoint, true));
286 } else {
287 var hasEnabled = breakpoints.some(breakpoint => breakpoint.enabled());
288 if (hasEnabled) {
289 contextMenu.appendItem(
290 WebInspector.UIString('Disable breakpoints in line'),
291 () => breakpoints.map(breakpoint => breakpoint.setEnabled(false) ));
292 }
293 var hasDisabled = breakpoints.some(breakpoint => !breakpoint.enabled() );
294 if (hasDisabled) {
295 contextMenu.appendItem(
296 WebInspector.UIString('Enable breakpoints in line'),
297 () => breakpoints.map(breakpoint => breakpoint.setEnabled(true)) );
298 }
270 299
271 // This row has a breakpoint, we want to show edit and remove breakpoint , and either disable or enable. 300 var breakpoint = breakpoints[0];
272 contextMenu.appendItem(WebInspector.UIString('Remove breakpoint'), break point.remove.bind(breakpoint)); 301
273 contextMenu.appendItem( 302 }
274 WebInspector.UIString('Edit breakpoint…'),
275 this._editBreakpointCondition.bind(this, lineNumber, breakpoint));
276 if (breakpoint.enabled())
277 contextMenu.appendItem(
278 WebInspector.UIString('Disable breakpoint'), breakpoint.setEnabled .bind(breakpoint, false));
279 else
280 contextMenu.appendItem(
281 WebInspector.UIString('Enable breakpoint'), breakpoint.setEnabled. bind(breakpoint, true));
282 } 303 }
283 resolve(); 304 resolve();
284 } 305 }
285 return new Promise(populate.bind(this)); 306 return new Promise(populate.bind(this));
286 } 307 }
287 308
288 /** 309 /**
289 * @override 310 * @override
290 * @return {!Promise} 311 * @return {!Promise}
291 */ 312 */
(...skipping 29 matching lines...) Expand all
321 contextMenu.appendSeparator(); 342 contextMenu.appendSeparator();
322 } 343 }
323 } 344 }
324 } 345 }
325 346
326 return super.populateTextAreaContextMenu(contextMenu, lineNumber, columnNumb er) 347 return super.populateTextAreaContextMenu(contextMenu, lineNumber, columnNumb er)
327 .then(populateSourceMapMembers.bind(this)); 348 .then(populateSourceMapMembers.bind(this));
328 } 349 }
329 350
330 _workingCopyChanged(event) { 351 _workingCopyChanged(event) {
331 if (this._supportsEnabledBreakpointsWhileEditing() || this._scriptFileForTar get.size)
lushnikov 2016/11/11 19:56:00 where did this go?
332 return;
333
334 if (this.uiSourceCode().isDirty()) 352 if (this.uiSourceCode().isDirty())
335 this._muteBreakpointsWhileEditing(); 353 this._muteBreakpointsWhileEditing();
336 else 354 else
337 this._restoreBreakpointsAfterEditing(); 355 this._restoreBreakpointsAfterEditing();
338 } 356 }
339 357
340 _workingCopyCommitted(event) { 358 _workingCopyCommitted(event) {
341 this._scriptsPanel.updateLastModificationTime(); 359 this._scriptsPanel.updateLastModificationTime();
342 if (this._supportsEnabledBreakpointsWhileEditing())
343 return;
344
345 if (!this._scriptFileForTarget.size) 360 if (!this._scriptFileForTarget.size)
346 this._restoreBreakpointsAfterEditing(); 361 this._restoreBreakpointsAfterEditing();
347 } 362 }
348 363
349 _didMergeToVM() { 364 _didMergeToVM() {
350 if (this._supportsEnabledBreakpointsWhileEditing())
351 return;
352 this._updateDivergedInfobar(); 365 this._updateDivergedInfobar();
353 this._restoreBreakpointsIfConsistentScripts(); 366 this._restoreBreakpointsIfConsistentScripts();
354 } 367 }
355 368
356 _didDivergeFromVM() { 369 _didDivergeFromVM() {
357 if (this._supportsEnabledBreakpointsWhileEditing())
358 return;
359 this._updateDivergedInfobar(); 370 this._updateDivergedInfobar();
360 this._muteBreakpointsWhileEditing(); 371 this._muteBreakpointsWhileEditing();
361 } 372 }
362 373
363 _muteBreakpointsWhileEditing() { 374 _muteBreakpointsWhileEditing() {
364 if (this._muted) 375 if (this._muted)
365 return; 376 return;
366 for (var lineNumber = 0; lineNumber < this._textEditor.linesCount; ++lineNum ber) { 377 for (var lineNumber = 0; lineNumber < this._textEditor.linesCount; ++lineNum ber)
lushnikov 2016/11/11 19:56:00 that's unfortunate. Maybe it's time to teach edito
367 var breakpointDecoration = this._textEditor.getAttribute(lineNumber, 'brea kpoint'); 378 this._scheduleBreakpointDecorationsUpdate(lineNumber);
368 if (!breakpointDecoration)
369 continue;
370 this._removeBreakpointDecoration(lineNumber);
371 this._addBreakpointDecoration(
372 lineNumber, breakpointDecoration.columnNumber, breakpointDecoration.co ndition, breakpointDecoration.enabled,
373 true);
374 }
375 this._muted = true; 379 this._muted = true;
376 } 380 }
377 381
378 _updateDivergedInfobar() { 382 _updateDivergedInfobar() {
379 if (this.uiSourceCode().project().type() !== WebInspector.projectTypes.FileS ystem) { 383 if (this.uiSourceCode().project().type() !== WebInspector.projectTypes.FileS ystem) {
380 this._hideDivergedInfobar(); 384 this._hideDivergedInfobar();
381 return; 385 return;
382 } 386 }
383 387
384 var scriptFiles = this._scriptFileForTarget.valuesArray(); 388 var scriptFiles = this._scriptFileForTarget.valuesArray();
385 var hasDivergedScript = false; 389 var hasDivergedScript = false;
386 for (var i = 0; i < scriptFiles.length; ++i) 390 for (var i = 0; i < scriptFiles.length; ++i)
387 hasDivergedScript = hasDivergedScript || scriptFiles[i].hasDivergedFromVM( ); 391 hasDivergedScript = hasDivergedScript || scriptFiles[i].hasDivergedFromVM( );
388 392
389 if (this._divergedInfobar) { 393 if (this._divergedInfobar) {
390 if (!hasDivergedScript) 394 if (!hasDivergedScript)
391 this._hideDivergedInfobar(); 395 this._hideDivergedInfobar();
392 } else { 396 } else {
393 if (hasDivergedScript && !this.uiSourceCode().isDirty()) 397 if (hasDivergedScript && !this.uiSourceCode().isDirty())
394 this._showDivergedInfobar(); 398 this._showDivergedInfobar();
395 } 399 }
396 } 400 }
397 401
398 _supportsEnabledBreakpointsWhileEditing() {
399 return this.uiSourceCode().project().type() === WebInspector.projectTypes.Sn ippets;
400 }
401
402 _restoreBreakpointsIfConsistentScripts() { 402 _restoreBreakpointsIfConsistentScripts() {
403 var scriptFiles = this._scriptFileForTarget.valuesArray(); 403 var scriptFiles = this._scriptFileForTarget.valuesArray();
404 for (var i = 0; i < scriptFiles.length; ++i) 404 for (var i = 0; i < scriptFiles.length; ++i)
405 if (scriptFiles[i].hasDivergedFromVM() || scriptFiles[i].isMergingToVM()) 405 if (scriptFiles[i].hasDivergedFromVM() || scriptFiles[i].isMergingToVM())
406 return; 406 return;
407 407
408 this._restoreBreakpointsAfterEditing(); 408 this._restoreBreakpointsAfterEditing();
409 } 409 }
410 410
411 _restoreBreakpointsAfterEditing() { 411 _restoreBreakpointsAfterEditing() {
412 delete this._muted; 412 delete this._muted;
413 var breakpoints = {};
414 // Save and remove muted breakpoint decorations.
415 for (var lineNumber = 0; lineNumber < this._textEditor.linesCount; ++lineNum ber) {
416 var breakpointDecoration = this._textEditor.getAttribute(lineNumber, 'brea kpoint');
417 if (breakpointDecoration) {
418 breakpoints[lineNumber] = breakpointDecoration;
419 this._removeBreakpointDecoration(lineNumber);
420 }
421 }
422 413
423 // Remove all breakpoints. 414 var allBreakpoints = this._breakpointManager.breakpointsForUISourceCode(this .uiSourceCode());
424 this._removeAllBreakpoints(); 415 for (var breakpoint of allBreakpoints)
425 416 breakpoint.remove();
426 // Restore all breakpoints from saved decorations. 417 for (var breakpoint of allBreakpoints)
427 for (var lineNumberString in breakpoints) { 418 this._createNewBreakpoint(breakpoint.lineNumber(), breakpoint.condition(), breakpoint.enabled());
428 var lineNumber = parseInt(lineNumberString, 10);
429 if (isNaN(lineNumber))
430 continue;
431 var breakpointDecoration = breakpoints[lineNumberString];
432 this._setBreakpoint(
433 lineNumber, breakpointDecoration.columnNumber, breakpointDecoration.co ndition, breakpointDecoration.enabled);
434 }
435 } 419 }
436 420
437 _removeAllBreakpoints() { 421 _removeAllBreakpoints() {
438 var breakpoints = this._breakpointManager.breakpointsForUISourceCode(this.ui SourceCode()); 422 var breakpoints = this._breakpointManager.breakpointsForUISourceCode(this.ui SourceCode());
439 for (var i = 0; i < breakpoints.length; ++i) 423 for (var i = 0; i < breakpoints.length; ++i)
440 breakpoints[i].remove(); 424 breakpoints[i].remove();
441 } 425 }
442 426
443 /** 427 /**
444 * @param {string} tokenType 428 * @param {string} tokenType
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 } 541 }
558 542
559 _onHidePopover() { 543 _onHidePopover() {
560 if (!this._popoverAnchorBox) 544 if (!this._popoverAnchorBox)
561 return; 545 return;
562 if (this._popoverAnchorBox._highlightDescriptor) 546 if (this._popoverAnchorBox._highlightDescriptor)
563 this.textEditor.removeHighlight(this._popoverAnchorBox._highlightDescripto r); 547 this.textEditor.removeHighlight(this._popoverAnchorBox._highlightDescripto r);
564 delete this._popoverAnchorBox; 548 delete this._popoverAnchorBox;
565 } 549 }
566 550
567 /**
568 * @param {number} lineNumber
569 * @param {number} columnNumber
570 * @param {string} condition
571 * @param {boolean} enabled
572 * @param {boolean} mutedWhileEditing
573 */
574 _addBreakpointDecoration(lineNumber, columnNumber, condition, enabled, mutedWh ileEditing) {
575 var breakpoint = {condition: condition, enabled: enabled, columnNumber: colu mnNumber};
576
577 this.textEditor.setAttribute(lineNumber, 'breakpoint', breakpoint);
578
579 var disabled = !enabled || mutedWhileEditing;
580 this.textEditor.addBreakpoint(lineNumber, disabled, !!condition);
581 }
582
583 _removeBreakpointDecoration(lineNumber) {
584 this.textEditor.removeAttribute(lineNumber, 'breakpoint');
585 this.textEditor.removeBreakpoint(lineNumber);
586 }
587
588 _onKeyDown(event) { 551 _onKeyDown(event) {
589 if (event.key === 'Escape') { 552 if (event.key === 'Escape') {
590 if (this._popoverHelper.isPopoverVisible()) { 553 if (this._popoverHelper.isPopoverVisible()) {
591 this._popoverHelper.hidePopover(); 554 this._popoverHelper.hidePopover();
592 event.consume(); 555 event.consume();
593 } 556 }
594 } 557 }
595 } 558 }
596 559
597 /** 560 /**
598 * @param {number} lineNumber 561 * @param {number} lineNumber
599 * @param {!WebInspector.BreakpointManager.Breakpoint=} breakpoint 562 * @param {!WebInspector.BreakpointManager.Breakpoint=} breakpoint
600 */ 563 */
601 _editBreakpointCondition(lineNumber, breakpoint) { 564 _editBreakpointCondition(lineNumber, breakpoint) {
602 this._conditionElement = this._createConditionElement(lineNumber); 565 this._conditionElement = this._createConditionElement(lineNumber);
603 this.textEditor.addDecoration(this._conditionElement, lineNumber); 566 this.textEditor.addDecoration(this._conditionElement, lineNumber);
604 567
605 /** 568 /**
606 * @this {WebInspector.JavaScriptSourceFrame} 569 * @this {WebInspector.JavaScriptSourceFrame}
607 */ 570 */
608 function finishEditing(committed, element, newText) { 571 function finishEditing(committed, element, newText) {
609 this.textEditor.removeDecoration(this._conditionElement, lineNumber); 572 this.textEditor.removeDecoration(this._conditionElement, lineNumber);
610 delete this._conditionEditorElement; 573 delete this._conditionEditorElement;
611 delete this._conditionElement; 574 delete this._conditionElement;
612 if (!committed) 575 if (!committed)
613 return; 576 return;
614 577
615 if (breakpoint) 578 if (breakpoint) {
616 breakpoint.setCondition(newText); 579 breakpoint.setCondition(newText);
617 else 580 breakpoint.setEnabled(true);
581 } else
618 this._createNewBreakpoint(lineNumber, newText, true); 582 this._createNewBreakpoint(lineNumber, newText, true);
619 } 583 }
620 584
621 var config = new WebInspector.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false)); 585 var config = new WebInspector.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false));
622 WebInspector.InplaceEditor.startEditing(this._conditionEditorElement, config ); 586 WebInspector.InplaceEditor.startEditing(this._conditionEditorElement, config );
623 this._conditionEditorElement.value = breakpoint ? breakpoint.condition() : ' '; 587 this._conditionEditorElement.value = breakpoint ? breakpoint.condition() : ' ';
624 this._conditionEditorElement.select(); 588 this._conditionEditorElement.select();
625 } 589 }
626 590
627 _createConditionElement(lineNumber) { 591 _createConditionElement(lineNumber) {
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 this._clearValueWidgetsTimer = setTimeout(this._clearValueWidgets.bind(this) , 1000); 789 this._clearValueWidgetsTimer = setTimeout(this._clearValueWidgets.bind(this) , 1000);
826 } 790 }
827 791
828 _clearValueWidgets() { 792 _clearValueWidgets() {
829 delete this._clearValueWidgetsTimer; 793 delete this._clearValueWidgetsTimer;
830 for (var line of this._valueWidgets.keys()) 794 for (var line of this._valueWidgets.keys())
831 this.textEditor.removeDecoration(this._valueWidgets.get(line), line); 795 this.textEditor.removeDecoration(this._valueWidgets.get(line), line);
832 this._valueWidgets.clear(); 796 this._valueWidgets.clear();
833 } 797 }
834 798
835 /** 799 _breakpointChanged(event) {
836 * @return {boolean}
837 */
838 _shouldIgnoreExternalBreakpointEvents() {
839 if (this._supportsEnabledBreakpointsWhileEditing())
840 return false;
841 if (this._muted)
842 return true;
843 var scriptFiles = this._scriptFileForTarget.valuesArray();
844 for (var i = 0; i < scriptFiles.length; ++i) {
845 if (scriptFiles[i].isDivergingFromVM() || scriptFiles[i].isMergingToVM())
846 return true;
847 }
848 return false;
849 }
850
851 _breakpointAdded(event) {
852 var uiLocation = /** @type {!WebInspector.UILocation} */ (event.data.uiLocat ion); 800 var uiLocation = /** @type {!WebInspector.UILocation} */ (event.data.uiLocat ion);
853 if (uiLocation.uiSourceCode !== this.uiSourceCode()) 801 if (uiLocation.uiSourceCode !== this.uiSourceCode())
854 return; 802 return;
855 if (this._shouldIgnoreExternalBreakpointEvents()) 803 this._scheduleBreakpointDecorationsUpdate(uiLocation.lineNumber);
856 return;
857
858 var breakpoint = /** @type {!WebInspector.BreakpointManager.Breakpoint} */ ( event.data.breakpoint);
859 if (this.loaded)
860 this._addBreakpointDecoration(
861 uiLocation.lineNumber, uiLocation.columnNumber, breakpoint.condition() , breakpoint.enabled(), false);
862 } 804 }
863 805
864 _breakpointRemoved(event) { 806 _scheduleBreakpointDecorationsUpdate(lineNumber) {
865 var uiLocation = /** @type {!WebInspector.UILocation} */ (event.data.uiLocat ion); 807 if (this._scheduledBreakpointDecorationsUpdates.has(lineNumber))
866 if (uiLocation.uiSourceCode !== this.uiSourceCode())
867 return; 808 return;
868 if (this._shouldIgnoreExternalBreakpointEvents()) 809 if (!this._scheduledBreakpointDecorationsUpdates.size)
869 return; 810 setImmediate(() => this.textEditor.operation(update.bind(this)));
811 this._scheduledBreakpointDecorationsUpdates.add(lineNumber);
870 812
871 var remainingBreakpoints = this._breakpointManager.findBreakpoints(this.uiSo urceCode(), uiLocation.lineNumber); 813 /**
872 if (!remainingBreakpoints.length && this.loaded) 814 * @this {!WebInspector.JavaScriptSourceFrame}
873 this._removeBreakpointDecoration(uiLocation.lineNumber); 815 */
816 function update() {
817 for (var lineNumber of this._scheduledBreakpointDecorationsUpdates)
818 this._updateBreakpointDecorations(lineNumber);
819 this._scheduledBreakpointDecorationsUpdates.clear();
820 }
874 } 821 }
875 822
876 /** 823 /**
824 * @param {number} lineNumber
825 */
826 _updateBreakpointDecorations(lineNumber) {
827 if (lineNumber >= this.textEditor.linesCount)
828 return;
829 var lineLength = this.textEditor.line(lineNumber).length;
830 var bookmarks = this.textEditor.bookmarks(new WebInspector.TextRange(lineNum ber, 0, lineNumber, lineLength), this._inlineBreakpointSymbol);
831 for (var bookmark of bookmarks)
832 bookmark.clear();
833
834 var breakpoints = this._breakpointManager.findBreakpoints(this.uiSourceCode( ), lineNumber);
835 breakpoints.sort((breakpoint1, breakpoint2) => breakpoint1.columnNumber() - breakpoint2.columnNumber());
lushnikov 2016/11/11 19:56:00 why do you need to sort them?
836 var hasEnabled = breakpoints.some(breakpoint => breakpoint.enabled());
837 var hasConditional = breakpoints.some(breakpoint => !!breakpoint.condition() );
838 var hasEnabledConditional = breakpoints.some(breakpoint => !!breakpoint.cond ition() && breakpoint.enabled());
839
840 if (!breakpoints.length) {
841 this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint', false);
842 return;
843 }
844 this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint', true);
845 this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint-conditional', has EnabledConditional || (!hasEnabled && hasConditional));
846 this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint-disabled', !hasEn abled || this._muted);
847 if (breakpoints.length <= 1 || this._muted)
848 return;
849 for (var i = 0; i < breakpoints.length; ++i) {
850 let breakpoint = breakpoints[i];
851 var inlineBreakpoint = WebInspector.InlineBreakpoint.create();
852 inlineBreakpoint.setEnabled(breakpoint.enabled() || this._muted);
853 inlineBreakpoint.setConditional(!!breakpoint.condition());
854 inlineBreakpoint.addEventListener('click', () => breakpoint.setEnabled(!br eakpoint.enabled()), true);
855 inlineBreakpoint.addEventListener('contextmenu', this._populateInlineBreak pointMenu.bind(this, breakpoint), true);
856 this.textEditor.addBookmark(breakpoint.lineNumber(), breakpoint.columnNumb er(), inlineBreakpoint, this._inlineBreakpointSymbol);
857 }
858 }
859
860 /**
861 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
862 * @param {!Event} event
863 */
864 _populateInlineBreakpointMenu(breakpoint, event) {
865 event.consume(true);
866 var contextMenu = new WebInspector.ContextMenu(event);
867 if (!breakpoint.enabled()) {
868 contextMenu.appendItem(WebInspector.UIString('Never pause here'), () => {
869 breakpoint.setCondition('false'); breakpoint.setEnabled(true);
870 });
871 }
872 var conditionalBreakpointTitle = breakpoint.enabled() ? WebInspector.UIStrin g('Edit breakpoint…')
873 : WebInspector.UIString('Add conditional breakpoint…');
874 contextMenu.appendItem(
875 conditionalBreakpointTitle,
876 this._editBreakpointCondition.bind(this, breakpoint.lineNumber(), breakp oint));
877 contextMenu.show();
878 }
879
880 /**
877 * @param {!WebInspector.Event} event 881 * @param {!WebInspector.Event} event
878 */ 882 */
879 _onSourceMappingChanged(event) { 883 _onSourceMappingChanged(event) {
880 var data = /** @type {{target: !WebInspector.Target}} */ (event.data); 884 var data = /** @type {{target: !WebInspector.Target}} */ (event.data);
881 this._updateScriptFile(data.target); 885 this._updateScriptFile(data.target);
882 this._updateLinesWithoutMappingHighlight(); 886 this._updateLinesWithoutMappingHighlight();
883 } 887 }
884 888
885 _updateLinesWithoutMappingHighlight() { 889 _updateLinesWithoutMappingHighlight() {
886 var linesCount = this.textEditor.linesCount; 890 var linesCount = this.textEditor.linesCount;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 /** 941 /**
938 * @override 942 * @override
939 */ 943 */
940 onTextEditorContentSet() { 944 onTextEditorContentSet() {
941 super.onTextEditorContentSet(); 945 super.onTextEditorContentSet();
942 if (this._executionLocation) 946 if (this._executionLocation)
943 this.setExecutionLocation(this._executionLocation); 947 this.setExecutionLocation(this._executionLocation);
944 948
945 var breakpointLocations = this._breakpointManager.breakpointLocationsForUISo urceCode(this.uiSourceCode()); 949 var breakpointLocations = this._breakpointManager.breakpointLocationsForUISo urceCode(this.uiSourceCode());
946 for (var i = 0; i < breakpointLocations.length; ++i) 950 for (var i = 0; i < breakpointLocations.length; ++i)
947 this._breakpointAdded({data: breakpointLocations[i]}); 951 this._breakpointChanged({data: breakpointLocations[i]});
948 952
949 var scriptFiles = this._scriptFileForTarget.valuesArray(); 953 var scriptFiles = this._scriptFileForTarget.valuesArray();
950 for (var i = 0; i < scriptFiles.length; ++i) 954 for (var i = 0; i < scriptFiles.length; ++i)
951 scriptFiles[i].checkMapping(); 955 scriptFiles[i].checkMapping();
952 956
953 this._updateLinesWithoutMappingHighlight(); 957 this._updateLinesWithoutMappingHighlight();
954 this._detectMinified(); 958 this._detectMinified();
955 } 959 }
956 960
957 _detectMinified() { 961 _detectMinified() {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 eventObject.consume(true); 1014 eventObject.consume(true);
1011 } 1015 }
1012 1016
1013 /** 1017 /**
1014 * @param {number} lineNumber 1018 * @param {number} lineNumber
1015 * @param {boolean} onlyDisable 1019 * @param {boolean} onlyDisable
1016 */ 1020 */
1017 _toggleBreakpoint(lineNumber, onlyDisable) { 1021 _toggleBreakpoint(lineNumber, onlyDisable) {
1018 var breakpoints = this._breakpointManager.findBreakpoints(this.uiSourceCode( ), lineNumber); 1022 var breakpoints = this._breakpointManager.findBreakpoints(this.uiSourceCode( ), lineNumber);
1019 if (breakpoints.length) { 1023 if (breakpoints.length) {
1020 if (onlyDisable) 1024 for (var breakpoint of breakpoints) {
1021 breakpoints[0].setEnabled(!breakpoints[0].enabled()); 1025 if (onlyDisable)
1022 else 1026 breakpoint.setEnabled(false);
1023 breakpoints[0].remove(); 1027 else
1024 } else 1028 breakpoint.remove();
1029 }
1030 } else {
1025 this._createNewBreakpoint(lineNumber, '', true); 1031 this._createNewBreakpoint(lineNumber, '', true);
1032 }
1026 } 1033 }
1027 1034
1028 /** 1035 /**
1029 * @param {number} lineNumber 1036 * @param {number} lineNumber
1030 * @param {string} condition 1037 * @param {string} condition
1031 * @param {boolean} enabled 1038 * @param {boolean} enabled
1032 */ 1039 */
1033 _createNewBreakpoint(lineNumber, condition, enabled) { 1040 _createNewBreakpoint(lineNumber, condition, enabled) {
1034 findPossibleBreakpoints.call(this, lineNumber) 1041 findPossibleBreakpoints.call(this, lineNumber)
1035 .then(checkNextLineIfNeeded.bind(this, lineNumber, 4)) 1042 .then(checkNextLineIfNeeded.bind(this, lineNumber, 4))
1036 .then(setBreakpoint.bind(this)); 1043 .then(setBreakpoint.bind(this));
1037 1044
1038 /** 1045 /**
1039 * @this {!WebInspector.JavaScriptSourceFrame} 1046 * @this {!WebInspector.JavaScriptSourceFrame}
1040 * @param {number} lineNumber 1047 * @param {number} lineNumber
1041 * @return {!Promise<?Array<!WebInspector.UILocation>>} 1048 * @return {!Promise<?Array<!WebInspector.UILocation>>}
1042 */ 1049 */
1043 function findPossibleBreakpoints(lineNumber) { 1050 function findPossibleBreakpoints(lineNumber) {
1044 const maxLengthToCheck = 1024; 1051 const maxLengthToCheck = 1024;
1045 if (lineNumber >= this._textEditor.linesCount) 1052 if (lineNumber >= this._textEditor.linesCount)
1046 return Promise.resolve(/** @type {?Array<!WebInspector.UILocation>} */([ ])); 1053 return Promise.resolve(/** @type {?Array<!WebInspector.UILocation>} */([ ]));
1047 if (this._textEditor.line(lineNumber).length >= maxLengthToCheck) 1054 if (this._textEditor.line(lineNumber).length >= maxLengthToCheck)
1048 return Promise.resolve(/** @type {?Array<!WebInspector.UILocation>} */([ ])); 1055 return Promise.resolve(/** @type {?Array<!WebInspector.UILocation>} */([ ]));
1049 return this._breakpointManager.possibleBreakpoints(this.uiSourceCode(), ne w WebInspector.TextRange(lineNumber, 0, lineNumber + 1, 0)) 1056 return this._breakpointManager.possibleBreakpoints(this.uiSourceCode(), ne w WebInspector.TextRange(lineNumber, 0, lineNumber + 1, 0))
1050 .then(locations => locations.length ? locations : null); 1057 .then(locations => locations.length ? locations : null);
lushnikov 2016/11/11 19:56:00 while we're here - we probably can just drop this
1051 } 1058 }
1052 1059
1053 /** 1060 /**
1054 * @this {!WebInspector.JavaScriptSourceFrame} 1061 * @this {!WebInspector.JavaScriptSourceFrame}
1055 * @param {number} currentLineNumber 1062 * @param {number} currentLineNumber
1056 * @param {number} linesToCheck 1063 * @param {number} linesToCheck
1057 * @param {?Array<!WebInspector.UILocation>} locations 1064 * @param {?Array<!WebInspector.UILocation>} locations
1058 * @return {!Promise<?Array<!WebInspector.UILocation>>} 1065 * @return {!Promise<?Array<!WebInspector.UILocation>>}
1059 */ 1066 */
1060 function checkNextLineIfNeeded(currentLineNumber, linesToCheck, locations) { 1067 function checkNextLineIfNeeded(currentLineNumber, linesToCheck, locations) {
1061 if (locations || linesToCheck <= 0) 1068 if (locations || linesToCheck <= 0)
1062 return Promise.resolve(locations); 1069 return Promise.resolve(locations);
1063 return findPossibleBreakpoints.call(this, currentLineNumber + 1) 1070 return findPossibleBreakpoints.call(this, currentLineNumber + 1)
1064 .then(checkNextLineIfNeeded.bind(this, currentLineNumber + 1, linesToC heck - 1)); 1071 .then(checkNextLineIfNeeded.bind(this, currentLineNumber + 1, linesToC heck - 1));
1065 } 1072 }
1066 1073
1067 /** 1074 /**
1068 * @this {!WebInspector.JavaScriptSourceFrame} 1075 * @this {!WebInspector.JavaScriptSourceFrame}
1069 * @param {?Array<!WebInspector.UILocation>} locations 1076 * @param {?Array<!WebInspector.UILocation>} locations
1070 */ 1077 */
1071 function setBreakpoint(locations) { 1078 function setBreakpoint(locations) {
1072 if (!locations || !locations.length) 1079 if (!locations || !locations.length) {
1073 this._setBreakpoint(lineNumber, 0, condition, enabled); 1080 this._setBreakpoint(lineNumber, 0, condition, enabled);
1074 else 1081 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.Scr iptsBreakpointSet);
1075 this._setBreakpoint(locations[0].lineNumber, locations[0].columnNumber, condition, enabled); 1082 return;
1083 }
1084 for (var i = 0; i < locations.length; ++i)
1085 this._setBreakpoint(locations[i].lineNumber, locations[i].columnNumber, condition, enabled && i === 0);
1076 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.Scrip tsBreakpointSet); 1086 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.Scrip tsBreakpointSet);
1077 } 1087 }
1078 } 1088 }
1079 1089
1080 toggleBreakpointOnCurrentLine() { 1090 toggleBreakpointOnCurrentLine() {
1081 if (this._muted) 1091 if (this._muted)
1082 return; 1092 return;
1083 1093
1084 var selection = this.textEditor.selection(); 1094 var selection = this.textEditor.selection();
1085 if (!selection) 1095 if (!selection)
(...skipping 22 matching lines...) Expand all
1108 * @param {boolean} enabled 1118 * @param {boolean} enabled
1109 */ 1119 */
1110 _breakpointWasSetForTest(lineNumber, columnNumber, condition, enabled) { 1120 _breakpointWasSetForTest(lineNumber, columnNumber, condition, enabled) {
1111 } 1121 }
1112 1122
1113 /** 1123 /**
1114 * @override 1124 * @override
1115 */ 1125 */
1116 dispose() { 1126 dispose() {
1117 this._breakpointManager.removeEventListener( 1127 this._breakpointManager.removeEventListener(
1118 WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointA dded, this); 1128 WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointC hanged, this);
1119 this._breakpointManager.removeEventListener( 1129 this._breakpointManager.removeEventListener(
1120 WebInspector.BreakpointManager.Events.BreakpointRemoved, this._breakpoin tRemoved, this); 1130 WebInspector.BreakpointManager.Events.BreakpointRemoved, this._breakpoin tChanged, this);
1121 this.uiSourceCode().removeEventListener( 1131 this.uiSourceCode().removeEventListener(
1122 WebInspector.UISourceCode.Events.SourceMappingChanged, this._onSourceMap pingChanged, this); 1132 WebInspector.UISourceCode.Events.SourceMappingChanged, this._onSourceMap pingChanged, this);
1123 this.uiSourceCode().removeEventListener( 1133 this.uiSourceCode().removeEventListener(
1124 WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyCh anged, this); 1134 WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyCh anged, this);
1125 this.uiSourceCode().removeEventListener( 1135 this.uiSourceCode().removeEventListener(
1126 WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopy Committed, this); 1136 WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopy Committed, this);
1127 this.uiSourceCode().removeEventListener( 1137 this.uiSourceCode().removeEventListener(
1128 WebInspector.UISourceCode.Events.TitleChanged, this._showBlackboxInfobar IfNeeded, this); 1138 WebInspector.UISourceCode.Events.TitleChanged, this._showBlackboxInfobar IfNeeded, this);
1129 WebInspector.moduleSetting('skipStackFramesPattern').removeChangeListener(th is._showBlackboxInfobarIfNeeded, this); 1139 WebInspector.moduleSetting('skipStackFramesPattern').removeChangeListener(th is._showBlackboxInfobarIfNeeded, this);
1130 WebInspector.moduleSetting('skipContentScripts').removeChangeListener(this._ showBlackboxInfobarIfNeeded, this); 1140 WebInspector.moduleSetting('skipContentScripts').removeChangeListener(this._ showBlackboxInfobarIfNeeded, this);
1131 super.dispose(); 1141 super.dispose();
1132 } 1142 }
1133 }; 1143 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698