chrome-devtools-frontend 1.0.1543472 → 1.0.1544076

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 (109) hide show
  1. package/AUTHORS +1 -0
  2. package/front_end/core/host/AidaClient.ts +10 -7
  3. package/front_end/core/host/DispatchHttpRequestClient.ts +18 -3
  4. package/front_end/core/root/Runtime.ts +8 -7
  5. package/front_end/core/sdk/CPUThrottlingManager.ts +0 -4
  6. package/front_end/core/sdk/CSSMatchedStyles.ts +7 -9
  7. package/front_end/core/sdk/CSSModel.ts +1 -1
  8. package/front_end/core/sdk/CSSRule.ts +18 -6
  9. package/front_end/core/sdk/ChildTargetManager.ts +2 -2
  10. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotLoader.ts +2 -0
  11. package/front_end/entrypoints/main/MainImpl.ts +0 -16
  12. package/front_end/foundation/Universe.ts +12 -1
  13. package/front_end/models/ai_assistance/agents/AiAgent.ts +10 -8
  14. package/front_end/models/ai_assistance/agents/PatchAgent.ts +7 -1
  15. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +0 -5
  16. package/front_end/models/ai_assistance/agents/StylingAgent.ts +4 -8
  17. package/front_end/models/ai_code_completion/AiCodeCompletion.ts +1 -1
  18. package/front_end/models/ai_code_generation/AiCodeGeneration.ts +5 -3
  19. package/front_end/models/bindings/CSSWorkspaceBinding.ts +8 -7
  20. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +9 -8
  21. package/front_end/models/bindings/ResourceMapping.ts +57 -15
  22. package/front_end/models/live-metrics/LiveMetrics.ts +12 -20
  23. package/front_end/panels/accessibility/AccessibilityNodeView.ts +6 -2
  24. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +1 -1
  25. package/front_end/panels/ai_assistance/components/ChatView.ts +2 -4
  26. package/front_end/panels/ai_assistance/components/PerformanceAgentMarkdownRenderer.ts +2 -1
  27. package/front_end/panels/animation/AnimationTimeline.ts +6 -6
  28. package/front_end/panels/application/components/ReportsGrid.ts +7 -2
  29. package/front_end/panels/application/components/SharedStorageAccessGrid.ts +5 -3
  30. package/front_end/panels/application/components/TrustTokensView.ts +7 -1
  31. package/front_end/panels/application/preloading/PreloadingView.ts +10 -4
  32. package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +7 -11
  33. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +15 -3
  34. package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +12 -13
  35. package/front_end/panels/{elements → common}/DOMLinkifier.ts +6 -6
  36. package/front_end/panels/common/common.ts +1 -0
  37. package/front_end/panels/console/ConsoleViewMessage.ts +4 -4
  38. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +2 -1
  39. package/front_end/panels/elements/ElementsTreeElement.ts +3 -1
  40. package/front_end/panels/elements/StylePropertiesSection.ts +52 -15
  41. package/front_end/panels/elements/StylePropertyTreeElement.ts +8 -3
  42. package/front_end/panels/elements/StylesSidebarPane.ts +24 -14
  43. package/front_end/panels/elements/elements-meta.ts +11 -2
  44. package/front_end/panels/elements/elements.ts +0 -3
  45. package/front_end/panels/explain/components/ConsoleInsight.ts +31 -20
  46. package/front_end/panels/issues/AffectedResourcesView.ts +2 -1
  47. package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +2 -1
  48. package/front_end/panels/network/NetworkLogView.ts +1 -1
  49. package/front_end/panels/recorder/RecorderController.ts +7 -1
  50. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +42 -294
  51. package/front_end/panels/sources/DebuggerPausedMessage.ts +3 -3
  52. package/front_end/panels/sources/SourcesPanel.ts +5 -1
  53. package/front_end/panels/timeline/TimelineUIUtils.ts +3 -2
  54. package/front_end/panels/timeline/components/LiveMetricsView.ts +7 -4
  55. package/front_end/panels/timeline/components/insights/NodeLink.ts +3 -2
  56. package/front_end/third_party/puppeteer/README.chromium +2 -2
  57. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.d.ts +1 -0
  58. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.d.ts.map +1 -1
  59. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.js +4 -1
  60. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.js.map +1 -1
  61. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkEventManager.d.ts +1 -0
  62. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkEventManager.d.ts.map +1 -1
  63. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkEventManager.js +8 -0
  64. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkEventManager.js.map +1 -1
  65. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
  66. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.js +22 -0
  67. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.js.map +1 -1
  68. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  69. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
  70. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
  71. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  72. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  73. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  74. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  75. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +34 -6
  76. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.d.ts +1 -0
  77. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.d.ts.map +1 -1
  78. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.js +4 -1
  79. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.js.map +1 -1
  80. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkEventManager.d.ts +1 -0
  81. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkEventManager.d.ts.map +1 -1
  82. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkEventManager.js +8 -0
  83. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkEventManager.js.map +1 -1
  84. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
  85. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.js +22 -0
  86. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.js.map +1 -1
  87. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
  88. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
  89. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  90. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  91. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  92. package/front_end/third_party/puppeteer/package/package.json +2 -2
  93. package/front_end/third_party/puppeteer/package/src/cdp/HTTPRequest.ts +5 -1
  94. package/front_end/third_party/puppeteer/package/src/cdp/NetworkEventManager.ts +16 -1
  95. package/front_end/third_party/puppeteer/package/src/cdp/NetworkManager.ts +28 -0
  96. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  97. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  98. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +8 -5
  99. package/front_end/ui/i18n/i18n.ts +16 -0
  100. package/front_end/ui/legacy/UIUtils.ts +1 -1
  101. package/front_end/ui/legacy/Widget.ts +56 -25
  102. package/front_end/ui/legacy/XLink.ts +0 -2
  103. package/front_end/ui/legacy/components/object_ui/ObjectPopoverHelper.ts +3 -1
  104. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +155 -198
  105. package/front_end/ui/legacy/inspectorCommon.css +0 -4
  106. package/mcp/mcp.ts +1 -0
  107. package/package.json +1 -1
  108. package/front_end/ui/components/expandable_list/ExpandableList.docs.ts +0 -30
  109. /package/front_end/panels/{elements → common}/domLinkifier.css +0 -0
