chrome-devtools-frontend 1.0.1597448 → 1.0.1597624
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/AidaClient.ts +4 -0
- package/front_end/core/sdk/CPUThrottlingManager.ts +5 -1
- package/front_end/core/sdk/CSSMatchedStyles.ts +2 -0
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +28 -0
- package/front_end/models/ai_assistance/AiConversation.ts +24 -8
- package/front_end/models/ai_assistance/ChangeManager.ts +16 -0
- package/front_end/models/ai_assistance/ExtensionScope.ts +11 -3
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +127 -0
- package/front_end/models/ai_assistance/agents/AiAgent.ts +22 -3
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +1 -1
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +11 -8
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +34 -4
- package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +27 -0
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +21 -0
- package/front_end/models/trace/Processor.ts +1 -0
- package/front_end/models/trace/handlers/PageLoadMetricsHandler.ts +33 -0
- package/front_end/models/trace/insights/CharacterSet.ts +172 -0
- package/front_end/models/trace/insights/Models.ts +1 -0
- package/front_end/models/trace/insights/types.ts +1 -0
- package/front_end/models/trace/types/TraceEvents.ts +17 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +16 -3
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +90 -46
- package/front_end/panels/ai_assistance/components/MarkdownRendererWithCodeBlock.ts +18 -9
- package/front_end/panels/ai_assistance/components/chatMessage.css +11 -0
- package/front_end/panels/application/AppManifestView.ts +3 -4
- package/front_end/panels/application/DeviceBoundSessionsView.ts +18 -22
- package/front_end/panels/application/FrameDetailsView.ts +9 -15
- package/front_end/panels/application/OriginTrialTreeView.ts +2 -3
- package/front_end/panels/application/ReportingApiView.ts +13 -17
- package/front_end/panels/application/components/BackForwardCacheView.ts +3 -3
- package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +2 -3
- package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +3 -2
- package/front_end/panels/changes/ChangesView.ts +6 -4
- package/front_end/panels/console/ConsolePinPane.ts +3 -3
- package/front_end/panels/coverage/CoverageListView.ts +1 -1
- package/front_end/panels/css_overview/CSSOverviewPanel.ts +11 -15
- package/front_end/panels/developer_resources/DeveloperResourcesView.ts +3 -5
- package/front_end/panels/elements/EventListenersWidget.ts +3 -2
- package/front_end/panels/elements/StandaloneStylesContainer.ts +21 -6
- package/front_end/panels/elements/StylePropertyTreeElement.ts +49 -4
- package/front_end/panels/layer_viewer/Layers3DView.ts +5 -4
- package/front_end/panels/linear_memory_inspector/components/LinearMemoryInspector.ts +5 -6
- package/front_end/panels/linear_memory_inspector/components/LinearMemoryValueInterpreter.ts +6 -11
- package/front_end/panels/network/RequestCookiesView.ts +3 -4
- package/front_end/panels/network/RequestInitiatorView.ts +7 -5
- package/front_end/panels/network/RequestResponseView.ts +10 -15
- package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +3 -4
- package/front_end/panels/recorder/components/RecordingView.ts +31 -36
- package/front_end/panels/recorder/components/StepEditor.ts +6 -7
- package/front_end/panels/search/SearchView.ts +2 -3
- package/front_end/panels/settings/WorkspaceSettingsTab.ts +2 -5
- package/front_end/panels/timeline/components/LiveMetricsView.ts +5 -8
- package/front_end/panels/timeline/components/insights/Cache.ts +8 -10
- package/front_end/panels/timeline/components/insights/CharacterSet.ts +38 -0
- package/front_end/panels/timeline/components/insights/DOMSize.ts +16 -20
- package/front_end/panels/timeline/components/insights/DocumentLatency.ts +2 -6
- package/front_end/panels/timeline/components/insights/DuplicatedJavaScript.ts +3 -4
- package/front_end/panels/timeline/components/insights/FontDisplay.ts +3 -4
- package/front_end/panels/timeline/components/insights/ForcedReflow.ts +5 -7
- package/front_end/panels/timeline/components/insights/INPBreakdown.ts +3 -4
- package/front_end/panels/timeline/components/insights/ImageDelivery.ts +3 -4
- package/front_end/panels/timeline/components/insights/ImageRef.ts +2 -4
- package/front_end/panels/timeline/components/insights/InsightRenderer.ts +2 -0
- package/front_end/panels/timeline/components/insights/LCPBreakdown.ts +5 -7
- package/front_end/panels/timeline/components/insights/LCPDiscovery.ts +2 -4
- package/front_end/panels/timeline/components/insights/LegacyJavaScript.ts +3 -4
- package/front_end/panels/timeline/components/insights/ModernHTTP.ts +3 -4
- package/front_end/panels/timeline/components/insights/NetworkDependencyTree.ts +7 -11
- package/front_end/panels/timeline/components/insights/NodeLink.ts +2 -4
- package/front_end/panels/timeline/components/insights/RenderBlocking.ts +3 -4
- package/front_end/panels/timeline/components/insights/SlowCSSSelector.ts +7 -10
- package/front_end/panels/timeline/components/insights/ThirdParties.ts +5 -7
- package/front_end/panels/timeline/components/insights/insights.ts +2 -0
- package/front_end/panels/web_audio/WebAudioView.ts +3 -4
- package/front_end/ui/components/settings/SettingCheckbox.ts +2 -0
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +3 -3
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +8 -8
- package/front_end/ui/visual_logging/Debugging.ts +0 -32
- package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
- package/package.json +1 -1
|
@@ -203,6 +203,10 @@ export class PerformanceInsightFormatter {
|
|
|
203
203
|
{title: 'Is my site polyfilling modern JavaScript features?'},
|
|
204
204
|
{title: 'How can I reduce the amount of legacy JavaScript on my page?'},
|
|
205
205
|
];
|
|
206
|
+
case 'CharacterSet':
|
|
207
|
+
return [
|
|
208
|
+
{title: 'How do I declare a character encoding for my page?'},
|
|
209
|
+
];
|
|
206
210
|
default:
|
|
207
211
|
throw new Error(`Unknown insight key '${this.#insight.insightKey}'`);
|
|
208
212
|
}
|
|
@@ -881,6 +885,20 @@ ${requestSummary}`;
|
|
|
881
885
|
* @param insight The Network Dependency Tree Insight Model to query.
|
|
882
886
|
* @returns a string formatted for sending to Ask AI.
|
|
883
887
|
*/
|
|
888
|
+
formatCharacterSetInsight(insight: Trace.Insights.Models.CharacterSet.CharacterSetInsightModel): string {
|
|
889
|
+
let output = '';
|
|
890
|
+
if (insight.data) {
|
|
891
|
+
output += 'HTTP Content-Type header charset: ' + (insight.data.hasHttpCharset ? 'present' : 'missing') + '.\n';
|
|
892
|
+
output += 'HTML meta charset disposition: ' + (insight.data.metaCharsetDisposition ?? 'unknown') + '.\n';
|
|
893
|
+
|
|
894
|
+
if (!insight.data.hasHttpCharset && insight.data.metaCharsetDisposition !== 'found-in-first-1024-bytes') {
|
|
895
|
+
output +=
|
|
896
|
+
'\nThe page does not declare character encoding via HTTP header or a meta charset tag in the first 1024 bytes.\n';
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
return output;
|
|
900
|
+
}
|
|
901
|
+
|
|
884
902
|
formatViewportInsight(insight: Trace.Insights.Models.Viewport.ViewportInsightModel): string {
|
|
885
903
|
let output = '';
|
|
886
904
|
|
|
@@ -995,6 +1013,10 @@ ${this.#links()}`;
|
|
|
995
1013
|
return this.formatViewportInsight(this.#insight);
|
|
996
1014
|
}
|
|
997
1015
|
|
|
1016
|
+
if (Trace.Insights.Models.CharacterSet.isCharacterSetInsight(this.#insight)) {
|
|
1017
|
+
return this.formatCharacterSetInsight(this.#insight);
|
|
1018
|
+
}
|
|
1019
|
+
|
|
998
1020
|
return '';
|
|
999
1021
|
}
|
|
1000
1022
|
|
|
@@ -1074,6 +1096,9 @@ ${this.#links()}`;
|
|
|
1074
1096
|
links.push('https://web.dev/articles/baseline-and-polyfills');
|
|
1075
1097
|
links.push('https://philipwalton.com/articles/the-state-of-es5-on-the-web/');
|
|
1076
1098
|
break;
|
|
1099
|
+
case 'CharacterSet':
|
|
1100
|
+
links.push('https://developer.chrome.com/docs/insights/charset/');
|
|
1101
|
+
break;
|
|
1077
1102
|
}
|
|
1078
1103
|
|
|
1079
1104
|
return links.map(link => '- ' + link).join('\n');
|
|
@@ -1158,6 +1183,8 @@ To pass this insight, ensure your server supports and prioritizes a modern HTTP
|
|
|
1158
1183
|
return `This insight identified legacy JavaScript in your application's modules that may be creating unnecessary code.
|
|
1159
1184
|
|
|
1160
1185
|
Polyfills and transforms enable older browsers to use new JavaScript features. However, many are not necessary for modern browsers. Consider modifying your JavaScript build process to not transpile Baseline features, unless you know you must support older browsers.`;
|
|
1186
|
+
case 'CharacterSet':
|
|
1187
|
+
return `This insight checks that the page declares a character encoding, ideally via the Content-Type HTTP response header. A missing or late charset declaration can force the browser to re-parse the document once it finally determines the encoding, delaying first contentful paint. Best practice: include charset=utf-8 in the Content-Type header and add <meta charset="utf-8"> as the very first element inside <head>.`;
|
|
1161
1188
|
}
|
|
1162
1189
|
}
|
|
1163
1190
|
}
|
package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt
CHANGED
|
@@ -467,6 +467,7 @@ Here are all the insights that contain some related request from the given range
|
|
|
467
467
|
- DocumentLatency: news.yahoo.com/ (news.yahoo.com) (eventKey: s-2116, ts: 157423489126)
|
|
468
468
|
- ThirdParties: cmp.js (consent.cmp.oath.com) (eventKey: s-3382, ts: 157423742399), gpt.js (securepubads.g.doubleclick.net) (eventKey: s-6244, ts: 157423760529), loader.js (cdn.taboola.com) (eventKey: s-6352, ts: 157423761978)
|
|
469
469
|
- Cache: prebid-2.0.js (s.yimg.com) (eventKey: s-6279, ts: 157423760925), cmp.js (consent.cmp.oath.com) (eventKey: s-3382, ts: 157423742399), d1irmdsmbztlvx.js (s.yimg.com) (eventKey: s-6185, ts: 157423759200), consent.js (s.yimg.com) (eventKey: s-3384, ts: 157423742450), wnsrvbjmeprtfrnfx.js (s.yimg.com) (eventKey: s-6273, ts: 157423760794)
|
|
470
|
+
- CharacterSet: news.yahoo.com/ (news.yahoo.com) (eventKey: s-2116, ts: 157423489126)
|
|
470
471
|
- LegacyJavaScript: benji-2.2.99.js (s.yimg.com) (eventKey: s-3387, ts: 157423742567), 25fa214.caas-news_web.min.js (s.yimg.com) (eventKey: s-3412, ts: 157423743431), wnsrvbjmeprtfrnfx.js (s.yimg.com) (eventKey: s-6273, ts: 157423760794), consent.js (s.yimg.com) (eventKey: s-3384, ts: 157423742450), news.yahoo.com/ (news.yahoo.com) (eventKey: s-2116, ts: 157423489126)
|
|
471
472
|
=== end content
|
|
472
473
|
|
|
@@ -510,6 +511,10 @@ Available insights:
|
|
|
510
511
|
description: 3rd party code can significantly impact load performance. [Reduce and defer loading of 3rd party code](https://developer.chrome.com/docs/performance/insights/third-parties) to prioritize your page's content.
|
|
511
512
|
relevant trace bounds: {min: 1020034871372, max: 1020035171789}
|
|
512
513
|
example question: Which third parties are having the largest impact on my page performance?
|
|
514
|
+
- insight name: CharacterSet
|
|
515
|
+
description: A character encoding declaration is required. It can be done with a meta charset tag in the first 1024 bytes of the HTML or in the Content-Type HTTP response header. [Learn more about declaring the character encoding](https://developer.chrome.com/docs/insights/charset/).
|
|
516
|
+
relevant trace bounds: {min: 1020034836013, max: 1020034892491}
|
|
517
|
+
example question: How do I declare a character encoding for my page?
|
|
513
518
|
=== end content
|
|
514
519
|
|
|
515
520
|
Title: PerformanceTraceFormatter formatTraceSummary yahoo-news.json.gz
|
|
@@ -617,6 +622,10 @@ Available insights:
|
|
|
617
622
|
relevant trace bounds: {min: 171608170438, max: 171608877165}
|
|
618
623
|
example question: Show me the most impactful render-blocking requests that I should focus on
|
|
619
624
|
example question: How can I reduce the number of render-blocking requests?
|
|
625
|
+
- insight name: CharacterSet
|
|
626
|
+
description: A character encoding declaration is required. It can be done with a meta charset tag in the first 1024 bytes of the HTML or in the Content-Type HTTP response header. [Learn more about declaring the character encoding](https://developer.chrome.com/docs/insights/charset/).
|
|
627
|
+
relevant trace bounds: {min: 171607584346, max: 171608171143}
|
|
628
|
+
example question: How do I declare a character encoding for my page?
|
|
620
629
|
|
|
621
630
|
## insight set id: NAVIGATION_1
|
|
622
631
|
|
|
@@ -641,6 +650,10 @@ Available insights:
|
|
|
641
650
|
relevant trace bounds: {min: 171614330544, max: 171615043224}
|
|
642
651
|
example question: Show me the most impactful render-blocking requests that I should focus on
|
|
643
652
|
example question: How can I reduce the number of render-blocking requests?
|
|
653
|
+
- insight name: CharacterSet
|
|
654
|
+
description: A character encoding declaration is required. It can be done with a meta charset tag in the first 1024 bytes of the HTML or in the Content-Type HTTP response header. [Learn more about declaring the character encoding](https://developer.chrome.com/docs/insights/charset/).
|
|
655
|
+
relevant trace bounds: {min: 171613750986, max: 171614330870}
|
|
656
|
+
example question: How do I declare a character encoding for my page?
|
|
644
657
|
=== end content
|
|
645
658
|
|
|
646
659
|
Title: PerformanceTraceFormatter formatTraceSummary deals with CrUX manager errors
|
|
@@ -714,6 +727,10 @@ Available insights:
|
|
|
714
727
|
description: 3rd party code can significantly impact load performance. [Reduce and defer loading of 3rd party code](https://developer.chrome.com/docs/performance/insights/third-parties) to prioritize your page's content.
|
|
715
728
|
relevant trace bounds: {min: 59728701403, max: 59729465969}
|
|
716
729
|
example question: Which third parties are having the largest impact on my page performance?
|
|
730
|
+
- insight name: CharacterSet
|
|
731
|
+
description: A character encoding declaration is required. It can be done with a meta charset tag in the first 1024 bytes of the HTML or in the Content-Type HTTP response header. [Learn more about declaring the character encoding](https://developer.chrome.com/docs/insights/charset/).
|
|
732
|
+
relevant trace bounds: {min: 59728651057, max: 59728790724}
|
|
733
|
+
example question: How do I declare a character encoding for my page?
|
|
717
734
|
=== end content
|
|
718
735
|
|
|
719
736
|
Title: PerformanceTraceFormatter formatTraceSummary image-delivery.json.gz
|
|
@@ -794,6 +811,10 @@ Available insights:
|
|
|
794
811
|
description: 3rd party code can significantly impact load performance. [Reduce and defer loading of 3rd party code](https://developer.chrome.com/docs/performance/insights/third-parties) to prioritize your page's content.
|
|
795
812
|
relevant trace bounds: {min: 59728701403, max: 59729465969}
|
|
796
813
|
example question: Which third parties are having the largest impact on my page performance?
|
|
814
|
+
- insight name: CharacterSet
|
|
815
|
+
description: A character encoding declaration is required. It can be done with a meta charset tag in the first 1024 bytes of the HTML or in the Content-Type HTTP response header. [Learn more about declaring the character encoding](https://developer.chrome.com/docs/insights/charset/).
|
|
816
|
+
relevant trace bounds: {min: 59728651057, max: 59728790724}
|
|
817
|
+
example question: How do I declare a character encoding for my page?
|
|
797
818
|
=== end content
|
|
798
819
|
|
|
799
820
|
Title: PerformanceTraceFormatter formatTraceSummary includes INP insight when there is no navigation
|
|
@@ -40,11 +40,17 @@ let metricScoresByFrameId = new Map<FrameId, Map<AnyNavigationStart, Map<MetricN
|
|
|
40
40
|
*/
|
|
41
41
|
let allMarkerEvents: Types.Events.PageLoadEvent[] = [];
|
|
42
42
|
|
|
43
|
+
// Grouped by navigation to make it easier for insights to scope checks.
|
|
44
|
+
let metaCharsetCheckEventsByNavigation = new Map<AnyNavigationStart, Types.Events.MetaCharsetCheck[]>();
|
|
45
|
+
let metaCharsetCheckEventsArray: Types.Events.MetaCharsetCheck[] = [];
|
|
46
|
+
|
|
43
47
|
export function reset(): void {
|
|
44
48
|
metricScoresByFrameId = new Map();
|
|
45
49
|
pageLoadEventsArray = [];
|
|
46
50
|
allMarkerEvents = [];
|
|
47
51
|
selectedLCPCandidateEvents = new Set();
|
|
52
|
+
metaCharsetCheckEventsByNavigation = new Map();
|
|
53
|
+
metaCharsetCheckEventsArray = [];
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
let pageLoadEventsArray: Types.Events.PageLoadEvent[] = [];
|
|
@@ -60,6 +66,11 @@ let pageLoadEventsArray: Types.Events.PageLoadEvent[] = [];
|
|
|
60
66
|
let selectedLCPCandidateEvents = new Set<Types.Events.AnyLargestContentfulPaintCandidate>();
|
|
61
67
|
|
|
62
68
|
export function handleEvent(event: Types.Events.Event): void {
|
|
69
|
+
if (Types.Events.isMetaCharsetCheck(event)) {
|
|
70
|
+
metaCharsetCheckEventsArray.push(event);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
63
74
|
if (!Types.Events.eventIsPageLoadEvent(event)) {
|
|
64
75
|
return;
|
|
65
76
|
}
|
|
@@ -393,6 +404,23 @@ export async function finalize(): Promise<void> {
|
|
|
393
404
|
storePageLoadMetricAgainstNavigationId(navigation, pageLoadEvent);
|
|
394
405
|
}
|
|
395
406
|
}
|
|
407
|
+
|
|
408
|
+
const {navigationsByFrameId} = metaHandlerData();
|
|
409
|
+
metaCharsetCheckEventsArray.sort((a, b) => a.ts - b.ts);
|
|
410
|
+
for (const metaCharsetCheckEvent of metaCharsetCheckEventsArray) {
|
|
411
|
+
const frameId = metaCharsetCheckEvent.args.data?.frame;
|
|
412
|
+
if (!frameId) {
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
const navigation = Helpers.Trace.getNavigationForTraceEvent(metaCharsetCheckEvent, frameId, navigationsByFrameId);
|
|
416
|
+
if (!navigation) {
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
const eventsForNavigation =
|
|
420
|
+
Platform.MapUtilities.getWithDefault(metaCharsetCheckEventsByNavigation, navigation, () => []);
|
|
421
|
+
eventsForNavigation.push(metaCharsetCheckEvent);
|
|
422
|
+
}
|
|
423
|
+
|
|
396
424
|
// NOTE: if you are looking for the TBT calculation, it has temporarily been
|
|
397
425
|
// removed. See crbug.com/1424335 for details.
|
|
398
426
|
const allFinalLCPEvents = gatherFinalLCPEvents();
|
|
@@ -421,12 +449,17 @@ export interface PageLoadMetricsData {
|
|
|
421
449
|
* main frame.
|
|
422
450
|
*/
|
|
423
451
|
allMarkerEvents: Types.Events.PageLoadEvent[];
|
|
452
|
+
/**
|
|
453
|
+
* MetaCharsetCheck events grouped by navigation.
|
|
454
|
+
*/
|
|
455
|
+
metaCharsetCheckEventsByNavigation: Map<AnyNavigationStart, Types.Events.MetaCharsetCheck[]>;
|
|
424
456
|
}
|
|
425
457
|
|
|
426
458
|
export function data(): PageLoadMetricsData {
|
|
427
459
|
return {
|
|
428
460
|
metricScoresByFrameId,
|
|
429
461
|
allMarkerEvents,
|
|
462
|
+
metaCharsetCheckEventsByNavigation,
|
|
430
463
|
};
|
|
431
464
|
}
|
|
432
465
|
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// Copyright 2026 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
|
+
import * as i18n from '../../../core/i18n/i18n.js';
|
|
6
|
+
import type * as Handlers from '../handlers/handlers.js';
|
|
7
|
+
import type * as Types from '../types/types.js';
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
type Checklist,
|
|
11
|
+
InsightCategory,
|
|
12
|
+
InsightKeys,
|
|
13
|
+
type InsightModel,
|
|
14
|
+
type InsightSetContext,
|
|
15
|
+
InsightWarning,
|
|
16
|
+
type PartialInsightModel,
|
|
17
|
+
} from './types.js';
|
|
18
|
+
|
|
19
|
+
export const UIStrings = {
|
|
20
|
+
/**
|
|
21
|
+
* @description Title of an insight that checks whether the page declares a character encoding early enough.
|
|
22
|
+
*/
|
|
23
|
+
title: 'Declare a character encoding',
|
|
24
|
+
/**
|
|
25
|
+
* @description Description of an insight that checks whether the page has a proper character encoding declaration via HTTP header or early meta tag.
|
|
26
|
+
*/
|
|
27
|
+
description:
|
|
28
|
+
'A character encoding declaration is required. It can be done with a meta charset tag in the first 1024 bytes of the HTML or in the Content-Type HTTP response header. [Learn more about declaring the character encoding](https://developer.chrome.com/docs/insights/charset/).',
|
|
29
|
+
/**
|
|
30
|
+
* @description Text to tell the user that the charset is declared in the Content-Type HTTP response header.
|
|
31
|
+
*/
|
|
32
|
+
passingHttpHeader: 'Declares charset in HTTP header',
|
|
33
|
+
/**
|
|
34
|
+
* @description Text to tell the user that the charset is NOT declared in the Content-Type HTTP response header.
|
|
35
|
+
*/
|
|
36
|
+
failedHttpHeader: 'Does not declare charset in HTTP header',
|
|
37
|
+
/**
|
|
38
|
+
* @description Text to tell the user that a meta charset tag was found in the first 1024 bytes of the HTML.
|
|
39
|
+
*/
|
|
40
|
+
passingMetaCharsetEarly: 'Declares charset using a meta tag in the first 1024 bytes',
|
|
41
|
+
/**
|
|
42
|
+
* @description Text to tell the user that a meta charset tag was found, but too late in the HTML.
|
|
43
|
+
*/
|
|
44
|
+
failedMetaCharsetLate: 'Declares charset using a meta tag after the first 1024 bytes',
|
|
45
|
+
/**
|
|
46
|
+
* @description Text to tell the user that no meta charset tag was found in the HTML.
|
|
47
|
+
*/
|
|
48
|
+
failedMetaCharsetMissing: 'Does not declare charset using a meta tag',
|
|
49
|
+
/**
|
|
50
|
+
* @description Text to tell the user that trace data did not include the Blink signal for meta charset.
|
|
51
|
+
*/
|
|
52
|
+
failedMetaCharsetUnknown: 'Could not determine meta charset declaration from trace',
|
|
53
|
+
} as const;
|
|
54
|
+
|
|
55
|
+
const str_ = i18n.i18n.registerUIStrings('models/trace/insights/CharacterSet.ts', UIStrings);
|
|
56
|
+
export const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
57
|
+
|
|
58
|
+
const CHARSET_HTTP_REGEX = /charset\s*=\s*[a-zA-Z0-9\-_:.()]{2,}/i;
|
|
59
|
+
|
|
60
|
+
export type CharacterSetInsightModel = InsightModel<typeof UIStrings, {
|
|
61
|
+
data?: {
|
|
62
|
+
hasHttpCharset: boolean,
|
|
63
|
+
checklist: Checklist<'httpCharset'|'metaCharset'>,
|
|
64
|
+
metaCharsetDisposition?: Types.Events.MetaCharsetDisposition,
|
|
65
|
+
documentRequest?: Types.Events.SyntheticNetworkRequest,
|
|
66
|
+
},
|
|
67
|
+
}>;
|
|
68
|
+
|
|
69
|
+
export function isCharacterSetInsight(model: InsightModel): model is CharacterSetInsightModel {
|
|
70
|
+
return model.insightKey === InsightKeys.CHARACTER_SET;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function finalize(partialModel: PartialInsightModel<CharacterSetInsightModel>): CharacterSetInsightModel {
|
|
74
|
+
let hasFailure = false;
|
|
75
|
+
if (partialModel.data) {
|
|
76
|
+
hasFailure = !partialModel.data.checklist.httpCharset.value && !partialModel.data.checklist.metaCharset.value;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
insightKey: InsightKeys.CHARACTER_SET,
|
|
81
|
+
strings: UIStrings,
|
|
82
|
+
title: i18nString(UIStrings.title),
|
|
83
|
+
description: i18nString(UIStrings.description),
|
|
84
|
+
docs: 'https://developer.chrome.com/docs/insights/charset/',
|
|
85
|
+
category: InsightCategory.ALL,
|
|
86
|
+
state: hasFailure ? 'fail' : 'pass',
|
|
87
|
+
...partialModel,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function hasCharsetInContentType(request: Types.Events.SyntheticNetworkRequest): boolean {
|
|
92
|
+
if (!request.args.data.responseHeaders) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
for (const header of request.args.data.responseHeaders) {
|
|
96
|
+
if (header.name.toLowerCase() === 'content-type') {
|
|
97
|
+
return CHARSET_HTTP_REGEX.test(header.value);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function findMetaCharsetDisposition(
|
|
104
|
+
data: Handlers.Types.HandlerData,
|
|
105
|
+
context: InsightSetContext,
|
|
106
|
+
): Types.Events.MetaCharsetDisposition|undefined {
|
|
107
|
+
if (!context.navigation) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
return data.PageLoadMetrics.metaCharsetCheckEventsByNavigation.get(context.navigation)
|
|
111
|
+
?.at(-1)
|
|
112
|
+
?.args.data?.disposition;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function metaCharsetLabel(disposition: Types.Events.MetaCharsetDisposition|undefined): ReturnType<typeof i18nString> {
|
|
116
|
+
switch (disposition) {
|
|
117
|
+
case 'found-in-first-1024-bytes':
|
|
118
|
+
return i18nString(UIStrings.passingMetaCharsetEarly);
|
|
119
|
+
case 'found-after-first-1024-bytes':
|
|
120
|
+
return i18nString(UIStrings.failedMetaCharsetLate);
|
|
121
|
+
case 'not-found':
|
|
122
|
+
return i18nString(UIStrings.failedMetaCharsetMissing);
|
|
123
|
+
default:
|
|
124
|
+
return i18nString(UIStrings.failedMetaCharsetUnknown);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function generateInsight(
|
|
129
|
+
data: Handlers.Types.HandlerData, context: InsightSetContext): CharacterSetInsightModel {
|
|
130
|
+
if (!context.navigation) {
|
|
131
|
+
return finalize({});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const documentRequest = data.NetworkRequests.byId.get(context.navigationId);
|
|
135
|
+
if (!documentRequest) {
|
|
136
|
+
return finalize({warnings: [InsightWarning.NO_DOCUMENT_REQUEST]});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const hasHttpCharset = hasCharsetInContentType(documentRequest);
|
|
140
|
+
const metaCharsetDisposition = findMetaCharsetDisposition(data, context);
|
|
141
|
+
const hasMetaCharsetInFirst1024Bytes = metaCharsetDisposition === 'found-in-first-1024-bytes';
|
|
142
|
+
|
|
143
|
+
return finalize({
|
|
144
|
+
relatedEvents: [documentRequest],
|
|
145
|
+
data: {
|
|
146
|
+
hasHttpCharset,
|
|
147
|
+
metaCharsetDisposition,
|
|
148
|
+
documentRequest,
|
|
149
|
+
checklist: {
|
|
150
|
+
httpCharset: {
|
|
151
|
+
label: hasHttpCharset ? i18nString(UIStrings.passingHttpHeader) : i18nString(UIStrings.failedHttpHeader),
|
|
152
|
+
value: hasHttpCharset,
|
|
153
|
+
},
|
|
154
|
+
metaCharset: {
|
|
155
|
+
label: metaCharsetLabel(metaCharsetDisposition),
|
|
156
|
+
value: hasMetaCharsetInFirst1024Bytes,
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function createOverlays(model: CharacterSetInsightModel): Types.Overlays.Overlay[] {
|
|
164
|
+
if (!model.data?.documentRequest) {
|
|
165
|
+
return [];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return [{
|
|
169
|
+
type: 'ENTRY_SELECTED',
|
|
170
|
+
entry: model.data.documentRequest,
|
|
171
|
+
}];
|
|
172
|
+
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
export * as Cache from './Cache.js';
|
|
6
|
+
export * as CharacterSet from './CharacterSet.js';
|
|
6
7
|
export * as CLSCulprits from './CLSCulprits.js';
|
|
7
8
|
export * as DocumentLatency from './DocumentLatency.js';
|
|
8
9
|
export * as DOMSize from './DOMSize.js';
|
|
@@ -1360,6 +1360,22 @@ export function isParseMetaViewport(event: Event): event is ParseMetaViewport {
|
|
|
1360
1360
|
return event.name === Name.PARSE_META_VIEWPORT;
|
|
1361
1361
|
}
|
|
1362
1362
|
|
|
1363
|
+
export type MetaCharsetDisposition = 'found-in-first-1024-bytes'|'found-after-first-1024-bytes'|'not-found';
|
|
1364
|
+
|
|
1365
|
+
export interface MetaCharsetCheck extends Instant {
|
|
1366
|
+
name: Name.META_CHARSET_CHECK;
|
|
1367
|
+
args: Args&{
|
|
1368
|
+
data: {
|
|
1369
|
+
frame: string,
|
|
1370
|
+
disposition: MetaCharsetDisposition,
|
|
1371
|
+
},
|
|
1372
|
+
};
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
export function isMetaCharsetCheck(event: Event): event is MetaCharsetCheck {
|
|
1376
|
+
return event.name === Name.META_CHARSET_CHECK;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1363
1379
|
export interface LinkPreconnect extends Instant {
|
|
1364
1380
|
name: Name.LINK_PRECONNECT;
|
|
1365
1381
|
args: Args&{
|
|
@@ -3110,6 +3126,7 @@ export const enum Name {
|
|
|
3110
3126
|
SELECTOR_STATS = 'SelectorStats',
|
|
3111
3127
|
BEGIN_COMMIT_COMPOSITOR_FRAME = 'BeginCommitCompositorFrame',
|
|
3112
3128
|
PARSE_META_VIEWPORT = 'ParseMetaViewport',
|
|
3129
|
+
META_CHARSET_CHECK = 'MetaCharsetCheck',
|
|
3113
3130
|
|
|
3114
3131
|
/* Paint */
|
|
3115
3132
|
SCROLL_LAYER = 'ScrollLayer',
|
|
@@ -1699,8 +1699,14 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1699
1699
|
parts: [],
|
|
1700
1700
|
};
|
|
1701
1701
|
this.#messages.push(systemMessage);
|
|
1702
|
-
|
|
1703
|
-
|
|
1702
|
+
// If the walkthrough is currently expanded in the sidebar, we want to
|
|
1703
|
+
// automatically swap it to the newly created message's walkthrough.
|
|
1704
|
+
// This ensures that when a user asks a new question, the sidebar updates
|
|
1705
|
+
// immediately to show the "loading" state of the new walkthrough.
|
|
1706
|
+
const isSidebarWalkthroughOpen = this.#walkthrough.isExpanded && !this.#walkthrough.isInlined;
|
|
1707
|
+
if (isSidebarWalkthroughOpen ||
|
|
1708
|
+
(Greendev.Prototypes.instance().isEnabled('breakpointDebuggerAgent') &&
|
|
1709
|
+
this.#conversation?.type === AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT)) {
|
|
1704
1710
|
this.#openWalkthrough(systemMessage);
|
|
1705
1711
|
}
|
|
1706
1712
|
break;
|
|
@@ -1788,6 +1794,13 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1788
1794
|
systemMessage.parts.push(newPart);
|
|
1789
1795
|
}
|
|
1790
1796
|
|
|
1797
|
+
if (data.widgets && Root.Runtime.hostConfig.devToolsAiAssistanceV2?.enabled) {
|
|
1798
|
+
systemMessage.parts.push({
|
|
1799
|
+
type: 'widget',
|
|
1800
|
+
widgets: data.widgets,
|
|
1801
|
+
});
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1791
1804
|
// When there is an answer without any thinking steps, we don't want to show the thinking step.
|
|
1792
1805
|
// TODO(crbug.com/463323934): Remove specially handling this case.
|
|
1793
1806
|
if (systemMessage.parts.length > 1) {
|
|
@@ -1881,7 +1894,7 @@ export function getResponseMarkdown(message: ModelChatMessage): string {
|
|
|
1881
1894
|
for (const part of message.parts) {
|
|
1882
1895
|
if (part.type === 'answer') {
|
|
1883
1896
|
contentParts.push(`### Answer\n\n${part.text}`);
|
|
1884
|
-
} else {
|
|
1897
|
+
} else if (part.type === 'step') {
|
|
1885
1898
|
const step = part.step;
|
|
1886
1899
|
if (step.title) {
|
|
1887
1900
|
contentParts.push(`### ${step.title}`);
|