chrome-devtools-frontend 1.0.943986 → 1.0.944427

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 (37) hide show
  1. package/front_end/core/host/UserMetrics.ts +0 -1
  2. package/front_end/core/i18n/locales/en-US.json +0 -12
  3. package/front_end/core/i18n/locales/en-XL.json +0 -12
  4. package/front_end/core/sdk/CSSStyleDeclaration.ts +4 -0
  5. package/front_end/core/sdk/OverlayModel.ts +0 -9
  6. package/front_end/core/sdk/sdk-meta.ts +0 -26
  7. package/front_end/entrypoints/inspector_main/RenderingOptions.ts +0 -13
  8. package/front_end/entrypoints/main/MainImpl.ts +0 -2
  9. package/front_end/models/timeline_model/TimelineJSProfile.ts +3 -16
  10. package/front_end/models/timeline_model/TimelineModel.ts +0 -1
  11. package/front_end/panels/console/ConsolePinPane.ts +1 -0
  12. package/front_end/panels/console/ConsolePrompt.ts +121 -171
  13. package/front_end/panels/console/ConsoleView.ts +1 -1
  14. package/front_end/panels/console/consoleView.css +1 -1
  15. package/front_end/panels/css_overview/cssOverviewCompletedView.css +2 -2
  16. package/front_end/panels/elements/AccessibilityTreeUtils.ts +2 -1
  17. package/front_end/panels/elements/ElementsTreeElement.ts +1 -0
  18. package/front_end/panels/elements/StyleEditorWidget.ts +13 -2
  19. package/front_end/panels/elements/StylePropertyHighlighter.ts +29 -19
  20. package/front_end/panels/elements/StylePropertyTreeElement.ts +7 -4
  21. package/front_end/panels/elements/StylesSidebarPane.ts +1 -1
  22. package/front_end/panels/elements/components/AccessibilityTreeNode.ts +27 -3
  23. package/front_end/panels/network/NetworkDataGridNode.ts +5 -1
  24. package/front_end/panels/sources/BreakpointEditDialog.ts +1 -0
  25. package/front_end/panels/timeline/TimelineController.ts +0 -3
  26. package/front_end/third_party/codemirror.next/bundle.ts +3 -2
  27. package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
  28. package/front_end/third_party/codemirror.next/codemirror.next.d.ts +32 -1
  29. package/front_end/third_party/codemirror.next/codemirror.next.js +1 -1
  30. package/front_end/third_party/codemirror.next/package.json +4 -4
  31. package/front_end/ui/components/text_editor/config.ts +34 -14
  32. package/front_end/ui/components/text_editor/javascript.ts +14 -9
  33. package/front_end/ui/components/text_editor/theme.ts +29 -4
  34. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +1 -0
  35. package/front_end/ui/legacy/components/utils/Linkifier.ts +49 -79
  36. package/front_end/ui/legacy/themeColors.css +2 -0
  37. package/package.json +1 -1
@@ -6,9 +6,9 @@ import * as Common from '../../core/common/common.js';
6
6
  import * as Host from '../../core/host/host.js';
7
7
  import * as i18n from '../../core/i18n/i18n.js';
8
8
  import * as SDK from '../../core/sdk/sdk.js';
9
- import * as TextUtils from '../../models/text_utils/text_utils.js';
9
+ import * as CodeMirror from '../../third_party/codemirror.next/codemirror.next.js';
10
+ import * as TextEditor from '../../ui/components/text_editor/text_editor.js';
10
11
  import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
11
- import * as TextEditor from '../../ui/legacy/components/text_editor/text_editor.js';
12
12
  import * as UI from '../../ui/legacy/legacy.js';
13
13
 
14
14
  import {ConsolePanel} from './ConsolePanel.js';
@@ -27,17 +27,17 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
27
27
  private addCompletionsFromHistory: boolean;
28
28
  private historyInternal: ConsoleHistoryManager;
29
29
  private initialText: string;
30
- private editor: UI.TextEditor.TextEditor|null;
30
+ private editor: TextEditor.TextEditor.TextEditor;
31
31
  private readonly eagerPreviewElement: HTMLDivElement;
