chrome-devtools-frontend 1.0.927127 → 1.0.927419

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/config/gni/devtools_grd_files.gni +3 -0
  2. package/front_end/core/host/UserMetrics.ts +0 -1
  3. package/front_end/core/i18n/locales/en-US.json +27 -9
  4. package/front_end/core/i18n/locales/en-XL.json +27 -9
  5. package/front_end/core/platform/keyboard-utilities.ts +1 -0
  6. package/front_end/entrypoints/main/MainImpl.ts +0 -1
  7. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +0 -6
  8. package/front_end/panels/snippets/SnippetsQuickOpen.ts +8 -3
  9. package/front_end/panels/sources/sources-meta.ts +22 -7
  10. package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
  11. package/front_end/third_party/codemirror.next/package.json +4 -4
  12. package/front_end/ui/components/code_highlighter/CodeHighlighter.ts +137 -0
  13. package/front_end/ui/components/code_highlighter/codeHighlighter.css +51 -0
  14. package/front_end/ui/components/code_highlighter/code_highlighter.ts +11 -0
  15. package/front_end/ui/components/docs/text_editor/basic.html +28 -0
  16. package/front_end/ui/components/docs/text_editor/basic.ts +14 -0
  17. package/front_end/ui/components/docs/text_prompt/basic.html +35 -0
  18. package/front_end/ui/components/docs/text_prompt/basic.ts +19 -0
  19. package/front_end/ui/components/render_coordinator/RenderCoordinator.ts +17 -0
  20. package/front_end/ui/components/text_editor/TextEditor.ts +161 -0
  21. package/front_end/ui/components/text_editor/config.ts +264 -0
  22. package/front_end/ui/components/text_editor/text_editor.ts +6 -0
  23. package/front_end/ui/components/text_editor/theme.ts +113 -0
  24. package/front_end/ui/components/text_prompt/TextPrompt.ts +144 -0
  25. package/front_end/ui/components/text_prompt/textPrompt.css +33 -0
  26. package/front_end/ui/components/text_prompt/text_prompt.ts +9 -0
  27. package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +8 -3
  28. package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +38 -38
  29. package/front_end/ui/legacy/components/quick_open/HelpQuickOpen.ts +10 -4
  30. package/front_end/ui/legacy/components/quick_open/QuickOpen.ts +23 -6
  31. package/front_end/ui/legacy/components/quick_open/filteredListWidget.css +7 -8
  32. package/front_end/ui/legacy/filter.css +1 -0
  33. package/inspector_overlay/main.ts +2 -1
  34. package/inspector_overlay/tool_screenshot.ts +8 -1
  35. package/package.json +1 -1
