chrome-devtools-frontend 1.0.1544076 → 1.0.1545096

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 (67) hide show
  1. package/config/typescript/tsconfig.eslint.json +1 -0
  2. package/front_end/core/common/ParsedURL.ts +1 -1
  3. package/front_end/core/common/common.ts +0 -2
  4. package/front_end/core/protocol_client/CDPConnection.ts +3 -3
  5. package/front_end/core/protocol_client/DevToolsCDPConnection.ts +2 -1
  6. package/front_end/core/sdk/CSSMetadata.ts +17 -5
  7. package/front_end/core/sdk/NetworkManager.ts +6 -8
  8. package/front_end/core/sdk/NetworkRequest.ts +4 -0
  9. package/front_end/core/sdk/SDKModel.ts +4 -2
  10. package/front_end/core/sdk/TargetManager.ts +14 -15
  11. package/front_end/generated/Deprecation.ts +4 -0
  12. package/front_end/generated/InspectorBackendCommands.ts +2 -5
  13. package/front_end/generated/SupportedCSSProperties.js +0 -23
  14. package/front_end/generated/protocol-mapping.d.ts +0 -15
  15. package/front_end/generated/protocol-proxy-api.d.ts +0 -11
  16. package/front_end/generated/protocol.ts +2 -34
  17. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +2 -1
  18. package/front_end/panels/ai_assistance/components/UserActionRow.ts +2 -1
  19. package/front_end/panels/application/ApplicationPanelSidebar.ts +6 -7
  20. package/front_end/panels/application/{components/FrameDetailsView.ts → FrameDetailsView.ts} +134 -165
  21. package/front_end/panels/application/{components/OriginTrialTreeView.ts → OriginTrialTreeView.ts} +9 -9
  22. package/front_end/panels/application/application.ts +4 -0
  23. package/front_end/panels/application/components/StackTrace.ts +5 -3
  24. package/front_end/panels/application/components/components.ts +2 -4
  25. package/front_end/panels/application/{components/frameDetailsReportView.css → frameDetailsReportView.css} +5 -1
  26. package/front_end/panels/common/BadgeNotification.ts +2 -1
  27. package/front_end/panels/common/DOMLinkifier.ts +7 -2
  28. package/front_end/panels/common/GdpSignUpDialog.ts +2 -1
  29. package/front_end/panels/elements/ElementStatePaneWidget.ts +2 -1
  30. package/front_end/panels/elements/StylePropertiesSection.ts +1 -1
  31. package/front_end/panels/elements/elements-meta.ts +0 -22
  32. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +3 -6
  33. package/front_end/panels/settings/FrameworkIgnoreListSettingsTab.ts +2 -1
  34. package/front_end/panels/settings/SettingsScreen.ts +3 -2
  35. package/front_end/panels/timeline/components/LiveMetricsView.ts +14 -5
  36. package/front_end/panels/timeline/components/MetricCard.ts +2 -2
  37. package/front_end/panels/timeline/components/insights/NodeLink.ts +2 -3
  38. package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +2 -1
  39. package/front_end/panels/timeline/timeline-meta.ts +0 -10
  40. package/front_end/panels/timeline/timeline.ts +0 -2
  41. package/front_end/panels/whats_new/ReleaseNoteView.ts +2 -1
  42. package/front_end/panels/whats_new/WhatsNewImpl.ts +3 -2
  43. package/front_end/third_party/chromium/README.chromium +1 -1
  44. package/front_end/tsconfig.json +1 -0
  45. package/front_end/ui/components/buttons/Button.docs.ts +6 -5
  46. package/front_end/ui/components/snackbars/Snackbars.docs.ts +1 -1
  47. package/front_end/ui/components/spinners/Spinners.docs.ts +1 -1
  48. package/front_end/ui/components/survey_link/SurveyLink.docs.ts +2 -1
  49. package/front_end/ui/components/switch/Switch.docs.ts +1 -1
  50. package/front_end/ui/components/tooltips/Tooltip.docs.ts +3 -3
  51. package/front_end/ui/helpers/OpenInNewTab.ts +87 -0
  52. package/front_end/ui/helpers/helpers.ts +5 -0
  53. package/front_end/ui/legacy/ContextMenu.docs.ts +12 -11
  54. package/front_end/ui/legacy/RadioButton.docs.ts +1 -1
  55. package/front_end/ui/legacy/SelectMenu.docs.ts +1 -1
  56. package/front_end/ui/legacy/Slider.docs.ts +1 -1
  57. package/front_end/ui/legacy/UIUtils.ts +0 -33
  58. package/front_end/ui/legacy/XLink.ts +4 -4
  59. package/front_end/ui/legacy/components/color_picker/ContrastDetails.ts +2 -1
  60. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +144 -143
  61. package/front_end/ui/legacy/components/utils/Linkifier.ts +2 -1
  62. package/mcp/tsconfig.json +16 -0
  63. package/package.json +2 -2
  64. package/front_end/core/common/Linkifier.ts +0 -55
  65. package/front_end/panels/timeline/CLSLinkifier.ts +0 -58
  66. /package/front_end/panels/application/{components/originTrialTokenRows.css → originTrialTokenRows.css} +0 -0
  67. /package/front_end/panels/application/{components/originTrialTreeView.css → originTrialTreeView.css} +0 -0
