chrome-devtools-frontend 1.0.1632065 → 1.0.1635648
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.
- package/front_end/core/host/UserMetrics.ts +5 -2
- package/front_end/core/root/ExperimentNames.ts +1 -0
- package/front_end/core/root/Runtime.ts +5 -0
- package/front_end/entrypoints/main/MainImpl.ts +8 -0
- package/front_end/generated/InspectorBackendCommands.ts +3 -4
- package/front_end/generated/SupportedCSSProperties.js +272 -2
- package/front_end/generated/protocol-mapping.d.ts +0 -10
- package/front_end/generated/protocol-proxy-api.d.ts +0 -8
- package/front_end/generated/protocol.ts +5 -7
- package/front_end/models/ai_assistance/AiConversation.ts +16 -11
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +13 -2
- package/front_end/models/ai_assistance/agents/AiAgent.ts +65 -11
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +42 -2
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +30 -1
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +4 -2
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +5 -2
- package/front_end/models/extensions/RecorderExtensionEndpoint.ts +9 -1
- package/front_end/models/extensions/RecorderPluginManager.ts +1 -0
- package/front_end/models/trace/handlers/FramesHandler.ts +19 -13
- package/front_end/panels/ai_assistance/components/AccessibilityAgentMarkdownRenderer.ts +3 -0
- package/front_end/panels/ai_assistance/components/ChatInput.ts +4 -2
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +3 -1
- package/front_end/panels/application/preloading/components/PreloadingString.ts +0 -8
- package/front_end/panels/common/ExtensionServer.ts +34 -11
- package/front_end/panels/elements/CSSRuleValidator.ts +37 -34
- package/front_end/panels/elements/CSSRuleValidatorHelper.ts +8 -6
- package/front_end/panels/elements/ElementsTreeElement.ts +8 -2
- package/front_end/panels/elements/components/CSSHintDetailsView.ts +5 -5
- package/front_end/panels/js_timeline/js_timeline-meta.ts +30 -0
- package/front_end/panels/protocol_monitor/JSONEditor.ts +4 -4
- package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +2 -2
- package/front_end/panels/recorder/RecorderController.ts +50 -1
- package/front_end/panels/recorder/extensions/ExtensionManager.ts +1 -0
- package/front_end/panels/recorder/models/RecordingPlayer.ts +12 -3
- package/front_end/panels/recorder/testing/RecorderHelpers.ts +2 -0
- package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +5 -2
- package/front_end/panels/timeline/timeline-meta.ts +10 -6
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/legacy/InspectorDrawerView.ts +2 -1
- package/front_end/ui/legacy/InspectorView.ts +1 -1
- package/front_end/ui/legacy/PlusButton.ts +269 -0
- package/front_end/ui/legacy/ViewManager.ts +38 -11
- package/front_end/ui/legacy/components/source_frame/ImageView.ts +16 -0
- package/front_end/ui/legacy/components/source_frame/imageView.css +13 -0
- package/front_end/ui/legacy/components/utils/Linkifier.ts +1 -1
- package/front_end/ui/legacy/legacy.ts +2 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +19 -0
- package/mcp/mcp.ts +1 -1
- package/package.json +1 -1
|
@@ -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(
|
|
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(
|
|
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
|
|
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(
|
|
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
|
-
|
|
624
|
-
|
|
625
|
-
|
|
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
|
-
|
|
170
|
+
i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
|
|
168
171
|
REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
|
|
169
172
|
AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
|
|
170
173
|
}),
|
|
171
|
-
|
|
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
|
-
|
|
192
|
+
i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
|
|
190
193
|
REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
|
|
191
194
|
AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
|
|
192
195
|
}),
|
|
193
|
-
|
|
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
|
-
|
|
221
|
+
i18nLazyStringTemplate(UIStrings.ruleViolatedByParentElementRuleReason, {
|
|
219
222
|
REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
|
|
220
223
|
AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
|
|
221
224
|
}),
|
|
222
|
-
|
|
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
|
-
|
|
250
|
+
i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
|
|
248
251
|
REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
|
|
249
252
|
AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
|
|
250
253
|
}),
|
|
251
|
-
|
|
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
|
-
|
|
285
|
+
i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
|
|
283
286
|
REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
|
|
284
287
|
AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
|
|
285
288
|
}),
|
|
286
|
-
|
|
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
|
-
|
|
321
|
+
i18nLazyStringTemplate(UIStrings.ruleViolatedByParentElementRuleReason, {
|
|
319
322
|
REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
|
|
320
323
|
AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
|
|
321
324
|
}),
|
|
322
|
-
|
|
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
|
-
|
|
354
|
+
i18nLazyStringTemplate(UIStrings.ruleViolatedByParentElementRuleReason, {
|
|
352
355
|
REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
|
|
353
356
|
AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
|
|
354
357
|
}),
|
|
355
|
-
|
|
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
|
-
|
|
389
|
+
i18nLazyStringTemplate(UIStrings.flexGridContainerPropertyRuleReason, {
|
|
387
390
|
CONTAINER_DISPLAY_NAME: reasonContainerDisplayName,
|
|
388
391
|
PROPERTY_NAME: reasonPropertyName,
|
|
389
392
|
}),
|
|
390
|
-
|
|
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
|
-
|
|
404
|
+
i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
|
|
402
405
|
REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
|
|
403
406
|
AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
|
|
404
407
|
}),
|
|
405
|
-
|
|
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
|
-
|
|
442
|
+
i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
|
|
440
443
|
REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
|
|
441
444
|
AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
|
|
442
445
|
}),
|
|
443
|
-
|
|
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
|
-
|
|
486
|
+
i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
|
|
484
487
|
REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
|
|
485
488
|
AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
|
|
486
489
|
}),
|
|
487
|
-
|
|
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
|
-
|
|
521
|
+
i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
|
|
519
522
|
REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
|
|
520
523
|
AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
|
|
521
524
|
}),
|
|
522
|
-
|
|
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
|
-
|
|
555
|
+
i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
|
|
553
556
|
REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
|
|
554
557
|
AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
|
|
555
558
|
}),
|
|
556
|
-
|
|
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
|
-
|
|
621
|
+
i18nLazyStringTemplate(UIStrings.ruleViolatedBySameElementRuleReason, {
|
|
619
622
|
REASON_PROPERTY_DECLARATION_CODE: reasonPropertyDeclaration,
|
|
620
623
|
AFFECTED_PROPERTY_DECLARATION_CODE: affectedPropertyDeclarationCode,
|
|
621
624
|
}),
|
|
622
|
-
|
|
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
|
-
|
|
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
|
|
11
|
+
return html`<code class="unbreakable-text"><span class="property">${property}</span>: ${value}</code>`;
|
|
10
12
|
};
|
|
11
13
|
|
|
12
|
-
export const buildPropertyName = (property: string):
|
|
13
|
-
return
|
|
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):
|
|
17
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
-
${
|
|
46
|
+
${this.#authoringHint.getMessage()}
|
|
47
47
|
</div>
|
|
48
48
|
${this.#authoringHint.getPossibleFixMessage() ? html`
|
|
49
49
|
<div class="hint-popup-possible-fix">
|
|
50
|
-
${
|
|
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
|
|
515
|
+
popupContent = html`${tail}Returns: ${replyArgs}<br>`;
|
|
516
516
|
} else if (type) {
|
|
517
|
-
popupContent = tail
|
|
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
|
-
|
|
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'});
|
|
@@ -245,6 +245,8 @@ export class RecorderController extends LitElement {
|
|
|
245
245
|
@state() declare private replayExtensions: Extensions.ExtensionManager.Extension[];
|
|
246
246
|
|
|
247
247
|
@state() declare private viewDescriptor?: PublicExtensions.RecorderPluginManager.ViewDescriptor;
|
|
248
|
+
#extensionViewShowRequestedListener?:
|
|
249
|
+
(event: Common.EventTarget.EventTargetEvent<PublicExtensions.RecorderPluginManager.ViewDescriptor>) => void;
|
|
248
250
|
|
|
249
251
|
#recorderSettings = new Models.RecorderSettings.RecorderSettings();
|
|
250
252
|
#shortcutHelper = new Models.RecorderShortcutHelper.RecorderShortcutHelper();
|
|
@@ -294,6 +296,13 @@ export class RecorderController extends LitElement {
|
|
|
294
296
|
if (this.currentRecordingSession) {
|
|
295
297
|
void this.currentRecordingSession.stop();
|
|
296
298
|
}
|
|
299
|
+
if (this.#extensionViewShowRequestedListener) {
|
|
300
|
+
PublicExtensions.RecorderPluginManager.RecorderPluginManager.instance().removeEventListener(
|
|
301
|
+
PublicExtensions.RecorderPluginManager.Events.SHOW_VIEW_REQUESTED,
|
|
302
|
+
this.#extensionViewShowRequestedListener,
|
|
303
|
+
);
|
|
304
|
+
this.#extensionViewShowRequestedListener = undefined;
|
|
305
|
+
}
|
|
297
306
|
}
|
|
298
307
|
|
|
299
308
|
#updateExtensions(extensions: Extensions.ExtensionManager.Extension[]): void {
|
|
@@ -482,7 +491,40 @@ export class RecorderController extends LitElement {
|
|
|
482
491
|
return;
|
|
483
492
|
}
|
|
484
493
|
const pluginManager = PublicExtensions.RecorderPluginManager.RecorderPluginManager.instance();
|
|
485
|
-
|
|
494
|
+
|
|
495
|
+
if (this.#extensionViewShowRequestedListener) {
|
|
496
|
+
pluginManager.removeEventListener(
|
|
497
|
+
PublicExtensions.RecorderPluginManager.Events.SHOW_VIEW_REQUESTED,
|
|
498
|
+
this.#extensionViewShowRequestedListener,
|
|
499
|
+
);
|
|
500
|
+
this.#extensionViewShowRequestedListener = undefined;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
let resolveView: (descriptor: PublicExtensions.RecorderPluginManager.ViewDescriptor) => void;
|
|
504
|
+
const promise = new Promise<PublicExtensions.RecorderPluginManager.ViewDescriptor>(resolve => {
|
|
505
|
+
resolveView = resolve;
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
this.#extensionViewShowRequestedListener =
|
|
509
|
+
(event: Common.EventTarget.EventTargetEvent<PublicExtensions.RecorderPluginManager.ViewDescriptor>): void => {
|
|
510
|
+
const descriptor = event.data;
|
|
511
|
+
if (descriptor.extensionOrigin === extension.getOrigin()) {
|
|
512
|
+
if (this.#extensionViewShowRequestedListener) {
|
|
513
|
+
pluginManager.removeEventListener(
|
|
514
|
+
PublicExtensions.RecorderPluginManager.Events.SHOW_VIEW_REQUESTED,
|
|
515
|
+
this.#extensionViewShowRequestedListener,
|
|
516
|
+
);
|
|
517
|
+
this.#extensionViewShowRequestedListener = undefined;
|
|
518
|
+
}
|
|
519
|
+
resolveView(descriptor);
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
pluginManager.addEventListener(
|
|
524
|
+
PublicExtensions.RecorderPluginManager.Events.SHOW_VIEW_REQUESTED,
|
|
525
|
+
this.#extensionViewShowRequestedListener,
|
|
526
|
+
);
|
|
527
|
+
|
|
486
528
|
extension.replay(this.currentRecording.flow);
|
|
487
529
|
const descriptor = await promise;
|
|
488
530
|
this.viewDescriptor = descriptor;
|
|
@@ -496,6 +538,13 @@ export class RecorderController extends LitElement {
|
|
|
496
538
|
if (this.viewDescriptor) {
|
|
497
539
|
this.viewDescriptor = undefined;
|
|
498
540
|
}
|
|
541
|
+
if (this.#extensionViewShowRequestedListener) {
|
|
542
|
+
PublicExtensions.RecorderPluginManager.RecorderPluginManager.instance().removeEventListener(
|
|
543
|
+
PublicExtensions.RecorderPluginManager.Events.SHOW_VIEW_REQUESTED,
|
|
544
|
+
this.#extensionViewShowRequestedListener,
|
|
545
|
+
);
|
|
546
|
+
this.#extensionViewShowRequestedListener = undefined;
|
|
547
|
+
}
|
|
499
548
|
if (event.extension) {
|
|
500
549
|
return await this.#onPlayViaExtension(event.extension);
|
|
501
550
|
}
|