Chromium Code Reviews| 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 13de635127018497c6d13123c4da6abc652c2562..4e27d14ffa94f357a6aaa9f02ec3da3505fd637b 100644 |
| --- a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js |
| +++ b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js |
| @@ -257,20 +257,33 @@ Sources.JavaScriptSourceFrame = class extends Sources.UISourceCodeFrame { |
| contextMenu.appendItem( |
| Common.UIString('Add breakpoint'), this._createNewBreakpoint.bind(this, lineNumber, '', true)); |
| contextMenu.appendItem( |
| - Common.UIString('Add conditional breakpoint…'), this._editBreakpointCondition.bind(this, lineNumber)); |
| + Common.UIString('Add conditional breakpoint\u2026'), this._editBreakpointCondition.bind(this, lineNumber)); |
| contextMenu.appendItem( |
| Common.UIString('Never pause here'), this._createNewBreakpoint.bind(this, lineNumber, 'false', true)); |
| } else { |
| - var breakpoint = breakpoints[0]; |
| + var hasOneBreakpoint = breakpoints.length === 1; |
| + var removeTitle = |
| + hasOneBreakpoint ? Common.UIString('Remove breakpoint') : Common.UIString('Remove all breakpoints in line'); |
| + contextMenu.appendItem(removeTitle, () => breakpoints.map(breakpoint => breakpoint.remove())); |
| + if (hasOneBreakpoint) { |
| + contextMenu.appendItem( |
| + Common.UIString('Edit breakpoint\u2026'), |
| + this._editBreakpointCondition.bind(this, lineNumber, breakpoints[0])); |
| + } |
| - // This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable. |
| - contextMenu.appendItem(Common.UIString('Remove breakpoint'), breakpoint.remove.bind(breakpoint)); |
| - contextMenu.appendItem( |
| - Common.UIString('Edit breakpoint…'), this._editBreakpointCondition.bind(this, lineNumber, breakpoint)); |
| - if (breakpoint.enabled()) |
| - contextMenu.appendItem(Common.UIString('Disable breakpoint'), breakpoint.setEnabled.bind(breakpoint, false)); |
| - else |
| - contextMenu.appendItem(Common.UIString('Enable breakpoint'), breakpoint.setEnabled.bind(breakpoint, true)); |
| + var hasEnabled = breakpoints.some(breakpoint => breakpoint.enabled()); |
| + if (hasEnabled) { |
| + var title = hasOneBreakpoint ? Common.UIString('Disable breakpoint') : |
| + Common.UIString('Disable all breakpoints in line'); |
| + contextMenu.appendItem(title, () => breakpoints.map(breakpoint => breakpoint.setEnabled(false))); |
| + } |
| + |
| + var hasDisabled = breakpoints.some(breakpoint => !breakpoint.enabled()); |
| + if (hasDisabled) { |
| + var title = hasOneBreakpoint ? Common.UIString('Enable breakpoint') : |
| + Common.UIString('Enabled all breakpoints in line'); |
| + contextMenu.appendItem(title, () => breakpoints.map(breakpoint => breakpoint.setEnabled(true))); |
| + } |
| } |
| resolve(); |
| } |
| @@ -355,16 +368,9 @@ Sources.JavaScriptSourceFrame = class extends Sources.UISourceCodeFrame { |
| _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); |
| - } |
| this._muted = true; |
| + for (var breakpointLocation of this._breakpointManager.breakpointLocationsForUISourceCode(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.
|
| + this._updateBreakpointDecorations(breakpointLocation.uiLocation.lineNumber); |
| } |
| _updateDivergedInfobar() { |
| @@ -403,28 +409,29 @@ Sources.JavaScriptSourceFrame = class extends Sources.UISourceCodeFrame { |
| _restoreBreakpointsAfterEditing() { |
| delete this._muted; |
| - var breakpoints = {}; |
| + /** @type {!Map<number, !{lineNumber: number, columnNumber: number, condition: string, enabled: boolean }>} */ |
| + var breakpoints = new Map(); |
| // Save and remove muted breakpoint decorations. |
| - for (var lineNumber = 0; lineNumber < this._textEditor.linesCount; ++lineNumber) { |
|
lushnikov
2016/11/17 22:14:52
unfortunately we need to traverse lines, because e
kozy
2016/11/18 16:32:40
Done.
|
| - var breakpointDecoration = this._textEditor.getAttribute(lineNumber, 'breakpoint'); |
| - if (breakpointDecoration) { |
| - breakpoints[lineNumber] = breakpointDecoration; |
| - this._removeBreakpointDecoration(lineNumber); |
| - } |
| + for (var breakpointLocation of this._breakpointManager.breakpointLocationsForUISourceCode(this.uiSourceCode())) { |
|
lushnikov
2016/11/17 21:33:18
same question here about file system UISourceCodes
kozy
2016/11/18 16:32:40
returns.
|
| + var uiLocation = breakpointLocation.uiLocation; |
| + if (breakpoints.has(uiLocation.lineNumber)) |
| + continue; |
| + var breakpoint = breakpointLocation.breakpoint; |
| + breakpoints.set(uiLocation.lineNumber, { |
| + lineNumber: uiLocation.lineNumber, |
| + columnNumber: uiLocation.columnNumber, |
| + condition: breakpoint.condition(), |
| + enabled: breakpoint.enabled() |
| + }); |
| + this._updateBreakpointDecorations(uiLocation.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); |
| - } |
| + for (var breakpoint of breakpoints.valuesArray()) |
| + this._setBreakpoint(breakpoint.lineNumber, breakpoint.columnNumber, breakpoint.condition, breakpoint.enabled); |
| } |
| _removeAllBreakpoints() { |
| @@ -559,23 +566,47 @@ Sources.JavaScriptSourceFrame = class extends Sources.UISourceCodeFrame { |
| /** |
| * @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}; |
| + _updateBreakpointDecorations(lineNumber) { |
| + if (!this._scheduledBreakpointDecorationUpdates) |
| + this._scheduledBreakpointDecorationUpdates = new Set(); |
| + if (!this._scheduledBreakpointDecorationUpdates.size) |
| + setImmediate(() => this.textEditor.operation(update.bind(this))); |
| + this._scheduledBreakpointDecorationUpdates.add(lineNumber); |
| - this.textEditor.setAttribute(lineNumber, 'breakpoint', breakpoint); |
| - |
| - var disabled = !enabled || mutedWhileEditing; |
| - this.textEditor.addBreakpoint(lineNumber, disabled, !!condition); |
| + /** |
| + * @this {Sources.JavaScriptSourceFrame} |
| + */ |
| + function update() { |
| + for (var lineNumber of this._scheduledBreakpointDecorationUpdates) { |
| + var breakpointLocations = this._breakpointManager.breakpointLocationsForLine(this.uiSourceCode(), lineNumber); |
| + var breakpoints = breakpointLocations.map(breakpointLocation => breakpointLocation.breakpoint); |
| + |
| + var hasAny = !!breakpoints.length; |
| + var hasEnabled = false; |
| + var hasConditional = false; |
| + var hasEnabledConditional = false; |
| + 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.
|
| + if (breakpoint.enabled()) |
| + hasEnabled = true; |
| + if (!!breakpoint.condition()) { |
| + hasConditional = true; |
| + if (breakpoint.enabled()) |
| + hasEnabledConditional = true; |
| + } |
| + } |
| + this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint', hasAny); |
| + this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint-disabled', hasAny && (!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
|
| + this.textEditor.toggleLineClass( |
| + lineNumber, 'cm-breakpoint-conditional', |
| + hasEnabledConditional || (hasAny && !hasEnabled && hasConditional)); |
| + this._breakpointDecorationsUpdatedForTest(lineNumber, !hasEnabled, !hasAny); |
| + } |
| + delete this._scheduledBreakpointDecorationUpdates; |
| + } |
| } |
| - _removeBreakpointDecoration(lineNumber) { |
| - this.textEditor.removeAttribute(lineNumber, 'breakpoint'); |
| - this.textEditor.removeBreakpoint(lineNumber); |
| + _breakpointDecorationsUpdatedForTest(lineNumber, disabled, removed) { |
| } |
| _onKeyDown(event) { |
| @@ -850,10 +881,8 @@ Sources.JavaScriptSourceFrame = class extends Sources.UISourceCodeFrame { |
| return; |
| var breakpoint = /** @type {!Bindings.BreakpointManager.Breakpoint} */ (event.data.breakpoint); |
| - if (this.loaded) { |
| - this._addBreakpointDecoration( |
| - uiLocation.lineNumber, uiLocation.columnNumber, breakpoint.condition(), breakpoint.enabled(), false); |
| - } |
| + if (this.loaded) |
| + this._updateBreakpointDecorations(uiLocation.lineNumber); |
| } |
| _breakpointRemoved(event) { |
| @@ -863,9 +892,10 @@ Sources.JavaScriptSourceFrame = class extends Sources.UISourceCodeFrame { |
| if (this._shouldIgnoreExternalBreakpointEvents()) |
| return; |
| - var remainingBreakpoints = this._breakpointManager.findBreakpoints(this.uiSourceCode(), uiLocation.lineNumber); |
| + var remainingBreakpoints = |
| + this._breakpointManager.breakpointLocationsForLine(this.uiSourceCode(), uiLocation.lineNumber); |
| if (!remainingBreakpoints.length && this.loaded) |
| - this._removeBreakpointDecoration(uiLocation.lineNumber); |
| + this._updateBreakpointDecorations(uiLocation.lineNumber); |
| } |
| /** |