chrome-devtools-frontend 1.0.1632065 → 1.0.1635876

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 (107) hide show
  1. package/front_end/core/host/UserMetrics.ts +5 -2
  2. package/front_end/core/root/ExperimentNames.ts +1 -0
  3. package/front_end/core/root/Runtime.ts +5 -0
  4. package/front_end/core/sdk/SourceMapCache.ts +13 -11
  5. package/front_end/core/sdk/SourceMapManager.ts +7 -3
  6. package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +84 -22
  7. package/front_end/entrypoints/main/MainImpl.ts +8 -0
  8. package/front_end/generated/InspectorBackendCommands.ts +3 -4
  9. package/front_end/generated/SupportedCSSProperties.js +272 -2
  10. package/front_end/generated/protocol-mapping.d.ts +0 -10
  11. package/front_end/generated/protocol-proxy-api.d.ts +0 -8
  12. package/front_end/generated/protocol.ts +5 -7
  13. package/front_end/models/ai_assistance/AiConversation.ts +16 -11
  14. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +13 -2
  15. package/front_end/models/ai_assistance/agents/AiAgent.ts +65 -11
  16. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +42 -2
  17. package/front_end/models/ai_assistance/agents/GreenDevAgent.ts +68 -5
  18. package/front_end/models/ai_assistance/agents/GreenDevAgentAntigravityCliSocketClient.ts +53 -0
  19. package/front_end/models/ai_assistance/agents/GreenDevAgentGeminiCliSocketClient.ts +117 -0
  20. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +30 -1
  21. package/front_end/models/ai_assistance/ai_assistance.ts +4 -0
  22. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +4 -2
  23. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +5 -2
  24. package/front_end/models/extensions/RecorderExtensionEndpoint.ts +9 -1
  25. package/front_end/models/extensions/RecorderPluginManager.ts +1 -0
  26. package/front_end/models/greendev/Prototypes.ts +17 -5
  27. package/front_end/models/trace/handlers/FramesHandler.ts +19 -13
  28. package/front_end/panels/ai_assistance/components/AccessibilityAgentMarkdownRenderer.ts +3 -0
  29. package/front_end/panels/ai_assistance/components/ChatInput.ts +4 -2
  30. package/front_end/panels/ai_assistance/components/ChatMessage.ts +3 -1
  31. package/front_end/panels/application/preloading/components/PreloadingString.ts +0 -8
  32. package/front_end/panels/common/ExtensionServer.ts +34 -11
  33. package/front_end/panels/elements/CSSRuleValidator.ts +37 -34
  34. package/front_end/panels/elements/CSSRuleValidatorHelper.ts +8 -6
  35. package/front_end/panels/elements/ElementsTreeElement.ts +8 -2
  36. package/front_end/panels/elements/components/CSSHintDetailsView.ts +5 -5
  37. package/front_end/panels/js_timeline/js_timeline-meta.ts +30 -0
  38. package/front_end/panels/protocol_monitor/JSONEditor.ts +4 -4
  39. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +2 -2
  40. package/front_end/panels/recorder/RecorderController.ts +50 -1
  41. package/front_end/panels/recorder/extensions/ExtensionManager.ts +1 -0
  42. package/front_end/panels/recorder/models/RecordingPlayer.ts +12 -3
  43. package/front_end/panels/recorder/testing/RecorderHelpers.ts +2 -0
  44. package/front_end/panels/settings/SettingsScreen.ts +3 -2
  45. package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +5 -2
  46. package/front_end/panels/timeline/timeline-meta.ts +10 -6
  47. package/front_end/panels/whats_new/ReleaseNoteText.ts +9 -9
  48. package/front_end/panels/whats_new/resources/WNDT.md +9 -9
  49. package/front_end/third_party/chromium/README.chromium +1 -1
  50. package/front_end/third_party/puppeteer/README.chromium +2 -2
  51. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +8 -5
  52. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +35 -33
  53. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.d.ts.map +1 -1
  54. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.js +0 -1
  55. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.js.map +1 -1
  56. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebMCP.d.ts.map +1 -1
  57. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebMCP.js +0 -3
  58. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebMCP.js.map +1 -1
  59. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.d.ts +8 -8
  60. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.d.ts.map +1 -1
  61. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.js +8 -8
  62. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.js.map +1 -1
  63. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts +1 -1
  64. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts.map +1 -1
  65. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js +1 -1
  66. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js.map +1 -1
  67. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/CustomQuerySelector.d.ts +2 -2
  68. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/CustomQuerySelector.d.ts.map +1 -1
  69. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/CustomQuerySelector.js +2 -1
  70. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/CustomQuerySelector.js.map +1 -1
  71. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/injected.d.ts +2 -7
  72. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/injected.d.ts.map +1 -1
  73. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/PuppeteerNode.d.ts +1 -1
  74. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/PuppeteerNode.js +1 -1
  75. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.d.ts +3 -3
  76. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js +3 -3
  77. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js.map +1 -1
  78. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/Mutex.d.ts +10 -7
  79. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/Mutex.d.ts.map +1 -1
  80. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/Mutex.js +16 -12
  81. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/Mutex.js.map +1 -1
  82. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.d.ts +1 -1
  83. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.js +1 -1
  84. package/front_end/third_party/puppeteer/package/lib/types.d.ts +8 -5
  85. package/front_end/third_party/puppeteer/package/package.json +5 -7
  86. package/front_end/third_party/puppeteer/package/src/cdp/TargetManager.ts +0 -1
  87. package/front_end/third_party/puppeteer/package/src/cdp/WebMCP.ts +0 -3
  88. package/front_end/third_party/puppeteer/package/src/common/Debug.ts +11 -11
  89. package/front_end/third_party/puppeteer/package/src/generated/injected.ts +1 -1
  90. package/front_end/third_party/puppeteer/package/src/injected/CustomQuerySelector.ts +3 -2
  91. package/front_end/third_party/puppeteer/package/src/node/PuppeteerNode.ts +1 -1
  92. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  93. package/front_end/third_party/puppeteer/package/src/util/Mutex.ts +17 -12
  94. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  95. package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +7 -0
  96. package/front_end/ui/legacy/InspectorDrawerView.ts +2 -1
  97. package/front_end/ui/legacy/InspectorView.ts +1 -1
  98. package/front_end/ui/legacy/PlusButton.ts +269 -0
  99. package/front_end/ui/legacy/ViewManager.ts +38 -11
  100. package/front_end/ui/legacy/components/source_frame/FontView.ts +11 -3
  101. package/front_end/ui/legacy/components/source_frame/ImageView.ts +16 -0
  102. package/front_end/ui/legacy/components/source_frame/imageView.css +13 -0
  103. package/front_end/ui/legacy/components/utils/Linkifier.ts +1 -1
  104. package/front_end/ui/legacy/legacy.ts +2 -0
  105. package/front_end/ui/visual_logging/KnownContextValues.ts +21 -0
  106. package/mcp/mcp.ts +1 -1
  107. package/package.json +1 -10