@@ -56,6 +56,7 @@ import * as Components from '../../ui/legacy/components/utils/utils.js';
56
56
  import * as UI from '../../ui/legacy/legacy.js';
57
57
  import * as Lit from '../../ui/lit/lit.js';
58
58
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
59
+ import * as PanelsCommon from '../common/common.js';
59
60
  import * as Emulation from '../emulation/emulation.js';
60
61
  import * as Media from '../media/media.js';
61
62
 
@@ -66,6 +67,7 @@ import {ElementsPanel} from './ElementsPanel.js';
66
67
  import {type ElementsTreeOutline, MappedCharToEntity} from './ElementsTreeOutline.js';
67
68
  import {ImagePreviewPopover} from './ImagePreviewPopover.js';
68
69
  import {getRegisteredDecorators, type MarkerDecorator, type MarkerDecoratorRegistration} from './MarkerDecorator.js';
70
+
69
71
  const {html, nothing, render, Directives: {ref, repeat}} = Lit;
70
72
 
71
73
  const UIStrings = {
@@ -2149,7 +2151,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2149
2151
  if (!relatedElement) {
2150
2152
  return;
2151
2153
  }
2152
- const link = await Common.Linkifier.Linkifier.linkify(relatedElement, {
2154
+ const link = PanelsCommon.DOMLinkifier.Linkifier.instance().linkify(relatedElement, {
2153
2155
  preventKeyboardFocus: true,
2154
2156
  tooltip,
2155
2157
  textContent: linkContainer.textContent || undefined,
@@ -49,10 +49,10 @@ import * as Tooltips from '../../ui/components/tooltips/tooltips.js';
49
49
  import type * as Components from '../../ui/legacy/components/utils/utils.js';
50
50
  import * as UI from '../../ui/legacy/legacy.js';
51
51
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
52
+ import * as PanelsCommon from '../common/common.js';
52
53
 
53
54
  import {FontEditorSectionManager} from './ColorSwatchPopoverIcon.js';
54
55
  import * as ElementsComponents from './components/components.js';
55
- import {DeferredDOMNodeLink} from './DOMLinkifier.js';
56
56
  import {ElementsPanel} from './ElementsPanel.js';
57
57
  import stylePropertiesTreeOutlineStyles from './stylePropertiesTreeOutline.css.js';
58
58
  import {type Context, StylePropertyTreeElement} from './StylePropertyTreeElement.js';
@@ -402,8 +402,10 @@ export class StylePropertiesSection {
402
402
 
403
403
  function linkifyNode(label: string): Node|null {
404
404
  if (header?.ownerNode) {
405
- const link = document.createElement('devtools-widget') as UI.Widget.WidgetElement<DeferredDOMNodeLink>;
406
- link.widgetConfig = UI.Widget.widgetConfig(e => new DeferredDOMNodeLink(e, header.ownerNode));
405
+ const link = document.createElement('devtools-widget') as
406
+ UI.Widget.WidgetElement<PanelsCommon.DOMLinkifier.DeferredDOMNodeLink>;
407
+ link.widgetConfig =
408
+ UI.Widget.widgetConfig(e => new PanelsCommon.DOMLinkifier.DeferredDOMNodeLink(e, header.ownerNode));
407
409
  link.textContent = label;
408
410
  return link;
409
411
  }
@@ -633,6 +635,17 @@ export class StylePropertiesSection {
633
635
  if (this.styleInternal.parentRule instanceof SDK.CSSRule.CSSStyleRule) {
634
636
  return this.styleInternal.parentRule.selectorText();
635
637
  }
638
+ if (this.styleInternal.parentRule instanceof SDK.CSSRule.CSSAtRule) {
639
+ if (this.styleInternal.parentRule.subsection()) {
640
+ return '@' + this.styleInternal.parentRule.subsection();
641
+ }
642
+ const atRule = '@' + this.styleInternal.parentRule.type();
643
+ const name = this.styleInternal.parentRule.name();
644
+ if (name) {
645
+ return atRule + ' ' + name.text;
646
+ }
647
+ return atRule;
648
+ }
636
649
  return '';
637
650
  }
638
651
 
@@ -813,11 +826,36 @@ export class StylePropertiesSection {
813
826
  // We reduce one level since no selector means one less pair of braces are added for declarations.
814
827
  this.nestingLevel--;
815
828
  }
829
+ }
830
+
831
+ protected createAtRuleAncestor(rule: SDK.CSSRule.CSSAtRule): void {
832
+ if (rule.subsection()) {
833
+ const atRuleElement = new ElementsComponents.CSSQuery.CSSQuery();
834
+ atRuleElement.data = {
835
+ queryPrefix: '@' + rule.type(),
836
+ queryText: rule.name()?.text ?? '',
837
+ jslogContext: 'at-rule-' + rule.type(),
838
+ };
816
839
 
817
- let curNestingLevel = 0;
818
- for (const element of this.#ancestorRuleListElement.children) {
819
- this.indentElement(element as HTMLElement, curNestingLevel);
820
- curNestingLevel++;
840
+ this.#ancestorRuleListElement.prepend(atRuleElement);
841
+ this.#ancestorClosingBracesElement.prepend(this.indentElement(this.createClosingBrace(), 0));
842
+ this.nestingLevel++;
843
+ }
844
+ }
845
+
846
+ protected maybeCreateAncestorRules(style: SDK.CSSStyleDeclaration.CSSStyleDeclaration): void {
847
+ if (style.parentRule) {
848
+ if (style.parentRule instanceof SDK.CSSRule.CSSStyleRule) {
849
+ this.createAncestorRules(style.parentRule);
850
+ } else if (style.parentRule instanceof SDK.CSSRule.CSSAtRule) {
851
+ this.createAtRuleAncestor(style.parentRule);
852
+ }
853
+
854
+ let curNestingLevel = 0;
855
+ for (const element of this.#ancestorRuleListElement.children) {
856
+ this.indentElement(element as HTMLElement, curNestingLevel);
857
+ curNestingLevel++;
858
+ }
821
859
  }
822
860
  }
823
861
 
@@ -994,9 +1032,7 @@ export class StylePropertiesSection {
994
1032
  private updateAncestorRuleList(): void {
995
1033
  this.#ancestorRuleListElement.removeChildren();
996
1034
  this.#ancestorClosingBracesElement.removeChildren();
997
- if (this.styleInternal.parentRule && this.styleInternal.parentRule instanceof SDK.CSSRule.CSSStyleRule) {
998
- this.createAncestorRules(this.styleInternal.parentRule);
999
- }
1035
+ this.maybeCreateAncestorRules(this.styleInternal);
1000
1036
  this.#styleRuleElement.style.paddingLeft = `${this.nestingLevel}ch`;
1001
1037
  }
1002
1038
 
@@ -1640,9 +1676,7 @@ export class BlankStylePropertiesSection extends StylePropertiesSection {
1640
1676
  this.selectorRefElement.removeChildren();
1641
1677
  this.selectorRefElement.appendChild(StylePropertiesSection.linkifyRuleLocation(
1642
1678
  cssModel, this.parentPane.linkifier, styleSheetHeader, this.actualRuleLocation()));
1643
- if (insertAfterStyle?.parentRule && insertAfterStyle.parentRule instanceof SDK.CSSRule.CSSStyleRule) {
1644
- this.createAncestorRules(insertAfterStyle.parentRule);
1645
- }
1679
+ this.maybeCreateAncestorRules(insertAfterStyle);
1646
1680
  this.element.classList.add('blank-section');
1647
1681
  }
1648
1682
 
@@ -1830,12 +1864,15 @@ export class FunctionRuleSection extends StylePropertiesSection {
1830
1864
  }
1831
1865
  }
1832
1866
 
1833
- export class FontPaletteValuesRuleSection extends StylePropertiesSection {
1867
+ export class AtRuleSection extends StylePropertiesSection {
1834
1868
  constructor(
1835
1869
  stylesPane: StylesSidebarPane, matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles,
1836
- style: SDK.CSSStyleDeclaration.CSSStyleDeclaration, sectionIdx: number) {
1870
+ style: SDK.CSSStyleDeclaration.CSSStyleDeclaration, sectionIdx: number, expandedByDefault: boolean) {
1837
1871
  super(stylesPane, matchedStyles, style, sectionIdx, null, null);
1838
1872
  this.selectorElement.className = 'font-palette-values-key';
1873
+ if (!expandedByDefault) {
1874
+ this.element.classList.add('hidden');
1875
+ }
1839
1876
  }
1840
1877
  }
1841
1878
 
@@ -1088,8 +1088,9 @@ export class LinkableNameRenderer extends rendererBase(SDK.CSSPropertyParserMatc
1088
1088
  return {
1089
1089
  jslogContext: 'css-font-palette',
1090
1090
  metric: null,
1091
- ruleBlock: '@font-palette-values',
1092
- isDefined: this.#matchedStyles.fontPaletteValuesRule()?.name().text === match.text,
1091
+ ruleBlock: '@font-*',
1092
+ isDefined: Boolean(this.#matchedStyles.atRules().find(
1093
+ ar => ar.type() === 'font-palette-values' && ar.name()?.text === match.text)),
1093
1094
  };
1094
1095
  case SDK.CSSPropertyParserMatchers.LinkableNameProperties.POSITION_TRY:
1095
1096
  case SDK.CSSPropertyParserMatchers.LinkableNameProperties.POSITION_TRY_FALLBACKS:
@@ -1111,7 +1112,11 @@ export class LinkableNameRenderer extends rendererBase(SDK.CSSPropertyParserMatc
1111
1112
  isDefined,
1112
1113
  onLinkActivate: (): void => {
1113
1114
  metric && Host.userMetrics.swatchActivated(metric);
1114
- this.#stylesPane.jumpToSectionBlock(`${ruleBlock} ${match.text}`);
1115
+ if (match.propertyName === SDK.CSSPropertyParserMatchers.LinkableNameProperties.FONT_PALETTE) {
1116
+ this.#stylesPane.jumpToFontPaletteDefinition(match.text);
1117
+ } else {
1118
+ this.#stylesPane.jumpToSectionBlock(`${ruleBlock} ${match.text}`);
1119
+ }
1115
1120
  },
1116
1121
  jslogContext,
1117
1122
  };
@@ -49,6 +49,7 @@ import * as InlineEditor from '../../ui/legacy/components/inline_editor/inline_e
49
49
  import * as Components from '../../ui/legacy/components/utils/utils.js';
50
50
  import * as UI from '../../ui/legacy/legacy.js';
51
51
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
52
+ import * as PanelsCommon from '../common/common.js';
52
53
 
53
54
  import * as ElementsComponents from './components/components.js';
54
55
  import type {ComputedStyleModel, CSSModelChangedEvent} from './ComputedStyleModel.js';
@@ -58,8 +59,8 @@ import {ImagePreviewPopover} from './ImagePreviewPopover.js';
58
59
  import * as LayersWidget from './LayersWidget.js';
59
60
  import {StyleEditorWidget} from './StyleEditorWidget.js';
60
61
  import {
62
+ AtRuleSection,
61
63
  BlankStylePropertiesSection,
62
- FontPaletteValuesRuleSection,
63
64
  FunctionRuleSection,
64
65
  HighlightPseudoStylePropertiesSection,
65
66
  KeyframePropertiesSection,
@@ -139,6 +140,8 @@ const MIN_FOLDED_SECTIONS_COUNT = 5;
139
140
  export const REGISTERED_PROPERTY_SECTION_NAME = '@property';
140
141
  /** Title of the function section **/
141
142
  export const FUNCTION_SECTION_NAME = '@function';
143
+ /** Title of the general at-rule section */
144
+ export const AT_RULE_SECTION_NAME = '@font-*';
142
145
 
143
146
  // Highlightable properties are those that can be hovered in the sidebar to trigger a specific
144
147
  // highlighting mode on the current element.
@@ -354,6 +357,10 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
354
357
  this.jumpToSection(functionName, FUNCTION_SECTION_NAME);
355
358
  }
356
359
 
360
+ jumpToFontPaletteDefinition(paletteName: string): void {
361
+ this.jumpToSection(`@font-palette-values ${paletteName}`, AT_RULE_SECTION_NAME);
362
+ }
363
+
357
364
  forceUpdate(): void {
358
365
  this.needsForceUpdate = true;
359
366
  this.#swatchPopoverHelper.hide();
@@ -1153,14 +1160,16 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1153
1160
  blocks.push(block);
1154
1161
  }
1155
1162
 
1156
- const fontPaletteValuesRule = matchedStyles.fontPaletteValuesRule();
1157
- if (fontPaletteValuesRule) {
1158
- const block = SectionBlock.createFontPaletteValuesRuleBlock(fontPaletteValuesRule.name().text);
1159
- this.idleCallbackManager.schedule(() => {
1160
- block.sections.push(
1161
- new FontPaletteValuesRuleSection(this, matchedStyles, fontPaletteValuesRule.style, sectionIdx));
1162
- sectionIdx++;
1163
- });
1163
+ const atRules = matchedStyles.atRules();
1164
+ if (atRules.length > 0) {
1165
+ const expandedByDefault = atRules.length <= MIN_FOLDED_SECTIONS_COUNT;
1166
+ const block = SectionBlock.createAtRuleBlock(expandedByDefault);
1167
+ for (const atRule of atRules) {
1168
+ this.idleCallbackManager.schedule(() => {
1169
+ block.sections.push(new AtRuleSection(this, matchedStyles, atRule.style, sectionIdx, expandedByDefault));
1170
+ sectionIdx++;
1171
+ });
1172
+ }
1164
1173
  blocks.push(block);
1165
1174
  }
1166
1175
 
@@ -1543,7 +1552,7 @@ export class SectionBlock {
1543
1552
  const pseudoArgumentString = pseudoArgument ? `(${pseudoArgument})` : '';
1544
1553
  const pseudoTypeString = `${pseudoType}${pseudoArgumentString}`;
1545
1554
  UI.UIUtils.createTextChild(separatorElement, i18nString(UIStrings.inheritedFromSPseudoOf, {PH1: pseudoTypeString}));
1546
- const link = await Common.Linkifier.Linkifier.linkify(node, {
1555
+ const link = PanelsCommon.DOMLinkifier.Linkifier.instance().linkify(node, {
1547
1556
  preventKeyboardFocus: true,
1548
1557
  tooltip: undefined,
1549
1558
  });
@@ -1575,11 +1584,12 @@ export class SectionBlock {
1575
1584
  return new SectionBlock(separatorElement);
1576
1585
  }
1577
1586
 
1578
- static createFontPaletteValuesRuleBlock(name: string): SectionBlock {
1587
+ static createAtRuleBlock(expandedByDefault: boolean): SectionBlock {
1579
1588
  const separatorElement = document.createElement('div');
1589
+ const block = new SectionBlock(separatorElement, true, expandedByDefault);
1580
1590
  separatorElement.className = 'sidebar-separator';
1581
- separatorElement.textContent = `@font-palette-values ${name}`;
1582
- return new SectionBlock(separatorElement);
1591
+ separatorElement.appendChild(document.createTextNode(AT_RULE_SECTION_NAME));
1592
+ return block;
1583
1593
  }
1584
1594
 
1585
1595
  static createPositionTryBlock(positionTryName: string): SectionBlock {
@@ -1595,7 +1605,7 @@ export class SectionBlock {
1595
1605
  separatorElement.className = 'sidebar-separator';
1596
1606
  separatorElement.setAttribute('jslog', `${VisualLogging.sectionHeader('inherited')}`);
1597
1607
  UI.UIUtils.createTextChild(separatorElement, i18nString(UIStrings.inheritedFroms));
1598
- const link = await Common.Linkifier.Linkifier.linkify(node, {
1608
+ const link = PanelsCommon.DOMLinkifier.Linkifier.instance().linkify(node, {
1599
1609
  preventKeyboardFocus: true,
1600
1610
  tooltip: undefined,
1601
1611
  });
@@ -7,6 +7,7 @@ import * as i18n from '../../core/i18n/i18n.js';
7
7
  import * as Root from '../../core/root/root.js';
8
8
  import * as SDK from '../../core/sdk/sdk.js';
9
9
  import * as UI from '../../ui/legacy/legacy.js';
10
+ import type * as PanelsCommon from '../common/common.js';
10
11
 
11
12
  import type * as Elements from './elements.js';
12
13
 
@@ -177,6 +178,14 @@ function maybeRetrieveContextTypes<T = unknown>(getClassCallBack: (elementsModul
177
178
  return getClassCallBack(loadedElementsModule);
178
179
  }
179
180
 
181
+ let loadedPanelsCommonModule: (typeof PanelsCommon|undefined);
182
+ async function loadPanelsCommonModule(): Promise<typeof PanelsCommon> {
183
+ if (!loadedPanelsCommonModule) {
184
+ loadedPanelsCommonModule = await import('../common/common.js');
185
+ }
186
+ return loadedPanelsCommonModule;
187
+ }
188
+
180
189
  UI.ViewManager.registerViewExtension({
181
190
  location: UI.ViewManager.ViewLocationValues.PANEL,
182
191
  id: 'elements',
@@ -698,7 +707,7 @@ Common.Linkifier.registerLinkifier({
698
707
  ];
699
708
  },
700
709
  async loadLinkifier() {
701
- const Elements = await loadElementsModule();
702
- return Elements.DOMLinkifier.Linkifier.instance();
710
+ const PanelsCommon = await loadPanelsCommonModule();
711
+ return PanelsCommon.DOMLinkifier.Linkifier.instance();
703
712
  },
704
713
  });
@@ -5,7 +5,6 @@
5
5
  import './InspectElementModeController.js';
6
6
  import './ColorSwatchPopoverIcon.js';
7
7
  import './ComputedStyleModel.js';
8
- import './DOMLinkifier.js';
9
8
  import './DOMPath.js';
10
9
  import './ElementsSidebarPane.js';
11
10
  import './ElementsTreeElement.js';
@@ -37,7 +36,6 @@ import * as ComputedStyleModel from './ComputedStyleModel.js';
37
36
  import * as ComputedStyleWidget from './ComputedStyleWidget.js';
38
37
  import * as CSSRuleValidator from './CSSRuleValidator.js';
39
38
  import * as CSSValueTraceView from './CSSValueTraceView.js';
40
- import * as DOMLinkifier from './DOMLinkifier.js';
41
39
  import * as DOMPath from './DOMPath.js';
42
40
  import * as ElementsPanel from './ElementsPanel.js';
43
41
  import * as ElementsSidebarPane from './ElementsSidebarPane.js';
@@ -73,7 +71,6 @@ export {
73
71
  ComputedStyleWidget,
74
72
  CSSRuleValidator,
75
73
  CSSValueTraceView,
76
- DOMLinkifier,
77
74
  DOMPath,
78
75
  ElementsPanel,
79
76
  ElementsSidebarPane,
@@ -196,7 +196,7 @@ interface ViewInput {
196
196
  callbacks: {
197
197
  onClose: () => void,
198
198
  onSearch: () => void,
199
- onRating: (event: Event) => void,
199
+ onRating: (isPositive: boolean) => void,
200
200
  onReport: () => void,
201
201
  onGoToSignIn: () => void,
202
202
  onConsentReminderConfirmed: () => Promise<void>,
@@ -209,6 +209,8 @@ interface ViewInput {
209
209
 
210
210
  interface ViewOutput {
211
211
  referenceDetailsRef: Lit.Directives.Ref<HTMLDetailsElement>;
212
+ headerRef: Lit.Directives.Ref<HTMLHeadingElement>;
213
+ citationLinks: HTMLElement[];
212
214
  }
213
215
 
214
216
  const enum State {
@@ -297,7 +299,7 @@ function renderLearnMoreAboutInsights(): Lit.TemplateResult {
297
299
  // clang-format on
298
300
  }
299
301
 
300
- function maybeRenderSources(directCitationUrls: string[]): Lit.LitTemplate {
302
+ function maybeRenderSources(directCitationUrls: string[], output: ViewOutput): Lit.LitTemplate {
301
303
  if (!directCitationUrls.length) {
302
304
  return Lit.nothing;
303
305
  }
@@ -310,8 +312,8 @@ function maybeRenderSources(directCitationUrls: string[]): Lit.LitTemplate {
310
312
  <x-link
311
313
  href=${url}
312
314
  class="link"
313
- data-index=${index + 1}
314
315
  jslog=${VisualLogging.link('references.console-insights').track({click: true})}
316
+ ${Directives.ref(e => { output.citationLinks[index] = e as HTMLElement; })}
315
317
  >
316
318
  ${url}
317
319
  </x-link>
@@ -376,7 +378,7 @@ function renderInsight(
376
378
  ${isSearchRagResponse(insight.metadata) ? html`
377
379
  <details class="references" ${Directives.ref(output.referenceDetailsRef)} @toggle=${callbacks.onToggleReferenceDetails} jslog=${VisualLogging.expand('references').track({click: true})}>
378
380
  <summary>${i18nString(UIStrings.references)}</summary>
379
- ${maybeRenderSources(insight.directCitationUrls)}
381
+ ${maybeRenderSources(insight.directCitationUrls, output)}
380
382
  ${maybeRenderRelatedContent(insight.relatedUrls, insight.directCitationUrls)}
381
383
  </details>
382
384
  ` : Lit.nothing}
@@ -557,7 +559,7 @@ function renderInsightFooter(noLogging: ViewInput['noLogging'], selectedRating:
557
559
  .toggled=${selectedRating === true}
558
560
  .title=${i18nString(UIStrings.goodResponse)}
559
561
  .jslogContext=${'thumbs-up'}
560
- @click=${callbacks.onRating}
562
+ @click=${() => callbacks.onRating(true)}
561
563
  ></devtools-button>
562
564
  <devtools-button
563
565
  data-rating="false"
@@ -571,7 +573,7 @@ function renderInsightFooter(noLogging: ViewInput['noLogging'], selectedRating:
571
573
  .toggled=${selectedRating === false}
572
574
  .title=${i18nString(UIStrings.badResponse)}
573
575
  .jslogContext=${'thumbs-down'}
574
- @click=${callbacks.onRating}
576
+ @click=${() => callbacks.onRating(false)}
575
577
  ></devtools-button>
576
578
  <devtools-button
577
579
  .iconName=${'report'}
@@ -602,13 +604,15 @@ interface HeaderInput {
602
604
  onClose: ViewInput['callbacks']['onClose'];
603
605
  }
604
606
 
605
- function renderHeader({headerText, showIcon = false, showSpinner = false, onClose}: HeaderInput): Lit.LitTemplate {
607
+ function renderHeader(
608
+ {headerText, showIcon = false, showSpinner = false, onClose}: HeaderInput,
609
+ headerRef: Lit.Directives.Ref<HTMLHeadingElement>): Lit.LitTemplate {
606
610
  // clang-format off
607
611
  return html`
608
612
  <header>
609
613
  ${showIcon ? renderHeaderIcon() : Lit.nothing}
610
614
  <div class="filler">
611
- <h2 tabindex="-1">
615
+ <h2 tabindex="-1" ${Directives.ref(headerRef)}>
612
616
  ${headerText}
613
617
  </h2>
614
618
  ${showSpinner ? html`<devtools-spinner></devtools-spinner>` : Lit.nothing}
@@ -644,7 +648,9 @@ export class ConsoleInsight extends HTMLElement {
644
648
 
645
649
  // Main state.
646
650
  #state: StateData;
647
- #referenceDetailsRef = Lit.Directives.createRef<HTMLDetailsElement>();
651
+ #referenceDetailsRef = Directives.createRef<HTMLDetailsElement>();
652
+ #headerRef = Directives.createRef<HTMLHeadingElement>();
653
+ #citationLinks: HTMLElement[] = [];
648
654
  #areReferenceDetailsOpen = false;
649
655
 
650
656
  // Rating sub-form state.
@@ -694,8 +700,7 @@ export class ConsoleInsight extends HTMLElement {
694
700
  this.#areReferenceDetailsOpen = true;
695
701
  this.#render();
696
702
 
697
- const highlightedElement =
698
- this.#shadow.querySelector(`.sources-list x-link[data-index="${index}"]`) as HTMLElement | null;
703
+ const highlightedElement = this.#citationLinks[index - 1];
699
704
  if (highlightedElement) {
700
705
  UI.UIUtils.runCSSAnimationOnce(highlightedElement, 'highlighted');
701
706
  if (areDetailsAlreadyExpanded) {
@@ -856,7 +861,7 @@ export class ConsoleInsight extends HTMLElement {
856
861
  this.classList.add('closing');
857
862
  }
858
863
 
859
- #onRating(event: Event): void {
864
+ #onRating(isPositive: boolean): void {
860
865
  if (this.#state.type !== State.INSIGHT) {
861
866
  throw new Error('Unexpected state');
862
867
  }
@@ -868,7 +873,7 @@ export class ConsoleInsight extends HTMLElement {
868
873
  return;
869
874
  }
870
875
 
871
- this.#selectedRating = (event.target as HTMLElement).dataset.rating === 'true';
876
+ this.#selectedRating = isPositive;
872
877
  this.#render();
873
878
  if (this.#selectedRating) {
874
879
  Host.userMetrics.actionTaken(Host.UserMetrics.Action.InsightRatedPositive);
@@ -1071,7 +1076,7 @@ export class ConsoleInsight extends HTMLElement {
1071
1076
 
1072
1077
  #focusHeader(): void {
1073
1078
  this.addEventListener('animationend', () => {
1074
- (this.#shadow.querySelector('header h2') as HTMLElement | undefined)?.focus();
1079
+ this.#headerRef.value?.focus();
1075
1080
  }, {once: true});
1076
1081
  }
1077
1082
 
@@ -1118,6 +1123,8 @@ export class ConsoleInsight extends HTMLElement {
1118
1123
  };
1119
1124
  const output: ViewOutput = {
1120
1125
  referenceDetailsRef: this.#referenceDetailsRef,
1126
+ headerRef: this.#headerRef,
1127
+ citationLinks: [],
1121
1128
  };
1122
1129
 
1123
1130
  // Future Widget view function starts here.
@@ -1132,21 +1139,23 @@ export class ConsoleInsight extends HTMLElement {
1132
1139
 
1133
1140
  switch (state.type) {
1134
1141
  case State.LOADING:
1135
- header = renderHeader({headerText: i18nString(UIStrings.generating), onClose});
1142
+ header = renderHeader({headerText: i18nString(UIStrings.generating), onClose}, output.headerRef);
1136
1143
  main = renderLoading();
1137
1144
  break;
1138
1145
  case State.INSIGHT:
1139
- header = renderHeader({headerText: i18nString(UIStrings.insight), onClose, showSpinner: !state.completed});
1146
+ header = renderHeader(
1147
+ {headerText: i18nString(UIStrings.insight), onClose, showSpinner: !state.completed}, output.headerRef);
1140
1148
  main = renderInsight(state, input.renderer, input.disableAnimations, callbacks, output);
1141
1149
  footer = renderInsightFooter(noLogging, input.selectedRating, callbacks);
1142
1150
  break;
1143
1151
  case State.ERROR:
1144
- header = renderHeader({headerText: i18nString(UIStrings.error), onClose});
1152
+ header = renderHeader({headerText: i18nString(UIStrings.error), onClose}, output.headerRef);
1145
1153
  main = renderError(i18nString(UIStrings.errorBody));
1146
1154
  footer = renderDisclaimerFooter(noLogging, onDisclaimerSettingsLink);
1147
1155
  break;
1148
1156
  case State.CONSENT_REMINDER:
1149
- header = renderHeader({headerText: 'Understand console messages with AI', onClose, showIcon: true});
1157
+ header = renderHeader(
1158
+ {headerText: 'Understand console messages with AI', onClose, showIcon: true}, output.headerRef);
1150
1159
  mainClasses['reminder-container'] = true;
1151
1160
  main = renderConsentReminder(noLogging);
1152
1161
  footer = renderConsentReminderFooter(callbacks.onReminderSettingsLink, callbacks.onConsentReminderConfirmed);
@@ -1157,12 +1166,12 @@ export class ConsoleInsight extends HTMLElement {
1157
1166
  break;
1158
1167
  case State.NOT_LOGGED_IN:
1159
1168
  case State.SYNC_IS_PAUSED:
1160
- header = renderHeader({headerText: i18nString(UIStrings.signInToUse), onClose});
1169
+ header = renderHeader({headerText: i18nString(UIStrings.signInToUse), onClose}, output.headerRef);
1161
1170
  main = renderNotLoggedIn();
1162
1171
  footer = renderSignInFooter(callbacks.onGoToSignIn);
1163
1172
  break;
1164
1173
  case State.OFFLINE:
1165
- header = renderHeader({headerText: i18nString(UIStrings.offlineHeader), onClose});
1174
+ header = renderHeader({headerText: i18nString(UIStrings.offlineHeader), onClose}, output.headerRef);
1166
1175
  main = renderError(i18nString(UIStrings.offline));
1167
1176
  footer = renderDisclaimerFooter(noLogging, onDisclaimerSettingsLink);
1168
1177
  break;
@@ -1188,6 +1197,8 @@ export class ConsoleInsight extends HTMLElement {
1188
1197
  });
1189
1198
  // clang-format on
1190
1199
 
1200
+ this.#citationLinks = output.citationLinks;
1201
+
1191
1202
  if (this.#referenceDetailsRef.value) {
1192
1203
  this.#referenceDetailsRef.value.open = this.#areReferenceDetailsOpen;
1193
1204
  }
@@ -17,6 +17,7 @@ import * as RequestLinkIcon from '../../ui/components/request_link_icon/request_
17
17
  import * as Components from '../../ui/legacy/components/utils/utils.js';
18
18
  import * as UI from '../../ui/legacy/legacy.js';
19
19
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
20
+ import * as PanelsCommon from '../common/common.js';
20
21
 
21
22
  import type {IssueView} from './IssueView.js';
22
23
 
@@ -230,7 +231,7 @@ export abstract class AffectedResourcesView extends UI.TreeOutline.TreeElement {
230
231
  }
231
232
 
232
233
  const deferredDOMNode = new SDK.DOMModel.DeferredDOMNode(target, backendNodeId);
233
- const anchorElement = (await Common.Linkifier.Linkifier.linkify(deferredDOMNode)) as HTMLElement;
234
+ const anchorElement = PanelsCommon.DOMLinkifier.Linkifier.instance().linkify(deferredDOMNode) as HTMLElement;
234
235
  anchorElement.textContent = nodeName;
235
236
  anchorElement.addEventListener('click', () => sendTelemetry());
236
237
  anchorElement.addEventListener('keydown', (event: Event) => {
@@ -13,6 +13,7 @@ import * as Components from '../../ui/legacy/components/utils/utils.js';
13
13
  import * as UI from '../../ui/legacy/legacy.js';
14
14
  import * as ThemeSupport from '../../ui/legacy/theme_support/theme_support.js';
15
15
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
16
+ import * as PanelsCommon from '../common/common.js';
16
17
 
17
18
  import type {
18
19
  NodeDetailsJSON, ReportJSON, RunnerResultArtifacts, SourceLocationDetailsJSON} from './LighthouseReporterTypes.js';
@@ -148,7 +149,7 @@ export class LighthouseReportRenderer {
148
149
  continue;
149
150
  }
150
151
 
151
- const element = await Common.Linkifier.Linkifier.linkify(
152
+ const element = PanelsCommon.DOMLinkifier.Linkifier.instance().linkify(
152
153
  node, {tooltip: detailsItem.snippet, preventKeyboardFocus: undefined});
153
154
  UI.Tooltip.Tooltip.install(origHTMLElement, '');
154
155
 
@@ -2484,7 +2484,7 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
2484
2484
  .replace(/"/g, '\\"')
2485
2485
  .replace(/[^a-zA-Z0-9\s_\-:=+~'\/.',?;()*`]/g, '^$&')
2486
2486
  .replace(/%(?=[a-zA-Z0-9_])/g, '%^')
2487
- .replace(/[^\S \r\n]/g, ' ')
2487
+ .replace(/[^ -~\r\n]/g, ' ')
2488
2488
  .replace(/\r?\n|\r/g, '^\n\n') +
2489
2489
  encapsChars;
2490
2490
  }
@@ -1179,7 +1179,13 @@ export class RecorderController extends LitElement {
1179
1179
  <div class="empty-state-header">${i18nString(UIStrings.header)}</div>
1180
1180
  <div class="empty-state-description">
1181
1181
  <span>${i18nString(UIStrings.recordingDescription)}</span>
1182
- ${UI.XLink.XLink.create(RECORDER_EXPLANATION_URL, i18nString(UIStrings.learnMore), 'x-link', undefined, 'learn-more')}
1182
+ <x-link
1183
+ class="x-link devtools-link"
1184
+ href=${RECORDER_EXPLANATION_URL}
1185
+ jslog=${VisualLogging.link()
1186
+ .track({ click: true, keydown: 'Enter|Space' })
1187
+ .context('learn-more')}
1188
+ >${i18nString(UIStrings.learnMore)}</x-link>
1183
1189
  </div>
1184
1190
  <devtools-button .variant=${Buttons.Button.Variant.TONAL} jslogContext=${Actions.RecorderActions.CREATE_RECORDING} @click=${this.#onCreateNewRecording}>${i18nString(UIStrings.createRecording)}</devtools-button>
1185
1191
  </div>