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

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

Issue 2505413002: [DevTools] Prepare JavaScriptSourceFrame for multiple breakpoints per line (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
« no previous file with comments | « third_party/WebKit/Source/devtools/front_end/source_frame/SourcesTextEditor.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 */ 250 */
251 function populate(resolve, reject) { 251 function populate(resolve, reject) {
252 var uiLocation = new Workspace.UILocation(this.uiSourceCode(), lineNumber, 0); 252 var uiLocation = new Workspace.UILocation(this.uiSourceCode(), lineNumber, 0);
253 this._scriptsPanel.appendUILocationItems(contextMenu, uiLocation); 253 this._scriptsPanel.appendUILocationItems(contextMenu, uiLocation);
254 var breakpoints = this._breakpointManager.findBreakpoints(this.uiSourceCod e(), lineNumber); 254 var breakpoints = this._breakpointManager.findBreakpoints(this.uiSourceCod e(), lineNumber);
255 if (!breakpoints.length) { 255 if (!breakpoints.length) {
256 // This row doesn't have a breakpoint: We want to show Add Breakpoint an d Add and Edit Breakpoint. 256 // This row doesn't have a breakpoint: We want to show Add Breakpoint an d Add and Edit Breakpoint.
257 contextMenu.appendItem( 257 contextMenu.appendItem(
258 Common.UIString('Add breakpoint'), this._createNewBreakpoint.bind(th is, lineNumber, '', true)); 258 Common.UIString('Add breakpoint'), this._createNewBreakpoint.bind(th is, lineNumber, '', true));
259 contextMenu.appendItem( 259 contextMenu.appendItem(
260 Common.UIString('Add conditional breakpoint'), this._editBreakpoint Condition.bind(this, lineNumber)); 260 Common.UIString('Add conditional breakpoint\u2026'), this._editBreak pointCondition.bind(this, lineNumber));
261 contextMenu.appendItem( 261 contextMenu.appendItem(
262 Common.UIString('Never pause here'), this._createNewBreakpoint.bind( this, lineNumber, 'false', true)); 262 Common.UIString('Never pause here'), this._createNewBreakpoint.bind( this, lineNumber, 'false', true));
263 } else { 263 } else {
264 var breakpoint = breakpoints[0]; 264 var hasOneBreakpoint = breakpoints.length === 1;
265 var removeTitle =
266 hasOneBreakpoint ? Common.UIString('Remove breakpoint') : Common.UIS tring('Remove all breakpoints in line');
267 contextMenu.appendItem(removeTitle, () => breakpoints.map(breakpoint => breakpoint.remove()));
268 if (hasOneBreakpoint) {
269 contextMenu.appendItem(
270 Common.UIString('Edit breakpoint\u2026'),
271 this._editBreakpointCondition.bind(this, lineNumber, breakpoints[0 ]));
272 }
265 273
266 // This row has a breakpoint, we want to show edit and remove breakpoint , and either disable or enable. 274 var hasEnabled = breakpoints.some(breakpoint => breakpoint.enabled());
267 contextMenu.appendItem(Common.UIString('Remove breakpoint'), breakpoint. remove.bind(breakpoint)); 275 if (hasEnabled) {
268 contextMenu.appendItem( 276 var title = hasOneBreakpoint ? Common.UIString('Disable breakpoint') :
269 Common.UIString('Edit breakpoint…'), this._editBreakpointCondition.b ind(this, lineNumber, breakpoint)); 277 Common.UIString('Disable all breakpoint s in line');
270 if (breakpoint.enabled()) 278 contextMenu.appendItem(title, () => breakpoints.map(breakpoint => brea kpoint.setEnabled(false)));
271 contextMenu.appendItem(Common.UIString('Disable breakpoint'), breakpoi nt.setEnabled.bind(breakpoint, false)); 279 }
272 else 280
273 contextMenu.appendItem(Common.UIString('Enable breakpoint'), breakpoin t.setEnabled.bind(breakpoint, true)); 281 var hasDisabled = breakpoints.some(breakpoint => !breakpoint.enabled());
282 if (hasDisabled) {
283 var title = hasOneBreakpoint ? Common.UIString('Enable breakpoint') :
284 Common.UIString('Enabled all breakpoint s in line');
285 contextMenu.appendItem(title, () => breakpoints.map(breakpoint => brea kpoint.setEnabled(true)));
286 }
274 } 287 }
275 resolve(); 288 resolve();
276 } 289 }
277 return new Promise(populate.bind(this)); 290 return new Promise(populate.bind(this));
278 } 291 }
279 292
280 /** 293 /**
281 * @override 294 * @override
282 * @return {!Promise} 295 * @return {!Promise}
283 */ 296 */
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 _didDivergeFromVM() { 361 _didDivergeFromVM() {
349 if (this._supportsEnabledBreakpointsWhileEditing()) 362 if (this._supportsEnabledBreakpointsWhileEditing())
350 return; 363 return;
351 this._updateDivergedInfobar(); 364 this._updateDivergedInfobar();
352 this._muteBreakpointsWhileEditing(); 365 this._muteBreakpointsWhileEditing();
353 } 366 }
354 367
355 _muteBreakpointsWhileEditing() { 368 _muteBreakpointsWhileEditing() {
356 if (this._muted) 369 if (this._muted)
357 return; 370 return;
358 for (var lineNumber = 0; lineNumber < this._textEditor.linesCount; ++lineNum ber) {
359 var breakpointDecoration = this._textEditor.getAttribute(lineNumber, 'brea kpoint');
360 if (!breakpointDecoration)
361 continue;
362 this._removeBreakpointDecoration(lineNumber);
363 this._addBreakpointDecoration(
364 lineNumber, breakpointDecoration.columnNumber, breakpointDecoration.co ndition, breakpointDecoration.enabled,
365 true);
366 }
367 this._muted = true; 371 this._muted = true;
372 for (var breakpointLocation of this._breakpointManager.breakpointLocationsFo rUISourceCode(this.uiSourceCode()))
lushnikov 2016/11/17 21:33:18 i don't think it returns provisional breakpoints.
kozy 2016/11/18 16:32:40 It returns.
373 this._updateBreakpointDecorations(breakpointLocation.uiLocation.lineNumber );
368 } 374 }
369 375
370 _updateDivergedInfobar() { 376 _updateDivergedInfobar() {
371 if (this.uiSourceCode().project().type() !== Workspace.projectTypes.FileSyst em) { 377 if (this.uiSourceCode().project().type() !== Workspace.projectTypes.FileSyst em) {
372 this._hideDivergedInfobar(); 378 this._hideDivergedInfobar();
373 return; 379 return;
374 } 380 }
375 381
376 var scriptFiles = this._scriptFileForTarget.valuesArray(); 382 var scriptFiles = this._scriptFileForTarget.valuesArray();
377 var hasDivergedScript = false; 383 var hasDivergedScript = false;
(...skipping 18 matching lines...) Expand all
396 for (var i = 0; i < scriptFiles.length; ++i) { 402 for (var i = 0; i < scriptFiles.length; ++i) {
397 if (scriptFiles[i].hasDivergedFromVM() || scriptFiles[i].isMergingToVM()) 403 if (scriptFiles[i].hasDivergedFromVM() || scriptFiles[i].isMergingToVM())
398 return; 404 return;
399 } 405 }
400 406
401 this._restoreBreakpointsAfterEditing(); 407 this._restoreBreakpointsAfterEditing();
402 } 408 }
403 409
404 _restoreBreakpointsAfterEditing() { 410 _restoreBreakpointsAfterEditing() {
405 delete this._muted; 411 delete this._muted;
406 var breakpoints = {}; 412 /** @type {!Map<number, !{lineNumber: number, columnNumber: number, conditio n: string, enabled: boolean }>} */
413 var breakpoints = new Map();
407 // Save and remove muted breakpoint decorations. 414 // Save and remove muted breakpoint decorations.
408 for (var lineNumber = 0; lineNumber < this._textEditor.linesCount; ++lineNum ber) { 415 for (var breakpointLocation of this._breakpointManager.breakpointLocationsFo rUISourceCode(this.uiSourceCode())) {
lushnikov 2016/11/17 22:14:52 unfortunately we need to traverse lines, because e
kozy 2016/11/18 16:32:40 Done.
lushnikov 2016/11/17 21:33:18 same question here about file system UISourceCodes
kozy 2016/11/18 16:32:40 returns.
409 var breakpointDecoration = this._textEditor.getAttribute(lineNumber, 'brea kpoint'); 416 var uiLocation = breakpointLocation.uiLocation;
410 if (breakpointDecoration) { 417 if (breakpoints.has(uiLocation.lineNumber))
411 breakpoints[lineNumber] = breakpointDecoration; 418 continue;
412 this._removeBreakpointDecoration(lineNumber); 419 var breakpoint = breakpointLocation.breakpoint;
413 } 420 breakpoints.set(uiLocation.lineNumber, {
421 lineNumber: uiLocation.lineNumber,
422 columnNumber: uiLocation.columnNumber,
423 condition: breakpoint.condition(),
424 enabled: breakpoint.enabled()
425 });
426 this._updateBreakpointDecorations(uiLocation.lineNumber);
414 } 427 }
415 428
416 // Remove all breakpoints. 429 // Remove all breakpoints.
417 this._removeAllBreakpoints(); 430 this._removeAllBreakpoints();
418 431
419 // Restore all breakpoints from saved decorations. 432 // Restore all breakpoints from saved decorations.
420 for (var lineNumberString in breakpoints) { 433 for (var breakpoint of breakpoints.valuesArray())
421 var lineNumber = parseInt(lineNumberString, 10); 434 this._setBreakpoint(breakpoint.lineNumber, breakpoint.columnNumber, breakp oint.condition, breakpoint.enabled);
422 if (isNaN(lineNumber))
423 continue;
424 var breakpointDecoration = breakpoints[lineNumberString];
425 this._setBreakpoint(
426 lineNumber, breakpointDecoration.columnNumber, breakpointDecoration.co ndition, breakpointDecoration.enabled);
427 }
428 } 435 }
429 436
430 _removeAllBreakpoints() { 437 _removeAllBreakpoints() {
431 var breakpoints = this._breakpointManager.breakpointsForUISourceCode(this.ui SourceCode()); 438 var breakpoints = this._breakpointManager.breakpointsForUISourceCode(this.ui SourceCode());
432 for (var i = 0; i < breakpoints.length; ++i) 439 for (var i = 0; i < breakpoints.length; ++i)
433 breakpoints[i].remove(); 440 breakpoints[i].remove();
434 } 441 }
435 442
436 /** 443 /**
437 * @param {string} tokenType 444 * @param {string} tokenType
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 _onHidePopover() { 559 _onHidePopover() {
553 if (!this._popoverAnchorBox) 560 if (!this._popoverAnchorBox)
554 return; 561 return;
555 if (this._popoverAnchorBox._highlightDescriptor) 562 if (this._popoverAnchorBox._highlightDescriptor)
556 this.textEditor.removeHighlight(this._popoverAnchorBox._highlightDescripto r); 563 this.textEditor.removeHighlight(this._popoverAnchorBox._highlightDescripto r);
557 delete this._popoverAnchorBox; 564 delete this._popoverAnchorBox;
558 } 565 }
559 566
560 /** 567 /**
561 * @param {number} lineNumber 568 * @param {number} lineNumber
562 * @param {number} columnNumber
563 * @param {string} condition
564 * @param {boolean} enabled
565 * @param {boolean} mutedWhileEditing
566 */ 569 */
567 _addBreakpointDecoration(lineNumber, columnNumber, condition, enabled, mutedWh ileEditing) { 570 _updateBreakpointDecorations(lineNumber) {
568 var breakpoint = {condition: condition, enabled: enabled, columnNumber: colu mnNumber}; 571 if (!this._scheduledBreakpointDecorationUpdates)
572 this._scheduledBreakpointDecorationUpdates = new Set();
573 if (!this._scheduledBreakpointDecorationUpdates.size)
574 setImmediate(() => this.textEditor.operation(update.bind(this)));
575 this._scheduledBreakpointDecorationUpdates.add(lineNumber);
569 576
570 this.textEditor.setAttribute(lineNumber, 'breakpoint', breakpoint); 577 /**
578 * @this {Sources.JavaScriptSourceFrame}
579 */
580 function update() {
581 for (var lineNumber of this._scheduledBreakpointDecorationUpdates) {
582 var breakpointLocations = this._breakpointManager.breakpointLocationsFor Line(this.uiSourceCode(), lineNumber);
583 var breakpoints = breakpointLocations.map(breakpointLocation => breakpoi ntLocation.breakpoint);
571 584
572 var disabled = !enabled || mutedWhileEditing; 585 var hasAny = !!breakpoints.length;
573 this.textEditor.addBreakpoint(lineNumber, disabled, !!condition); 586 var hasEnabled = false;
587 var hasConditional = false;
588 var hasEnabledConditional = false;
589 for (var breakpoint of breakpoints) {
lushnikov 2016/11/17 22:14:52 breakpoints.sort((b1, b2) => { if (!!b1.conditio
kozy 2016/11/18 16:32:40 Done.
590 if (breakpoint.enabled())
591 hasEnabled = true;
592 if (!!breakpoint.condition()) {
593 hasConditional = true;
594 if (breakpoint.enabled())
595 hasEnabledConditional = true;
596 }
597 }
598 this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint', hasAny);
599 this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint-disabled', ha sAny && (!hasEnabled && !this._muted));
lushnikov 2016/11/17 21:33:18 what is this._muted flag? do we really need it?
kozy 2016/11/18 16:32:40 We can remove it later with better understanding w
600 this.textEditor.toggleLineClass(
601 lineNumber, 'cm-breakpoint-conditional',
602 hasEnabledConditional || (hasAny && !hasEnabled && hasConditional));
603 this._breakpointDecorationsUpdatedForTest(lineNumber, !hasEnabled, !hasA ny);
604 }
605 delete this._scheduledBreakpointDecorationUpdates;
606 }
574 } 607 }
575 608
576 _removeBreakpointDecoration(lineNumber) { 609 _breakpointDecorationsUpdatedForTest(lineNumber, disabled, removed) {
577 this.textEditor.removeAttribute(lineNumber, 'breakpoint');
578 this.textEditor.removeBreakpoint(lineNumber);
579 } 610 }
580 611
581 _onKeyDown(event) { 612 _onKeyDown(event) {
582 if (event.key === 'Escape') { 613 if (event.key === 'Escape') {
583 if (this._popoverHelper.isPopoverVisible()) { 614 if (this._popoverHelper.isPopoverVisible()) {
584 this._popoverHelper.hidePopover(); 615 this._popoverHelper.hidePopover();
585 event.consume(); 616 event.consume();
586 } 617 }
587 } 618 }
588 } 619 }
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 } 874 }
844 875
845 _breakpointAdded(event) { 876 _breakpointAdded(event) {
846 var uiLocation = /** @type {!Workspace.UILocation} */ (event.data.uiLocation ); 877 var uiLocation = /** @type {!Workspace.UILocation} */ (event.data.uiLocation );
847 if (uiLocation.uiSourceCode !== this.uiSourceCode()) 878 if (uiLocation.uiSourceCode !== this.uiSourceCode())
848 return; 879 return;
849 if (this._shouldIgnoreExternalBreakpointEvents()) 880 if (this._shouldIgnoreExternalBreakpointEvents())
850 return; 881 return;
851 882
852 var breakpoint = /** @type {!Bindings.BreakpointManager.Breakpoint} */ (even t.data.breakpoint); 883 var breakpoint = /** @type {!Bindings.BreakpointManager.Breakpoint} */ (even t.data.breakpoint);
853 if (this.loaded) { 884 if (this.loaded)
854 this._addBreakpointDecoration( 885 this._updateBreakpointDecorations(uiLocation.lineNumber);
855 uiLocation.lineNumber, uiLocation.columnNumber, breakpoint.condition() , breakpoint.enabled(), false);
856 }
857 } 886 }
858 887
859 _breakpointRemoved(event) { 888 _breakpointRemoved(event) {
860 var uiLocation = /** @type {!Workspace.UILocation} */ (event.data.uiLocation ); 889 var uiLocation = /** @type {!Workspace.UILocation} */ (event.data.uiLocation );
861 if (uiLocation.uiSourceCode !== this.uiSourceCode()) 890 if (uiLocation.uiSourceCode !== this.uiSourceCode())
862 return; 891 return;
863 if (this._shouldIgnoreExternalBreakpointEvents()) 892 if (this._shouldIgnoreExternalBreakpointEvents())
864 return; 893 return;
865 894
866 var remainingBreakpoints = this._breakpointManager.findBreakpoints(this.uiSo urceCode(), uiLocation.lineNumber); 895 var remainingBreakpoints =
896 this._breakpointManager.breakpointLocationsForLine(this.uiSourceCode(), uiLocation.lineNumber);
867 if (!remainingBreakpoints.length && this.loaded) 897 if (!remainingBreakpoints.length && this.loaded)
868 this._removeBreakpointDecoration(uiLocation.lineNumber); 898 this._updateBreakpointDecorations(uiLocation.lineNumber);
869 } 899 }
870 900
871 /** 901 /**
872 * @param {!Common.Event} event 902 * @param {!Common.Event} event
873 */ 903 */
874 _onSourceMappingChanged(event) { 904 _onSourceMappingChanged(event) {
875 var data = /** @type {{target: !SDK.Target}} */ (event.data); 905 var data = /** @type {{target: !SDK.Target}} */ (event.data);
876 this._updateScriptFile(data.target); 906 this._updateScriptFile(data.target);
877 this._updateLinesWithoutMappingHighlight(); 907 this._updateLinesWithoutMappingHighlight();
878 } 908 }
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChang ed, this); 1150 Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChang ed, this);
1121 this.uiSourceCode().removeEventListener( 1151 this.uiSourceCode().removeEventListener(
1122 Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCom mitted, this); 1152 Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCom mitted, this);
1123 this.uiSourceCode().removeEventListener( 1153 this.uiSourceCode().removeEventListener(
1124 Workspace.UISourceCode.Events.TitleChanged, this._showBlackboxInfobarIfN eeded, this); 1154 Workspace.UISourceCode.Events.TitleChanged, this._showBlackboxInfobarIfN eeded, this);
1125 Common.moduleSetting('skipStackFramesPattern').removeChangeListener(this._sh owBlackboxInfobarIfNeeded, this); 1155 Common.moduleSetting('skipStackFramesPattern').removeChangeListener(this._sh owBlackboxInfobarIfNeeded, this);
1126 Common.moduleSetting('skipContentScripts').removeChangeListener(this._showBl ackboxInfobarIfNeeded, this); 1156 Common.moduleSetting('skipContentScripts').removeChangeListener(this._showBl ackboxInfobarIfNeeded, this);
1127 super.dispose(); 1157 super.dispose();
1128 } 1158 }
1129 }; 1159 };
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/devtools/front_end/source_frame/SourcesTextEditor.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698