@@ -5,6 +5,7 @@
5
5
  import * as i18n from '../../core/i18n/i18n.js';
6
6
  import * as SDK from '../../core/sdk/sdk.js';
7
7
  import * as Buttons from '../../ui/components/buttons/buttons.js';
8
+ import * as UIHelpers from '../../ui/helpers/helpers.js';
8
9
  import * as UI from '../../ui/legacy/legacy.js';
9
10
  import {html, render, type TemplateResult} from '../../ui/lit/lit.js';
10
11
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
@@ -108,7 +109,7 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
108
109
  jslog=${VisualLogging.toggle('emulate-page-focus').track({change: true})} ${bindToSetting('emulate-page-focus')}>${
109
110
  i18nString(UIStrings.emulateFocusedPage)}</devtools-checkbox>
110
111
  <devtools-button
111
- @click=${() => UI.UIUtils.openInNewTab('https://developer.chrome.com/docs/devtools/rendering/apply-effects#emulate_a_focused_page')}
112
+ @click=${() => UIHelpers.openInNewTab('https://developer.chrome.com/docs/devtools/rendering/apply-effects#emulate_a_focused_page')}
112
113
  .data=${{
113
114
  variant: Buttons.Button.Variant.ICON,
114
115
  iconName: 'help',
@@ -839,7 +839,7 @@ export class StylePropertiesSection {
839
839
 
840
840
  this.#ancestorRuleListElement.prepend(atRuleElement);
841
841
  this.#ancestorClosingBracesElement.prepend(this.indentElement(this.createClosingBrace(), 0));
842
- this.nestingLevel++;
842
+ this.nestingLevel = 1;
843
843
  }
844
844
  }
845
845
 
@@ -7,7 +7,6 @@ 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';
11
10
 
12
11
  import type * as Elements from './elements.js';
13
12
 
@@ -178,14 +177,6 @@ function maybeRetrieveContextTypes<T = unknown>(getClassCallBack: (elementsModul
178
177
  return getClassCallBack(loadedElementsModule);
179
178
  }
180
179
 
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
-
189
180
  UI.ViewManager.registerViewExtension({
190
181
  location: UI.ViewManager.ViewLocationValues.PANEL,
191
182
  id: 'elements',
@@ -698,16 +689,3 @@ UI.UIUtils.registerRenderer({
698
689
  return Elements.ElementsTreeOutlineRenderer.Renderer.instance();
699
690
  },
700
691
  });
701
-
702
- Common.Linkifier.registerLinkifier({
703
- contextTypes() {
704
- return [
705
- SDK.DOMModel.DOMNode,
706
- SDK.DOMModel.DeferredDOMNode,
707
- ];
708
- },
709
- async loadLinkifier() {
710
- const PanelsCommon = await loadPanelsCommonModule();
711
- return PanelsCommon.DOMLinkifier.Linkifier.instance();
712
- },
713
- });
@@ -275,12 +275,9 @@ export class ProtocolService implements ProtocolClient.CDPConnection.CDPConnecti
275
275
  // Instead, we ignore the ID coming from the worker when sending the command, but
276
276
  // patch it back in when sending the response back to the worker.
277
277
  void this.connection?.send(method, params, sessionId).then(response => {
278
- this.dispatchProtocolMessage({
279
- id,
280
- sessionId,
281
- result: 'result' in response ? response.result : undefined,
282
- error: 'error' in response ? response.error : undefined,
283
- });
278
+ const message =
279
+ 'result' in response ? {id, sessionId, result: response.result} : {id, sessionId, error: response.error};
280
+ this.dispatchProtocolMessage(message);
284
281
  });
285
282
  }
286
283
 
@@ -8,6 +8,7 @@ import '../../ui/components/cards/cards.js';
8
8
  import * as Common from '../../core/common/common.js';
9
9
  import * as i18n from '../../core/i18n/i18n.js';
10
10
  import * as Buttons from '../../ui/components/buttons/buttons.js';
11
+ import * as UIHelpers from '../../ui/helpers/helpers.js';
11
12
  import * as SettingsUI from '../../ui/legacy/components/settings_ui/settings_ui.js';
12
13
  import * as UI from '../../ui/legacy/legacy.js';
13
14
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
@@ -144,7 +145,7 @@ export class FrameworkIgnoreListSettingsTab extends UI.Widget.VBox implements
144
145
  };
145
146
  automaticallyIgnoreLinkButton.addEventListener(
146
147
  'click',
147
- () => UI.UIUtils.openInNewTab(
148
+ () => UIHelpers.openInNewTab(
148
149
  'https://developer.chrome.com/docs/devtools/settings/ignore-list/#skip-third-party'));
149
150
  automaticallyIgnoreListContainer.appendChild(automaticallyIgnoreLinkButton);
150
151
 
@@ -14,6 +14,7 @@ import * as Root from '../../core/root/root.js';
14
14
  import * as Buttons from '../../ui/components/buttons/buttons.js';
15
15
  import type * as Cards from '../../ui/components/cards/cards.js';
16
16
  import * as IconButton from '../../ui/components/icon_button/icon_button.js';
17
+ import * as UIHelpers from '../../ui/helpers/helpers.js';
17
18
  import * as SettingsUI from '../../ui/legacy/components/settings_ui/settings_ui.js';
18
19
  import * as Components from '../../ui/legacy/components/utils/utils.js';
19
20
  import * as UI from '../../ui/legacy/legacy.js';
@@ -497,7 +498,7 @@ export class ExperimentsSettingsTab extends UI.Widget.VBox implements SettingsTa
497
498
  jslogContext: `${experiment.name}-documentation`,
498
499
  title: i18nString(UIStrings.learnMore),
499
500
  };
500
- linkButton.addEventListener('click', () => UI.UIUtils.openInNewTab(experimentLink));
501
+ linkButton.addEventListener('click', () => UIHelpers.openInNewTab(experimentLink));
501
502
  linkButton.classList.add('link-icon');
502
503
 
503
504
  p.appendChild(linkButton);
@@ -542,7 +543,7 @@ export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
542
543
  void SettingsScreen.showSettingsScreen({focusTabHeader: true} as ShowSettingsScreenOptions);
543
544
  return true;
544
545
  case 'settings.documentation':
545
- UI.UIUtils.openInNewTab('https://developer.chrome.com/docs/devtools/');
546
+ UIHelpers.openInNewTab('https://developer.chrome.com/docs/devtools/');
546
547
  return true;
547
548
  case 'settings.shortcuts':
548
549
  void SettingsScreen.showSettingsScreen({name: 'keybinds', focusTabHeader: true});
@@ -41,6 +41,7 @@ import metricValueStyles from './metricValueStyles.css.js';
41
41
  import {CLS_THRESHOLDS, INP_THRESHOLDS, renderMetricValue} from './Utils.js';
42
42
 
43
43
  const {html, nothing} = Lit;
44
+ const {widgetConfig} = UI.Widget;
44
45
 
45
46
  type DeviceOption = CrUXManager.DeviceScope|'AUTO';
46
47
 
@@ -475,7 +476,10 @@ export class LiveMetricsView extends LegacyWrapper.LegacyWrapper.WrappableCompon
475
476
  ${nodeLink ? html`
476
477
  <div class="related-info" slot="extra-info">
477
478
  <span class="related-info-label">${i18nString(UIStrings.lcpElement)}</span>
478
- <span class="related-info-link">${nodeLink}</span>
479
+ <span class="related-info-link">
480
+ <devtools-widget .widgetConfig=${widgetConfig(PanelsCommon.DOMLinkifier.DOMNodeLink, {node: this.#lcpValue?.nodeRef})}>
481
+ </devtools-widget>
482
+ </span>
479
483
  </div>
480
484
  `
481
485
  : nothing}
@@ -638,7 +642,7 @@ export class LiveMetricsView extends LegacyWrapper.LegacyWrapper.WrappableCompon
638
642
  </ul>
639
643
  ` : nothing}
640
644
  <div class="environment-option">
641
- <devtools-widget .widgetConfig=${UI.Widget.widgetConfig(CPUThrottlingSelector, {recommendedOption: recs.cpuOption})}></devtools-widget>
645
+ <devtools-widget .widgetConfig=${widgetConfig(CPUThrottlingSelector, {recommendedOption: recs.cpuOption})}></devtools-widget>
642
646
  </div>
643
647
  <div class="environment-option">
644
648
  <devtools-network-throttling-selector .recommendedConditions=${recs.networkConditions}></devtools-network-throttling-selector>
@@ -948,7 +952,6 @@ export class LiveMetricsView extends LegacyWrapper.LegacyWrapper.WrappableCompon
948
952
 
949
953
  const isP98Excluded = this.#inpValue && this.#inpValue.value < interaction.duration;
950
954
  const isInp = this.#inpValue?.interactionId === interaction.interactionId;
951
- const nodeLink = interaction.nodeRef ? PanelsCommon.DOMLinkifier.Linkifier.instance().linkify(interaction.nodeRef) : Lit.nothing;
952
955
 
953
956
  return html`
954
957
  <li id=${interaction.interactionId} class="log-item interaction" tabindex="-1">
@@ -959,7 +962,10 @@ export class LiveMetricsView extends LegacyWrapper.LegacyWrapper.WrappableCompon
959
962
  html`<span class="interaction-inp-chip" title=${i18nString(UIStrings.inpInteraction)}>INP</span>`
960
963
  : nothing}