32
32
  private textChangeThrottler: Common.Throttler.Throttler;
33
33
  private readonly formatter: ObjectUI.RemoteObjectPreviewFormatter.RemoteObjectPreviewFormatter;
34
34
  private requestPreviewBound: () => Promise<void>;
35
+ private requestPreviewCurrent = 0;
35
36
  private readonly innerPreviewElement: HTMLElement;
36
37
  private readonly promptIcon: UI.Icon.Icon;
37
38
  private readonly iconThrottler: Common.Throttler.Throttler;
38
39
  private readonly eagerEvalSetting: Common.Settings.Setting<boolean>;
39
40
  private previewRequestForTest: Promise<void>|null;
40
- private defaultAutocompleteConfig: UI.TextEditor.AutocompleteConfig|null;
41
41
  private highlightingNode: boolean;
42
42
 
43
43
  constructor() {
@@ -46,7 +46,6 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
46
46
  this.historyInternal = new ConsoleHistoryManager();
47
47
 
48
48
  this.initialText = '';
49
- this.editor = null;
50
49
  this.eagerPreviewElement = document.createElement('div');
51
50
  this.eagerPreviewElement.classList.add('console-eager-preview');
52
51
  this.textChangeThrottler = new Common.Throttler.Throttler(150);
@@ -68,41 +67,41 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
68
67
 
69
68
  this.element.tabIndex = 0;
70
69
  this.previewRequestForTest = null;
70
+ this.highlightingNode = false;
71
71
 
72
- this.defaultAutocompleteConfig = null;
72
+ const editorState = CodeMirror.EditorState.create({
73
+ doc: this.initialText,
74
+ extensions: [
75
+ CodeMirror.keymap.of(this.editorKeymap()),
76
+ CodeMirror.EditorView.updateListener.of(update => this.editorUpdate(update)),
77
+ TextEditor.JavaScript.argumentHints(),
78
+ TextEditor.JavaScript.completion(),
79
+ TextEditor.Config.showCompletionHint,
80
+ CodeMirror.javascript.javascript(),
81
+ TextEditor.Config.baseConfiguration(this.initialText),
82
+ TextEditor.Config.autocompletion,
83
+ CodeMirror.javascript.javascriptLanguage.data.of({
84
+ autocomplete: (context: CodeMirror.CompletionContext): CodeMirror.CompletionResult | null =>
85
+ this.historyCompletions(context),
86
+ }),
87
+ CodeMirror.EditorView.contentAttributes.of({'aria-label': i18nString(UIStrings.consolePrompt)}),
88
+ CodeMirror.EditorView.lineWrapping,
89
+ CodeMirror.autocompletion({aboveCursor: true}),
90
+ ],
91
+ });
73
92
 
74
- this.highlightingNode = false;
93
+ this.editor = new TextEditor.TextEditor.TextEditor(editorState);
94
+ this.editor.addEventListener('keydown', (event): void => {
95
+ if (event.defaultPrevented) {
96
+ event.stopPropagation();
97
+ }
98
+ });
99
+ editorContainerElement.appendChild(this.editor);
75
100
 
76
- const factory = TextEditor.CodeMirrorTextEditor.CodeMirrorTextEditorFactory.instance();
77
-
78
- const options = {
79
- devtoolsAccessibleName: (i18nString(UIStrings.consolePrompt) as string),
80
- lineNumbers: false,
81
- lineWrapping: true,
82
- mimeType: 'javascript',
83
- autoHeight: true,
84
- };
85
- this.editor = factory.createEditor((options as UI.TextEditor.Options));
86
-
87
- this.defaultAutocompleteConfig =
88
- ObjectUI.JavaScriptAutocomplete.JavaScriptAutocompleteConfig.createConfigForEditor(this.editor);
89
- this.editor.configureAutocomplete(Object.assign({}, this.defaultAutocompleteConfig, {
90
- suggestionsCallback: this.wordsWithQuery.bind(this),
91
- anchorBehavior: UI.GlassPane.AnchorBehavior.PreferTop,
92
- }));
93
- this.editor.widget().element.addEventListener('keydown', this.editorKeyDown.bind(this), true);
94
- this.editor.widget().show(editorContainerElement);
95
- this.editor.addEventListener(UI.TextEditor.Events.CursorChanged, this.updatePromptIcon, this);
96
- this.editor.addEventListener(UI.TextEditor.Events.TextChanged, this.onTextChanged, this);
97
- this.editor.addEventListener(UI.TextEditor.Events.SuggestionChanged, this.onTextChanged, this);
98
-
99
- this.setText(this.initialText);
100
- this.initialText = '';
101
101
  if (this.hasFocus()) {
102
102
  this.focus();
103
103
  }
104
104
  this.element.removeAttribute('tabindex');
105
- this.editor.widget().element.tabIndex = -1;
106
105
 
107
106
  this.editorSetForTest();
108
107
 
@@ -126,7 +125,7 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
126
125
  // ConsoleView and prompt both use a throttler, so we clear the preview
127
126
  // ASAP to avoid inconsistency between a fresh viewport and stale preview.
128
127
  if (this.eagerEvalSetting.get()) {
129
- const asSoonAsPossible = !this.editor || !this.editor.textWithCurrentSuggestion();
128
+ const asSoonAsPossible = !TextEditor.Config.contentIncludingHint(this.editor.editor);
130
129
  this.previewRequestForTest = this.textChangeThrottler.schedule(this.requestPreviewBound, asSoonAsPossible);
131
130
  }
132
131
  this.updatePromptIcon();
@@ -134,15 +133,16 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
134
133
  }
