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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
index 46310859b8332b71005a7c9b91259332d1ebc768..71fbe43c95c03154b719b01867ad2ee8d22c5e35 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
@@ -54,9 +54,9 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
WebInspector.SourcesTextEditor.Events.GutterClick, this._handleGutterClick.bind(this), this);
this._breakpointManager.addEventListener(
- WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointAdded, this);
+ WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointChanged, this);
this._breakpointManager.addEventListener(
- WebInspector.BreakpointManager.Events.BreakpointRemoved, this._breakpointRemoved, this);
+ WebInspector.BreakpointManager.Events.BreakpointRemoved, this._breakpointChanged, this);
this.uiSourceCode().addEventListener(
WebInspector.UISourceCode.Events.SourceMappingChanged, this._onSourceMappingChanged, this);
@@ -67,6 +67,10 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
this.uiSourceCode().addEventListener(
WebInspector.UISourceCode.Events.TitleChanged, this._showBlackboxInfobarIfNeeded, this);
+ /** @type {!Set<number>} */
+ this._scheduledBreakpointDecorationsUpdates = new Set();
+ this._inlineBreakpointSymbol = Symbol('inline-breakpoint');
+
/** @type {!Map.<!WebInspector.Target, !WebInspector.ResourceScriptFile>}*/
this._scriptFileForTarget = new Map();
var targets = WebInspector.targetManager.targets();
@@ -266,19 +270,36 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
WebInspector.UIString('Never pause here'),
this._createNewBreakpoint.bind(this, lineNumber, 'false', true));
} else {
- var breakpoint = breakpoints[0];
-
- // This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable.
- contextMenu.appendItem(WebInspector.UIString('Remove breakpoint'), breakpoint.remove.bind(breakpoint));
- contextMenu.appendItem(
- WebInspector.UIString('Edit breakpoint…'),
- this._editBreakpointCondition.bind(this, lineNumber, breakpoint));
- if (breakpoint.enabled())
- contextMenu.appendItem(
- WebInspector.UIString('Disable breakpoint'), breakpoint.setEnabled.bind(breakpoint, false));
- else
+ if (breakpoints.length === 1) {
lushnikov 2016/11/11 19:56:00 nit: can we make it non-nested?
+ var breakpoint = breakpoints[0];
+ // This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable.
+ contextMenu.appendItem(WebInspector.UIString('Remove breakpoint'), breakpoint.remove.bind(breakpoint));
contextMenu.appendItem(
- WebInspector.UIString('Enable breakpoint'), breakpoint.setEnabled.bind(breakpoint, true));
+ WebInspector.UIString('Edit breakpoint…'),
lushnikov 2016/11/11 19:56:00 nit: use \u.. for unicode
+ this._editBreakpointCondition.bind(this, lineNumber, breakpoint));
+ if (breakpoint.enabled())
+ contextMenu.appendItem(
+ WebInspector.UIString('Disable breakpoint'), breakpoint.setEnabled.bind(breakpoint, false));
+ else
+ contextMenu.appendItem(
+ WebInspector.UIString('Enable breakpoint'), breakpoint.setEnabled.bind(breakpoint, true));
+ } else {
+ var hasEnabled = breakpoints.some(breakpoint => breakpoint.enabled());
+ if (hasEnabled) {
+ contextMenu.appendItem(
+ WebInspector.UIString('Disable breakpoints in line'),
+ () => breakpoints.map(breakpoint => breakpoint.setEnabled(false)));
+ }
+ var hasDisabled = breakpoints.some(breakpoint => !breakpoint.enabled());
+ if (hasDisabled) {
+ contextMenu.appendItem(
+ WebInspector.UIString('Enable breakpoints in line'),
+ () => breakpoints.map(breakpoint => breakpoint.setEnabled(true)));
+ }
+
+ var breakpoint = breakpoints[0];
+
+ }
}
resolve();
}
@@ -328,9 +349,6 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
}
_workingCopyChanged(event) {
- if (this._supportsEnabledBreakpointsWhileEditing() || this._scriptFileForTarget.size)
lushnikov 2016/11/11 19:56:00 where did this go?
- return;
-
if (this.uiSourceCode().isDirty())
this._muteBreakpointsWhileEditing();
else
@@ -339,23 +357,16 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
_workingCopyCommitted(event) {
this._scriptsPanel.updateLastModificationTime();
- if (this._supportsEnabledBreakpointsWhileEditing())
- return;
-
if (!this._scriptFileForTarget.size)
this._restoreBreakpointsAfterEditing();
}
_didMergeToVM() {
- if (this._supportsEnabledBreakpointsWhileEditing())
- return;
this._updateDivergedInfobar();
this._restoreBreakpointsIfConsistentScripts();
}
_didDivergeFromVM() {
- if (this._supportsEnabledBreakpointsWhileEditing())
- return;
this._updateDivergedInfobar();
this._muteBreakpointsWhileEditing();
}
@@ -363,15 +374,8 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
_muteBreakpointsWhileEditing() {
if (this._muted)
return;
- for (var lineNumber = 0; lineNumber < this._textEditor.linesCount; ++lineNumber) {
- var breakpointDecoration = this._textEditor.getAttribute(lineNumber, 'breakpoint');
- if (!breakpointDecoration)
- continue;
- this._removeBreakpointDecoration(lineNumber);
- this._addBreakpointDecoration(
- lineNumber, breakpointDecoration.columnNumber, breakpointDecoration.condition, breakpointDecoration.enabled,
- true);
- }
+ for (var lineNumber = 0; lineNumber < this._textEditor.linesCount; ++lineNumber)
lushnikov 2016/11/11 19:56:00 that's unfortunate. Maybe it's time to teach edito
+ this._scheduleBreakpointDecorationsUpdate(lineNumber);
this._muted = true;
}
@@ -395,10 +399,6 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
}
}
- _supportsEnabledBreakpointsWhileEditing() {
- return this.uiSourceCode().project().type() === WebInspector.projectTypes.Snippets;
- }
-
_restoreBreakpointsIfConsistentScripts() {
var scriptFiles = this._scriptFileForTarget.valuesArray();
for (var i = 0; i < scriptFiles.length; ++i)
@@ -410,28 +410,12 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
_restoreBreakpointsAfterEditing() {
delete this._muted;
- var breakpoints = {};
- // Save and remove muted breakpoint decorations.
- for (var lineNumber = 0; lineNumber < this._textEditor.linesCount; ++lineNumber) {
- var breakpointDecoration = this._textEditor.getAttribute(lineNumber, 'breakpoint');
- if (breakpointDecoration) {
- breakpoints[lineNumber] = breakpointDecoration;
- this._removeBreakpointDecoration(lineNumber);
- }
- }
-
- // Remove all breakpoints.
- this._removeAllBreakpoints();
- // Restore all breakpoints from saved decorations.
- for (var lineNumberString in breakpoints) {
- var lineNumber = parseInt(lineNumberString, 10);
- if (isNaN(lineNumber))
- continue;
- var breakpointDecoration = breakpoints[lineNumberString];
- this._setBreakpoint(
- lineNumber, breakpointDecoration.columnNumber, breakpointDecoration.condition, breakpointDecoration.enabled);
- }
+ var allBreakpoints = this._breakpointManager.breakpointsForUISourceCode(this.uiSourceCode());
+ for (var breakpoint of allBreakpoints)
+ breakpoint.remove();
+ for (var breakpoint of allBreakpoints)
+ this._createNewBreakpoint(breakpoint.lineNumber(), breakpoint.condition(), breakpoint.enabled());
}
_removeAllBreakpoints() {
@@ -564,27 +548,6 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
delete this._popoverAnchorBox;
}
- /**
- * @param {number} lineNumber
- * @param {number} columnNumber
- * @param {string} condition
- * @param {boolean} enabled
- * @param {boolean} mutedWhileEditing
- */
- _addBreakpointDecoration(lineNumber, columnNumber, condition, enabled, mutedWhileEditing) {
- var breakpoint = {condition: condition, enabled: enabled, columnNumber: columnNumber};
-
- this.textEditor.setAttribute(lineNumber, 'breakpoint', breakpoint);
-
- var disabled = !enabled || mutedWhileEditing;
- this.textEditor.addBreakpoint(lineNumber, disabled, !!condition);
- }
-
- _removeBreakpointDecoration(lineNumber) {
- this.textEditor.removeAttribute(lineNumber, 'breakpoint');
- this.textEditor.removeBreakpoint(lineNumber);
- }
-
_onKeyDown(event) {
if (event.key === 'Escape') {
if (this._popoverHelper.isPopoverVisible()) {
@@ -612,9 +575,10 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
if (!committed)
return;
- if (breakpoint)
+ if (breakpoint) {
breakpoint.setCondition(newText);
- else
+ breakpoint.setEnabled(true);
+ } else
this._createNewBreakpoint(lineNumber, newText, true);
}
@@ -832,45 +796,85 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
this._valueWidgets.clear();
}
- /**
- * @return {boolean}
- */
- _shouldIgnoreExternalBreakpointEvents() {
- if (this._supportsEnabledBreakpointsWhileEditing())
- return false;
- if (this._muted)
- return true;
- var scriptFiles = this._scriptFileForTarget.valuesArray();
- for (var i = 0; i < scriptFiles.length; ++i) {
- if (scriptFiles[i].isDivergingFromVM() || scriptFiles[i].isMergingToVM())
- return true;
- }
- return false;
- }
-
- _breakpointAdded(event) {
+ _breakpointChanged(event) {
var uiLocation = /** @type {!WebInspector.UILocation} */ (event.data.uiLocation);
if (uiLocation.uiSourceCode !== this.uiSourceCode())
return;
- if (this._shouldIgnoreExternalBreakpointEvents())
+ this._scheduleBreakpointDecorationsUpdate(uiLocation.lineNumber);
+ }
+
+ _scheduleBreakpointDecorationsUpdate(lineNumber) {
+ if (this._scheduledBreakpointDecorationsUpdates.has(lineNumber))
return;
+ if (!this._scheduledBreakpointDecorationsUpdates.size)
+ setImmediate(() => this.textEditor.operation(update.bind(this)));
+ this._scheduledBreakpointDecorationsUpdates.add(lineNumber);
- var breakpoint = /** @type {!WebInspector.BreakpointManager.Breakpoint} */ (event.data.breakpoint);
- if (this.loaded)
- this._addBreakpointDecoration(
- uiLocation.lineNumber, uiLocation.columnNumber, breakpoint.condition(), breakpoint.enabled(), false);
+ /**
+ * @this {!WebInspector.JavaScriptSourceFrame}
+ */
+ function update() {
+ for (var lineNumber of this._scheduledBreakpointDecorationsUpdates)
+ this._updateBreakpointDecorations(lineNumber);
+ this._scheduledBreakpointDecorationsUpdates.clear();
+ }
}
- _breakpointRemoved(event) {
- var uiLocation = /** @type {!WebInspector.UILocation} */ (event.data.uiLocation);
- if (uiLocation.uiSourceCode !== this.uiSourceCode())
+ /**
+ * @param {number} lineNumber
+ */
+ _updateBreakpointDecorations(lineNumber) {
+ if (lineNumber >= this.textEditor.linesCount)
return;
- if (this._shouldIgnoreExternalBreakpointEvents())
+ var lineLength = this.textEditor.line(lineNumber).length;
+ var bookmarks = this.textEditor.bookmarks(new WebInspector.TextRange(lineNumber, 0, lineNumber, lineLength), this._inlineBreakpointSymbol);
+ for (var bookmark of bookmarks)
+ bookmark.clear();
+
+ var breakpoints = this._breakpointManager.findBreakpoints(this.uiSourceCode(), lineNumber);
+ breakpoints.sort((breakpoint1, breakpoint2) => breakpoint1.columnNumber() - breakpoint2.columnNumber());
lushnikov 2016/11/11 19:56:00 why do you need to sort them?
+ var hasEnabled = breakpoints.some(breakpoint => breakpoint.enabled());
+ var hasConditional = breakpoints.some(breakpoint => !!breakpoint.condition());
+ var hasEnabledConditional = breakpoints.some(breakpoint => !!breakpoint.condition() && breakpoint.enabled());
+
+ if (!breakpoints.length) {
+ this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint', false);
return;
+ }
+ this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint', true);
+ this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint-conditional', hasEnabledConditional || (!hasEnabled && hasConditional));
+ this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint-disabled', !hasEnabled || this._muted);
+ if (breakpoints.length <= 1 || this._muted)
+ return;
+ for (var i = 0; i < breakpoints.length; ++i) {
+ let breakpoint = breakpoints[i];
+ var inlineBreakpoint = WebInspector.InlineBreakpoint.create();
+ inlineBreakpoint.setEnabled(breakpoint.enabled() || this._muted);
+ inlineBreakpoint.setConditional(!!breakpoint.condition());
+ inlineBreakpoint.addEventListener('click', () => breakpoint.setEnabled(!breakpoint.enabled()), true);
+ inlineBreakpoint.addEventListener('contextmenu', this._populateInlineBreakpointMenu.bind(this, breakpoint), true);
+ this.textEditor.addBookmark(breakpoint.lineNumber(), breakpoint.columnNumber(), inlineBreakpoint, this._inlineBreakpointSymbol);
+ }
+ }
- var remainingBreakpoints = this._breakpointManager.findBreakpoints(this.uiSourceCode(), uiLocation.lineNumber);
- if (!remainingBreakpoints.length && this.loaded)
- this._removeBreakpointDecoration(uiLocation.lineNumber);
+ /**
+ * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
+ * @param {!Event} event
+ */
+ _populateInlineBreakpointMenu(breakpoint, event) {
+ event.consume(true);
+ var contextMenu = new WebInspector.ContextMenu(event);
+ if (!breakpoint.enabled()) {
+ contextMenu.appendItem(WebInspector.UIString('Never pause here'), () => {
+ breakpoint.setCondition('false'); breakpoint.setEnabled(true);
+ });
+ }
+ var conditionalBreakpointTitle = breakpoint.enabled() ? WebInspector.UIString('Edit breakpoint…')
+ : WebInspector.UIString('Add conditional breakpoint…');
+ contextMenu.appendItem(
+ conditionalBreakpointTitle,
+ this._editBreakpointCondition.bind(this, breakpoint.lineNumber(), breakpoint));
+ contextMenu.show();
}
/**
@@ -944,7 +948,7 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
var breakpointLocations = this._breakpointManager.breakpointLocationsForUISourceCode(this.uiSourceCode());
for (var i = 0; i < breakpointLocations.length; ++i)
- this._breakpointAdded({data: breakpointLocations[i]});
+ this._breakpointChanged({data: breakpointLocations[i]});
var scriptFiles = this._scriptFileForTarget.valuesArray();
for (var i = 0; i < scriptFiles.length; ++i)
@@ -1017,12 +1021,15 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
_toggleBreakpoint(lineNumber, onlyDisable) {
var breakpoints = this._breakpointManager.findBreakpoints(this.uiSourceCode(), lineNumber);
if (breakpoints.length) {
- if (onlyDisable)
- breakpoints[0].setEnabled(!breakpoints[0].enabled());
- else
- breakpoints[0].remove();
- } else
+ for (var breakpoint of breakpoints) {
+ if (onlyDisable)
+ breakpoint.setEnabled(false);
+ else
+ breakpoint.remove();
+ }
+ } else {
this._createNewBreakpoint(lineNumber, '', true);
+ }
}
/**
@@ -1069,10 +1076,13 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
* @param {?Array<!WebInspector.UILocation>} locations
*/
function setBreakpoint(locations) {
- if (!locations || !locations.length)
+ if (!locations || !locations.length) {
this._setBreakpoint(lineNumber, 0, condition, enabled);
- else
- this._setBreakpoint(locations[0].lineNumber, locations[0].columnNumber, condition, enabled);
+ WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ScriptsBreakpointSet);
+ return;
+ }
+ for (var i = 0; i < locations.length; ++i)
+ this._setBreakpoint(locations[i].lineNumber, locations[i].columnNumber, condition, enabled && i === 0);
WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ScriptsBreakpointSet);
}
}
@@ -1115,9 +1125,9 @@ WebInspector.JavaScriptSourceFrame = class extends WebInspector.UISourceCodeFram
*/
dispose() {
this._breakpointManager.removeEventListener(
- WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointAdded, this);
+ WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointChanged, this);
this._breakpointManager.removeEventListener(
- WebInspector.BreakpointManager.Events.BreakpointRemoved, this._breakpointRemoved, this);
+ WebInspector.BreakpointManager.Events.BreakpointRemoved, this._breakpointChanged, this);
this.uiSourceCode().removeEventListener(
WebInspector.UISourceCode.Events.SourceMappingChanged, this._onSourceMappingChanged, this);
this.uiSourceCode().removeEventListener(

Powered by Google App Engine
This is Rietveld 408576698