chrome-devtools-frontend 1.0.1026673 → 1.0.1027585

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 (28) hide show
  1. package/config/owner/LIGHTHOUSE_OWNERS +1 -1
  2. package/front_end/core/host/UserMetrics.ts +2 -1
  3. package/front_end/core/i18n/locales/en-US.json +6 -0
  4. package/front_end/core/i18n/locales/en-XL.json +6 -0
  5. package/front_end/core/root/Runtime.ts +1 -0
  6. package/front_end/core/sdk/NetworkManager.ts +24 -3
  7. package/front_end/core/sdk/ResourceTreeModel.ts +1 -1
  8. package/front_end/core/sdk/sdk-meta.ts +7 -0
  9. package/front_end/devtools_compatibility.js +1 -0
  10. package/front_end/entrypoints/main/MainImpl.ts +5 -0
  11. package/front_end/generated/ARIAProperties.js +723 -723
  12. package/front_end/generated/SupportedCSSProperties.js +2835 -2835
  13. package/front_end/legacy_test_runner/axe_core_test_runner/axe_core_test_runner.js +1 -1
  14. package/front_end/models/bindings/DebuggerLanguagePlugins.ts +38 -11
  15. package/front_end/models/bindings/IgnoreListManager.ts +20 -5
  16. package/front_end/panels/accessibility/ARIAAttributesView.ts +2 -0
  17. package/front_end/panels/console/consoleView.css +4 -0
  18. package/front_end/panels/elements/components/ElementsBreadcrumbs.ts +45 -50
  19. package/front_end/panels/lighthouse/LighthousePanel.ts +2 -0
  20. package/front_end/panels/settings/FrameworkIgnoreListSettingsTab.ts +16 -0
  21. package/front_end/panels/sources/DebuggerPlugin.ts +6 -0
  22. package/front_end/ui/components/panel_feedback/PreviewToggle.ts +15 -16
  23. package/front_end/ui/components/panel_feedback/previewToggle.css +13 -15
  24. package/front_end/ui/legacy/ARIAUtils.ts +1 -75
  25. package/front_end/ui/legacy/ListControl.ts +4 -0
  26. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +13 -3
  27. package/front_end/ui/legacy/inspectorCommon.css +0 -9
  28. package/package.json +1 -1
@@ -133,7 +133,7 @@ const DEFAULT_CONFIG = {
133
133
  // ignored by the 'aria-valid-attr' rule.
134
134
  // This should be removed after axe-core is updated.
135
135
  // See: https://github.com/dequelabs/axe-core/issues/1457
136
- {id: 'aria-valid-attr', options: ['aria-placeholder']}
136
+ {id: 'aria-valid-attr', options: ['aria-placeholder', 'aria-description']}
137
137
  ],
138
138
  runOnly: {type: 'tags', values: {include: ['wcag2a', 'best-practice'], exclude: ['experimental']}}
139
139
  };
@@ -656,15 +656,23 @@ class SourceScopeRemoteObject extends SDK.RemoteObject.RemoteObjectImpl {
656
656
  }
657
657
 