@@ -2090,11 +2090,13 @@ async function makeLighthouseReportWidget(widgetData: LighthouseReportAiWidget):
2090
2090
  return null;
2091
2091
  }
2092
2092
 
2093
+ const snapshotReport = widgetData.data.snapshotReport;
2094
+
2093
2095
  return {
2094
2096
  renderedWidget: html`<div class="lighthouse-report-widget">${reportEl}</div>`,
2095
2097
  revealable: new Lighthouse.LighthousePanel.ActiveLighthouseReport(widgetData.data.report),
2096
2098
  accessibleRevealLabel: lockedString(UIStringsNotTranslate.revealLighthouse),
2097
2099
  title: lockedString(UIStringsNotTranslate.lighthouseReport),
2098
- jslogContext: 'lighthouse-report-widget',
2100
+ jslogContext: snapshotReport ? 'lighthouse-snapshot-report-widget' : 'lighthouse-report-widget',
2099
2101
  };
2100
2102
  }
@@ -11,11 +11,6 @@ import * as Protocol from '../../../../generated/protocol.js';
11
11
  import * as Bindings from '../../../../models/bindings/bindings.js';
12
12
 
13
13
  const UIStrings = {
14
- /**
15
- * @description Descrption text for Prefetch status PrefetchCancelledOnUserNavigation.
16
- */
17
- PrefetchCancelledOnUserNavigation:
18
- 'The prefetch was cancelled because the user navigated the page before the prefetch finished',
19
14
  /**
20
15
  * @description Description text for Prefetch status PrefetchFailedIneligibleRedirect.
21
16
  */
@@ -459,7 +454,6 @@ export const PrefetchReasonDescription: Record<string, {name: () => Platform.UIS
459
454
  PrefetchNotEligibleRedirectFromServiceWorker: {name: () => i18n.i18n.lockedString('Unknown')},
460
455
  PrefetchNotEligibleRedirectToServiceWorker: {name: () => i18n.i18n.lockedString('Unknown')},
461
456
  PrefetchEvictedAfterBrowsingDataRemoved: {name: i18nLazyString(UIStrings.PrefetchEvictedAfterBrowsingDataRemoved)},
462
- PrefetchCancelledOnUserNavigation: {name: i18nLazyString(UIStrings.PrefetchCancelledOnUserNavigation)},
463
457
  };
464
458
 
465
459
  /** Decoding PrefetchFinalStatus prefetchAttempt to failure description. **/
@@ -546,8 +540,6 @@ export function prefetchFailureReason(
546
540
  return PrefetchReasonDescription['PrefetchNotEligibleRedirectToServiceWorker'].name();
547
541
  case Protocol.Preload.PrefetchStatus.PrefetchEvictedAfterBrowsingDataRemoved:
548
542
  return PrefetchReasonDescription['PrefetchEvictedAfterBrowsingDataRemoved'].name();
549
- case Protocol.Preload.PrefetchStatus.PrefetchCancelledOnUserNavigation:
550
- return PrefetchReasonDescription['PrefetchCancelledOnUserNavigation'].name();
551
543
  default:
552
544
  // Note that we use switch and exhaustiveness check to prevent to
553
545
  // forget updating these strings, but allow to handle unknown
@@ -141,6 +141,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
141
141
  private inspectedTabId?: string;
142
142
  private readonly extensionAPITestHook?: (server: unknown, api: unknown) => unknown;
143
143
  private themeChangeHandlers = new Map<string, MessagePort>();
144
+ private readonly recorderViewPortMap: Map<string, MessagePort>;
144
145
  readonly #pendingExtensions: Host.InspectorFrontendHostAPI.ExtensionDescriptor[] = [];
145
146
 
146
147
  private constructor() {
@@ -148,6 +149,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
148
149
  this.clientObjects = new Map();
149
150
  this.handlers = new Map();
150
151
  this.subscribers = new Map();
152
+ this.recorderViewPortMap = new Map();
151
153
  this.subscriptionStartHandlers = new Map();
152
154
  this.subscriptionStopHandlers = new Map();
153
155
  this.extraHeaders = new Map();
@@ -430,8 +432,10 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
430
432
  'command', `expected ${Extensions.ExtensionAPI.PrivateAPI.Commands.RegisterRecorderExtensionPlugin}`);
431
433
  }
432
434
  const {pluginName, mediaType, port, capabilities} = message;
435
+ const extensionOrigin = this.getExtensionOrigin(_shared_port);
433
436
  Extensions.RecorderPluginManager.RecorderPluginManager.instance().addPlugin(
434
- new Extensions.RecorderExtensionEndpoint.RecorderExtensionEndpoint(pluginName, port, capabilities, mediaType));
437
+ new Extensions.RecorderExtensionEndpoint.RecorderExtensionEndpoint(
438
+ pluginName, port, capabilities, extensionOrigin, mediaType));
435
439
  return this.status.OK();
