| /* | |
| * Copyright 2018 The Chromium Authors. All rights reserved. | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| Sources.BreakpointEditDialog = class extends UI.Widget { | |
| /** | |
| * @param {number} editorLineNumber | |
| * @param {string} oldCondition | |
| * @param {boolean} preferLogpoint | |
| * @param {function({committed: boolean, condition: string})} onFinish | |
| */ | |
| constructor(editorLineNumber, oldCondition, preferLogpoint, onFinish) { | |
| super(true); | |
| this.registerRequiredCSS('sources/breakpointEditDialog.css'); | |
| this._onFinish = onFinish; | |
| this._finished = false; | |
| /** @type {?UI.TextEditor} */ | |
| this._editor = null; | |
| this.element.tabIndex = -1; | |
| const logpointPrefix = Sources.BreakpointEditDialog.LogpointPrefix; | |
| const logpointSuffix = Sources.BreakpointEditDialog._LogpointSuffix; | |
| this._isLogpoint = oldCondition.startsWith(logpointPrefix) && oldCondition.endsWith(logpointSuffix); | |
| if (this._isLogpoint) { | |
| oldCondition = oldCondition.substring(logpointPrefix.length, oldCondition.length - logpointSuffix.length); | |
| } | |
| this._isLogpoint = this._isLogpoint || preferLogpoint; | |
| this.element.classList.add('sources-edit-breakpoint-dialog'); | |
| const toolbar = new UI.Toolbar('source-frame-breakpoint-toolbar', this.contentElement); | |
| toolbar.appendText(`Line ${editorLineNumber + 1}:`); | |
| this._typeSelector = new UI.ToolbarComboBox(this._onTypeChanged.bind(this), ls`Breakpoint type`); | |
| this._typeSelector.createOption(ls`Breakpoint`, Sources.BreakpointEditDialog.BreakpointType.Breakpoint); | |
| const conditionalOption = this._typeSelector.createOption( | |
| ls`Conditional breakpoint`, Sources.BreakpointEditDialog.BreakpointType.Conditional); | |
| const logpointOption = | |
| this._typeSelector.createOption(ls`Logpoint`, Sources.BreakpointEditDialog.BreakpointType.Logpoint); | |
| this._typeSelector.select(this._isLogpoint ? logpointOption : conditionalOption); | |
| toolbar.appendToolbarItem(this._typeSelector); | |
| self.runtime.extension(UI.TextEditorFactory).instance().then(factory => { | |
| const editorOptions = {lineNumbers: false, lineWrapping: true, mimeType: 'javascript', autoHeight: true}; | |
| this._editor = factory.createEditor(editorOptions); | |
| this._updatePlaceholder(); | |
| this._editor.widget().element.classList.add('condition-editor'); | |
| this._editor.configureAutocomplete(ObjectUI.JavaScriptAutocompleteConfig.createConfigForEditor(this._editor)); | |
| if (oldCondition) { | |
| this._editor.setText(oldCondition); | |
| } | |
| this._editor.widget().markAsExternallyManaged(); | |
| this._editor.widget().show(this.contentElement); | |
| this._editor.setSelection(this._editor.fullRange()); | |
| this._editor.widget().focus(); | |
| this._editor.widget().element.addEventListener('keydown', this._onKeyDown.bind(this), true); | |
| this.contentElement.addEventListener('blur', event => { | |
| if (event.relatedTarget && !event.relatedTarget.isSelfOrDescendant(this.element)) { | |
| this._finishEditing(true); | |
| } | |
| }, true); | |
| }); | |
| } | |
| /** | |
| * @param {string} condition | |
| * @return {string} | |
| */ | |
| static _conditionForLogpoint(condition) { | |
| return `${Sources.BreakpointEditDialog.LogpointPrefix}${condition}${Sources.BreakpointEditDialog._LogpointSuffix}`; | |
| } | |
| _onTypeChanged() { | |
| const value = this._typeSelector.selectedOption().value; | |
| this._isLogpoint = value === Sources.BreakpointEditDialog.BreakpointType.Logpoint; | |
| this._updatePlaceholder(); | |
| if (value === Sources.BreakpointEditDialog.BreakpointType.Breakpoint) { | |
| this._editor.setText(''); | |
| this._finishEditing(true); | |
| } | |
| } | |
| _updatePlaceholder() { | |
| const selectedValue = this._typeSelector.selectedOption().value; | |
| if (selectedValue === Sources.BreakpointEditDialog.BreakpointType.Conditional) { | |
| this._editor.setPlaceholder(ls`Expression to check before pausing, e.g. x > 5`); | |
| this._typeSelector.element.title = ls`Pause only when the condition is true`; | |
| } else if (selectedValue === Sources.BreakpointEditDialog.BreakpointType.Logpoint) { | |
| this._editor.setPlaceholder(ls`Log message, e.g. 'x is', x`); | |
| this._typeSelector.element.title = ls`Log a message to Console, do not break`; | |
| } | |
| } | |
| /** | |
| * @param {boolean} committed | |
| */ | |
| _finishEditing(committed) { | |
| if (this._finished) { | |
| return; | |
| } | |
| this._finished = true; | |
| this._editor.widget().detach(); | |
| let condition = this._editor.text(); | |
| if (this._isLogpoint) { | |
| condition = Sources.BreakpointEditDialog._conditionForLogpoint(condition); | |
| } | |
| this._onFinish({committed, condition}); | |
| } | |
| /** | |
| * @param {!Event} event | |
| */ | |
| async _onKeyDown(event) { | |
| if (isEnterKey(event) && !event.shiftKey) { | |
| event.consume(true); | |
| const expression = this._editor.text(); | |
| if (event.ctrlKey || await ObjectUI.JavaScriptAutocomplete.isExpressionComplete(expression)) { | |
| this._finishEditing(true); | |
| } else { | |
| this._editor.newlineAndIndent(); | |
| } | |
| } | |
| if (isEscKey(event)) { | |
| this._finishEditing(false); | |
| } | |
| } | |
| }; | |
| Sources.BreakpointEditDialog.LogpointPrefix = '/** DEVTOOLS_LOGPOINT */ console.log('; | |
| Sources.BreakpointEditDialog._LogpointSuffix = ')'; | |
| Sources.BreakpointEditDialog.BreakpointType = { | |
| Breakpoint: 'Breakpoint', | |
| Conditional: 'Conditional', | |
| Logpoint: 'Logpoint', | |
| }; |