chrome-devtools-frontend 1.0.930109 → 1.0.930993

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 (61) hide show
  1. package/config/gni/devtools_grd_files.gni +2 -1
  2. package/front_end/core/host/InspectorFrontendHost.ts +8 -1
  3. package/front_end/core/host/InspectorFrontendHostAPI.ts +12 -0
  4. package/front_end/core/i18n/locales/en-US.json +3 -0
  5. package/front_end/core/i18n/locales/en-XL.json +3 -0
  6. package/front_end/core/protocol_client/InspectorBackend.ts +71 -71
  7. package/front_end/core/sdk/NetworkManager.ts +6 -2
  8. package/front_end/devtools_compatibility.js +8 -0
  9. package/front_end/legacy_test_runner/sources_test_runner/DebuggerTestRunner.js +2 -2
  10. package/front_end/legacy_test_runner/test_runner/TestRunner.js +2 -3
  11. package/front_end/models/bindings/BreakpointManager.ts +158 -154
  12. package/front_end/models/bindings/CSSWorkspaceBinding.ts +64 -56
  13. package/front_end/models/bindings/CompilerScriptMapping.ts +70 -70
  14. package/front_end/models/bindings/ContentProviderBasedProject.ts +20 -20
  15. package/front_end/models/bindings/DebuggerLanguagePlugins.ts +132 -132
  16. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +73 -72
  17. package/front_end/models/bindings/DefaultScriptMapping.ts +22 -22
  18. package/front_end/models/bindings/FileUtils.ts +81 -81
  19. package/front_end/models/bindings/IgnoreListManager.ts +17 -17
  20. package/front_end/models/bindings/LiveLocation.ts +21 -21
  21. package/front_end/models/bindings/PresentationConsoleMessageHelper.ts +28 -28
  22. package/front_end/models/bindings/ResourceMapping.ts +50 -50
  23. package/front_end/models/bindings/ResourceScriptMapping.ts +71 -71
  24. package/front_end/models/bindings/SASSSourceMapping.ts +32 -32
  25. package/front_end/models/bindings/StylesSourceMapping.ts +57 -57
  26. package/front_end/models/bindings/TempFile.ts +34 -34
  27. package/front_end/models/emulation/DeviceModeModel.ts +208 -203
  28. package/front_end/models/emulation/EmulatedDevices.ts +34 -34
  29. package/front_end/panels/console/ConsoleView.ts +2 -1
  30. package/front_end/panels/console/ConsoleViewMessage.ts +3 -3
  31. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +133 -133
  32. package/front_end/panels/css_overview/CSSOverviewModel.ts +16 -16
  33. package/front_end/panels/css_overview/CSSOverviewPanel.ts +77 -77
  34. package/front_end/panels/css_overview/CSSOverviewProcessingView.ts +5 -5
  35. package/front_end/panels/css_overview/components/CSSOverviewStartView.ts +4 -4
  36. package/front_end/panels/elements/ElementsTreeElement.ts +6 -10
  37. package/front_end/panels/elements/ElementsTreeOutline.ts +3 -1
  38. package/front_end/panels/elements/components/LayoutPane.ts +6 -0
  39. package/front_end/panels/elements/elementsPanel.css +0 -1
  40. package/front_end/panels/elements/elementsTreeOutline.css +0 -4
  41. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +7 -2
  42. package/front_end/panels/network/BlockedURLsPane.ts +8 -5
  43. package/front_end/panels/network/blockedURLsPane.css +0 -1
  44. package/front_end/panels/search/SearchView.ts +0 -2
  45. package/front_end/panels/sources/BreakpointEditDialog.ts +98 -81
  46. package/front_end/panels/sources/DebuggerPlugin.ts +15 -14
  47. package/front_end/ui/components/code_highlighter/CodeHighlighter.ts +18 -2
  48. package/front_end/ui/components/text_editor/config.ts +6 -0
  49. package/front_end/ui/components/text_editor/cursor_tooltip.ts +70 -0
  50. package/front_end/ui/components/text_editor/javascript.ts +590 -0
  51. package/front_end/ui/components/text_editor/text_editor.ts +1 -0
  52. package/front_end/ui/components/text_editor/theme.ts +11 -0
  53. package/front_end/ui/components/tree_outline/TreeOutline.ts +3 -1
  54. package/front_end/ui/legacy/ARIAUtils.ts +24 -8
  55. package/front_end/ui/legacy/components/text_editor/cmdevtools.css +1 -0
  56. package/front_end/ui/legacy/components/text_editor/text_editor-legacy.ts +0 -3
  57. package/front_end/ui/legacy/components/text_editor/text_editor.ts +0 -2
  58. package/package.json +1 -1
  59. package/scripts/migration/class-fields/migrate.js +15 -2
  60. package/scripts/migration/class-fields/migrate.sh +10 -0
  61. package/front_end/ui/legacy/components/text_editor/SyntaxHighlighter.ts +0 -62