961
964
  </span>
962
- <span class="interaction-node">${nodeLink}</span>
965
+ <span class="interaction-node">
966
+ <devtools-widget .widgetConfig=${widgetConfig(PanelsCommon.DOMLinkifier.DOMNodeLink, {node: interaction.nodeRef})}>
967
+ </devtools-widget>
968
+ </span>
963
969
  ${isP98Excluded ? html`<devtools-icon
964
970
  class="interaction-info"
965
971
  name="info"
@@ -1066,7 +1072,10 @@ export class LiveMetricsView extends LegacyWrapper.LegacyWrapper.WrappableCompon
1066
1072
  <div class="layout-shift-score">Layout shift score: ${metricValue}</div>
1067
1073
  <div class="layout-shift-nodes">
1068
1074
  ${layoutShift.affectedNodeRefs.map(node => html`
1069
- <div class="layout-shift-node">${PanelsCommon.DOMLinkifier.Linkifier.instance().linkify(node)}</div>
1075
+ <div class="layout-shift-node">
1076
+ <devtools-widget .widgetConfig=${widgetConfig(PanelsCommon.DOMLinkifier.DOMNodeLink, {node})}>
1077
+ </devtools-widget>
1078
+ </div>
1070
1079
  `)}
1071
1080
  </div>
1072
1081
  </li>
@@ -9,7 +9,7 @@ import * as CrUXManager from '../../../models/crux-manager/crux-manager.js';
9
9
  import type * as Trace from '../../../models/trace/trace.js';
10
10
  import * as Buttons from '../../../ui/components/buttons/buttons.js';
11
11
  import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
12
- import * as UI from '../../../ui/legacy/legacy.js';
12
+ import * as UIHelpers from '../../../ui/helpers/helpers.js';
13
13
  import * as Lit from '../../../ui/lit/lit.js';
14
14
 
15
15
  import metricCardStyles from './metricCard.css.js';
@@ -622,7 +622,7 @@ export class MetricCard extends HTMLElement {
622
622
  title=${this.#getHelpTooltip()}
623
623
  .iconName=${'help'}
624
624
  .variant=${Buttons.Button.Variant.ICON}
625
- @click=${() => UI.UIUtils.openInNewTab(helpLink)}
625
+ @click=${() => UIHelpers.openInNewTab(helpLink)}
626
626
  ></devtools-button>
627
627
  </h3>
628
628
  <div tabindex="0" class="metric-values-section"
@@ -5,7 +5,6 @@
5
5
 
6
6
  // TODO: move to ui/components/node_link?
7
7
 
8
- import type * as Common from '../../../../core/common/common.js';
9
8
  import type * as Platform from '../../../../core/platform/platform.js';
10
9
  import * as SDK from '../../../../core/sdk/sdk.js';
11
10
  import type * as Protocol from '../../../../generated/protocol.js';
@@ -20,7 +19,7 @@ const {html} = Lit;
20
19
  export interface NodeLinkData {
21
20
  backendNodeId: Protocol.DOM.BackendNodeId;
22
21
  frame: string;
23
- options?: Common.Linkifier.Options;
22
+ options?: PanelsCommon.DOMLinkifier.Options;
24
23
  /**
25
24
  * URL to display if backendNodeId cannot be resolved (ie for traces loaded from disk).
26
25
  * Will be given to linkifyURL. Use this or one of the other fallback fields.
@@ -42,7 +41,7 @@ export class NodeLink extends HTMLElement {
42
41
  readonly #shadow = this.attachShadow({mode: 'open'});
43
42
  #backendNodeId?: Protocol.DOM.BackendNodeId;
44
43
  #frame?: string;
45
- #options?: Common.Linkifier.Options;
44
+ #options?: PanelsCommon.DOMLinkifier.Options;
46
45
  #fallbackUrl?: Platform.DevToolsPath.UrlString;
47
46
  #fallbackHtmlSnippet?: string;
48
47
  #fallbackText?: string;
@@ -15,6 +15,7 @@ import * as Root from '../../../../core/root/root.js';
15
15
  import * as AiAssistanceModels from '../../../../models/ai_assistance/ai_assistance.js';
16
16
  import * as Buttons from '../../../../ui/components/buttons/buttons.js';
17
17
  import * as ComponentHelpers from '../../../../ui/components/helpers/helpers.js';
18
+ import * as UIHelpers from '../../../../ui/helpers/helpers.js';
18
19
  import * as UI from '../../../../ui/legacy/legacy.js';
19
20
  import * as ThemeSupport from '../../../../ui/legacy/theme_support/theme_support.js';
20
21
  import * as Lit from '../../../../ui/lit/lit.js';
@@ -574,7 +575,7 @@ export class EntryLabelOverlay extends HTMLElement {
574
575
  },
575
576
  ],
576
577
  onLearnMoreClick: () => {
577
- UI.UIUtils.openInNewTab('https://developer.chrome.com/docs/devtools/performance/annotations#auto-annotations');
578
+ UIHelpers.openInNewTab('https://developer.chrome.com/docs/devtools/performance/annotations#auto-annotations');
578
579
  },
579
580
  learnMoreButtonText: UIStringsNotTranslate.learnMoreButton,
580
581
  });
@@ -323,16 +323,6 @@ Common.Settings.registerSettingExtension({
323
323
  defaultValue: false,
324
324
  });
325
325
 
326
- Common.Linkifier.registerLinkifier({
327
- contextTypes() {
328
- return maybeRetrieveContextTypes(Timeline => [Timeline.CLSLinkifier.CLSRect]);
329
- },
330
- async loadLinkifier() {
331
- const Timeline = await loadTimelineModule();
332
- return Timeline.CLSLinkifier.Linkifier.instance();
333
- },
334
- });
335
-
336
326
  UI.ContextMenu.registerItem({
337
327
  location: UI.ContextMenu.ItemLocation.TIMELINE_MENU_OPEN,
338
328
  actionId: 'timeline.load-from-file',
@@ -6,7 +6,6 @@ import * as AnimationsTrackAppender from './AnimationsTrackAppender.js';
6
6
  import * as AnnotationHelpers from './AnnotationHelpers.js';
7
7
  import * as AppenderUtils from './AppenderUtils.js';
8
8
  import * as BenchmarkEvents from './BenchmarkEvents.js';
9
- import * as CLSLinkifier from './CLSLinkifier.js';
10
9
  import * as CompatibilityTracksAppender from './CompatibilityTracksAppender.js';
11
10
  import * as CountersGraph from './CountersGraph.js';
12
11
  import * as EntriesFilter from './EntriesFilter.js';
@@ -51,7 +50,6 @@ export {
51
50
  AnnotationHelpers,
52
51
  AppenderUtils,
53
52
  BenchmarkEvents,
54
- CLSLinkifier,
55
53
  CompatibilityTracksAppender,
56
54
  CountersGraph,
57
55
  EntriesFilter,
@@ -8,6 +8,7 @@ import * as i18n from '../../core/i18n/i18n.js';
8
8
  import type * as Platform from '../../core/platform/platform.js';
9
9
  import * as Marked from '../../third_party/marked/marked.js';
10
10
  import * as Buttons from '../../ui/components/buttons/buttons.js';
11
+ import * as UIHelpers from '../../ui/helpers/helpers.js';
11
12
  import * as UI from '../../ui/legacy/legacy.js';
12
13
  import {html, render} from '../../ui/lit/lit.js';
13
14
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
@@ -131,7 +132,7 @@ export class ReleaseNoteView extends UI.Panel.Panel {
131
132
  this.#view(
132
133
  {
133
134
  getReleaseNote,
134
- openNewTab: UI.UIUtils.openInNewTab,
135
+ openNewTab: UIHelpers.openInNewTab,
135
136
  markdownContent,
136
137
  getThumbnailPath: this.#getThumbnailPath,
137
138
  },
@@ -4,6 +4,7 @@
4
4
 
5
5
  import * as Common from '../../core/common/common.js';
6
6
  import * as Host from '../../core/host/host.js';
7
+ import * as UIHelpers from '../../ui/helpers/helpers.js';
7
8
  import * as UI from '../../ui/legacy/legacy.js';
8
9
 
9
10
  import {getReleaseNote} from './ReleaseNoteText.js';
@@ -69,7 +70,7 @@ let releaseNotesActionDelegateInstance: ReleaseNotesActionDelegate;
69
70
  export class ReleaseNotesActionDelegate implements UI.ActionRegistration.ActionDelegate {
70
71
  handleAction(_context: UI.Context.Context, _actionId: string): boolean {
71
72
  const releaseNote = getReleaseNote();
72
- UI.UIUtils.openInNewTab(releaseNote.link);
73
+ UIHelpers.openInNewTab(releaseNote.link);
73
74
  return true;
74
75
  }
75
76
  static instance(opts: {forceNew: boolean|null} = {forceNew: null}): ReleaseNotesActionDelegate {
@@ -85,7 +86,7 @@ export class ReleaseNotesActionDelegate implements UI.ActionRegistration.ActionD
85
86
  let reportIssueActionDelegateInstance: ReportIssueActionDelegate;
86
87
  export class ReportIssueActionDelegate implements UI.ActionRegistration.ActionDelegate {
87
88
  handleAction(_context: UI.Context.Context, _actionId: string): boolean {
88
- UI.UIUtils.openInNewTab('https://goo.gle/devtools-bug');
89
+ UIHelpers.openInNewTab('https://goo.gle/devtools-bug');
89
90
  return true;
90
91
  }
91
92
  static instance(opts: {forceNew: boolean|null} = {forceNew: null}): ReportIssueActionDelegate {
@@ -1,7 +1,7 @@
1
1
  Name: Dependencies sourced from the upstream `chromium` repository
2
2
  URL: https://chromium.googlesource.com/chromium/src
3
3
  Version: N/A
4
- Revision: 3e8720c1c3a43f134e2008e1764e70380a5b8bc1
4
+ Revision: ee4cd283ea61d6cd89c8035af63ff05876860e3a
5
5
  Update Mechanism: Manual (https://crbug.com/428069060)
6
6
  License: BSD-3-Clause
7
7
  License File: LICENSE
@@ -3,6 +3,7 @@
3
3
  "compilerOptions": {
4
4
  "allowUmdGlobalAccess": true,
5
5
  "outDir": "ignored",
6
+ "rootDir": ".",
6
7
  "target": "ES2023",
7
8
  "lib": [
8
9
  "ES2023",
@@ -4,10 +4,11 @@
4
4
 
5
5
  import {Button, FloatingButton} from './buttons.js';
6
6
 
7
- export async function render(container: HTMLElement) {
7
+ export function render(container: HTMLElement) {
8
+ const buttonDocs = container.createChild('div', 'button-docs');
8
9
  const style = document.createElement('style');
9
10
  style.textContent = `
10
- #container > div {
11
+ .button-docs > div {
11
12
  width: 80%;
12
13
  padding: var(--sys-size-11);
13
14
  display: flex;
@@ -16,13 +17,13 @@ export async function render(container: HTMLElement) {
16
17
  gap: var(--sys-size-5);
17
18
  }
18
19
  `;
19
- container.appendChild(style);
20
+ buttonDocs.appendChild(style);
20
21
 
21
22
  const appendSection = (headerText: string, sectionElement: HTMLElement) => {
22
23
  const header = document.createElement('header');
23
24
  header.textContent = headerText;
24
- container.appendChild(header);
25
- container.appendChild(sectionElement);
25
+ buttonDocs.appendChild(header);
26
+ buttonDocs.appendChild(sectionElement);
26
27
  };
27
28
 
28
29
  const buttonsSection = document.createElement('div');
@@ -4,7 +4,7 @@
4
4
 
5
5
  import {Snackbar} from './snackbars.js';
6
6
 
7
- export async function render(container: HTMLElement) {
7
+ export function render(container: HTMLElement) {
8
8
  const onActionClick = (): void => {
9
9
  // eslint-disable-next-line no-console
10
10
  console.log('Action button clicked!');
@@ -8,6 +8,6 @@ import * as Lit from '../../lit/lit.js';
8
8
 
9
9
  const {html} = Lit;
10
10
 
11
- export async function render(container: HTMLElement) {
11
+ export function render(container: HTMLElement) {
12
12
  Lit.render(html`<devtools-spinner></devtools-spinner>`, container);
13
13
  }
@@ -3,7 +3,8 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import * as Common from '../../../core/common/common.js';
6
- import {SurveyLink} from '../survey_link/survey_link.js';
6
+
7
+ import {SurveyLink} from './survey_link.js';
7
8
 
8
9
  export function render(container: HTMLElement): void {
9
10
  const link = new SurveyLink.SurveyLink();
@@ -4,7 +4,7 @@
4
4
 
5
5
  import {Switch} from './switch.js';
6
6
 
7
- export async function render(container: HTMLElement) {
7
+ export function render(container: HTMLElement) {
8
8
  function switchExample({checked, disabled}: {checked: boolean, disabled: boolean}): HTMLElement {
9
9
  const example = document.createElement('div');
10
10
  example.style.marginTop = '20px';
@@ -4,11 +4,11 @@
4
4
 
5
5
  import * as Lit from '../../lit/lit.js';
6
6
 
7
- import {Tooltip} from './Tooltip.js';
7
+ import {Tooltip} from './tooltips.js';
8
8
 
9
9
  const {html} = Lit;
10
10
 
11
- export async function render(container: HTMLElement) {
11
+ export function render(container: HTMLElement) {
12
12
  Lit.render(
13
13
  html`
14
14
  <div style="position: relative; z-index: 0;">
@@ -44,7 +44,7 @@ export async function render(container: HTMLElement) {
44
44
  container);
45
45
 
46
46
  const anchor = container.querySelector('.anchor') as HTMLElement;
47
- const programmaticTooltip = new Tooltip({id: 'programatic', variant: 'rich', anchor});
47
+ const programmaticTooltip = new Tooltip.Tooltip({id: 'programatic', variant: 'rich', anchor});
48
48
  programmaticTooltip.append('Text content');
49
49
  anchor.insertAdjacentElement('afterend', programmaticTooltip);
50
50
 
@@ -0,0 +1,87 @@
1
+ // Copyright 2021 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ /*
6
+ * Copyright (C) 2011 Google Inc. All rights reserved.
7
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
8
+ * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
9
+ * Copyright (C) 2009 Joseph Pecoraro
10
+ *
11
+ * Redistribution and use in source and binary forms, with or without
12
+ * modification, are permitted provided that the following conditions
13
+ * are met:
14
+ *
15
+ * 1. Redistributions of source code must retain the above copyright
16
+ * notice, this list of conditions and the following disclaimer.
17
+ * 2. Redistributions in binary form must reproduce the above copyright
18
+ * notice, this list of conditions and the following disclaimer in the
19
+ * documentation and/or other materials provided with the distribution.
20
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
21
+ * its contributors may be used to endorse or promote products derived
22
+ * from this software without specific prior written permission.
23
+ *
24
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
25
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
28
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ */
35
+
36
+ import * as Common from '../../core/common/common.js';
37
+ import * as Host from '../../core/host/host.js';
38
+ import * as Platform from '../../core/platform/platform.js';
39
+ import * as Root from '../../core/root/root.js';
40
+ import * as SDK from '../../core/sdk/sdk.js';
41
+
42
+ /**
43
+ * Opens the given `url` in a new Chrome tab.
44
+ *
45
+ * If the `url` is a Google owned documentation page (currently that includes
46
+ * `web.dev`, `developers.google.com`, and `developer.chrome.com`), the `url`
47
+ * will also be checked for UTM parameters:
48
+ *
49
+ * - If no `utm_source` search parameter is present, this method will add a new
50
+ * search parameter `utm_source=devtools` to `url`.
51
+ * - If no `utm_campaign` search parameter is present, and DevTools is running
52
+ * within a branded build, this method will add `utm_campaign=<channel>` to
53
+ * the search parameters, with `<channel>` being the release channel of
54
+ * Chrome ("stable", "beta", "dev", or "canary").
55
+ *
56
+ * @param url the URL to open in a new tab.
57
+ * @throws TypeError if `url` is not a valid URL.
58
+ * @see https://en.wikipedia.org/wiki/UTM_parameters
59
+ */
60
+ export function openInNewTab(url: URL|string): void {
61
+ url = new URL(`${url}`);
62
+ // Navigating to a chrome:// link via a normal anchor doesn't work, so we "navigate"
63
+ // there using CDP.
64
+ if (Common.ParsedURL.schemeIs(url, 'chrome:')) {
65
+ const rootTarget = SDK.TargetManager.TargetManager.instance().rootTarget();
66
+ if (rootTarget === null) {
67
+ return;
68
+ }
69
+
70
+ void rootTarget.targetAgent().invoke_createTarget({url: url.toString()}).then(result => {
71
+ if (result.getError()) {
72
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.openInNewTab(Platform.DevToolsPath.urlString`${url}`);
73
+ }
74
+ });
75
+ } else {
76
+ if (['developer.chrome.com', 'developers.google.com', 'web.dev'].includes(url.hostname)) {
77
+ if (!url.searchParams.has('utm_source')) {
78
+ url.searchParams.append('utm_source', 'devtools');
79
+ }
80
+ const {channel} = Root.Runtime.hostConfig;
81
+ if (!url.searchParams.has('utm_campaign') && typeof channel === 'string') {
82
+ url.searchParams.append('utm_campaign', channel);
83
+ }
84
+ }
85
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.openInNewTab(Platform.DevToolsPath.urlString`${url}`);
86
+ }
87
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright 2025 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ export {openInNewTab} from './OpenInNewTab.js';
@@ -8,10 +8,11 @@ import {ContextMenu} from './legacy.js';
8
8
 
9
9
  const {html} = Lit;
10
10
 
11
- export async function render(container: HTMLElement) {
11
+ export function render(container: HTMLElement) {
12
+ const menuDocs = container.createChild('div', 'menu-docs');
12
13
  const style = document.createElement('style');
13
14
  style.textContent = `
14
- #container > div {
15
+ .menu-docs > div {
15
16
  width: var(--sys-size-34);
16
17
  padding: var(--sys-size-11);
17
18
  display: flex;
@@ -27,13 +28,13 @@ export async function render(container: HTMLElement) {
27
28
  }
28
29
  }
29
30
  `;
30
- container.appendChild(style);
31
+ menuDocs.appendChild(style);
31
32
 
32
33
  const menuButtonSection = document.createElement('div');
33
34
  const menuButtonHeader = document.createElement('header');
34
35
  menuButtonHeader.textContent = 'DevTools menu button (lit-html)';
35
- container.appendChild(menuButtonHeader);
36
- container.appendChild(menuButtonSection);
36
+ menuDocs.appendChild(menuButtonHeader);
37
+ menuDocs.appendChild(menuButtonSection);
37
38
 
38
39
  Lit.render(
39
40
  html`
@@ -53,8 +54,8 @@ export async function render(container: HTMLElement) {
53
54
  simpleItemsSection.innerHTML = '<p>Right-click here</p>';
54
55
  const simpleItemsHeader = document.createElement('header');
55
56
  simpleItemsHeader.textContent = 'Various simple menu items (imperative API)';
56
- container.appendChild(simpleItemsHeader);
57
- container.appendChild(simpleItemsSection);
57
+ menuDocs.appendChild(simpleItemsHeader);
58
+ menuDocs.appendChild(simpleItemsSection);
58
59
 
59
60
  let checked = true;
60
61
  simpleItemsSection.addEventListener('contextmenu', onSimpleMenu);
@@ -93,8 +94,8 @@ export async function render(container: HTMLElement) {
93
94
  customSection.innerHTML = '<p>Right-click here</p>';
94
95
  const customSectionHeader = document.createElement('header');
95
96
  customSectionHeader.textContent = 'Custom sections (imperative API)';
96
- container.appendChild(customSectionHeader);
97
- container.appendChild(customSection);
97
+ menuDocs.appendChild(customSectionHeader);
98
+ menuDocs.appendChild(customSection);
98
99
 
99
100
  customSection.addEventListener('contextmenu', onCustomSectionMenu);
100
101
 
@@ -117,8 +118,8 @@ export async function render(container: HTMLElement) {
117
118
  subMenuSection.innerHTML = '<p>Right-click here</p>';
118
119
  const subMenuHeader = document.createElement('header');
119
120
  subMenuHeader.textContent = 'Sub menu (imperative API)';
120
- container.appendChild(subMenuHeader);
121
- container.appendChild(subMenuSection);
121
+ menuDocs.appendChild(subMenuHeader);
122
+ menuDocs.appendChild(subMenuSection);
122
123
 
123
124
  subMenuSection.addEventListener('contextmenu', onSubMenu);
124
125
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  import {UIUtils} from './legacy.js';
6
6
 
7
- export async function render(container: HTMLElement) {
7
+ export function render(container: HTMLElement) {
8
8
  const styleElement = document.createElement('style');
9
9
  styleElement.textContent = 'fieldset { label { display: block; } }';
10
10
  container.appendChild(styleElement);
@@ -9,7 +9,7 @@ import {UIUtils} from './legacy.js';
9
9
 
10
10
  const {html} = Lit;
11
11
 
12
- export async function render(container: HTMLElement) {
12
+ export function render(container: HTMLElement) {
13
13
  function createDivWithP(text: string): HTMLDivElement {
14
14
  const div = document.createElement('div');
15
15
  div.style.paddingLeft = '25px';
@@ -4,7 +4,7 @@
4
4
 
5
5
  import {UIUtils} from './legacy.js';
6
6
 
7
- export async function render(container: HTMLElement) {
7
+ export function render(container: HTMLElement) {
8
8
  function sliderExample({min, max, tabIndex, disabled}: {
9
9
  min: number,
10
10
  max: number,