436
440
  }
437
441
 
@@ -483,12 +487,15 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
483
487
  return this.status.OK();
484
488
  }
485
489
 
486
- private onShowRecorderView(message: Extensions.ExtensionAPI.PrivateAPI.ExtensionServerRequestMessage): Record
487
- |undefined {
490
+ private onShowRecorderView(
491
+ message: Extensions.ExtensionAPI.PrivateAPI.ExtensionServerRequestMessage, port: MessagePort): Record|undefined {
488
492
  if (message.command !== Extensions.ExtensionAPI.PrivateAPI.Commands.ShowRecorderView) {
489
493
  return this.status.E_BADARG(
490
494
  'command', `expected ${Extensions.ExtensionAPI.PrivateAPI.Commands.ShowRecorderView}`);
491
495
  }
496
+ if (this.recorderViewPortMap.get(message.id) !== port) {
497
+ return this.status.E_FAILED('Permission denied');
498
+ }
492
499
  Extensions.RecorderPluginManager.RecorderPluginManager.instance().showView(message.id);
493
500
  return undefined;
494
501
  }
@@ -516,7 +523,8 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
516
523
  return this.status.E_EXISTS(id);
517
524
  }
518
525
 
519
- const pagePath = ExtensionServer.expandResourcePath(this.getExtensionOrigin(port), message.pagePath);
526
+ const extensionOrigin = this.getExtensionOrigin(port);
527
+ const pagePath = ExtensionServer.expandResourcePath(extensionOrigin, message.pagePath);
520
528
  if (pagePath === undefined) {
521
529
  return this.status.E_BADARG('pagePath', 'Resources paths cannot point to non-extension resources');
522
530
  }
@@ -528,7 +536,9 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
528
536
  title: message.title,
529
537
  onShown,
530
538
  onHidden,
539
+ extensionOrigin,
531
540
  });
541
+ this.recorderViewPortMap.set(id, port);
532
542
  return this.status.OK();
533
543
  }
534
544
 
@@ -614,15 +624,25 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
614
624
  return undefined;
615
625
  }
616
626
 