@@ -0,0 +1,264 @@
1
+ // Copyright 2021 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as Common from '../../../core/common/common.js';
6
+ import * as i18n from '../../../core/i18n/i18n.js';
7
+ import * as CM from '../../../third_party/codemirror.next/codemirror.next.js';
8
+ import * as CodeHighlighter from '../code_highlighter/code_highlighter.js';
9
+
10
+ import {editorTheme} from './theme.js';
11
+
12
+ const LINES_TO_SCAN_FOR_INDENTATION_GUESSING = 1000;
13
+
14
+ const UIStrings = {
15
+ /**
16
+ *@description Label text for the editor
17
+ */
18
+ codeEditor: 'Code editor',
19
+ };
20
+ const str_ = i18n.i18n.registerUIStrings('ui/components/text_editor/config.ts', UIStrings);
21
+ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
22
+
23
+ const empty: CM.Extension = [];
24
+
25
+ export const dynamicSetting = CM.Facet.define<DynamicSetting<unknown>>();
26
+
27
+ // The code below is used to wire up dynamic settings to editors. When
28
+ // you include one of these objects in an editor configuration, the
29
+ // TextEditor class will take care of listening to changes in the
30
+ // setting, and updating the configuration as appropriate.
31
+
32
+ export class DynamicSetting<T> {
33
+ compartment = new CM.Compartment();
34
+ extension: CM.Extension;
35
+
36
+ constructor(
37
+ readonly settingName: string,
38
+ private readonly getExtension: (value: T, state: CM.EditorState) => CM.Extension,
39
+ ) {
40
+ this.extension = [this.compartment.of(empty), dynamicSetting.of(this as DynamicSetting<unknown>)];
41
+ }
42
+
43
+ sync(state: CM.EditorState, value: T): CM.StateEffect<unknown>|null {
44
+ const cur = this.compartment.get(state);
45
+ const needed = this.getExtension(value, state);
46
+ return cur === needed ? null : this.compartment.reconfigure(needed);
47
+ }
48
+
49
+ static bool(name: string, enabled: CM.Extension, disabled: CM.Extension = empty): DynamicSetting<boolean> {
50
+ return new DynamicSetting<boolean>(name, val => val ? enabled : disabled);
51
+ }
52
+ }
53
+
54
+ export const tabMovesFocus = DynamicSetting.bool('textEditorTabMovesFocus', CM.keymap.of([{
55
+ key: 'Tab',
56
+ run: (view: CM.EditorView): boolean => view.state.doc.length ? CM.indentMore(view) : false,
57
+ shift: (view: CM.EditorView): boolean => view.state.doc.length ? CM.indentLess(view) : false,
58
+ }]));
59
+
60
+ export const bracketMatching = DynamicSetting.bool('textEditorBracketMatching', CM.bracketMatching());
61
+
62
+ export function guessIndent(doc: CM.Text): string {
63
+ const values: {[indent: string]: number} = Object.create(null);
64
+ let scanned = 0;
65
+ for (let cur = doc.iterLines(1, Math.min(doc.lines + 1, LINES_TO_SCAN_FOR_INDENTATION_GUESSING)); !cur.next().done;) {
66
+ let space = (/^\s*/.exec(cur.value) as string[])[0];
67
+ if (space.length === cur.value.length || !space.length) {
68
+ continue;
69
+ }
70
+ if (space[0] === '\t') {
71
+ space = '\t';
72
+ } else if (/[^ ]/.test(space)) {
73
+ continue;
74
+ }
75
+ scanned++;
76
+ values[space] = (values[space] || 0) + 1;
77
+ }
78
+ const minOccurrence = scanned * 0.05;
79
+ const sorted = Object.entries(values).filter(e => e[1] > minOccurrence).sort((a, b) => a[1] - b[1]);
80
+ return sorted.length ? sorted[0][0] : Common.Settings.Settings.instance().moduleSetting('textEditorIndent').get();
81
+ }
82
+
83
+ const cachedIndentUnit: {[indent: string]: CM.Extension} = Object.create(null);
84
+
85
+ function getIndentUnit(indent: string): CM.Extension {
86
+ let value = cachedIndentUnit[indent];
87
+ if (!value) {
88
+ value = cachedIndentUnit[indent] = CM.indentUnit.of(indent);
89
+ }
90
+ return value;
91
+ }
92
+
93
+ export const autoDetectIndent = new DynamicSetting<boolean>('textEditorAutoDetectIndent', (on, state) => {
94
+ return on ? CM.Prec.override(getIndentUnit(guessIndent(state.doc))) : empty;
95
+ });
96
+
97
+ function matcher(decorator: CM.MatchDecorator): CM.Extension {
98
+ return CM.ViewPlugin.define(
99
+ view => ({
100
+ decorations: decorator.createDeco(view),
101
+ update(u): void {
102
+ this.decorations = decorator.updateDeco(u, this.decorations);
103
+ },
104
+ }),
105
+ {
106
+ decorations: v => v.decorations,
107
+ });
108
+ }
109
+
110
+ const WhitespaceDeco = new Map<string, CM.Decoration>();
111
+
112
+ function getWhitespaceDeco(space: string): CM.Decoration {
113
+ const cached = WhitespaceDeco.get(space);
114
+ if (cached) {
115
+ return cached;
116
+ }
117
+ const result = CM.Decoration.mark({
118
+ attributes: space === '\t' ? {
119
+ class: 'cm-highlightedTab',
120
+ } :
121
+ {class: 'cm-highlightedSpaces', 'data-display': '·'.repeat(space.length)},
122
+ });
123
+ WhitespaceDeco.set(space, result);
124
+ return result;
125
+ }
126
+
127
+ const showAllWhitespace = matcher(new CM.MatchDecorator({
128
+ regexp: /\t| +/g,
129
+ decoration: (match: RegExpExecArray): CM.Decoration => getWhitespaceDeco(match[0]),
130
+ boundary: /\S/,
131
+ }));
132
+
133
+ const showTrailingWhitespace = matcher(new CM.MatchDecorator({
134
+ regexp: /\s+$/g,
135
+ decoration: CM.Decoration.mark({class: 'cm-trailingWhitespace'}),
136
+ boundary: /\S/,
137
+ }));
138
+
139
+ export const showWhitespace = new DynamicSetting<string>('showWhitespacesInEditor', value => {
140
+ if (value === 'all') {
141
+ return showAllWhitespace;
142
+ }
143
+ if (value === 'trailing') {
144
+ return showTrailingWhitespace;
145
+ }
146
+ return empty;
147
+ });
148
+
149
+ export const allowScrollPastEof = DynamicSetting.bool('allowScrollPastEof', CM.scrollPastEnd());
150
+
151
+ export const indentUnit = new DynamicSetting<string>('textEditorIndent', getIndentUnit);
152
+
153
+ export const domWordWrap = DynamicSetting.bool('domWordWrap', CM.EditorView.lineWrapping);
154
+
155
+ function detectLineSeparator(text: string): CM.Extension {
156
+ if (/\r\n/.test(text) && !/(^|[^\r])\n/.test(text)) {
157
+ return CM.EditorState.lineSeparator.of('\r\n');
158
+ }
159
+ return [];
160
+ }
161
+
162
+ const baseKeymap = CM.keymap.of([
163
+ {key: 'Ctrl-m', run: CM.cursorMatchingBracket, shift: CM.selectMatchingBracket},
164
+ {key: 'Mod-/', run: CM.toggleComment},
165
+ {key: 'Mod-d', run: CM.selectNextOccurrence},
166
+ {key: 'Alt-ArrowLeft', mac: 'Ctrl-ArrowLeft', run: CM.cursorSubwordBackward, shift: CM.selectSubwordBackward},
167
+ {key: 'Alt-ArrowRight', mac: 'Ctrl-ArrowRight', run: CM.cursorSubwordForward, shift: CM.selectSubwordForward},
168
+ ...CM.closeBracketsKeymap,
169
+ ...CM.standardKeymap,
170
+ ...CM.historyKeymap,
171
+ ]);
172
+
173
+ function themeIsDark(): boolean {
174
+ const setting = Common.Settings.Settings.instance().moduleSetting('uiTheme').get();
175
+ return setting === 'systemPreferred' ? window.matchMedia('(prefers-color-scheme: dark)').matches : setting === 'dark';
176
+ }
177
+
178
+ const dummyDarkTheme = CM.EditorView.theme({}, {dark: true});
179
+
180
+ export function baseConfiguration(text: string): CM.Extension {
181
+ return [
182
+ editorTheme,
183
+ themeIsDark() ? dummyDarkTheme : [],
184
+ CM.highlightSpecialChars(),
185
+ CM.history(),
186
+ CM.drawSelection(),
187
+ CM.EditorState.allowMultipleSelections.of(true),
188
+ CM.indentOnInput(),
189
+ CodeHighlighter.CodeHighlighter.getHighlightStyle(CM),
190
+ CM.closeBrackets(),
191
+ baseKeymap,
192
+ tabMovesFocus,
193
+ bracketMatching,
194
+ indentUnit,
195
+ CM.Prec.fallback(CM.EditorView.contentAttributes.of({'aria-label': i18nString(UIStrings.codeEditor)})),
196
+ detectLineSeparator(text),
197
+ CM.tooltips({position: 'absolute'}),
198
+ ];
199
+ }
200
+
201
+ class CompletionHint extends CM.WidgetType {
202
+ constructor(readonly text: string) {
203
+ super();
204
+ }
205
+
206
+ eq(other: CompletionHint): boolean {
207
+ return this.text === other.text;
208
+ }
209
+
210
+ toDOM(): HTMLElement {
211
+ const span = document.createElement('span');
212
+ span.className = 'cm-completionHint';
213
+ span.textContent = this.text;
214
+ return span;
215
+ }
216
+ }
217
+
218
+ export const showCompletionHint = CM.ViewPlugin.fromClass(class {
219
+ decorations: CM.DecorationSet = CM.Decoration.none;
220
+ currentHint: string|null = null;
221
+
222
+ update(update: CM.ViewUpdate): void {
223
+ const top = this.currentHint = this.topCompletion(update.state);
224
+ if (!top) {
225
+ this.decorations = CM.Decoration.none;
226
+ } else {
227
+ this.decorations = CM.Decoration.set(
228
+ [CM.Decoration.widget({widget: new CompletionHint(top), side: 1}).range(update.state.selection.main.head)]);
229
+ }
230
+ }
231
+
232
+ topCompletion(state: CM.EditorState): string|null {
233
+ const completions = CM.currentCompletions(state);
234
+ if (!completions.length) {
235
+ return null;
236
+ }
237
+ const {label} = completions[0];
238
+ if (label.length > 100 || label.indexOf('\n') > -1) {
239
+ return null;
240
+ }
241
+ const pos = state.selection.main.head;
242
+ const lineBefore = state.doc.lineAt(pos);
243
+ if (pos !== lineBefore.to) {
244
+ return null;
245
+ }
246
+ const textBefore = lineBefore.text.slice(0, pos - lineBefore.from);
247
+ for (let i = label.length - 1; i > 0; i--) {
248
+ if (textBefore.endsWith(label.slice(0, i)) && !/\w/.test(textBefore.charAt(textBefore.length - i - 1))) {
249
+ return label.slice(i);
250
+ }
251
+ }
252
+ return null;
253
+ }
254
+ }, {decorations: p => p.decorations});
255
+
256
+ export function contentIncludingHint(view: CM.EditorView): string {
257
+ const plugin = view.plugin(showCompletionHint);
258
+ let content = view.state.doc.toString();
259
+ if (plugin && plugin.currentHint) {
260
+ const {head} = view.state.selection.main;
261
+ content = content.slice(0, head) + plugin.currentHint + content.slice(head);
262
+ }
263
+ return content;
264
+ }
@@ -0,0 +1,6 @@
1
+ // Copyright 2021 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ export * as Config from './config.js';
6
+ export * as TextEditor from './TextEditor.js';
@@ -0,0 +1,113 @@
1
+ // Copyright 2021 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as CM from '../../../third_party/codemirror.next/codemirror.next.js';
6
+
7
+ export const editorTheme = CM.EditorView.theme({
8
+ '&.cm-editor': {
9
+ color: 'color: var(--color-text-primary)',
10
+ },
11
+
12
+ '.cm-scroller': {
13
+ lineHeight: '1.2em',
14
+ fontFamily: 'var(--source-code-font-family)',
15
+ fontSize: 'var(--source-code-font-size)',
16
+ },
17
+
18
+ '.cm-panels, .cm-tooltip': {
19
+ backgroundColor: 'var(--color-background-elevation-1)',
20
+ },
21
+
22
+ '.cm-selectionMatch': {
23
+ backgroundColor: 'var(--color-selection-highlight)',
24
+ },
25
+
26
+ '.cm-cursor': {
27
+ borderLeft: '1px solid var(--color-background-inverted)',
28
+ },
29
+
30
+ '&.cm-readonly .cm-cursor': {
31
+ display: 'none',
32
+ },
33
+
34
+ '.cm-cursor-secondary': {
35
+ borderLeft: '1px solid var(--color-secondary-cursor)',
36
+ },
37
+
38
+ '.cm-selectionBackground': {
39
+ background: 'var(--color-editor-selection-selection)',
40
+ },
41
+
42
+ '&.cm-focused .cm-selectionBackground': {
43
+ background: 'var(--color-editor-selection)',
44
+ },
45
+
46
+ '.cm-gutters': {
47
+ borderRight: '1px solid var(--color-details-hairline)',
48
+ whiteSpace: 'nowrap',
49
+ backgroundColor: 'var(--color-background)',
50
+ },
51
+
52
+ '.cm-lineNumbers .cm-gutterElement': {
53
+ color: 'var(--color-line-number)',
54
+ padding: '0 3px 0 9px',
55
+ },
56
+
57
+ '&:focus-within .cm-matchingBracket': {
58
+ color: 'inherit',
59
+ backgroundColor: 'var(--color-matching-bracket-background)',
60
+ borderBottom: '1px solid var(--color-matching-bracket-underline)',
61
+ },
62
+
63
+ '&:focus-within .cm-nonmatchingBracket': {
64
+ backgroundColor: 'var(--color-nonmatching-bracket-background)',
65
+ borderBottom: '1px solid var(--color-nonmatching-bracket-underline)',
66
+ },
67
+
68
+ '.cm-trailingWhitespace': {
69
+ backgroundColor: 'var(--color-error-text)',
70
+ },
71
+
72
+ '.cm-highlightedTab': {
73
+ display: 'inline-block',
74
+ position: 'relative',
75
+ '&:before': {
76
+ content: '""',
77
+ borderBottom: '1px solid var(--color-text-secondary)',
78
+ position: 'absolute',
79
+ left: '5%',
80
+ bottom: '50%',
81
+ width: '90%',
82
+ pointerEvents: 'none',
83
+ },
84
+ },
85
+
86
+ '.cm-highlightedSpaces:before': {
87
+ color: 'var(--color-text-secondary)',
88
+ content: 'attr(data-display)',
89
+ position: 'absolute',
90
+ pointerEvents: 'none',
91
+ },
92
+
93
+ '.cm-placeholder': {
94
+ color: 'var(--color-text-secondary)',
95
+ },
96
+
97
+ '.cm-completionHint': {
98
+ color: 'var(--color-text-secondary)',
99
+ },
100
+
101
+ '.cm-highlightedLine': {
102
+ animation: 'cm-fading-highlight 2s 0s',
103
+ },
104
+
105
+ '@keyframes cm-fading-highlight': {
106
+ from: {
107
+ backgroundColor: 'var(--color-highlighted-line)',
108
+ },
109
+ to: {
110
+ backgroundColor: 'transparent',
111
+ },
112
+ },
113
+ });
@@ -0,0 +1,144 @@
1
+ // Copyright 2021 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as Platform from '../../../core/platform/platform.js';
6
+ import * as ComponentHelpers from '../../components/helpers/helpers.js';
7
+ import * as LitHtml from '../../lit-html/lit-html.js';
8
+
9
+ import textPromptStyles from './textPrompt.css.js';
10
+
11
+ export interface TextPromptData {
12
+ ariaLabel: string;
13
+ prefix: string;
14
+ suggestion: string;
15
+ }
16
+
17
+ export class PromptInputEvent extends Event {
18
+ static readonly eventName = 'promptinputchanged';
19
+ data: string;
20
+
21
+ constructor(value: string) {
22
+ super(PromptInputEvent.eventName);
23
+ this.data = value;
24
+ }
25
+ }
26
+
27
+ export class TextPrompt extends HTMLElement {
28
+ static readonly litTagName = LitHtml.literal`devtools-text-prompt`;
29
+ private readonly shadow = this.attachShadow({mode: 'open'});
30
+ private ariaLabelText = '';
31
+ private prefixText = '';
32
+ private suggestionText = '';
33
+
34
+ connectedCallback(): void {
35
+ this.shadow.adoptedStyleSheets = [textPromptStyles];
36
+ }
37
+
38
+ set data(data: TextPromptData) {
39
+ this.ariaLabelText = data.ariaLabel;
40
+ this.prefixText = data.prefix;
41
+ this.suggestionText = data.suggestion;
42
+ this.render();
43
+ }
44
+
45
+ get data(): TextPromptData {
46
+ return {
47
+ ariaLabel: this.ariaLabelText,
48
+ prefix: this.prefixText,
49
+ suggestion: this.suggestionText,
50
+ };
51
+ }
52
+
53
+ focus(): void {
54
+ this.input().focus();
55
+ }
56
+
57
+ private input(): HTMLElement {
58
+ const inputElement = this.shadow.querySelector('.text-prompt-input');
59
+ if (!inputElement) {
60
+ throw new Error('Expected an input element!');
61
+ }
62
+ return /** @type {!HTMLElement} */ inputElement as HTMLElement;
63
+ }
64
+
65
+ moveCaretToEndOfInput(): void {
66
+ this.setSelectedRange(this.text().length, this.text().length);
67
+ }
68
+
69
+ onInput(): void {
70
+ this.dispatchEvent(new PromptInputEvent(this.text().trim()));
71
+ }
72
+
73
+ onKeyDown(event: KeyboardEvent): void {
74
+ if (event.key === Platform.KeyboardUtilities.ENTER_KEY) {
75
+ event.preventDefault();
76
+ }
77
+ }
78
+
79
+ setSelectedRange(startIndex: number, endIndex: number): void {
80
+ if (startIndex < 0) {
81
+ throw new RangeError('Selected range start must be a nonnegative integer');
82
+ }
83
+ const textContentLength = this.text().length;
84
+ if (endIndex > textContentLength) {
85
+ endIndex = textContentLength;
86
+ }
87
+ if (endIndex < startIndex) {
88
+ endIndex = startIndex;
89
+ }
90
+ const inputBox = this.input();
91
+ const range = document.createRange();
92
+ range.setStart(inputBox, startIndex);
93
+ range.setEnd(inputBox, endIndex);
94
+ const selection = window.getSelection();
95
+ if (selection) {
96
+ selection.removeAllRanges();
97
+ selection.addRange(range);
98
+ }
99
+ }
100
+
101
+ setPrefix(prefix: string): void {
102
+ this.prefixText = prefix;
103
+ this.render();
104
+ }
105
+
106
+ setSuggestion(suggestion: string): void {
107
+ this.suggestionText = suggestion;
108
+ this.render();
109
+ }
110
+
111
+ setText(text: string): void {
112
+ this.input().textContent = text;
113
+ if (this.input().hasFocus()) {
114
+ this.moveCaretToEndOfInput();
115
+ this.input().scrollIntoView();
116
+ }
117
+ }
118
+
119
+ private text(): string {
120
+ return this.input().textContent || '';
121
+ }
122
+
123
+ private render(): void {
124
+ const output = LitHtml.html`
125
+ <span class="prefix">${this.prefixText}</span>
126
+ <input aria-label=${this.ariaLabelText}>
127
+ <div class="text-prompt-input" spellcheck="false" contenteditable="plaintext-only" @keydown=${
128
+ this.onKeyDown} @input=${this.onInput} suggestion=" ${this.suggestionText}"></div>
129
+ </input>`;
130
+ LitHtml.render(output, this.shadow, {host: this});
131
+ }
132
+ }
133
+
134
+ ComponentHelpers.CustomElements.defineComponent('devtools-text-prompt', TextPrompt);
135
+
136
+ declare global {
137
+ interface HTMLElementTagNameMap {
138
+ 'devtools-text-prompt': TextPrompt;
139
+ }
140
+
141
+ interface HTMLElementEventMap {
142
+ 'promptinputchanged': PromptInputEvent;
143
+ }
144
+ }
@@ -0,0 +1,33 @@
1
+ /*
2
+ * Copyright 2021 The Chromium Authors. All rights reserved.
3
+ * Use of this source code is governed by a BSD-style license that can be
4
+ * found in the LICENSE file.
5
+ */
6
+
7
+ :host {
8
+ white-space: pre;
9
+ overflow: hidden;
10
+ display: inline-flex;
11
+ }
12
+
13
+ .prefix {
14
+ color: var(--color-primary);
15
+ }
16
+
17
+ input {
18
+ width: 0;
19
+ border: none;
20
+ outline: none;
21
+ }
22
+
23
+ .text-prompt-input {
24
+ border: none;
25
+ outline: none;
26
+ display: inline;
27
+ flex: 1 0 auto;
28
+ }
29
+
30
+ .text-prompt-input::after {
31
+ content: attr(suggestion);
32
+ color: var(--color-background-highlight);
33
+ }
@@ -0,0 +1,9 @@
1
+ // Copyright (c) 2021 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as TextPrompt from './TextPrompt.js';
6
+
7
+ export {
8
+ TextPrompt,
9
+ };
@@ -22,9 +22,13 @@ const UIStrings = {
22
22
  */
23
23
  noCommandsFound: 'No commands found',
24
24
  /**
25
- * @description Text in Command Menu of the Command Menu
25
+ * @description Text for command prefix of run a command
26
+ */
27
+ run: 'Run',
28
+ /**
29
+ * @description Text for command suggestion of run a command
26
30
  */
27
- runCommand: 'Run Command',
31
+ command: 'Command',
28
32
  };
29
33
  const str_ = i18n.i18n.registerUIStrings('ui/legacy/components/quick_open/CommandMenu.ts', UIStrings);
30
34
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -388,6 +392,7 @@ export class ShowActionDelegate implements UI.ActionRegistration.ActionDelegate
388
392
  registerProvider({
389
393
  prefix: '>',
390
394
  iconName: 'ic_command_run_command',
391
- title: (): Common.UIString.LocalizedString => i18nString(UIStrings.runCommand),
392
395
  provider: () => Promise.resolve(CommandMenuProvider.instance()),
396
+ titlePrefix: (): Common.UIString.LocalizedString => i18nString(UIStrings.run),
397
+ titleSuggestion: (): Common.UIString.LocalizedString => i18nString(UIStrings.command),
393
398
  });