658
658
  for (const variable of this.variables) {
659
- let sourceVar;
659
+ let sourceVar: SDK.RemoteObject.RemoteObject|undefined;
660
660
  try {
661
- sourceVar = await getValueTreeForExpression(this.#callFrame, this.#plugin, variable.name, ({
662
- generatePreview: false,
663
- includeCommandLineAPI: true,
664
- objectGroup: 'backtrace',
665
- returnByValue: false,
666
- silent: false,
667
- } as SDK.RuntimeModel.EvaluationOptions));
661
+ const evalResult = await this.#plugin.evaluate(variable.name, getRawLocation(this.#callFrame), this.stopId);
662
+ if (evalResult) {
663
+ sourceVar = new ExtensionRemoteObject(this.#callFrame, evalResult, this.#plugin);
664
+ }
665
+ // For backwards compatibility, fall back to the legacy API if the plugin doesn't define the new one.
666
+ // TODO(crbug.com/1342848) Remove
667
+ if (!sourceVar) {
668
+ sourceVar = await getValueTreeForExpression(this.#callFrame, this.#plugin, variable.name, ({
669
+ generatePreview: false,
670
+ includeCommandLineAPI: true,
671
+ objectGroup: 'backtrace',
672
+ returnByValue: false,
673
+ silent: false,
674
+ } as SDK.RuntimeModel.EvaluationOptions));
675
+ }
668
676
  } catch (e) {
669
677
  console.warn(e);
670
678
  sourceVar = new SDK.RemoteObject.LocalJSONObject(undefined);
@@ -918,7 +926,7 @@ export class DebuggerLanguagePluginManager implements
918
926
  error: string,
919
927
  }|null> {
920
928
  const {script} = callFrame;
921
- const {expression} = options;
929
+ const {expression, returnByValue, throwOnSideEffect} = options;
922
930
  const {plugin} = await this.rawModuleIdAndPluginForScript(script);
923
931
  if (!plugin) {
924
932
  return null;
@@ -929,9 +937,20 @@ export class DebuggerLanguagePluginManager implements
929
937
  return null;
930
938
  }
931
939
 
940
+ if (returnByValue) {
941
+ return {error: 'Cannot return by value'};
942
+ }
943
+ if (throwOnSideEffect) {
944
+ return {error: 'Cannot guarantee side-effect freedom'};
945
+ }
946
+
932
947
  try {
933
- const object = await getValueTreeForExpression(callFrame, plugin, expression, options);
934
- return {object, exceptionDetails: undefined};
948
+ const object = await plugin.evaluate(expression, location, this.stopIdForCallFrame(callFrame));
949
+ if (!object) {
950
+ const object = await getValueTreeForExpression(callFrame, plugin, expression, options);
951
+ return {object, exceptionDetails: undefined};
952
+ }
953
+ return {object: new ExtensionRemoteObject(callFrame, object, plugin), exceptionDetails: undefined};
935
954
  } catch (error) {
936
955
  if (error instanceof FormattingError) {
937
956
  const {exception: object, exceptionDetails} = error;
@@ -1542,4 +1561,12 @@ class ModelData {
1542
1561
  export interface DebuggerLanguagePlugin extends Chrome.DevTools.LanguageExtensionPlugin {
1543
1562
  name: string;
1544
1563
  handleScript(script: SDK.Script.Script): boolean;
1564
+
1565
+ // These are optional in the public interface for compatibility purposes, but ExtensionAPI handles the missing
1566
+ // functions gracefully, so we can mark them non-optional here.
1567
+ // TODO(crbug.com/1342848) Remove
1568
+ evaluate(expression: string, context: Chrome.DevTools.RawLocation, stopId: unknown):
1569
+ Promise<Chrome.DevTools.RemoteObject|null>;
1570
+ getProperties(objectId: Chrome.DevTools.RemoteObjectId): Promise<Chrome.DevTools.PropertyDescriptor[]>;
1571
+ releaseObject(objectId: Chrome.DevTools.RemoteObjectId): Promise<void>;
1545
1572
  }
@@ -28,6 +28,9 @@ export class IgnoreListManager implements SDK.TargetManager.SDKModelObserver<SDK
28
28
  Common.Settings.Settings.instance()
29
29
  .moduleSetting('skipContentScripts')
30
30
  .addChangeListener(this.patternChanged.bind(this));
31
+ Common.Settings.Settings.instance()
32
+ .moduleSetting('automaticallyIgnoreListKnownThirdPartyScripts')
33
+ .addChangeListener(this.patternChanged.bind(this));
31
34
 
32
35
  this.#listeners = new Set();
33
36
 
@@ -101,7 +104,7 @@ export class IgnoreListManager implements SDK.TargetManager.SDKModelObserver<SDK
101
104
  uiSourceCode: Workspace.UISourceCode.UISourceCode, sourceMap: SDK.SourceMap.SourceMap|null): boolean {
102
105
  const projectType = uiSourceCode.project().type();
103
106
  const isContentScript = projectType === Workspace.Workspace.projectTypes.ContentScripts;
104
- if (isContentScript && Common.Settings.Settings.instance().moduleSetting('skipContentScripts').get()) {
107
+ if (this.skipContentScripts && isContentScript) {
105
108
  return true;
106
109
  }
107
110
  const url = this.uiSourceCodeURL(uiSourceCode);
@@ -110,16 +113,20 @@ export class IgnoreListManager implements SDK.TargetManager.SDKModelObserver<SDK
110
113
 
111
114
  isUserOrSourceMapIgnoreListedURL(url: Platform.DevToolsPath.UrlString, sourceMap: SDK.SourceMap.SourceMap|null):
112
115
  boolean {
113
- const userIgnoreListed = this.isUserIgnoreListedURL(url);
114
- const sourceMapIgnoreListed = sourceMap?.hasIgnoreListHint(url) ?? false;
115
- return userIgnoreListed || sourceMapIgnoreListed;
116
+ if (this.isUserIgnoreListedURL(url)) {
117
+ return true;
118
+ }
119
+ if (this.automaticallyIgnoreListKnownThirdPartyScripts && sourceMap?.hasIgnoreListHint(url)) {
120
+ return true;
121
+ }
122
+ return false;
116
123
  }
117
124
 
118
125
  isUserIgnoreListedURL(url: Platform.DevToolsPath.UrlString, isContentScript?: boolean): boolean {
119
126
  if (this.#isIgnoreListedURLCache.has(url)) {
120
127
  return Boolean(this.#isIgnoreListedURLCache.get(url));
121
128
  }
122
- if (isContentScript && Common.Settings.Settings.instance().moduleSetting('skipContentScripts').get()) {
129
+ if (isContentScript && this.skipContentScripts) {
123
130
  return true;
124
131
  }
125
132
  const regex = this.getSkipStackFramesPatternSetting().asRegExp();
@@ -208,6 +215,14 @@ export class IgnoreListManager implements SDK.TargetManager.SDKModelObserver<SDK
208
215
  }
209
216
  }
210
217
 
218
+ get skipContentScripts(): boolean {
219
+ return Common.Settings.Settings.instance().moduleSetting('skipContentScripts').get();
220
+ }
221
+
222
+ get automaticallyIgnoreListKnownThirdPartyScripts(): boolean {
223
+ return Common.Settings.Settings.instance().moduleSetting('automaticallyIgnoreListKnownThirdPartyScripts').get();
224
+ }
225
+
211
226
  ignoreListContentScripts(): void {
212
227
  Common.Settings.Settings.instance().moduleSetting('skipContentScripts').set(true);
213
228
  }
@@ -229,6 +229,7 @@ const ATTRIBUTES = new Set<string>([
229
229
  'aria-activedescendant',
230
230
  'aria-atomic',
231
231
  'aria-autocomplete',
232
+ 'aria-braillelabel',
232
233
  'aria-brailleroledescription',
233
234
  'aria-busy',
234
235
  'aria-checked',
@@ -239,6 +240,7 @@ const ATTRIBUTES = new Set<string>([
239
240
  'aria-controls',
240
241
  'aria-current',
241
242
  'aria-describedby',
243
+ 'aria-description',
242
244
  'aria-details',
243
245
  'aria-disabled',
244
246
  'aria-dropeffect',
@@ -546,3 +546,7 @@
546
546
  --override-error-text-color: HighlightText;
547
547
  }
548
548
  }
549
+
550
+ [slot="insertion-point-sidebar"] {
551
+ contain: layout style;
552
+ }
@@ -45,6 +45,7 @@ export class ElementsBreadcrumbs extends HTMLElement {
45
45
  static readonly litTagName = LitHtml.literal`devtools-elements-breadcrumbs`;
46
46
  readonly #shadow = this.attachShadow({mode: 'open'});
47
47
  readonly #resizeObserver = new ResizeObserver(() => this.#checkForOverflowOnResize());
48
+ readonly #renderBound = this.#render.bind(this);
48
49
 
49
50
  #crumbsData: readonly DOMNode[] = [];
50
51
  #selectedDOMNode: Readonly<DOMNode>|null = null;
@@ -61,7 +62,7 @@ export class ElementsBreadcrumbs extends HTMLElement {
61
62
  this.#selectedDOMNode = data.selectedNode;
62
63
  this.#crumbsData = data.crumbs;
63
64
  this.#userHasManuallyScrolled = false;
64
- void this.#update();
65
+ void ComponentHelpers.ScheduledRender.scheduleRender(this, this.#renderBound);
65
66
  }
66
67
 
67
68
  disconnectedCallback(): void {
@@ -104,12 +105,6 @@ export class ElementsBreadcrumbs extends HTMLElement {
104
105
  }
105
106
  }
106
107
 
107
- async #update(): Promise<void> {
108
- await this.#render();
109
- this.#engageResizeObserver();
110
- void this.#ensureSelectedNodeIsVisible();
111
- }
112
-
113
108
  #onCrumbMouseMove(node: DOMNode): () => void {
114
109
  return (): void => node.highlightNode();
115
110
  }
@@ -267,53 +262,53 @@ export class ElementsBreadcrumbs extends HTMLElement {
267
262
  `;
268
263
  }
269
264
 
270
- async #render(): Promise<void> {
265
+ #render(): void {
271
266
  const crumbs = crumbsToRender(this.#crumbsData, this.#selectedDOMNode);
272
267
 
273
- await coordinator.write('Breadcrumbs render', () => {
274
- // Disabled until https://crbug.com/1079231 is fixed.
275
- // clang-format off
276
- LitHtml.render(LitHtml.html`
277
- <nav class="crumbs" aria-label=${i18nString(UIStrings.breadcrumbs)}>
278
- ${this.#renderOverflowButton('left', this.#userScrollPosition === 'start')}
279
-
280
- <div class="crumbs-window" @scroll=${this.#onCrumbsWindowScroll}>
281
- <ul class="crumbs-scroll-container">
282
- ${crumbs.map(crumb => {
283
- const crumbClasses = {
284
- crumb: true,
285
- selected: crumb.selected,
286
- };
287
- // eslint-disable-next-line rulesdir/ban_a_tags_in_lit_html
288
- return LitHtml.html`
289
- <li class=${LitHtml.Directives.classMap(crumbClasses)}
290
- data-node-id=${crumb.node.id}
291
- data-crumb="true"
292
- >
293
- <a href="#"
294
- draggable=false
295
- class="crumb-link"
296
- @click=${this.#onCrumbClick(crumb.node)}
297
- @mousemove=${this.#onCrumbMouseMove(crumb.node)}
298
- @mouseleave=${this.#onCrumbMouseLeave(crumb.node)}
299
- @focus=${this.#onCrumbFocus(crumb.node)}
300
- @blur=${this.#onCrumbBlur(crumb.node)}
301
- ><${NodeText.NodeText.NodeText.litTagName} data-node-title=${crumb.title.main} .data=${{
302
- nodeTitle: crumb.title.main,
303
- nodeId: crumb.title.extras.id,
304
- nodeClasses: crumb.title.extras.classes,
305
- } as NodeText.NodeText.NodeTextData}></${NodeText.NodeText.NodeText.litTagName}></a>
306
- </li>`;
307
- })}
308
- </ul>
309
- </div>
310
- ${this.#renderOverflowButton('right', this.#userScrollPosition === 'end')}
311
- </nav>
312
- `, this.#shadow, { host: this });
313
- // clang-format on
314
- });
268
+ // Disabled until https://crbug.com/1079231 is fixed.
269
+ // clang-format off
270
+ LitHtml.render(LitHtml.html`
271
+ <nav class="crumbs" aria-label=${i18nString(UIStrings.breadcrumbs)}>
272
+ ${this.#renderOverflowButton('left', this.#userScrollPosition === 'start')}
273
+
274
+ <div class="crumbs-window" @scroll=${this.#onCrumbsWindowScroll}>
275
+ <ul class="crumbs-scroll-container">
276
+ ${crumbs.map(crumb => {
277
+ const crumbClasses = {
278
+ crumb: true,
279
+ selected: crumb.selected,
280
+ };
281
+ // eslint-disable-next-line rulesdir/ban_a_tags_in_lit_html
282
+ return LitHtml.html`
283
+ <li class=${LitHtml.Directives.classMap(crumbClasses)}
284
+ data-node-id=${crumb.node.id}
285
+ data-crumb="true"
286
+ >
287
+ <a href="#"
288
+ draggable=false
289
+ class="crumb-link"
290
+ @click=${this.#onCrumbClick(crumb.node)}
291
+ @mousemove=${this.#onCrumbMouseMove(crumb.node)}
292
+ @mouseleave=${this.#onCrumbMouseLeave(crumb.node)}
293
+ @focus=${this.#onCrumbFocus(crumb.node)}
294
+ @blur=${this.#onCrumbBlur(crumb.node)}
295
+ ><${NodeText.NodeText.NodeText.litTagName} data-node-title=${crumb.title.main} .data=${{
296
+ nodeTitle: crumb.title.main,
297
+ nodeId: crumb.title.extras.id,
298
+ nodeClasses: crumb.title.extras.classes,
299
+ } as NodeText.NodeText.NodeTextData}></${NodeText.NodeText.NodeText.litTagName}></a>
300
+ </li>`;
301
+ })}
302
+ </ul>
303
+ </div>
304
+ ${this.#renderOverflowButton('right', this.#userScrollPosition === 'end')}
305
+ </nav>
306
+ `, this.#shadow, { host: this });
307
+ // clang-format on
315
308
 
316
309
  void this.#checkForOverflow();
310
+ this.#engageResizeObserver();
311
+ void this.#ensureSelectedNodeIsVisible();
317
312
  }
318
313
 
319
314
  async #ensureSelectedNodeIsVisible(): Promise<void> {
@@ -308,6 +308,8 @@ export class LighthousePanel extends UI.Panel.Panel {
308
308
  const reportContainer = this.auditResultsElement.createChild('div', 'lh-vars lh-root lh-devtools');
309
309
  // @ts-ignore Expose LHR on DOM for e2e tests
310
310
  reportContainer._lighthouseResultForTesting = lighthouseResult;
311
+ // @ts-ignore Expose Artifacts on DOM for e2e tests
312
+ reportContainer._lighthouseArtifactsForTesting = artifacts;
311
313
 
312
314
  const dom = new LighthouseReport.DOM(this.auditResultsElement.ownerDocument as Document, reportContainer);
313
315
  const renderer = new LighthouseReportRenderer(dom) as LighthouseReport.ReportRenderer;
@@ -26,6 +26,15 @@ const UIStrings = {
26
26
  */
27
27
  ignoreListContentScriptsExtension: 'Add content scripts to ignore list (extension scripts in the page)',
28
28
  /**
29
+ *@description Text in Framework Ignore List Settings Tab of the Settings
30
+ */
31
+ automaticallyIgnoreListKnownThirdPartyScripts: 'Automatically add known third-party scripts to ignore list',
32
+ /**
33
+ *@description Text in Framework Ignore List Settings Tab of the Settings
34
+ */
35
+ automaticallyIgnoreListKnownThirdPartyScriptsTooltip:
36
+ 'Add sources from the `x_google_ignoreList` field from source maps to the ignore list',
37
+ /**
29
38
  *@description Ignore List label in Framework Ignore List Settings Tab of the Settings
30
39
  */
31
40
  ignoreList: 'Ignore List',
@@ -98,6 +107,13 @@ export class FrameworkIgnoreListSettingsTab extends UI.Widget.VBox implements
98
107
  Common.Settings.Settings.instance().moduleSetting('skipContentScripts'), true));
99
108
  UI.Tooltip.Tooltip.install(ignoreListContentScripts, i18nString(UIStrings.ignoreListContentScriptsExtension));
100
109
 
110
+ const automaticallyIgnoreList = this.contentElement.createChild('div', 'automatically-ignore-list');
111
+ automaticallyIgnoreList.appendChild(UI.SettingsUI.createSettingCheckbox(
112
+ i18nString(UIStrings.automaticallyIgnoreListKnownThirdPartyScripts),
113
+ Common.Settings.Settings.instance().moduleSetting('automaticallyIgnoreListKnownThirdPartyScripts'), true));
114
+ UI.Tooltip.Tooltip.install(
115
+ automaticallyIgnoreList, i18nString(UIStrings.automaticallyIgnoreListKnownThirdPartyScriptsTooltip));
116
+
101
117
  this.ignoreListLabel = i18nString(UIStrings.ignoreList);
102
118
  this.disabledLabel = i18nString(UIStrings.disabled);
103
119
 
@@ -235,6 +235,9 @@ export class DebuggerPlugin extends Plugin {
235
235
  Common.Settings.Settings.instance()
236
236
  .moduleSetting('skipContentScripts')
237
237
  .addChangeListener(this.showIgnoreListInfobarIfNeeded, this);
238
+ Common.Settings.Settings.instance()
239
+ .moduleSetting('automaticallyIgnoreListKnownThirdPartyScripts')
240
+ .addChangeListener(this.showIgnoreListInfobarIfNeeded, this);
238
241
 
239
242
  UI.Context.Context.instance().addFlavorChangeListener(SDK.DebuggerModel.CallFrame, this.callFrameChanged, this);
240
243
  this.liveLocationPool = new Bindings.LiveLocation.LiveLocationPool();
@@ -1625,6 +1628,9 @@ export class DebuggerPlugin extends Plugin {
1625
1628
  Common.Settings.Settings.instance()
1626
1629
  .moduleSetting('skipContentScripts')
1627
1630
  .removeChangeListener(this.showIgnoreListInfobarIfNeeded, this);
1631
+ Common.Settings.Settings.instance()
1632
+ .moduleSetting('automaticallyIgnoreListKnownThirdPartyScripts')
1633
+ .removeChangeListener(this.showIgnoreListInfobarIfNeeded, this);
1628
1634
  super.dispose();
1629
1635
 
1630
1636
  UI.Context.Context.instance().removeFlavorChangeListener(SDK.DebuggerModel.CallFrame, this.callFrameChanged, this);
@@ -72,23 +72,22 @@ export class PreviewToggle extends HTMLElement {
72
72
  render(
73
73
  html`
74
74
  <div class="container">
75
- <div class="checkbox-line">
76
- <label class="experiment-preview">
77
- <input type="checkbox" ?checked=${checked} @change=${this.#checkboxChanged} aria-label=${this.#name}/>
78
- <${IconButton.Icon.Icon.litTagName} .data=${{
79
- iconName: 'ic_preview_feature',
80
- width: '16px',
81
- height: '16px',
82
- color: 'var(--color-text-secondary)',
83
- } as IconButton.Icon.IconData}>
84
- </${IconButton.Icon.Icon.litTagName}>${this.#name}
85
- </label>
86
- ${this.#feedbackURL && !this.#helperText
87
- ? html`<div class="feedback"><x-link class="x-link" href=${this.#feedbackURL}>${i18nString(UIStrings.shortFeedbackLink)}</x-link></div>`
88
- : nothing}
89
- </div>
75
+ <label class="experiment-preview">
76
+ <input type="checkbox" ?checked=${checked} @change=${this.#checkboxChanged} aria-label=${this.#name}/>
77
+ <${IconButton.Icon.Icon.litTagName} .data=${{
78
+ iconName: 'ic_preview_feature',
79
+ width: '16px',
80
+ height: '16px',
81
+ color: 'var(--color-text-secondary)',
82
+ } as IconButton.Icon.IconData}>
83
+ </${IconButton.Icon.Icon.litTagName}>${this.#name}
84
+ </label>
85
+ <div class="spacer"></div>
86
+ ${this.#feedbackURL && !this.#helperText
87
+ ? html`<div class="feedback"><x-link class="x-link" href=${this.#feedbackURL}>${i18nString(UIStrings.shortFeedbackLink)}</x-link></div>`
88
+ : nothing}
90
89
  ${this.#learnMoreURL
91
- ? html`<x-link class="x-link" href=${this.#learnMoreURL}>${i18nString(UIStrings.learnMoreLink)}</x-link>`
90
+ ? html`<div class="learn-more"><x-link class="x-link" href=${this.#learnMoreURL}>${i18nString(UIStrings.learnMoreLink)}</x-link></div>`
92
91
  : nothing}
93
92
  <div class="helper">
94
93
  ${this.#helperText && this.#feedbackURL
@@ -8,35 +8,33 @@
8
8
  display: block;
9
9
  }
10
10
 
11
- .experiment-preview {
11
+ .container {
12
+ display: flex;
13
+ flex-wrap: wrap;
14
+ padding: 4px;
15
+ }
16
+
17
+ .experiment-preview,
18
+ .feedback,
19
+ .learn-more {
12
20
  display: flex;
13
21
  align-items: center;
14
22
  }
15
23
 
16
24
  .helper {
25
+ flex-basis: 100%;
17
26
  text-align: center;
18
27
  font-style: italic;
19
28
  }
20
29
 
21
- .feedback {
22
- text-align: right;
23
- }
24
-
25
- .checkbox-line {
26
- display: flex;
27
- justify-content: space-between;
28
- align-items: center;
29
- flex-wrap: wrap;
30
- }
31
-
32
- .container {
33
- padding: 4px;
30
+ .spacer {
31
+ flex: 1;
34
32
  }
35
33
 
36
34
  .x-link {
37
35
  color: var(--color-primary);
38
36
  text-decoration-line: underline;
39
- margin: 4px;
37
+ margin: 0 4px;
40
38
  }
41
39
 
42
40
  .feedback .x-link {
@@ -344,10 +344,6 @@ export function setAccessibleName(element: Element, name: string): void {
344
344
  element.setAttribute('aria-label', name);
345
345
  }
346
346
 
347
- // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
348
- // eslint-disable-next-line @typescript-eslint/naming-convention
349
- const _descriptionMap = new WeakMap<Element, Element>();
350
-
351
347
  export function setDescription(element: Element, description: string): void {
352
348
  // Nodes in the accessibility tree are made up of a core
353
349
  // triplet of "name", "value", "description"
@@ -360,77 +356,7 @@ export function setDescription(element: Element, description: string): void {
360
356
  // to appear with the description when the element is hovered.
361
357
  // This is usually fine, except that DevTools has its own styled
362
358
  // tooltips which would interfere with the browser tooltips.
363
- //
364
- // In future, the aria-description attribute may be used once it
365
- // is unflagged.
366
- //
367
- // aria-describedby requires that an extra element exist in DOM
368
- // that this element can point to. Both elements also have to
369
- // be in the same shadow root. This is not trivial to manage.
370
- // The rest of DevTools shouldn't have to worry about this,
371
- // so there is some unfortunate code below.
372
-
373
- const oldDescription = _descriptionMap.get(element);
374
- if (oldDescription) {
375
- oldDescription.remove();
376
- }
377
- element.removeAttribute('data-aria-utils-animation-hack');
378
-
379
- if (!description) {
380
- _descriptionMap.delete(element);
381
- element.removeAttribute('aria-describedby');
382
- return;
383
- }
384
-
385
- // We make a hidden element that contains the decsription
386
- // and will be pointed to by aria-describedby.
387
- const descriptionElement = document.createElement('span');
388
- descriptionElement.textContent = description;
389
- descriptionElement.style.display = 'none';
390
- ensureId(descriptionElement);
391
- element.setAttribute('aria-describedby', descriptionElement.id);
392
- _descriptionMap.set(element, descriptionElement);
393
-
394
- // Now we have to actually put this description element
395
- // somewhere in the DOM so that we can point to it.
396
- // It would be nice to just put it in the body, but that
397
- // wouldn't work if the main element is in a shadow root.
398
- // So the cleanest approach is to add the description element
399
- // as a child of the main element. But wait! Some HTML elements
400
- // aren't supposed to have children. Blink won't search inside
401
- // these elements, and won't find our description element.
402
- const contentfulVoidTags = new Set<string>(['INPUT', 'IMG']);
403
- if (!contentfulVoidTags.has(element.tagName)) {
404
- element.appendChild(descriptionElement);
405
- // If we made it here, someone setting .textContent
406
- // or removeChildren on the element will blow away
407
- // our description. At least we tried our best!
408
- return;
409
- }
410
-
411
- // We have some special element, like an <input>, where putting the
412
- // description element inside it doesn't work.
413
- // Lets try the next best thing, and just put the description element
414
- // next to it in the DOM.
415
- const inserted = element.insertAdjacentElement('afterend', descriptionElement);
416
- if (inserted) {
417
- return;
418
- }
419
-
420
- // Uh oh, the insertion didn't work! That means we aren't currently in the DOM.
421
- // How can we find out when the element enters the DOM?
422
- // See inspectorCommon.css
423
- element.setAttribute('data-aria-utils-animation-hack', 'sorry');
424
- element.addEventListener('animationend', () => {
425
- // Someone might have made a new description in the meantime.
426
- if (_descriptionMap.get(element) !== descriptionElement) {
427
- return;
428
- }
429
- element.removeAttribute('data-aria-utils-animation-hack');
430
-
431
- // Try it again. This time we are in the DOM, so it *should* work.
432
- element.insertAdjacentElement('afterend', descriptionElement);
433
- }, {once: true});
359
+ element.setAttribute('aria-description', description);
434
360
  }
435
361
 
436
362
  export function setActiveDescendant(element: Element, activedescendant: Element|null): void {
@@ -428,6 +428,10 @@ export class ListControl<T> {
428
428
  }
429
429
  if (newElement) {
430
430
  ARIAUtils.setSelected(newElement, true);
431
+ const text = newElement.textContent;
432
+ if (text) {
433
+ ARIAUtils.alert(text);
434
+ }
431
435
  }
432
436
  ARIAUtils.setActiveDescendant(this.element, newElement);
433
437
  }
@@ -30,6 +30,7 @@
30
30
 
31
31
  import * as Common from '../../../../core/common/common.js';
32
32
  import type * as Components from '../utils/utils.js';
33
+ import * as Root from '../../../../core/root/root.js';
33
34
  import * as Host from '../../../../core/host/host.js';
34
35
  import * as i18n from '../../../../core/i18n/i18n.js';
35
36
  import * as LinearMemoryInspector from '../../../components/linear_memory_inspector/linear_memory_inspector.js';
@@ -222,8 +223,12 @@ export class ObjectPropertiesSection extends UI.TreeOutline.TreeOutlineInShadow
222
223
  return;
223
224
  }
224
225
 
226
+ const includedWebIdlTypes = webIdlType.includes?.map(className => domPinnedProperties[className]) ?? [];
227
+ const includedWebIdlProps = includedWebIdlTypes.flatMap(webIdlType => Object.entries(webIdlType.props ?? {}));
228
+ const webIdlProps = {...webIdlType.props, ...Object.fromEntries(includedWebIdlProps)};
229
+
225
230
  for (const property of properties) {
226
- const webIdlProperty = webIdlType?.props?.[property.name];
231
+ const webIdlProperty = webIdlProps[property.name];
227
232
  if (webIdlProperty) {
228
233
  property.webIdl = {info: webIdlProperty};
229
234
  }
@@ -1118,10 +1123,12 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1118
1123
  this.expandedValueElement = this.createExpandedValueElement(this.property.value);
1119
1124
  }
1120
1125
 
1126
+ const experiment = Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.IMPORTANT_DOM_PROPERTIES);
1127
+
1121
1128
  let adorner: Element|string = '';
1122
1129
  let container: Element;
1123
1130
 
1124
- if (this.property.webIdl?.applicable) {
1131
+ if (this.property.webIdl?.applicable && experiment) {
1125
1132
  const icon = new IconButton.Icon.Icon();
1126
1133
  icon.data = {
1127
1134
  iconName: 'star_outline',
@@ -1148,7 +1155,10 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1148
1155
  this.listItemElement.removeChildren();
1149
1156
  this.rowContainer = (container as HTMLElement);
1150
1157
  this.listItemElement.appendChild(this.rowContainer);
1151
- this.listItemElement.dataset.webidl = this.property.webIdl?.applicable ? 'true' : 'false';
1158
+
1159
+ if (experiment) {
1160
+ this.listItemElement.dataset.webidl = this.property.webIdl?.applicable ? 'true' : 'false';
1161
+ }
1152
1162
  }
1153
1163
 
1154
1164
  private updatePropertyPath(): void {
@@ -629,15 +629,6 @@ button.link:focus-visible {
629
629
  --override-link-focus-background-color: rgb(230 230 230 / 8%);
630
630
  }
631
631
 
632
- /* See ARIAUtils.js */
633
- [data-aria-utils-animation-hack] {
634
- animation: ANIMATION-HACK 0s;
635
- }
636
-
637
- @keyframes ANIMATION-HACK {
638
- /* empty keyframe to trigger the animation hack above */
639
- }
640
-
641
632
  @media (forced-colors: active) {
642
633
  .dimmed,
643
634
  .chrome-select:disabled {
package/package.json CHANGED
@@ -55,5 +55,5 @@
55
55
  "unittest": "scripts/test/run_unittests.py --no-text-coverage",
56
56
  "watch": "vpython third_party/node/node.py --output scripts/watch_build.js"
57
57
  },
58
- "version": "1.0.1026673"
58
+ "version": "1.0.1027585"
59
59
  }