617
- private onAddRequestHeaders(message: Extensions.ExtensionAPI.PrivateAPI.ExtensionServerRequestMessage): Record
618
- |undefined {
627
+ private onAddRequestHeaders(
628
+ message: Extensions.ExtensionAPI.PrivateAPI.ExtensionServerRequestMessage, port: MessagePort): Record|undefined {
619
629
  if (message.command !== Extensions.ExtensionAPI.PrivateAPI.Commands.AddRequestHeaders) {
620
630
  return this.status.E_BADARG(
621
631
  'command', `expected ${Extensions.ExtensionAPI.PrivateAPI.Commands.AddRequestHeaders}`);
622
632
  }
623
- const id = message.extensionId;
624
- if (typeof id !== 'string') {
625
- return this.status.E_BADARGTYPE('extensionId', typeof id, 'string');
633
+ // Use the authenticated port origin instead of the caller-supplied extensionId to
634
+ // prevent one extension from manipulating another extension's header set.
635
+ const id = this.getExtensionOrigin(port);
636
+ const extension = this.registeredExtensions.get(id);
637
+ if (!extension) {
638
+ return this.status.E_FAILED('Permission denied');
639
+ }
640
+ // Refuse the request if the extension has any runtime_blocked_hosts policy entries.
641
+ // MultitargetNetworkManager fans out setExtraHTTPHeaders to every attached network
642
+ // agent (including OOPIF/subframe targets), so there is no safe per-target URL check
643
+ // here. Blocking the call when blocked hosts exist is the minimal safe mitigation.
644
+ if (extension.hostsPolicy.runtimeBlockedHosts.length > 0) {
645
+ return this.status.E_FAILED('Permission denied');
626
646
  }
627
647
  let extensionHeaders = this.extraHeaders.get(id);
628
648
  if (!extensionHeaders) {
@@ -977,8 +997,6 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
977
997
  }
978
998
  const options = (message.options || {});
979
999
 
980
- SDK.NetworkManager.MultitargetNetworkManager.instance().setUserAgentOverride(
981
- typeof options.userAgent === 'string' ? options.userAgent : '', null);
982
1000
  let injectedScript;
983
1001
  if (options.injectedScript) {
984
1002
  injectedScript = '(function(){' + options.injectedScript + '})()';
@@ -991,6 +1009,11 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
991
1009
  if (!this.extensionAllowedOnTarget(target, port)) {
992
1010
  return this.status.E_FAILED('Permission denied');
993
1011
  }
1012
+ // Apply the UA override only after confirming the extension is allowed on this target,
1013
+ // so that extensions blocked by runtime_blocked_hosts cannot override the UA for the
1014
+ // primary page (and, via singleton persistence, for future targets that attach later).
1015
+ SDK.NetworkManager.MultitargetNetworkManager.instance().setUserAgentOverride(
1016
+ typeof options.userAgent === 'string' ? options.userAgent : '', null);
994
1017
  resourceTreeModel?.reloadPage(Boolean(options.ignoreCache), injectedScript);
995
1018
  return this.status.OK();
996
1019
  }
@@ -4,6 +4,8 @@
4
4
 
5
5
  import * as i18n from '../../core/i18n/i18n.js';
6
6
  import * as SDK from '../../core/sdk/sdk.js';
7
+ import * as uiI18n from '../../ui/i18n/i18n.js';
8
+ import {html, type LitTemplate} from '../../ui/lit/lit.js';
7
9
 
8
10
  import {
9
11
  buildPropertyDefinitionText,
@@ -102,6 +104,7 @@ const UIStrings = {
102
104
  } as const;
103
105
  const str_ = i18n.i18n.registerUIStrings('panels/elements/CSSRuleValidator.ts', UIStrings);
104
106
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
107
+ const i18nLazyStringTemplate = uiI18n.getFormatLocalizedStringTemplate.bind(undefined, str_);
105
108
 
106
109
  export const enum HintType {
107
110
  INACTIVE_PROPERTY = 'ruleValidation',
@@ -109,21 +112,21 @@ export const enum HintType {
109
112
  }
110
113
 
111
114
  export class Hint {
112
- readonly #hintMessage: string;
113
- readonly #possibleFixMessage: string|null;
115
+ readonly #hintMessage: LitTemplate|string;
116
+ readonly #possibleFixMessage: LitTemplate|string|null;
114
117
  readonly #learnMoreLink: string|undefined;
115
118
 
116
- constructor(hintMessage: string, possibleFixMessage: string|null, learnMoreLink?: string) {
119
+ constructor(hintMessage: LitTemplate|string, possibleFixMessage: LitTemplate|string|null, learnMoreLink?: string) {
117
120
  this.#hintMessage = hintMessage;
118
121
  this.#possibleFixMessage = possibleFixMessage;
119
122
  this.#learnMoreLink = learnMoreLink;
120
123
  }
121
124
 
122
- getMessage(): string {
125
+ getMessage(): LitTemplate|string {
123
126
  return this.#hintMessage;
124
127
  }
125
128
 
126
- getPossibleFixMessage(): string|null {
129
+ getPossibleFixMessage(): LitTemplate|string|null {
127
130
  return this.#possibleFixMessage;
128
131
  }
129
132
 
@@ -164,11 +167,11 @@ export class AlignContentValidator extends CSSRuleValidator {
164
167
  const affectedPropertyDeclarationCode = buildPropertyName('align-content');
165
168
 
166
169
  return new Hint(
167
- i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
170
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
168
171
  REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
169
172
  AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
170
173
  }),
171
- i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
174
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleFix, {
172
175
  PROPERTY_NAME: buildPropertyName('display'),
173
176
  PROPERTY_VALUE: buildPropertyValue(computedStyles?.get('display') as string),
174
177
  }),
@@ -186,11 +189,11 @@ export class AlignContentValidator extends CSSRuleValidator {
186
189
  const affectedPropertyDeclarationCode = buildPropertyName('align-content');
187
190
 
188
191
  return new Hint(
189
- i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
192
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
190
193
  REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
191
194
  AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
192
195
  }),
193
- i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
196
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleFix, {
194
197
  PROPERTY_NAME: buildPropertyName('flex-wrap'),
195
198
  PROPERTY_VALUE: buildPropertyValue('nowrap'),
196
199
  }),
@@ -215,11 +218,11 @@ export class FlexItemValidator extends CSSRuleValidator {
215
218
  const affectedPropertyDeclarationCode = buildPropertyName(propertyName);
216
219
  const targetParentPropertyDeclaration = buildPropertyDefinitionText('display', 'flex');
217
220
  return new Hint(
218
- i18nString(UIStrings.ruleViolatedByParentElementRuleReason, {
221
+ i18nLazyStringTemplate(UIStrings.ruleViolatedByParentElementRuleReason, {
219
222
  REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
220
223
  AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
221
224
  }),
222
- i18nString(UIStrings.ruleViolatedByParentElementRuleFix, {
225
+ i18nLazyStringTemplate(UIStrings.ruleViolatedByParentElementRuleFix, {
223
226
  EXISTING_PARENT_ELEMENT_RULE: reasonPropertyDeclaration,
224
227
  TARGET_PARENT_ELEMENT_RULE: targetParentPropertyDeclaration,
225
228
  }),
@@ -244,11 +247,11 @@ export class FlexContainerValidator extends CSSRuleValidator {
244
247
  const affectedPropertyDeclarationCode = buildPropertyName(propertyName);
245
248
 
246
249
  return new Hint(
247
- i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
250
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
248
251
  REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
249
252
  AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
250
253
  }),
251
- i18nString(UIStrings.ruleViolatedBySameElementRuleChangeSuggestion, {
254
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleChangeSuggestion, {
252
255
  EXISTING_PROPERTY_DECLARATION: reasonPropertyDeclaration,
253
256
  TARGET_PROPERTY_DECLARATION: targetRuleCode,
254
257
  }),
@@ -279,11 +282,11 @@ export class GridContainerValidator extends CSSRuleValidator {
279
282
  const affectedPropertyDeclarationCode = buildPropertyName(propertyName);
280
283
 
281
284
  return new Hint(
282
- i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
285
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
283
286
  REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
284
287
  AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
285
288
  }),
286
- i18nString(UIStrings.ruleViolatedBySameElementRuleChangeSuggestion, {
289
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleChangeSuggestion, {
287
290
  EXISTING_PROPERTY_DECLARATION: reasonPropertyDeclaration,
288
291
  TARGET_PROPERTY_DECLARATION: targetRuleCode,
289
292
  }),
@@ -315,11 +318,11 @@ export class GridItemValidator extends CSSRuleValidator {
315
318
  const affectedPropertyDeclarationCode = buildPropertyName(propertyName);
316
319
 
317
320
  return new Hint(
318
- i18nString(UIStrings.ruleViolatedByParentElementRuleReason, {
321
+ i18nLazyStringTemplate(UIStrings.ruleViolatedByParentElementRuleReason, {
319
322
  REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
320
323
  AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
321
324
  }),
322
- i18nString(UIStrings.ruleViolatedByParentElementRuleFix, {
325
+ i18nLazyStringTemplate(UIStrings.ruleViolatedByParentElementRuleFix, {
323
326
  EXISTING_PARENT_ELEMENT_RULE: reasonPropertyDeclaration,
324
327
  TARGET_PARENT_ELEMENT_RULE: targetParentPropertyDeclaration,
325
328
  }),
@@ -344,15 +347,15 @@ export class FlexOrGridItemValidator extends CSSRuleValidator {
344
347
  }
345
348
  const reasonPropertyDeclaration = buildPropertyDefinitionText('display', parentComputedStyles?.get('display'));
346
349
  const targetParentPropertyDeclaration =
347
- `${buildPropertyDefinitionText('display', 'flex')} or ${buildPropertyDefinitionText('display', 'grid')}`;
350
+ html`${buildPropertyDefinitionText('display', 'flex')} or ${buildPropertyDefinitionText('display', 'grid')}`;
348
351
  const affectedPropertyDeclarationCode = buildPropertyName(propertyName);
349
352
 
350
353
  return new Hint(
351
- i18nString(UIStrings.ruleViolatedByParentElementRuleReason, {
354
+ i18nLazyStringTemplate(UIStrings.ruleViolatedByParentElementRuleReason, {
352
355
  REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
353
356
  AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
354
357
  }),
355
- i18nString(UIStrings.ruleViolatedByParentElementRuleFix, {
358
+ i18nLazyStringTemplate(UIStrings.ruleViolatedByParentElementRuleFix, {
356
359
  EXISTING_PARENT_ELEMENT_RULE: reasonPropertyDeclaration,
357
360
  TARGET_PARENT_ELEMENT_RULE: targetParentPropertyDeclaration,
358
361
  }),
@@ -383,11 +386,11 @@ export class FlexGridValidator extends CSSRuleValidator {
383
386
  const reasonPropertyName = buildPropertyName(propertyName);
384
387
  const reasonAlternativePropertyName = buildPropertyName('justify-self');
385
388
  return new Hint(
386
- i18nString(UIStrings.flexGridContainerPropertyRuleReason, {
389
+ i18nLazyStringTemplate(UIStrings.flexGridContainerPropertyRuleReason, {
387
390
  CONTAINER_DISPLAY_NAME: reasonContainerDisplayName,
388
391
  PROPERTY_NAME: reasonPropertyName,
389
392
  }),
390
- i18nString(UIStrings.flexGridContainerPropertyRuleFix, {
393
+ i18nLazyStringTemplate(UIStrings.flexGridContainerPropertyRuleFix, {
391
394
  PROPERTY_NAME: reasonPropertyName,
392
395
  ALTERNATIVE_PROPERTY_NAME: reasonAlternativePropertyName,
393
396
  }),
@@ -398,11 +401,11 @@ export class FlexGridValidator extends CSSRuleValidator {
398
401
  const affectedPropertyDeclarationCode = buildPropertyName(propertyName);
399
402
 
400
403
  return new Hint(
401
- i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
404
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
402
405
  REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
403
406
  AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
404
407
  }),
405
- i18nString(UIStrings.ruleViolatedBySameElementRuleChangeFlexOrGrid, {
408
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleChangeFlexOrGrid, {
406
409
  DISPLAY_GRID_RULE: buildPropertyDefinitionText('display', 'grid'),
407
410
  DISPLAY_FLEX_RULE: buildPropertyDefinitionText('display', 'flex'),
408
411
  }),
@@ -436,11 +439,11 @@ export class MulticolFlexGridValidator extends CSSRuleValidator {
436
439
  const affectedPropertyDeclarationCode = buildPropertyName(propertyName);
437
440
 
438
441
  return new Hint(
439
- i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
442
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
440
443
  REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
441
444
  AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
442
445
  }),
443
- i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
446
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleFix, {
444
447
  PROPERTY_NAME: buildPropertyName('display'),
445
448
  PROPERTY_VALUE: buildPropertyValue(computedStyles?.get('display') as string),
446
449
  }),
@@ -480,11 +483,11 @@ export class PaddingValidator extends CSSRuleValidator {
480
483
  const affectedPropertyDeclarationCode = buildPropertyName(propertyName);
481
484
 
482
485
  return new Hint(
483
- i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
486
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
484
487
  REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
485
488
  AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
486
489
  }),
487
- i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
490
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleFix, {
488
491
  PROPERTY_NAME: buildPropertyName('display'),
489
492
  PROPERTY_VALUE: buildPropertyValue(computedStyles?.get('display') as string),
490
493
  }),
@@ -515,11 +518,11 @@ export class PositionValidator extends CSSRuleValidator {
515
518
  const affectedPropertyDeclarationCode = buildPropertyName(propertyName);
516
519
 
517
520
  return new Hint(
518
- i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
521
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
519
522
  REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
520
523
  AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
521
524
  }),
522
- i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
525
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleFix, {
523
526
  PROPERTY_NAME: buildPropertyName('position'),
524
527
  PROPERTY_VALUE: buildPropertyValue(computedStyles?.get('position') as string),
525
528
  }),
@@ -549,11 +552,11 @@ export class ZIndexValidator extends CSSRuleValidator {
549
552
  const affectedPropertyDeclarationCode = buildPropertyName(propertyName);
550
553
 
551
554
  return new Hint(
552
- i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
555
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
553
556
  REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
554
557
  AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
555
558
  }),
556
- i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
559
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleFix, {
557
560
  PROPERTY_NAME: buildPropertyName('position'),
558
561
  PROPERTY_VALUE: buildPropertyValue(computedStyles?.get('position') as string),
559
562
  }),
@@ -615,11 +618,11 @@ export class SizingValidator extends CSSRuleValidator {
615
618
  const affectedPropertyDeclarationCode = buildPropertyName(propertyName);
616
619
 
617
620
  return new Hint(
618
- i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
621
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
619
622
  REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
620
623
  AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
621
624
  }),
622
- i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
625
+ i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleFix, {
623
626
  PROPERTY_NAME: buildPropertyName('display'),
624
627
  PROPERTY_VALUE: buildPropertyValue(computedStyles?.get('display') as string),
625
628
  }),
@@ -2,19 +2,21 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
- export const buildPropertyDefinitionText = (property: string, value?: string): string => {
5
+ import {html, type LitTemplate} from '../../ui/lit/lit.js';
6
+
7
+ export const buildPropertyDefinitionText = (property: string, value?: string): LitTemplate => {
6
8
  if (value === undefined) {
7
9
  return buildPropertyName(property);
8
10
  }
9
- return '<code class="unbreakable-text"><span class="property">' + property + '</span>: ' + value + '</code>';
11
+ return html`<code class="unbreakable-text"><span class="property">${property}</span>: ${value}</code>`;
10
12
  };
11
13
 
12
- export const buildPropertyName = (property: string): string => {
13
- return '<code class="unbreakable-text"><span class="property">' + property + '</span></code>';
14
+ export const buildPropertyName = (property: string): LitTemplate => {
15
+ return html`<code class="unbreakable-text"><span class="property">${property}</span></code>`;
14
16
  };
15
17
 
16
- export const buildPropertyValue = (property: string): string => {
17
- return '<code class="unbreakable-text">' + property + '</code>';
18
+ export const buildPropertyValue = (property: string): LitTemplate => {
19
+ return html`<code class="unbreakable-text">${property}</code>`;
18
20
  };
19
21
 
20
22
  export const isFlexContainer = (computedStyles?: Map<string, string>): boolean => {
@@ -1299,6 +1299,12 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1299
1299
 
1300
1300
  // ClearNode param is used to clean DOM after in-place editing..
1301
1301
  performUpdate(clearNode = false): void {
1302
+ // Skip updating when in-place editing (not HTML editing indicated by the
1303
+ // editorState) is happening. Doing an update would break editing
1304
+ // (crbug.com/515639787).
1305
+ if (this.editing && !this.#editorState) {
1306
+ return;
1307
+ }
1302
1308
  const output: ViewOutput = {};
1303
1309
  DEFAULT_VIEW(
1304
1310
  {
@@ -2384,7 +2390,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2384
2390
  return this.startEditingAttribute(attr, attr);
2385
2391
  }
2386
2392
 
2387
- private triggerEditAttribute(attributeName: string): boolean|undefined {
2393
+ triggerEditAttribute(attributeName: string): boolean|undefined {
2388
2394
  const attributeElements = this.listItemElement.getElementsByClassName('webkit-html-attribute-name');
2389
2395
  for (let i = 0, len = attributeElements.length; i < len; ++i) {
2390
2396
  if (attributeElements[i].textContent === attributeName) {
@@ -2823,7 +2829,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2823
2829
  textNode.setNodeValue(newText, callback.bind(this));
2824
2830
  }
2825
2831
 
2826
- private editingCancelled(_element: Element, _tagName: string|null): void {
2832
+ editingCancelled(_element: Element, _tagName: string|null): void {
2827
2833
  this.editing = null;
2828
2834
 
2829
2835
  // Need to restore attributes structure.
@@ -7,7 +7,7 @@ import '../../../ui/kit/kit.js';
7
7
  import '../../../ui/legacy/legacy.js';
8
8
 
9
9
  import * as i18n from '../../../core/i18n/i18n.js';
10
- import {Directives, html, render} from '../../../ui/lit/lit.js';
10
+ import {html, type LitTemplate, render} from '../../../ui/lit/lit.js';
11
11
 
12
12
  import cssHintDetailsViewStyles from './cssHintDetailsView.css.js';
13
13
 
@@ -21,8 +21,8 @@ const str_ = i18n.i18n.registerUIStrings('panels/elements/components/CSSHintDeta
21
21
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
22
22
 
23
23
  interface Hint {
24
- getMessage(): string;
25
- getPossibleFixMessage(): string|null;
24
+ getMessage(): LitTemplate|string;
25
+ getPossibleFixMessage(): LitTemplate|string|null;
26
26
  getLearnMoreLink(): string|undefined;
27
27
  }
28
28
 
@@ -43,11 +43,11 @@ export class CSSHintDetailsView extends HTMLElement {
43
43
  <style>${cssHintDetailsViewStyles}</style>
44
44
  <div class="hint-popup-wrapper">
45
45
  <div class="hint-popup-reason">
46
- ${Directives.unsafeHTML(this.#authoringHint.getMessage())}
46
+ ${this.#authoringHint.getMessage()}
47
47
  </div>
48
48
  ${this.#authoringHint.getPossibleFixMessage() ? html`
49
49
  <div class="hint-popup-possible-fix">
50
- ${Directives.unsafeHTML(this.#authoringHint.getPossibleFixMessage())}
50
+ ${this.#authoringHint.getPossibleFixMessage()}
51
51
  </div>
52
52
  ` : ''}
53
53
  ${link ? html`
@@ -33,6 +33,14 @@ const UIStrings = {
33
33
  * @description Title of an action in the timeline tool to record a reload of the current page
34
34
  */
35
35
  recordAndReload: 'Record and reload',
36
+ /**
37
+ * @description Title of a setting under the Performance category in Settings
38
+ */
39
+ timelineShowAllEvents: 'Show all events',
40
+ /**
41
+ * @description Title of a setting under the Performance category in Settings
42
+ */
43
+ timelineDebugMode: 'Timeline debug mode (trace event details, etc.)',
36
44
  } as const;
37
45
  const str_ = i18n.i18n.registerUIStrings('panels/js_timeline/js_timeline-meta.ts', UIStrings);
38
46
  const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
@@ -152,6 +160,28 @@ UI.ActionRegistration.registerActionExtension({
152
160
  ],
153
161
  });
154
162
 
163
+ // IMPORTANT: if you are updating this, you should also update the setting in
164
+ // timeline-meta.
165
+ Common.Settings.registerSettingExtension({
166
+ category: Common.Settings.SettingCategory.PERFORMANCE,
167
+ storageType: Common.Settings.SettingStorageType.SYNCED,
168
+ title: i18nLazyString(UIStrings.timelineShowAllEvents),
169
+ settingName: 'timeline-show-all-events',
170
+ settingType: Common.Settings.SettingType.BOOLEAN,
171
+ defaultValue: false,
172
+ });
173
+
174
+ // IMPORTANT: if you are updating this, you should also update the setting in
175
+ // timeline-meta.
176
+ Common.Settings.registerSettingExtension({
177
+ category: Common.Settings.SettingCategory.PERFORMANCE,
178
+ storageType: Common.Settings.SettingStorageType.SYNCED,
179
+ title: i18nLazyString(UIStrings.timelineDebugMode),
180
+ settingName: 'timeline-debug-mode',
181
+ settingType: Common.Settings.SettingType.BOOLEAN,
182
+ defaultValue: false,
183
+ });
184
+
155
185
  // IMPORTANT: if you are updating this, you should also update the setting in
156
186
  // timeline-meta.
157
187
  Common.Settings.registerSettingExtension({
@@ -509,12 +509,12 @@ export class JSONEditor extends Common.ObjectWrapper.eventMixin<EventTypes, type
509
509
  const [head, tail] = splitDescription(elementData.description);
510
510
  const type = elementData.type;
511
511
  const replyArgs = elementData.replyArgs;
512
- let popupContent = '';
512
+ let popupContent: Lit.LitTemplate|string;
513
513
  // replyArgs and type cannot get into conflict because replyArgs is attached to a command and type to a parameter
514
514
  if (replyArgs && replyArgs.length > 0) {
515
- popupContent = tail + `Returns: ${replyArgs}<br>`;
515
+ popupContent = html`${tail}Returns: ${replyArgs}<br>`;
516
516
  } else if (type) {
517
- popupContent = tail + `<br>Type: ${type}<br>`;
517
+ popupContent = html`${tail}<br>Type: ${type}<br>`;
518
518
  } else {
519
519
  popupContent = tail;
520
520
  }
@@ -523,7 +523,7 @@ export class JSONEditor extends Common.ObjectWrapper.eventMixin<EventTypes, type
523
523
  box: hintElement.boxInWindow(),
524
524
  show: async (popover: UI.GlassPane.GlassPane) => {
525
525
  const popupElement = new ElementsComponents.CSSHintDetailsView.CSSHintDetailsView({
526
- getMessage: () => `<span>${head}</span>`,
526
+ getMessage: () => html`<span>${head}</span>`,
527
527
  getPossibleFixMessage: () => popupContent,
528
528
  getLearnMoreLink: () =>
529
529
  `https://chromedevtools.github.io/devtools-protocol/tot/${this.command.split('.')[0]}/`,
@@ -5,7 +5,6 @@
5
5
  import '../../ui/legacy/legacy.js';
6
6
  import '../../ui/legacy/components/data_grid/data_grid.js';
7
7
 
8
- import * as Host from '../../core/host/host.js';
9
8
  import * as i18n from '../../core/i18n/i18n.js';
10
9
  import * as Platform from '../../core/platform/platform.js';
11
10
  import * as ProtocolClient from '../../core/protocol_client/protocol_client.js';
@@ -13,6 +12,7 @@ import * as SDK from '../../core/sdk/sdk.js';
13
12
  import * as Bindings from '../../models/bindings/bindings.js';
14
13
  import * as TextUtils from '../../models/text_utils/text_utils.js';
15
14
  import * as Buttons from '../../ui/components/buttons/buttons.js';
15
+ import * as UIHelpers from '../../ui/helpers/helpers.js';
16
16
  import * as SourceFrame from '../../ui/legacy/components/source_frame/source_frame.js';
17
17
  import * as UI from '../../ui/legacy/legacy.js';
18
18
  import {Directives, html, render} from '../../ui/lit/lit.js';
@@ -523,7 +523,7 @@ export class ProtocolMonitorImpl extends UI.Panel.Panel implements SDK.TargetMan
523
523
  menu.footerSection().appendItem(i18nString(UIStrings.documentation), () => {
524
524
  const [domain, method] = message.method.split('.');
525
525
  const type = 'id' in message ? 'method' : 'event';
526
- Host.InspectorFrontendHost.InspectorFrontendHostInstance.openInNewTab(
526
+ UIHelpers.openInNewTab(
527
527
  `https://chromedevtools.github.io/devtools-protocol/tot/${domain}#${type}-${method}` as
528
528
  Platform.DevToolsPath.UrlString);
529
529
  }, {jslogContext: 'documentation'});