@@ -3,8 +3,8 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import * as i18n from '../../core/i18n/i18n.js';
6
- import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
7
- import * as TextEditor from '../../ui/legacy/components/text_editor/text_editor.js';
6
+ import type * as TextEditor from '../../ui/components/text_editor/text_editor.js';
7
+ import type * as CodeMirror from '../../third_party/codemirror.next/codemirror.next.js';
8
8
  import * as UI from '../../ui/legacy/legacy.js';
9
9
 
10
10
  import breakpointEditDialogStyles from './breakpointEditDialog.css.js';
@@ -48,25 +48,51 @@ const UIStrings = {
48
48
  };
49
49
  const str_ = i18n.i18n.registerUIStrings('panels/sources/BreakpointEditDialog.ts', UIStrings);
50
50
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
51
+
51
52
  export class BreakpointEditDialog extends UI.Widget.Widget {
52
53
  private readonly onFinish: (arg0: {
53
54
  committed: boolean,
54
55
  condition: string,
55
56
  }) => Promise<void>;
56
57
  private finished: boolean;
57
- private editor: TextEditor.CodeMirrorTextEditor.CodeMirrorTextEditor|null;
58
+ private editor: TextEditor.TextEditor.TextEditor;
58
59
  private isLogpoint: boolean;
59
60
  private readonly typeSelector: UI.Toolbar.ToolbarComboBox;
61
+ private placeholderCompartment: CodeMirror.Compartment;
62
+
63
+ static async create(
64
+ editorLineNumber: number,
65
+ oldCondition: string,
66
+ preferLogpoint: boolean,
67
+ onFinish: (arg0: {committed: boolean, condition: string}) => Promise<void>,
68
+ ): Promise<BreakpointEditDialog> {
69
+ const TextEditor = await import('../../ui/components/text_editor/text_editor.js');
70
+ const CodeMirror = await import('../../third_party/codemirror.next/codemirror.next.js');
71
+ const editorConfig = [
72
+ (await CodeMirror.javascript()).javascriptLanguage,
73
+ TextEditor.Config.baseConfiguration(oldCondition || ''),
74
+ CodeMirror.EditorView.lineWrapping,
75
+ TextEditor.Config.showCompletionHint,
76
+ await TextEditor.JavaScript.completion(),
77
+ TextEditor.JavaScript.argumentHints(),
78
+ ];
79
+ return new BreakpointEditDialog(
80
+ editorLineNumber, oldCondition, preferLogpoint, onFinish, TextEditor, CodeMirror, editorConfig);
81
+ }
60
82
 
61
- constructor(editorLineNumber: number, oldCondition: string, preferLogpoint: boolean, onFinish: (arg0: {
62
- committed: boolean,
63
- condition: string,
64
- }) => Promise<void>) {
83
+ constructor(
84
+ editorLineNumber: number,
85
+ oldCondition: string,
86
+ preferLogpoint: boolean,
87
+ onFinish: (arg0: {committed: boolean, condition: string}) => Promise<void>,
88
+ modTextEditor: typeof TextEditor,
89
+ readonly modCodeMirror: typeof CodeMirror,
90
+ editorConfig: CodeMirror.Extension,
91
+ ) {
65
92
  super(true);
66
93
 
67
94
  this.onFinish = onFinish;
68
95
  this.finished = false;
69
- this.editor = null;
70
96
  this.element.tabIndex = -1;
71
97
 
72
98
  const logpointPrefix = LogpointPrefix;
@@ -90,113 +116,104 @@ export class BreakpointEditDialog extends UI.Widget.Widget {
90
116
  this.typeSelector.select(this.isLogpoint ? logpointOption : conditionalOption);
91
117
  toolbar.appendToolbarItem(this.typeSelector);
92
118
 
93
- const factory = TextEditor.CodeMirrorTextEditor.CodeMirrorTextEditorFactory.instance();
94
- const editorOptions = {
95
- lineNumbers: false,
96
- lineWrapping: true,
97
- mimeType: 'javascript',
98
- autoHeight: true,
99
- bracketMatchingSetting: undefined,
100
- devtoolsAccessibleName: undefined,
101
- padBottom: undefined,
102
- maxHighlightLength: undefined,
103
- placeholder: undefined,
104
- lineWiseCopyCut: undefined,
105
- inputStyle: undefined,
106
- };
107
- this.editor = factory.createEditor(editorOptions);
108
- this.updatePlaceholder();
109
- this.editor.widget().element.classList.add('condition-editor');
110
- this.editor.configureAutocomplete(
111
- ObjectUI.JavaScriptAutocomplete.JavaScriptAutocompleteConfig.createConfigForEditor(this.editor));
112
- if (oldCondition) {
113
- this.editor.setText(oldCondition);
114
- }
115
- this.editor.widget().markAsExternallyManaged();
116
- this.editor.widget().show(this.contentElement);
117
- this.editor.setSelection(this.editor.fullRange());
118
- this.editor.widget().element.addEventListener('keydown', this.onKeyDown.bind(this), true);
119
+ const content = oldCondition || '';
120
+ const keymap = [
121
+ {
122
+ key: 'Mod-Enter',
123
+ run: (view: CodeMirror.EditorView): boolean => {
124
+ if (modTextEditor.JavaScript.isExpressionComplete(view.state)) {
125
+ this.finishEditing(true, this.editor.state.doc.toString());
126
+ return true;
127
+ }
128
+ return false;
129
+ },
130
+ },
131
+ {
132
+ key: 'Escape',
133
+ run: (): boolean => {
134
+ this.finishEditing(false, '');
135
+ return true;
136
+ },
137
+ },
138
+ ];
139
+
140
+ this.placeholderCompartment = new modCodeMirror.Compartment();
141
+
142
+ this.editor = new modTextEditor.TextEditor.TextEditor(modCodeMirror.EditorState.create({
143
+ doc: content,
144
+ selection: {anchor: 0, head: content.length},
145
+ extensions: [
146
+ this.placeholderCompartment.of(this.getPlaceholder()),
147
+ modCodeMirror.keymap.of(keymap),
148
+ editorConfig,
149
+ ],
150
+ }));
151
+ this.editor.classList.add('condition-editor');
152
+
153
+ this.updateTooltip();
154
+ this.contentElement.appendChild(this.editor);
119
155
  this.element.addEventListener('blur', event => {
120
156
  if (!event.relatedTarget ||
121
157
  (event.relatedTarget && !(event.relatedTarget as Node).isSelfOrDescendant(this.element))) {
122
- this.finishEditing(true);
158
+ this.finishEditing(true, this.editor.state.doc.toString());
123
159
  }
124
160
  }, true);
125
161
  }
126
162
 
127
163
  focusEditor(): void {
128
- if (this.editor) {
129
- this.editor.widget().focus();
130
- }
164
+ this.editor.editor.focus();
131
165
  }
132
166
  private static conditionForLogpoint(condition: string): string {
133
167
  return `${LogpointPrefix}${condition}${LogpointSuffix}`;
134
168
  }
135
169
 
136
170
  private onTypeChanged(): void {
137
- const option = this.typeSelector.selectedOption();
138
- if (!option || !this.editor) {
139
- return;
140
- }
141
- const value = option.value;
142
- this.isLogpoint = value === BreakpointType.Logpoint;
143
- this.updatePlaceholder();
144
- if (value === BreakpointType.Breakpoint) {
145
- this.editor.setText('');
146
- this.finishEditing(true);
171
+ const type = this.breakpointType;
172
+ if (type === BreakpointType.Breakpoint) {
173
+ this.finishEditing(true, '');
174
+ } else {
175
+ this.editor.editor.dispatch({effects: this.placeholderCompartment.reconfigure(this.getPlaceholder())});
176
+ this.updateTooltip();
147
177
  }
148
178
  }
149
179
 
150
- private updatePlaceholder(): void {
180
+ private get breakpointType(): string|null {
151
181
  const option = this.typeSelector.selectedOption();
152
- if (!option || !this.editor) {
153
- return;
182
+ return option ? option.value : null;
183
+ }
184
+
185
+ private getPlaceholder(): CodeMirror.Extension {
186
+ const type = this.breakpointType;
187
+ if (type === BreakpointType.Conditional) {
188
+ return this.modCodeMirror.placeholder(i18nString(UIStrings.expressionToCheckBeforePausingEg));
189
+ }
190
+ if (type === BreakpointType.Logpoint) {
191
+ return this.modCodeMirror.placeholder(i18nString(UIStrings.logMessageEgXIsX));
154
192
  }
155
- const selectedValue = option.value;
156
- if (selectedValue === BreakpointType.Conditional) {
157
- this.editor.setPlaceholder(i18nString(UIStrings.expressionToCheckBeforePausingEg));
193
+ return [];
194
+ }
195
+
196
+ private updateTooltip(): void {
197
+ const type = this.breakpointType;
198
+ if (type === BreakpointType.Conditional) {
158
199
  UI.Tooltip.Tooltip.install((this.typeSelector.element), i18nString(UIStrings.pauseOnlyWhenTheConditionIsTrue));
159
- } else if (selectedValue === BreakpointType.Logpoint) {
160
- this.editor.setPlaceholder(i18nString(UIStrings.logMessageEgXIsX));
200
+ } else if (type === BreakpointType.Logpoint) {
161
201
  UI.Tooltip.Tooltip.install((this.typeSelector.element), i18nString(UIStrings.logAMessageToConsoleDoNotBreak));
162
202
  }
163
203
  }
164
204
 
165
- private finishEditing(committed: boolean): void {
205
+ private finishEditing(committed: boolean, condition: string): void {
166
206
  if (this.finished) {
167
207
  return;
168
208
  }
169
209
  this.finished = true;
170
- if (!this.editor) {
171
- return;
172
- }
173
- this.editor.widget().detach();
174
- let condition = this.editor.text();
210
+ this.editor.remove();
175
211
  if (this.isLogpoint) {
176
212
  condition = BreakpointEditDialog.conditionForLogpoint(condition);
177
213
  }
178
214
  this.onFinish({committed, condition});
179
215
  }
180
216
 
181
- private async onKeyDown(event: Event): Promise<void> {
182
- if (!(event instanceof KeyboardEvent) || !this.editor) {
183
- return;
184
- }
185
- if (event.key === 'Enter' && !event.shiftKey) {
186
- event.consume(true);
187
- const expression = this.editor.text();
188
- if (event.ctrlKey ||
189
- await ObjectUI.JavaScriptAutocomplete.JavaScriptAutocomplete.isExpressionComplete(expression)) {
190
- this.finishEditing(true);
191
- } else {
192
- this.editor.newlineAndIndent();
193
- }
194
- }
195
- if (isEscKey(event)) {
196
- this.finishEditing(false);
197
- event.stopImmediatePropagation();
198
- }
199
- }
200
217
  wasShown(): void {
201
218
  super.wasShown();
202
219
  this.registerCSSFiles([breakpointEditDialogStyles]);
@@ -899,20 +899,21 @@ export class DebuggerPlugin extends Plugin {
899
899
  preferLogpoint?: boolean): Promise<void> {
900
900
  const oldCondition = breakpoint ? breakpoint.condition() : '';
901
901
  const decorationElement = document.createElement('div');
902
- const dialog = new BreakpointEditDialog(editorLineNumber, oldCondition, Boolean(preferLogpoint), async result => {
903
- dialog.detach();
904
- this.textEditor.removeDecoration(decorationElement, editorLineNumber);
905
- if (!result.committed) {
906
- return;
907
- }
908
- if (breakpoint) {
909
- breakpoint.setCondition(result.condition);
910
- } else if (location) {
911
- await this.setBreakpoint(location.lineNumber, location.columnNumber, result.condition, true);
912
- } else {
913
- await this.createNewBreakpoint(editorLineNumber, result.condition, true);
914
- }
915
- });
902
+ const dialog =
903
+ await BreakpointEditDialog.create(editorLineNumber, oldCondition, Boolean(preferLogpoint), async result => {
904
+ dialog.detach();
905
+ this.textEditor.removeDecoration(decorationElement, editorLineNumber);
906
+ if (!result.committed) {
907
+ return;
908
+ }
909
+ if (breakpoint) {
910
+ breakpoint.setCondition(result.condition);
911
+ } else if (location) {
912
+ await this.setBreakpoint(location.lineNumber, location.columnNumber, result.condition, true);
913
+ } else {
914
+ await this.createNewBreakpoint(editorLineNumber, result.condition, true);
915
+ }
916
+ });
916
917
  this.textEditor.addDecoration(decorationElement, editorLineNumber);
917
918
  dialog.markAsExternallyManaged();
918
919
  dialog.show(decorationElement);
@@ -37,8 +37,8 @@ export function getHighlightStyle(modCM: typeof CodeMirror): CodeMirror.Highligh
37
37
 
38
38
  {tag: t.inserted, class: 'token-inserted'},
39
39
  {tag: t.deleted, class: 'token-deleted'},
40
- {tag: t.heading, class: 'token-variable-special'},
41
- {tag: t.link, class: 'token-variable-special'},
40
+ {tag: t.heading, class: 'token-heading'},
41
+ {tag: t.link, class: 'token-link'},
42
42
  {tag: t.strikethrough, class: 'token-strikethrough'},
43
43
  {tag: t.strong, class: 'token-strong'},
44
44
  {tag: t.emphasis, class: 'token-emphasis'},
@@ -54,6 +54,22 @@ export async function create(code: string, mimeType: string): Promise<CodeHighli
54
54
  return new CodeHighlighter(code, tree, CM);
55
55
  }
56
56
 
57
+ export async function highlightNode(node: Element, mimeType: string): Promise<void> {
58
+ const code = node.textContent || '';
59
+ const highlighter = await create(code, mimeType);
60
+ node.removeChildren();
61
+ highlighter.highlight((text, style) => {
62
+ let token: Node = document.createTextNode(text);
63
+ if (style) {
64
+ const span = document.createElement('span');
65
+ span.className = style;
66
+ span.appendChild(token);
67
+ token = span;
68
+ }
69
+ node.appendChild(token);
70
+ });
71
+ }
72
+
57
73
  export async function languageFromMIME(mimeType: string): Promise<CodeMirror.LanguageSupport|null> {
58
74
  const CM = await importCM();
59
75
 
@@ -57,8 +57,12 @@ export const tabMovesFocus = DynamicSetting.bool('textEditorTabMovesFocus', CM.k
57
57
  shift: (view: CM.EditorView): boolean => view.state.doc.length ? CM.indentLess(view) : false,
58
58
  }]));
59
59
 
60
+ export const autocompletion = DynamicSetting.bool('textEditorAutocompletion', CM.autocompletion());
61
+
60
62
  export const bracketMatching = DynamicSetting.bool('textEditorBracketMatching', CM.bracketMatching());
61
63
 
64
+ export const codeFolding = DynamicSetting.bool('textEditorCodeFolding', [CM.foldGutter(), CM.keymap.of(CM.foldKeymap)]);
65
+
62
66
  export function guessIndent(doc: CM.Text): string {
63
67
  const values: {[indent: string]: number} = Object.create(null);
64
68
  let scanned = 0;
@@ -160,6 +164,7 @@ function detectLineSeparator(text: string): CM.Extension {
160
164
  }
161
165
 
162
166
  const baseKeymap = CM.keymap.of([
167
+ {key: 'Tab', run: CM.acceptCompletion},
163
168
  {key: 'Ctrl-m', run: CM.cursorMatchingBracket, shift: CM.selectMatchingBracket},
164
169
  {key: 'Mod-/', run: CM.toggleComment},
165
170
  {key: 'Mod-d', run: CM.selectNextOccurrence},
@@ -194,6 +199,7 @@ export function baseConfiguration(text: string): CM.Extension {
194
199
  indentUnit,
195
200
  CM.Prec.fallback(CM.EditorView.contentAttributes.of({'aria-label': i18nString(UIStrings.codeEditor)})),
196
201
  detectLineSeparator(text),
202
+ autocompletion,
197
203
  CM.tooltips({position: 'absolute'}),
198
204
  ];
199
205
  }
@@ -0,0 +1,70 @@
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 CodeMirror from '../../../third_party/codemirror.next/codemirror.next.js';
6
+
7
+ export function cursorTooltip(
8
+ source: (state: CodeMirror.EditorState, pos: number) => Promise<(() => CodeMirror.TooltipView)|null>,
9
+ ): CodeMirror.Extension {
10
+ const openTooltip = CodeMirror.StateEffect.define<() => CodeMirror.TooltipView>();
11
+
12
+ const state = CodeMirror.StateField.define<null|CodeMirror.Tooltip>({
13
+ create() {
14
+ return null;
15
+ },
16
+ update(val, tr) {
17
+ if (tr.selection) {
18
+ val = null;
19
+ }
20
+ if (val && !tr.changes.empty) {
21
+ val = {pos: tr.changes.mapPos(val.pos), create: val.create, above: true};
22
+ }
23
+ for (const effect of tr.effects) {
24
+ if (effect.is(openTooltip)) {
25
+ val = {pos: tr.state.selection.main.from, create: effect.value, above: true};
26
+ }
27
+ }
28
+ return val;
29
+ },
30
+ provide: field => CodeMirror.showTooltip.from(field),
31
+ });
32
+
33
+ const plugin = CodeMirror.ViewPlugin.fromClass(class {
34
+ pending = -1;
35
+ updateID = 0;
36
+
37
+ update(update: CodeMirror.ViewUpdate): void {
38
+ this.updateID++;
39
+ if (update.transactions.some(tr => tr.selection) && update.state.selection.main.empty) {
40
+ this.scheduleUpdate(update.view);
41
+ }
42
+ }
43
+
44
+ scheduleUpdate(view: CodeMirror.EditorView): void {
45
+ if (this.pending > -1) {
46
+ clearTimeout(this.pending);
47
+ }
48
+ this.pending = setTimeout(() => this.startUpdate(view), 50) as unknown as number;
49
+ }
50
+
51
+ startUpdate(view: CodeMirror.EditorView): void {
52
+ this.pending = -1;
53
+ const {main} = view.state.selection;
54
+ if (main.empty) {
55
+ const {updateID} = this;
56
+ source(view.state, main.from).then(tooltip => {
57
+ if (this.updateID !== updateID) {
58
+ if (this.pending < 0) {
59
+ this.scheduleUpdate(view);
60
+ }
61
+ } else if (tooltip) {
62
+ view.dispatch({effects: openTooltip.of(tooltip)});
63
+ }
64
+ });
65
+ }
66
+ }
67
+ });
68
+
69
+ return [state, plugin];
70
+ }