135
134
 
136
135
  private async requestPreview(): Promise<void> {
137
- if (!this.editor) {
138
- return;
139
- }
140
- const text = this.editor.textWithCurrentSuggestion().trim();
136
+ const id = ++this.requestPreviewCurrent;
137
+ const text = TextEditor.Config.contentIncludingHint(this.editor.editor).trim();
141
138
  const executionContext = UI.Context.Context.instance().flavor(SDK.RuntimeModel.ExecutionContext);
142
139
  const {preview, result} = await ObjectUI.JavaScriptREPL.JavaScriptREPL.evaluateAndBuildPreview(
143
140
  text, true /* throwOnSideEffect */, true /* replMode */, 500 /* timeout */);
141
+ if (this.requestPreviewCurrent !== id) {
142
+ return;
143
+ }
144
144
  this.innerPreviewElement.removeChildren();
145
- if (preview.deepTextContent() !== this.editor.textWithCurrentSuggestion().trim()) {
145
+ if (preview.deepTextContent() !== TextEditor.Config.contentIncludingHint(this.editor.editor).trim()) {
146
146
  this.innerPreviewElement.appendChild(preview);
147
147
  }
148
148
  if (result && 'object' in result && result.object && result.object.subtype === 'node') {
@@ -174,149 +174,102 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
174
174
  }
175
175
 
176
176
  clearAutocomplete(): void {
177
- if (this.editor) {
178
- this.editor.clearAutocomplete();
179
- }
177
+ CodeMirror.closeCompletion(this.editor.editor);
180
178
  }
181
179
 
182
180
  private isCaretAtEndOfPrompt(): boolean {
183
- return this.editor !== null &&
184
- this.editor.selection().collapseToEnd().equal(this.editor.fullRange().collapseToEnd());
181
+ return this.editor.state.selection.main.head === this.editor.state.doc.length;
185
182
  }
186
183
 
187
184
  moveCaretToEndOfPrompt(): void {
188
- if (this.editor) {
189
- this.editor.setSelection(TextUtils.TextRange.TextRange.createFromLocation(Infinity, Infinity));
190
- }
185
+ this.editor.dispatch({
186
+ selection: CodeMirror.EditorSelection.cursor(this.editor.state.doc.length),
187
+ });
191
188
  }
192
189
 
193
- setText(text: string): void {
194
- if (this.editor) {
195
- this.editor.setText(text);
196
- } else {
197
- this.initialText = text;
198
- }
199
- this.dispatchEventToListeners(Events.TextChanged);
190
+ clear(): void {
191
+ this.editor.dispatch({
192
+ changes: {from: 0, to: this.editor.state.doc.length},
193
+ });
200
194
  }
201
195
 
202
196
  text(): string {
203
- return this.editor ? this.editor.text() : this.initialText;
197
+ return this.editor.state.doc.toString();
204
198
  }
205
199
 
206
200
  setAddCompletionsFromHistory(value: boolean): void {
207
201
  this.addCompletionsFromHistory = value;
208
202
  }
209
203
 
210
- private editorKeyDown(event: Event): void {
211
- if (!this.editor) {
212
- return;
213
- }
214
- const keyboardEvent = (event as KeyboardEvent);
215
- let newText;
216
- let isPrevious;
217
- // Check against visual coordinates in case lines wrap.
218
- const selection = this.editor.selection();
219
- const cursorY = this.editor.visualCoordinates(selection.endLine, selection.endColumn).y;
220
-
221
- switch (keyboardEvent.keyCode) {
222
- case UI.KeyboardShortcut.Keys.Up.code: {
223
- const startY = this.editor.visualCoordinates(0, 0).y;
224
- if (keyboardEvent.shiftKey || !selection.isEmpty() || cursorY !== startY) {
225
- break;
226
- }
227
- newText = this.historyInternal.previous(this.text());
228
- isPrevious = true;
229
- break;
230
- }
231
- case UI.KeyboardShortcut.Keys.Down.code: {
232
- const fullRange = this.editor.fullRange();
233
- const endY = this.editor.visualCoordinates(fullRange.endLine, fullRange.endColumn).y;
234
- if (keyboardEvent.shiftKey || !selection.isEmpty() || cursorY !== endY) {
235
- break;
236
- }
237
- newText = this.historyInternal.next();
238
- break;
239
- }
240
- case UI.KeyboardShortcut.Keys.P.code: { // Ctrl+P = Previous
241
- if (Host.Platform.isMac() && keyboardEvent.ctrlKey && !keyboardEvent.metaKey && !keyboardEvent.altKey &&
242
- !keyboardEvent.shiftKey) {
243
- newText = this.historyInternal.previous(this.text());
244
- isPrevious = true;
245
- }
246
- break;
247
- }
248
- case UI.KeyboardShortcut.Keys.N.code: { // Ctrl+N = Next
249
- if (Host.Platform.isMac() && keyboardEvent.ctrlKey && !keyboardEvent.metaKey && !keyboardEvent.altKey &&
250
- !keyboardEvent.shiftKey) {
251
- newText = this.historyInternal.next();
252
- }
253
- break;
254
- }
255
- case UI.KeyboardShortcut.Keys.Enter.code: {
256
- this.enterKeyPressed(keyboardEvent);
257
- break;
204
+ private editorKeymap(): readonly CodeMirror.KeyBinding[] {
205
+ return [
206
+ {key: 'ArrowUp', run: (): boolean => this.moveHistory(-1)},
207
+ {key: 'ArrowDown', run: (): boolean => this.moveHistory(1)},
208
+ {mac: 'Ctrl-p', run: (): boolean => this.moveHistory(-1, true)},
209
+ {mac: 'Ctrl-n', run: (): boolean => this.moveHistory(1, true)},
210
+ {key: 'Enter', run: (): boolean => this.evaluate(), shift: CodeMirror.insertNewlineAndIndent},
211
+ ];
212
+ }
213
+
214
+ private moveHistory(dir: -1|1, force = false): boolean {
215
+ const {editor} = this.editor, {main} = editor.state.selection;
216
+ if (!force) {
217
+ if (!main.empty) {
218
+ return false;
258
219
  }
259
- case UI.KeyboardShortcut.Keys.Tab.code: {
260
- if (!this.text()) {
261
- keyboardEvent.consume();
262
- }
263
- break;
220
+ const cursorCoords = editor.coordsAtPos(main.head);
221
+ const endCoords = editor.coordsAtPos(dir < 0 ? 0 : editor.state.doc.length);
222
+ // Check if there are wrapped lines in this direction, and let
223
+ // the cursor move normally if there are.
224
+ if (cursorCoords && endCoords &&
225
+ (dir < 0 ? cursorCoords.top > endCoords.top + 5 : cursorCoords.bottom < endCoords.bottom - 5)) {
226
+ return false;
264
227
  }
265
228
  }
266
229
 
230
+ const history = this.historyInternal;
231
+ const newText = dir < 0 ? history.previous(this.text()) : history.next();
267
232
  if (newText === undefined) {
268
- return;
233
+ return false;
269
234
  }
270
- keyboardEvent.consume(true);
271
- this.setText(newText);
272
235
 
273
- if (isPrevious) {
274
- this.editor.setSelection(TextUtils.TextRange.TextRange.createFromLocation(0, Infinity));
275
- } else {
276
- this.moveCaretToEndOfPrompt();
277
- }
236
+ const cursorPos = dir < 0 ? newText.search(/\n|$/) : newText.length;
237
+ this.editor.dispatch({
238
+ changes: {from: 0, to: this.editor.state.doc.length, insert: newText},
239
+ selection: CodeMirror.EditorSelection.cursor(cursorPos),
240
+ scrollIntoView: true,
241
+ });
242
+ return true;
243
+ }
244
+
245
+ private enterWillEvaluate(): boolean {
246
+ const {state} = this.editor;
247
+ return state.doc.length > 0 && TextEditor.JavaScript.isExpressionComplete(state);
278
248
  }
279
249
 
280
- private async enterWillEvaluate(): Promise<boolean> {
281
- if (!this.isCaretAtEndOfPrompt()) {
282
- return true;
250
+ private evaluate(): boolean {
251
+ if (this.enterWillEvaluate()) {
252
+ this.appendCommand(this.text(), true);
253
+ this.editor.dispatch({
254
+ changes: {from: 0, to: this.editor.state.doc.length},
255
+ scrollIntoView: true,
256
+ });
257
+ } else if (this.editor.state.doc.length) {
258
+ return CodeMirror.insertNewlineAndIndent(this.editor.editor);
259
+ } else {
260
+ this.editor.dispatch({scrollIntoView: true});
283
261
  }
284
- return await ObjectUI.JavaScriptAutocomplete.JavaScriptAutocomplete.isExpressionComplete(this.text());
262
+ this.enterProcessedForTest();
263
+ return true;
285
264
  }
286
265
 
287
266
  private updatePromptIcon(): void {
288
267
  this.iconThrottler.schedule(async () => {
289
- const canComplete = await this.enterWillEvaluate();
290
- this.promptIcon.classList.toggle('console-prompt-incomplete', !canComplete);
268
+ this.promptIcon.classList.toggle('console-prompt-incomplete', !this.enterWillEvaluate());
291
269
  });
292
270
  }
293
271
 
294
- private async enterKeyPressed(event: KeyboardEvent): Promise<void> {
295
- if (event.altKey || event.ctrlKey || event.shiftKey) {
296
- return;
297
- }
298
-
299
- event.consume(true);
300
-
301
- // Since we prevent default, manually emulate the native "scroll on key input" behavior.
302
- this.element.scrollIntoView();
303
- this.clearAutocomplete();
304
-
305
- const str = this.text();
306
- if (!str.length) {
307
- return;
308
- }
309
-
310
- if (await this.enterWillEvaluate()) {
311
- await this.appendCommand(str, true);
312
- } else if (this.editor) {
313
- this.editor.newlineAndIndent();
314
- }
315
- this.enterProcessedForTest();
316
- }
317
-
318
- private async appendCommand(text: string, useCommandLineAPI: boolean): Promise<void> {
319
- this.setText('');
272
+ private appendCommand(text: string, useCommandLineAPI: boolean): void {
320
273
  const currentExecutionContext = UI.Context.Context.instance().flavor(SDK.RuntimeModel.ExecutionContext);
321
274
  if (currentExecutionContext) {
322
275
  const executionContext = currentExecutionContext;
@@ -333,10 +286,19 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
333
286
  private enterProcessedForTest(): void {
334
287
  }
335
288
 
336
- private historyCompletions(prefix: string, force?: boolean): UI.SuggestBox.Suggestions {
289
+ private editorUpdate(update: CodeMirror.ViewUpdate): void {
290
+ if (update.docChanged ||
291
+ CodeMirror.selectedCompletion(update.state) !== CodeMirror.selectedCompletion(update.startState)) {
292
+ this.onTextChanged();
293
+ } else if (update.selectionSet) {
294
+ this.updatePromptIcon();
295
+ }
296
+ }
297
+
298
+ private historyCompletions(context: CodeMirror.CompletionContext): CodeMirror.CompletionResult|null {
337
299
  const text = this.text();
338
- if (!this.addCompletionsFromHistory || !this.isCaretAtEndOfPrompt() || (!text && !force)) {
339
- return [];
300
+ if (!this.addCompletionsFromHistory || !this.isCaretAtEndOfPrompt() || (!text.length && !context.explicit)) {
301
+ return null;
340
302
  }
341
303
  const result = [];
342
304
  const set = new Set<string>();
@@ -350,30 +312,18 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
350
312
  continue;
351
313
  }
352
314
  set.add(item);
353
- result.push(
354
- {text: item.substring(text.length - prefix.length), iconType: 'smallicon-text-prompt', isSecondary: true});
315
+ result.push({label: item, type: 'secondary', boost: -1e5});
355
316
  }
356
- return result as UI.SuggestBox.Suggestions;
317
+ return result.length ? {
318
+ from: 0,
319
+ to: text.length,
320
+ options: result,
321
+ } :
322
+ null;
357
323
  }
358
324
 
359
325
  focus(): void {
360
- if (this.editor) {
361
- this.editor.widget().focus();
362
- } else {
363
- this.element.focus();
364
- }
365
- }
366
-
367
- private async wordsWithQuery(
368
- queryRange: TextUtils.TextRange.TextRange, substituteRange: TextUtils.TextRange.TextRange,
369
- force?: boolean): Promise<UI.SuggestBox.Suggestions> {
370
- if (!this.editor || !this.defaultAutocompleteConfig || !this.defaultAutocompleteConfig.suggestionsCallback) {
371
- return [];
372
- }
373
- const query = this.editor.text(queryRange);
374
- const words = await this.defaultAutocompleteConfig.suggestionsCallback(queryRange, substituteRange, force);
375
- const historyWords = this.historyCompletions(query, force);
376
- return words ? words.concat(historyWords) : historyWords;
326
+ this.editor.focus();
377
327
  }
378
328
 
379
329
  private editorSetForTest(): void {
@@ -1218,7 +1218,7 @@ export class ConsoleView extends UI.Widget.VBox implements UI.SearchableView.Sea
1218
1218
  }
1219
1219
 
1220
1220
  private clearPromptBackwards(): void {
1221
- this.prompt.setText('');
1221
+ this.prompt.clear();
1222
1222
  }
1223
1223
 
1224
1224
  private promptKeyDown(event: Event): void {
@@ -345,13 +345,13 @@
345
345
  }
346
346
 
347
347
  #console-messages .link {
348
+ cursor: pointer;
348
349
  text-decoration: underline;
349
350
  }
350
351
 
351
352
  #console-messages .link,
352
353
  #console-messages .devtools-link {
353
354
  color: var(--color-text-secondary);
354
- cursor: pointer;
355
355
  word-break: break-all;
356
356
  }
357
357
 
@@ -338,7 +338,7 @@
338
338
  background: none;
339
339
  border: none;
340
340
  -webkit-mask-image: var(--image-file-ic_show_node_16x16);
341
- background-color: var(--color-background-elevation-1);
341
+ background-color: var(--color-text-secondary);
342
342
  width: 16px;
343
343
  height: 16px;
344
344
  display: none;
@@ -348,7 +348,7 @@
348
348
 
349
349
  .show-element:focus,
350
350
  .show-element:hover {
351
- background-color: var(--color-syntax-1);
351
+ background-color: var(--color-primary);
352
352
  }
353
353
 
354
354
  .nodeId-column:focus-within .show-element,
@@ -122,8 +122,9 @@ export function accessibilityNodeRenderer(node: AXTreeNode): LitHtml.TemplateRes
122
122
  const sdkNode = node.treeNodeData;
123
123
  const name = sdkNode.name()?.value || '';
124
124
  const role = sdkNode.role()?.value || '';
125
+ const properties = sdkNode.properties() || [];
125
126
  const ignored = sdkNode.ignored();
126
- return LitHtml.html`<${tag} .data=${{name, role, ignored} as Data}></${tag}>`;
127
+ return LitHtml.html`<${tag} .data=${{name, role, ignored, properties} as Data}></${tag}>`;
127
128
  }
128
129
 
129
130
  export function getNodeId(node: SDK.AccessibilityModel.AccessibilityNode): string {
@@ -1044,6 +1044,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1044
1044
  },
1045
1045
  ]),
1046
1046
  TextEditor.Config.baseConfiguration(initialValue),
1047
+ TextEditor.Config.closeBrackets,
1047
1048
  TextEditor.Config.autocompletion,
1048
1049
  CodeMirror.html.html(),
1049
1050
  TextEditor.Config.domWordWrap.instance(),
@@ -30,6 +30,8 @@ export class StyleEditorWidget extends UI.Widget.VBox {
30
30
  private section?: StylePropertiesSection;
31
31
  private editorContainer: HTMLElement;
32
32
 
33
+ #propertyIndex = -1;
34
+
33
35
  constructor() {
34
36
  super(true);
35
37
  this.contentElement.tabIndex = 0;
@@ -71,6 +73,14 @@ export class StyleEditorWidget extends UI.Widget.VBox {
71
73
  this.editor?.addEventListener('propertydeselected', this.onPropertyDeselected);
72
74
  }
73
75
 
76
+ setPropertyIndex(value: number): void {
77
+ this.#propertyIndex = value;
78
+ }
79
+
80
+ getPropertyIndex(): number {
81
+ return this.#propertyIndex;
82
+ }
83
+
74
84
  unbindContext(): void {
75
85
  this.pane = undefined;
76
86
  this.section = undefined;
@@ -105,8 +115,8 @@ export class StyleEditorWidget extends UI.Widget.VBox {
105
115
  }
106
116
 
107
117
  static createTriggerButton(
108
- pane: StylesSidebarPane, section: StylePropertiesSection, editorClass: {new(): Editor},
109
- buttonTitle: string): HTMLElement {
118
+ pane: StylesSidebarPane, section: StylePropertiesSection, editorClass: {new(): Editor}, buttonTitle: string,
119
+ propertyIndex: number): HTMLElement {
110
120
  const triggerButton = createButton(buttonTitle);
111
121
 
112
122
  triggerButton.onclick = async(event): Promise<void> => {
@@ -115,6 +125,7 @@ export class StyleEditorWidget extends UI.Widget.VBox {
115
125
  const widget = StyleEditorWidget.instance();
116
126
  widget.setEditor(editorClass);
117
127
  widget.bindContext(pane, section);
128
+ widget.setPropertyIndex(propertyIndex);
118
129
  await widget.render();
119
130
  const scrollerElement = triggerButton.enclosingNodeOrSelfWithClass('style-panes-wrapper');
120
131
  const onScroll = (): void => {
@@ -39,12 +39,19 @@ export class StylePropertyHighlighter {
39
39
  * Find the first non-overridden property that matches the provided name, scroll to it and highlight it.
40
40
  */
41
41
  findAndHighlightPropertyName(propertyName: string): void {
42
- const {treeElement, section} = this.findTreeElementAndSection(
43
- treeElement => treeElement.property.name === propertyName && !treeElement.overloaded());
44
- if (treeElement) {
45
- this.scrollAndHighlightTreeElement(treeElement);
46
- if (section) {
47
- section.element.focus();
42
+ for (const section of this.styleSidebarPane.allSections()) {
43
+ if (!section.style().hasActiveProperty(propertyName)) {
44
+ continue;
45
+ }
46
+ section.showAllItems();
47
+ const treeElement = this.findTreeElementFromSection(
48
+ treeElement => treeElement.property.name === propertyName && !treeElement.overloaded(), section);
49
+ if (treeElement) {
50
+ this.scrollAndHighlightTreeElement(treeElement);
51
+ if (section) {
52
+ section.element.focus();
53
+ }
54
+ return;
48
55
  }
49
56
  }
50
57
  }
@@ -57,23 +64,26 @@ export class StylePropertyHighlighter {
57
64
  treeElement: StylePropertyTreeElement|null,
58
65
  section: StylePropertiesSection|null,
59
66
  } {
60
- let result: StylePropertyTreeElement|null = null;
61
- let containingSection: StylePropertiesSection|null = null;
62
67
  for (const section of this.styleSidebarPane.allSections()) {
63
- let treeElement = section.propertiesTreeOutline.firstChild();
64
- while (treeElement && !result && (treeElement instanceof StylePropertyTreeElement)) {
65
- if (compareCb(treeElement)) {
66
- result = treeElement;
67
- break;
68
- }
69
- treeElement = treeElement.traverseNextTreeElement(false, null, true);
68
+ const treeElement = this.findTreeElementFromSection(compareCb, section);
69
+ if (treeElement) {
70
+ return {treeElement, section};
70
71
  }
71
- if (result) {
72
- containingSection = section;
73
- break;
72
+ }
73
+ return {treeElement: null, section: null};
74
+ }
75
+
76
+ private findTreeElementFromSection(
77
+ compareCb: (arg0: StylePropertyTreeElement) => boolean, section: StylePropertiesSection): StylePropertyTreeElement
78
+ |null {
79
+ let treeElement = section.propertiesTreeOutline.firstChild();
80
+ while (treeElement && (treeElement instanceof StylePropertyTreeElement)) {
81
+ if (compareCb(treeElement)) {
82
+ return treeElement;
74
83
  }
84
+ treeElement = treeElement.traverseNextTreeElement(false, null, true);
75
85
  }
76
- return {treeElement: result, section: containingSection};
86
+ return null;
77
87
  }
78
88
 
79
89
  private scrollAndHighlightTreeElement(treeElement: StylePropertyTreeElement): void {
@@ -670,19 +670,22 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
670
670
  const propertyValue = this.property.trimmedValueWithoutImportant();
671
671
  if (propertyValue === 'flex' || propertyValue === 'inline-flex') {
672
672
  const button = StyleEditorWidget.createTriggerButton(
673
- this.parentPaneInternal, section, FlexboxEditor, i18nString(UIStrings.flexboxEditorButton));
673
+ this.parentPaneInternal, section, FlexboxEditor, i18nString(UIStrings.flexboxEditorButton),
674
+ this.property.index);
674
675
  this.listItemElement.appendChild(button);
675
676
  const helper = this.parentPaneInternal.swatchPopoverHelper();
676
- if (helper.isShowing(StyleEditorWidget.instance())) {
677
+ if (helper.isShowing(StyleEditorWidget.instance()) &&
678
+ this.property.index === StyleEditorWidget.instance().getPropertyIndex()) {
677
679
  helper.setAnchorElement(button);
678
680
  }
679
681
  }
680
682
  if (propertyValue === 'grid' || propertyValue === 'inline-grid') {
681
683
  const button = StyleEditorWidget.createTriggerButton(
682
- this.parentPaneInternal, section, GridEditor, i18nString(UIStrings.gridEditorButton));
684
+ this.parentPaneInternal, section, GridEditor, i18nString(UIStrings.gridEditorButton), this.property.index);
683
685
  this.listItemElement.appendChild(button);
684
686
  const helper = this.parentPaneInternal.swatchPopoverHelper();
685
- if (helper.isShowing(StyleEditorWidget.instance())) {
687
+ if (helper.isShowing(StyleEditorWidget.instance()) &&
688
+ this.property.index === StyleEditorWidget.instance().getPropertyIndex()) {
686
689
  helper.setAnchorElement(button);
687
690
  }
688
691
  }
@@ -1922,7 +1922,7 @@ export class StylePropertiesSection {
1922
1922
  }
1923
1923
  }
1924
1924
 
1925
- private showAllItems(event?: Event): void {
1925
+ showAllItems(event?: Event): void {
1926
1926
  if (event) {
1927
1927
  event.consume();
1928
1928
  }