blob: 0e5128a868653c200a2c3aa01ffaa55f40b9a9c5 [file] [log] [blame]
/*
* 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',
};