chrome-devtools-frontend 1.0.1564932 → 1.0.1565595
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/AUTHORS +1 -0
- package/front_end/core/sdk/NetworkManager.ts +3 -0
- package/front_end/generated/InspectorBackendCommands.ts +9 -0
- package/front_end/generated/SupportedCSSProperties.js +46 -0
- package/front_end/generated/protocol-mapping.d.ts +18 -0
- package/front_end/generated/protocol-proxy-api.d.ts +15 -0
- package/front_end/generated/protocol.ts +152 -0
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +2 -2
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +2 -2
- package/front_end/models/emulation/EmulatedDevices.ts +28 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +4 -0
- package/front_end/models/trace/extras/Initiators.ts +59 -0
- package/front_end/models/trace/extras/extras.ts +1 -0
- package/front_end/models/trace/handlers/NetworkRequestsHandler.ts +19 -2
- package/front_end/models/trace/insights/NetworkDependencyTree.ts +3 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +10 -10
- package/front_end/panels/ai_assistance/ai_assistance.ts +1 -1
- package/front_end/panels/ai_assistance/components/{UserActionRow.ts → ChatMessage.ts} +10 -10
- package/front_end/panels/ai_assistance/components/ChatView.ts +5 -5
- package/front_end/panels/common/ExtensionServer.ts +6 -1
- package/front_end/panels/console/ConsolePinPane.ts +1 -2
- package/front_end/panels/console/ConsoleView.ts +6 -9
- package/front_end/panels/elements/CSSValueTraceView.ts +1 -1
- package/front_end/panels/elements/ElementsTreeElement.ts +1 -1
- package/front_end/panels/elements/LayersWidget.ts +1 -1
- package/front_end/panels/emulation/MediaQueryInspector.ts +1 -2
- package/front_end/panels/network/RequestResponseView.ts +1 -1
- package/front_end/panels/recorder/RecorderController.ts +16 -0
- package/front_end/panels/sources/AiCodeCompletionPlugin.ts +6 -9
- package/front_end/panels/timeline/Initiators.ts +7 -5
- package/front_end/panels/timeline/components/NetworkRequestDetails.ts +5 -3
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/codemirror.next/rebuild.sh +1 -1
- package/front_end/third_party/lit/rebuild.sh +1 -1
- package/front_end/ui/components/buttons/button.css +6 -0
- package/front_end/ui/components/text_editor/{AiCodeCompletionTeaserPlaceholder.ts → AccessiblePlaceholder.ts} +3 -22
- package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +16 -13
- package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +11 -10
- package/front_end/ui/components/text_editor/TextEditor.ts +3 -0
- package/front_end/ui/components/text_editor/text_editor.ts +1 -1
- package/front_end/ui/legacy/PopoverHelper.ts +10 -0
- package/front_end/ui/legacy/softContextMenu.css +2 -0
- package/front_end/ui/lit/lit.ts +1 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +6 -0
- package/package.json +1 -1
- /package/front_end/panels/ai_assistance/components/{userActionRow.css → chatMessage.css} +0 -0
|
@@ -55,7 +55,13 @@ let linkPreconnectEvents: Types.Events.LinkPreconnect[] = [];
|
|
|
55
55
|
interface NetworkRequestData {
|
|
56
56
|
byId: Map<string, Types.Events.SyntheticNetworkRequest>;
|
|
57
57
|
byTime: Types.Events.SyntheticNetworkRequest[];
|
|
58
|
-
|
|
58
|
+
requestIdsByURL: Map<string, string[]>;
|
|
59
|
+
/**
|
|
60
|
+
* IMPORTANT: you should prefer to use `Trace.Extras.Initiator` to find the initiator.
|
|
61
|
+
* This is because backend trace events have some bugs which means the initiators are not always accurate.
|
|
62
|
+
* See crrev.com/c/7032169 for context.
|
|
63
|
+
*/
|
|
64
|
+
incompleteInitiator: Map<Types.Events.SyntheticNetworkRequest, Types.Events.SyntheticNetworkRequest>;
|
|
59
65
|
webSocket: WebSocketTraceData[];
|
|
60
66
|
entityMappings: HandlerHelpers.EntityMappings;
|
|
61
67
|
linkPreconnectEvents: Types.Events.LinkPreconnect[];
|
|
@@ -65,6 +71,11 @@ let requestMap = new Map<string, TraceEventsForNetworkRequest>();
|
|
|
65
71
|
let requestsById = new Map<string, Types.Events.SyntheticNetworkRequest>();
|
|
66
72
|
let requestsByTime: Types.Events.SyntheticNetworkRequest[] = [];
|
|
67
73
|
|
|
74
|
+
/**
|
|
75
|
+
* URL => RequestId[]. There can be multiple requests for a single URL.
|
|
76
|
+
*/
|
|
77
|
+
let requestIdsByURL = new Map<string, string[]>();
|
|
78
|
+
|
|
68
79
|
let networkRequestEventByInitiatorUrl = new Map<string, Types.Events.SyntheticNetworkRequest[]>();
|
|
69
80
|
let eventToInitiatorMap = new Map<Types.Events.SyntheticNetworkRequest, Types.Events.SyntheticNetworkRequest>();
|
|
70
81
|
|
|
@@ -120,6 +131,7 @@ export function reset(): void {
|
|
|
120
131
|
networkRequestEventByInitiatorUrl = new Map();
|
|
121
132
|
eventToInitiatorMap = new Map();
|
|
122
133
|
webSocketData = new Map();
|
|
134
|
+
requestIdsByURL = new Map();
|
|
123
135
|
entityMappings = {
|
|
124
136
|
eventsByEntity: new Map<HandlerHelpers.Entity, Types.Events.Event[]>(),
|
|
125
137
|
entityByEvent: new Map<Types.Events.Event, HandlerHelpers.Entity>(),
|
|
@@ -587,6 +599,10 @@ export async function finalize(): Promise<void> {
|
|
|
587
599
|
requestsByTime.push(networkEvent);
|
|
588
600
|
requestsById.set(networkEvent.args.data.requestId, networkEvent);
|
|
589
601
|
|
|
602
|
+
const requestsForUrl = requestIdsByURL.get(networkEvent.args.data.url) ?? [];
|
|
603
|
+
requestsForUrl.push(networkEvent.args.data.requestId);
|
|
604
|
+
requestIdsByURL.set(networkEvent.args.data.url, requestsForUrl);
|
|
605
|
+
|
|
590
606
|
// Update entity relationships for network events
|
|
591
607
|
HandlerHelpers.addNetworkRequestToEntityMapping(networkEvent, entityMappings, request);
|
|
592
608
|
|
|
@@ -617,7 +633,8 @@ export function data(): NetworkRequestData {
|
|
|
617
633
|
return {
|
|
618
634
|
byId: requestsById,
|
|
619
635
|
byTime: requestsByTime,
|
|
620
|
-
|
|
636
|
+
requestIdsByURL,
|
|
637
|
+
incompleteInitiator: eventToInitiatorMap,
|
|
621
638
|
webSocket: [...webSocketData.values()],
|
|
622
639
|
entityMappings: {
|
|
623
640
|
entityByEvent: entityMappings.entityByEvent,
|
|
@@ -550,7 +550,9 @@ function candidateRequestsByOrigin(
|
|
|
550
550
|
}
|
|
551
551
|
|
|
552
552
|
// Filter out all resources that are loaded by the document. Connections are already early.
|
|
553
|
-
|
|
553
|
+
// TODO(jacktfranklin, b/392090449): swap this over to use the initiator
|
|
554
|
+
// lookup that fixes bugs with dynamically injected content.
|
|
555
|
+
if (data.NetworkRequests.incompleteInitiator.get(request) === mainResource) {
|
|
554
556
|
return;
|
|
555
557
|
}
|
|
556
558
|
|
|
@@ -28,6 +28,13 @@ import * as TimelinePanel from '../timeline/timeline.js';
|
|
|
28
28
|
|
|
29
29
|
import aiAssistancePanelStyles from './aiAssistancePanel.css.js';
|
|
30
30
|
import {ArtifactsViewer} from './components/ArtifactsViewer.js';
|
|
31
|
+
import {
|
|
32
|
+
type AnswerPart,
|
|
33
|
+
ChatMessageEntity,
|
|
34
|
+
type Message,
|
|
35
|
+
type ModelChatMessage,
|
|
36
|
+
type Step,
|
|
37
|
+
} from './components/ChatMessage.js';
|
|
31
38
|
import {
|
|
32
39
|
ChatView,
|
|
33
40
|
type Props as ChatViewProps,
|
|
@@ -36,18 +43,11 @@ import {DisabledWidget} from './components/DisabledWidget.js';
|
|
|
36
43
|
import {ExploreWidget} from './components/ExploreWidget.js';
|
|
37
44
|
import {MarkdownRendererWithCodeBlock} from './components/MarkdownRendererWithCodeBlock.js';
|
|
38
45
|
import {PerformanceAgentMarkdownRenderer} from './components/PerformanceAgentMarkdownRenderer.js';
|
|
39
|
-
import {
|
|
40
|
-
type AnswerPart,
|
|
41
|
-
type ChatMessage,
|
|
42
|
-
ChatMessageEntity,
|
|
43
|
-
type ModelChatMessage,
|
|
44
|
-
type Step,
|
|
45
|
-
} from './components/UserActionRow.js';
|
|
46
46
|
import {isAiAssistancePatchingEnabled} from './PatchWidget.js';
|
|
47
47
|
|
|
48
48
|
// FIXME: this export is temporary to avoid rewriting tests.
|
|
49
|
-
export {ChatMessageEntity} from './components/
|
|
50
|
-
export type {AnswerPart, ModelChatMessage, StepPart} from './components/
|
|
49
|
+
export {ChatMessageEntity} from './components/ChatMessage.js';
|
|
50
|
+
export type {AnswerPart, ModelChatMessage, StepPart} from './components/ChatMessage.js';
|
|
51
51
|
|
|
52
52
|
const {html} = Lit;
|
|
53
53
|
|
|
@@ -518,7 +518,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
518
518
|
#selectedRequest: AiAssistanceModel.NetworkAgent.RequestContext|null = null;
|
|
519
519
|
#isArtifactsSidebarOpen = false;
|
|
520
520
|
// Messages displayed in the `ChatView` component.
|
|
521
|
-
#messages:
|
|
521
|
+
#messages: Message[] = [];
|
|
522
522
|
|
|
523
523
|
// Whether the UI should show loading or not.
|
|
524
524
|
#isLoading = false;
|
|
@@ -8,7 +8,7 @@ export * as ChatInput from './components/ChatInput.js';
|
|
|
8
8
|
export * from './components/MarkdownRendererWithCodeBlock.js';
|
|
9
9
|
export * from './components/PerformanceAgentFlameChart.js';
|
|
10
10
|
export * from './SelectWorkspaceDialog.js';
|
|
11
|
-
export * as
|
|
11
|
+
export * as ChatMessage from './components/ChatMessage.js';
|
|
12
12
|
export * as ExploreWidget from './components/ExploreWidget.js';
|
|
13
13
|
export * as PatchWidget from './PatchWidget.js';
|
|
14
14
|
export * as DisabledWidget from './components/DisabledWidget.js';
|
|
@@ -19,7 +19,7 @@ import * as UI from '../../../ui/legacy/legacy.js';
|
|
|
19
19
|
import * as Lit from '../../../ui/lit/lit.js';
|
|
20
20
|
import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
|
|
21
21
|
|
|
22
|
-
import
|
|
22
|
+
import chatMessageStyles from './chatMessage.css.js';
|
|
23
23
|
|
|
24
24
|
const {html, Directives: {ref, ifDefined}} = Lit;
|
|
25
25
|
const lockedString = i18n.i18n.lockedString;
|
|
@@ -205,7 +205,7 @@ export interface ModelChatMessage {
|
|
|
205
205
|
rpcId?: Host.AidaClient.RpcGlobalId;
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
-
export type
|
|
208
|
+
export type Message = UserChatMessage|ModelChatMessage;
|
|
209
209
|
|
|
210
210
|
export interface RatingViewInput {
|
|
211
211
|
currentRating?: Host.AidaClient.Rating;
|
|
@@ -233,7 +233,7 @@ export interface FeedbackFormViewInput {
|
|
|
233
233
|
isSubmitButtonDisabled: boolean;
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
export type
|
|
236
|
+
export type ChatMessageViewInput =
|
|
237
237
|
MessageInput&RatingViewInput&ActionViewInput&SuggestionViewInput&FeedbackFormViewInput;
|
|
238
238
|
|
|
239
239
|
export interface ViewOutput {
|
|
@@ -244,7 +244,7 @@ export interface ViewOutput {
|
|
|
244
244
|
|
|
245
245
|
export interface MessageInput {
|
|
246
246
|
suggestions?: [string, ...string[]];
|
|
247
|
-
message:
|
|
247
|
+
message: Message;
|
|
248
248
|
isLoading: boolean;
|
|
249
249
|
isReadOnly: boolean;
|
|
250
250
|
isLastMessage: boolean;
|
|
@@ -256,7 +256,7 @@ export interface MessageInput {
|
|
|
256
256
|
onCopyResponseClick: (message: ModelChatMessage) => void;
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
export const DEFAULT_VIEW = (input:
|
|
259
|
+
export const DEFAULT_VIEW = (input: ChatMessageViewInput, output: ViewOutput, target: HTMLElement): void => {
|
|
260
260
|
const message = input.message;
|
|
261
261
|
if (message.entity === ChatMessageEntity.USER) {
|
|
262
262
|
const name = input.userInfo.accountFullName || lockedString(UIStringsNotTranslate.you);
|
|
@@ -272,7 +272,7 @@ export const DEFAULT_VIEW = (input: UserActionRowViewInput, output: ViewOutput,
|
|
|
272
272
|
// clang-format off
|
|
273
273
|
Lit.render(html`
|
|
274
274
|
<style>${Input.textInputStyles}</style>
|
|
275
|
-
<style>${
|
|
275
|
+
<style>${chatMessageStyles}</style>
|
|
276
276
|
<section
|
|
277
277
|
class="chat-message query ${input.isLastMessage ? 'is-last-message' : ''}"
|
|
278
278
|
jslog=${VisualLogging.section('question')}
|
|
@@ -294,7 +294,7 @@ export const DEFAULT_VIEW = (input: UserActionRowViewInput, output: ViewOutput,
|
|
|
294
294
|
// clang-format off
|
|
295
295
|
Lit.render(html`
|
|
296
296
|
<style>${Input.textInputStyles}</style>
|
|
297
|
-
<style>${
|
|
297
|
+
<style>${chatMessageStyles}</style>
|
|
298
298
|
<section
|
|
299
299
|
class="chat-message answer ${input.isLastMessage ? 'is-last-message' : ''}"
|
|
300
300
|
jslog=${VisualLogging.section('answer')}
|
|
@@ -585,7 +585,7 @@ function renderImageChatMessage(inlineData: Host.AidaClient.MediaBlob): Lit.LitT
|
|
|
585
585
|
// clang-format on
|
|
586
586
|
}
|
|
587
587
|
|
|
588
|
-
function renderActions(input:
|
|
588
|
+
function renderActions(input: ChatMessageViewInput, output: ViewOutput): Lit.LitTemplate {
|
|
589
589
|
// clang-format off
|
|
590
590
|
return html`
|
|
591
591
|
<div class="ai-assistance-feedback-row">
|
|
@@ -739,8 +739,8 @@ function renderActions(input: UserActionRowViewInput, output: ViewOutput): Lit.L
|
|
|
739
739
|
// clang-format on
|
|
740
740
|
}
|
|
741
741
|
|
|
742
|
-
export class
|
|
743
|
-
message:
|
|
742
|
+
export class ChatMessage extends UI.Widget.Widget {
|
|
743
|
+
message: Message = {entity: ChatMessageEntity.USER, text: ''};
|
|
744
744
|
isLoading = false;
|
|
745
745
|
isReadOnly = false;
|
|
746
746
|
canShowFeedbackForm = false;
|
|
@@ -17,8 +17,8 @@ import * as Lit from '../../../ui/lit/lit.js';
|
|
|
17
17
|
import {PatchWidget} from '../PatchWidget.js';
|
|
18
18
|
|
|
19
19
|
import {ChatInput} from './ChatInput.js';
|
|
20
|
+
import {ChatMessage, type Message, type ModelChatMessage} from './ChatMessage.js';
|
|
20
21
|
import chatViewStyles from './chatView.css.js';
|
|
21
|
-
import {type ChatMessage, type ModelChatMessage, UserActionRow} from './UserActionRow.js';
|
|
22
22
|
|
|
23
23
|
export {ChatInput, type ImageInputData} from './ChatInput.js';
|
|
24
24
|
|
|
@@ -50,7 +50,7 @@ export interface Props {
|
|
|
50
50
|
onCopyResponseClick: (message: ModelChatMessage) => void;
|
|
51
51
|
changeManager: AiAssistanceModel.ChangeManager.ChangeManager;
|
|
52
52
|
inspectElementToggled: boolean;
|
|
53
|
-
messages:
|
|
53
|
+
messages: Message[];
|
|
54
54
|
selectedContext: AiAssistanceModel.AiAgent.ConversationContext<unknown>|null;
|
|
55
55
|
isLoading: boolean;
|
|
56
56
|
canShowFeedbackForm: boolean;
|
|
@@ -282,7 +282,7 @@ function renderMainContents({
|
|
|
282
282
|
onCopyResponseClick,
|
|
283
283
|
onMessageContainerRef,
|
|
284
284
|
}: {
|
|
285
|
-
messages:
|
|
285
|
+
messages: Message[],
|
|
286
286
|
isLoading: boolean,
|
|
287
287
|
isReadOnly: boolean,
|
|
288
288
|
canShowFeedbackForm: boolean,
|
|
@@ -331,7 +331,7 @@ function renderMessages({
|
|
|
331
331
|
onCopyResponseClick,
|
|
332
332
|
onMessageContainerRef,
|
|
333
333
|
}: {
|
|
334
|
-
messages:
|
|
334
|
+
messages: Message[],
|
|
335
335
|
isLoading: boolean,
|
|
336
336
|
isReadOnly: boolean,
|
|
337
337
|
canShowFeedbackForm: boolean,
|
|
@@ -363,7 +363,7 @@ function renderMessages({
|
|
|
363
363
|
return html`
|
|
364
364
|
<div class="messages-container" ${ref(onMessageContainerRef)}>
|
|
365
365
|
${repeat(messages, message =>
|
|
366
|
-
html`<devtools-widget .widgetConfig=${UI.Widget.widgetConfig(
|
|
366
|
+
html`<devtools-widget .widgetConfig=${UI.Widget.widgetConfig(ChatMessage, {
|
|
367
367
|
message,
|
|
368
368
|
isLoading,
|
|
369
369
|
isReadOnly,
|
|
@@ -1669,7 +1669,12 @@ class ExtensionServerPanelView extends UI.View.SimpleView {
|
|
|
1669
1669
|
// used anywhere, since we override the `viewId()` method below. Ideally we'd pass the
|
|
1670
1670
|
// `name` as `viewId` to the constructor, but that doesn't work, since the `name` is not
|
|
1671
1671
|
// necessarily in Kebab case.
|
|
1672
|
-
|
|
1672
|
+
//
|
|
1673
|
+
// For non-ASCII titles (e.g., Chinese, Japanese, Arabic), the kebab-cased result may not
|
|
1674
|
+
// pass isExtendedKebabCase validation, so we fall back to 'extension-panel'.
|
|
1675
|
+
const kebabTitle = Platform.StringUtilities.toKebabCase(title);
|
|
1676
|
+
const viewId =
|
|
1677
|
+
Platform.StringUtilities.isExtendedKebabCase(kebabTitle) ? kebabTitle : 'extension-panel' as Lowercase<string>;
|
|
1673
1678
|
super({title, viewId});
|
|
1674
1679
|
this.name = name;
|
|
1675
1680
|
this.panel = panel;
|
|
@@ -8,14 +8,13 @@ import * as Platform from '../../core/platform/platform.js';
|
|
|
8
8
|
import * as Root from '../../core/root/root.js';
|
|
9
9
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
10
10
|
import * as CodeMirror from '../../third_party/codemirror.next/codemirror.next.js';
|
|
11
|
-
import {Directives, html, nothing, render} from '../../third_party/lit/lit.js';
|
|
12
11
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
13
12
|
import * as TextEditor from '../../ui/components/text_editor/text_editor.js';
|
|
14
13
|
import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
|
|
15
14
|
// eslint-disable-next-line @devtools/es-modules-import
|
|
16
15
|
import objectValueStyles from '../../ui/legacy/components/object_ui/objectValue.css.js';
|
|
17
16
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
18
|
-
import type
|
|
17
|
+
import {Directives, html, type LitTemplate, nothing, render} from '../../ui/lit/lit.js';
|
|
19
18
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
20
19
|
|
|
21
20
|
import consolePinPaneStyles from './consolePinPane.css.js';
|
|
@@ -340,7 +340,6 @@ export class ConsoleView extends UI.Widget.VBox implements
|
|
|
340
340
|
aiCodeCompletionConfig?: TextEditor.AiCodeCompletionProvider.AiCodeCompletionConfig;
|
|
341
341
|
private aiCodeCompletionSummaryToolbarContainer?: HTMLElement;
|
|
342
342
|
private aiCodeCompletionSummaryToolbar?: AiCodeCompletionSummaryToolbar;
|
|
343
|
-
private aiCodeCompletionCitations: Host.AidaClient.Citation[] = [];
|
|
344
343
|
|
|
345
344
|
constructor(viewportThrottlerTimeout: number) {
|
|
346
345
|
super();
|
|
@@ -657,21 +656,19 @@ export class ConsoleView extends UI.Widget.VBox implements
|
|
|
657
656
|
this.aiCodeCompletionSummaryToolbar.show(this.aiCodeCompletionSummaryToolbarContainer, undefined, true);
|
|
658
657
|
}
|
|
659
658
|
|
|
660
|
-
#onAiCodeCompletionSuggestionAccepted(): void {
|
|
661
|
-
if (!this.aiCodeCompletionSummaryToolbar ||
|
|
659
|
+
#onAiCodeCompletionSuggestionAccepted(citations: Host.AidaClient.Citation[]): void {
|
|
660
|
+
if (!this.aiCodeCompletionSummaryToolbar || citations.length === 0) {
|
|
662
661
|
return;
|
|
663
662
|
}
|
|
664
|
-
const citations
|
|
665
|
-
|
|
666
|
-
this.aiCodeCompletionSummaryToolbar.updateCitations(citations);
|
|
663
|
+
const citationsUri = citations.map(citation => citation.uri).filter((uri): uri is string => Boolean(uri));
|
|
664
|
+
this.aiCodeCompletionSummaryToolbar.updateCitations(citationsUri);
|
|
667
665
|
}
|
|
668
666
|
|
|
669
667
|
#onAiCodeCompletionRequestTriggered(): void {
|
|
670
668
|
this.aiCodeCompletionSummaryToolbar?.setLoading(true);
|
|
671
669
|
}
|
|
672
670
|
|
|
673
|
-
#onAiCodeCompletionResponseReceived(
|
|
674
|
-
this.aiCodeCompletionCitations = citations;
|
|
671
|
+
#onAiCodeCompletionResponseReceived(): void {
|
|
675
672
|
this.aiCodeCompletionSummaryToolbar?.setLoading(false);
|
|
676
673
|
}
|
|
677
674
|
|
|
@@ -1077,12 +1074,12 @@ export class ConsoleView extends UI.Widget.VBox implements
|
|
|
1077
1074
|
}
|
|
1078
1075
|
|
|
1079
1076
|
const currentGroup = viewMessage.consoleGroup();
|
|
1077
|
+
showGroup(currentGroup, this.visibleViewMessages);
|
|
1080
1078
|
|
|
1081
1079
|
if (!currentGroup?.messagesHidden()) {
|
|
1082
1080
|
const originatingMessage = viewMessage.consoleMessage().originatingMessage();
|
|
1083
1081
|
const adjacent = Boolean(originatingMessage && lastMessage?.consoleMessage() === originatingMessage);
|
|
1084
1082
|
viewMessage.setAdjacentUserCommandResult(adjacent);
|
|
1085
|
-
showGroup(currentGroup, this.visibleViewMessages);
|
|
1086
1083
|
this.visibleViewMessages.push(viewMessage);
|
|
1087
1084
|
this.searchMessage(this.visibleViewMessages.length - 1);
|
|
1088
1085
|
}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
import type * as SDK from '../../core/sdk/sdk.js';
|
|
6
|
-
import * as Lit from '../../third_party/lit/lit.js';
|
|
7
6
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
7
|
+
import * as Lit from '../../ui/lit/lit.js';
|
|
8
8
|
|
|
9
9
|
import cssValueTraceViewStyles from './cssValueTraceView.css.js';
|
|
10
10
|
import {
|
|
@@ -48,7 +48,6 @@ import type * as IssuesManager from '../../models/issues_manager/issues_manager.
|
|
|
48
48
|
import * as TextUtils from '../../models/text_utils/text_utils.js';
|
|
49
49
|
import * as Workspace from '../../models/workspace/workspace.js';
|
|
50
50
|
import * as CodeMirror from '../../third_party/codemirror.next/codemirror.next.js';
|
|
51
|
-
import type {DirectiveResult} from '../../third_party/lit/lib/directive.js';
|
|
52
51
|
import type * as Adorners from '../../ui/components/adorners/adorners.js';
|
|
53
52
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
54
53
|
import * as CodeHighlighter from '../../ui/components/code_highlighter/code_highlighter.js';
|
|
@@ -58,6 +57,7 @@ import {Icon} from '../../ui/kit/kit.js';
|
|
|
58
57
|
import * as Components from '../../ui/legacy/components/utils/utils.js';
|
|
59
58
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
60
59
|
import * as Lit from '../../ui/lit/lit.js';
|
|
60
|
+
import type {DirectiveResult} from '../../ui/lit/lit.js';
|
|
61
61
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
62
62
|
import * as PanelsCommon from '../common/common.js';
|
|
63
63
|
import * as Emulation from '../emulation/emulation.js';
|
|
@@ -6,9 +6,9 @@ import type * as Common from '../../core/common/common.js';
|
|
|
6
6
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
7
7
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
8
8
|
import type * as Protocol from '../../generated/protocol.js';
|
|
9
|
-
import * as Lit from '../../third_party/lit/lit.js';
|
|
10
9
|
import * as TreeOutline from '../../ui/components/tree_outline/tree_outline.js';
|
|
11
10
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
11
|
+
import * as Lit from '../../ui/lit/lit.js';
|
|
12
12
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
13
13
|
|
|
14
14
|
import {ElementsPanel} from './ElementsPanel.js';
|
|
@@ -8,9 +8,8 @@ import * as Platform from '../../core/platform/platform.js';
|
|
|
8
8
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
9
9
|
import * as Bindings from '../../models/bindings/bindings.js';
|
|
10
10
|
import type * as Workspace from '../../models/workspace/workspace.js';
|
|
11
|
-
import {Directives, html, nothing, render} from '../../third_party/lit/lit.js';
|
|
12
11
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
13
|
-
import type
|
|
12
|
+
import {Directives, html, type LitTemplate, nothing, render} from '../../ui/lit/lit.js';
|
|
14
13
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
15
14
|
|
|
16
15
|
import mediaQueryInspectorStyles from './mediaQueryInspector.css.js';
|
|
@@ -7,9 +7,9 @@ import * as Host from '../../core/host/host.js';
|
|
|
7
7
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
8
8
|
import type * as SDK from '../../core/sdk/sdk.js';
|
|
9
9
|
import * as TextUtils from '../../models/text_utils/text_utils.js';
|
|
10
|
-
import * as Lit from '../../third_party/lit/lit.js';
|
|
11
10
|
import * as SourceFrame from '../../ui/legacy/components/source_frame/source_frame.js';
|
|
12
11
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
12
|
+
import * as Lit from '../../ui/lit/lit.js';
|
|
13
13
|
|
|
14
14
|
import {BinaryResourceView} from './BinaryResourceView.js';
|
|
15
15
|
|
|
@@ -42,10 +42,18 @@ const UIStrings = {
|
|
|
42
42
|
* @description The title of the button that allows importing a recording.
|
|
43
43
|
*/
|
|
44
44
|
importRecording: 'Import recording',
|
|
45
|
+
/**
|
|
46
|
+
* @description The announcement text for screen readers when a recording is imported.
|
|
47
|
+
*/
|
|
48
|
+
recordingImported: 'Recording imported',
|
|
45
49
|
/**
|
|
46
50
|
* @description The title of the button that deletes the recording
|
|
47
51
|
*/
|
|
48
52
|
deleteRecording: 'Delete recording',
|
|
53
|
+
/**
|
|
54
|
+
* @description The announcement text for screen readers when a recording is deleted.
|
|
55
|
+
*/
|
|
56
|
+
recordingDeleted: 'Recording deleted',
|
|
49
57
|
/**
|
|
50
58
|
* @description The title of the select if user has no saved recordings
|
|
51
59
|
*/
|
|
@@ -88,6 +96,10 @@ const UIStrings = {
|
|
|
88
96
|
* panel that is followed by the list of built-in export formats.
|
|
89
97
|
*/
|
|
90
98
|
export: 'Export',
|
|
99
|
+
/**
|
|
100
|
+
* @description The announcement text for screen readers when a recording is exported successfully.
|
|
101
|
+
*/
|
|
102
|
+
recordingExported: 'Recording exported',
|
|
91
103
|
/**
|
|
92
104
|
* @description The title of the menu group in the export menu of the Recorder
|
|
93
105
|
* panel that is followed by the list of export formats available via browser
|
|
@@ -333,6 +345,7 @@ export class RecorderController extends LitElement {
|
|
|
333
345
|
this.#setCurrentRecording(await this.#storage.saveRecording(flow));
|
|
334
346
|
this.#setCurrentPage(Pages.RECORDING_PAGE);
|
|
335
347
|
this.#clearError();
|
|
348
|
+
UI.ARIAUtils.LiveAnnouncer.alert(i18nString(UIStrings.recordingImported));
|
|
336
349
|
}
|
|
337
350
|
|
|
338
351
|
setCurrentRecordingForTesting(recording: StoredRecording|undefined): void {
|
|
@@ -787,6 +800,7 @@ export class RecorderController extends LitElement {
|
|
|
787
800
|
await this.#storage.deleteRecording(this.currentRecording.storageName);
|
|
788
801
|
this.#screenshotStorage.deleteScreenshotsForRecording(this.currentRecording.storageName);
|
|
789
802
|
}
|
|
803
|
+
UI.ARIAUtils.LiveAnnouncer.alert(i18nString(UIStrings.recordingDeleted));
|
|
790
804
|
if ((await this.#storage.getRecordings()).length) {
|
|
791
805
|
this.#setCurrentPage(Pages.ALL_RECORDINGS_PAGE);
|
|
792
806
|
} else {
|
|
@@ -944,8 +958,10 @@ export class RecorderController extends LitElement {
|
|
|
944
958
|
const builtInMetric = CONVERTER_ID_TO_METRIC[converter.getId()];
|
|
945
959
|
if (builtInMetric) {
|
|
946
960
|
Host.userMetrics.recordingExported(builtInMetric);
|
|
961
|
+
UI.ARIAUtils.LiveAnnouncer.alert(i18nString(UIStrings.recordingExported));
|
|
947
962
|
} else if (converter.getId().startsWith(Converters.ExtensionConverter.EXTENSION_PREFIX)) {
|
|
948
963
|
Host.userMetrics.recordingExported(Host.UserMetrics.RecordingExported.TO_EXTENSION);
|
|
964
|
+
UI.ARIAUtils.LiveAnnouncer.alert(i18nString(UIStrings.recordingExported));
|
|
949
965
|
} else {
|
|
950
966
|
throw new Error('Could not find a metric for the export option with id = ' + id);
|
|
951
967
|
}
|
|
@@ -23,7 +23,6 @@ export class AiCodeCompletionPlugin extends Plugin {
|
|
|
23
23
|
#aiCodeCompletionDisclaimer?: PanelCommon.AiCodeCompletionDisclaimer;
|
|
24
24
|
#aiCodeCompletionDisclaimerContainer = document.createElement('div');
|
|
25
25
|
#aiCodeCompletionDisclaimerToolbarItem = new UI.Toolbar.ToolbarItem(this.#aiCodeCompletionDisclaimerContainer);
|
|
26
|
-
#aiCodeCompletionCitations: Host.AidaClient.Citation[] = [];
|
|
27
26
|
#aiCodeCompletionCitationsToolbar?: PanelCommon.AiCodeCompletionSummaryToolbar;
|
|
28
27
|
#aiCodeCompletionCitationsToolbarContainer = document.createElement('div');
|
|
29
28
|
#aiCodeCompletionCitationsToolbarAttached = false;
|
|
@@ -151,21 +150,19 @@ export class AiCodeCompletionPlugin extends Plugin {
|
|
|
151
150
|
}
|
|
152
151
|
};
|
|
153
152
|
|
|
154
|
-
#onAiResponseReceived = (
|
|
155
|
-
this.#aiCodeCompletionCitations = citations;
|
|
153
|
+
#onAiResponseReceived = (): void => {
|
|
156
154
|
if (this.#aiCodeCompletionDisclaimer) {
|
|
157
155
|
this.#aiCodeCompletionDisclaimer.loading = false;
|
|
158
156
|
}
|
|
159
157
|
};
|
|
160
158
|
|
|
161
|
-
#onAiCodeCompletionSuggestionAccepted(): void {
|
|
162
|
-
if (!this.#aiCodeCompletionCitationsToolbar ||
|
|
159
|
+
#onAiCodeCompletionSuggestionAccepted(citations: Host.AidaClient.Citation[]): void {
|
|
160
|
+
if (!this.#aiCodeCompletionCitationsToolbar || citations.length === 0) {
|
|
163
161
|
return;
|
|
164
162
|
}
|
|
165
|
-
const citations
|
|
166
|
-
|
|
167
|
-
this.#
|
|
168
|
-
if (!this.#aiCodeCompletionCitationsToolbarAttached && citations.length > 0) {
|
|
163
|
+
const citationsUri = citations.map(citation => citation.uri).filter((uri): uri is string => Boolean(uri));
|
|
164
|
+
this.#aiCodeCompletionCitationsToolbar.updateCitations(citationsUri);
|
|
165
|
+
if (!this.#aiCodeCompletionCitationsToolbarAttached && citationsUri.length > 0) {
|
|
169
166
|
this.#attachAiCodeCompletionCitationsToolbar();
|
|
170
167
|
}
|
|
171
168
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
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
|
-
import
|
|
5
|
+
import * as Trace from '../../models/trace/trace.js';
|
|
6
6
|
|
|
7
7
|
export interface InitiatorData {
|
|
8
8
|
event: Trace.Types.Events.Event;
|
|
@@ -38,7 +38,7 @@ export function initiatorsDataToDraw(
|
|
|
38
38
|
hiddenEntries: Trace.Types.Events.Event[],
|
|
39
39
|
expandableEntries: Trace.Types.Events.Event[]): readonly InitiatorData[] {
|
|
40
40
|
const initiatorsData = [
|
|
41
|
-
...findInitiatorDataPredecessors(parsedTrace, selectedEvent
|
|
41
|
+
...findInitiatorDataPredecessors(parsedTrace, selectedEvent),
|
|
42
42
|
...findInitiatorDataDirectSuccessors(selectedEvent, parsedTrace.data.Initiators.initiatorToEvents),
|
|
43
43
|
];
|
|
44
44
|
|
|
@@ -54,13 +54,12 @@ export function initiatorsDataToDrawForNetwork(
|
|
|
54
54
|
parsedTrace: Trace.TraceModel.ParsedTrace,
|
|
55
55
|
selectedEvent: Trace.Types.Events.Event,
|
|
56
56
|
): readonly InitiatorData[] {
|
|
57
|
-
return findInitiatorDataPredecessors(parsedTrace, selectedEvent
|
|
57
|
+
return findInitiatorDataPredecessors(parsedTrace, selectedEvent);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
function findInitiatorDataPredecessors(
|
|
61
61
|
parsedTrace: Trace.TraceModel.ParsedTrace,
|
|
62
62
|
selectedEvent: Trace.Types.Events.Event,
|
|
63
|
-
eventToInitiator: Map<Trace.Types.Events.Event, Trace.Types.Events.Event>,
|
|
64
63
|
): readonly InitiatorData[] {
|
|
65
64
|
const initiatorsData: InitiatorData[] = [];
|
|
66
65
|
let currentEvent: Trace.Types.Events.Event|null = selectedEvent;
|
|
@@ -69,7 +68,10 @@ function findInitiatorDataPredecessors(
|
|
|
69
68
|
|
|
70
69
|
// Build event initiator data up to the selected one
|
|
71
70
|
while (currentEvent && initiatorsData.length < MAX_PREDECESSOR_INITIATOR_LIMIT) {
|
|
72
|
-
const currentInitiator =
|
|
71
|
+
const currentInitiator: Trace.Types.Events.Event|undefined =
|
|
72
|
+
Trace.Types.Events.isSyntheticNetworkRequest(currentEvent) ?
|
|
73
|
+
Trace.Extras.Initiators.getNetworkInitiator(parsedTrace.data, currentEvent) :
|
|
74
|
+
parsedTrace.data.Initiators.eventToInitiator.get(currentEvent);
|
|
73
75
|
|
|
74
76
|
if (currentInitiator) {
|
|
75
77
|
if (visited.has(currentInitiator)) {
|
|
@@ -449,9 +449,11 @@ function renderInitiatedBy(
|
|
|
449
449
|
link = linkifier.maybeLinkifyConsoleCallFrame(target, topFrame, options);
|
|
450
450
|
}
|
|
451
451
|
}
|
|
452
|
-
// If we do not, we can see if the network handler found an initiator and try
|
|
453
|
-
|
|
454
|
-
|
|
452
|
+
// If we do not, we can see if the network handler found an initiator and try
|
|
453
|
+
// to link by URL
|
|
454
|
+
const initiator = parsedTrace ? Trace.Extras.Initiators.getNetworkInitiator(parsedTrace.data, request) : undefined;
|
|
455
|
+
// Initiator will always be a synthetic network request but TS doesn't know that.
|
|
456
|
+
if (initiator && Trace.Types.Events.isSyntheticNetworkRequest(initiator)) {
|
|
455
457
|
link = linkifier.maybeLinkifyScriptLocation(
|
|
456
458
|
target,
|
|
457
459
|
null, // this would be the scriptId, but we don't have one. The linkifier will fallback to using the URL.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Name: Dependencies sourced from the upstream `chromium` repository
|
|
2
2
|
URL: https://chromium.googlesource.com/chromium/src
|
|
3
3
|
Version: N/A
|
|
4
|
-
Revision:
|
|
4
|
+
Revision: 692cff7713662587bc857dc3f7cb434b2253d929
|
|
5
5
|
Update Mechanism: Manual (https://crbug.com/428069060)
|
|
6
6
|
License: BSD-3-Clause
|
|
7
7
|
License File: LICENSE
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
npm install
|
|
2
2
|
../../../node_modules/.bin/tsc -d -t esnext -m esnext --moduleResolution node bundle.ts
|
|
3
|
-
../../../node_modules
|
|
3
|
+
../../../node_modules/rollup/dist/bin/rollup -c
|
|
4
4
|
rm -rf node_modules bundle.js bundle.d.ts
|
|
5
5
|
# Because there's a bug in clang causing it to reformat import lists even where formatting is disabled, run it right away
|
|
6
6
|
git cl format --js
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
npm install
|
|
2
2
|
../../../node_modules/.bin/tsc -d -t esnext -m esnext --moduleResolution node src/*
|
|
3
|
-
../../../node_modules
|
|
3
|
+
../../../node_modules/rollup/dist/bin/rollup -c
|
|
4
4
|
rm -rf node_modules src/*.js src/*.d.ts
|
|
5
5
|
# Because there's a bug in clang causing it to reformat import lists even where formatting is disabled, run it right away
|
|
6
6
|
git cl format --js
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
/* eslint-disable @devtools/no-imperative-dom-api */
|
|
5
5
|
|
|
6
6
|
import * as CM from '../../../third_party/codemirror.next/codemirror.next.js';
|
|
7
|
-
import type * as UI from '
|
|
7
|
+
import type * as UI from '../../legacy/legacy.js';
|
|
8
8
|
|
|
9
9
|
export function flattenRect(rect: DOMRect, left: boolean): {
|
|
10
10
|
left: number,
|
|
@@ -16,7 +16,6 @@ export function flattenRect(rect: DOMRect, left: boolean): {
|
|
|
16
16
|
return {left: x, right: x, top: rect.top, bottom: rect.bottom};
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
// TODO(b/462393094): Rename this to be a generic accessible placeholder
|
|
20
19
|
/**
|
|
21
20
|
* A CodeMirror WidgetType that displays a UI.Widget.Widget as a placeholder.
|
|
22
21
|
*
|
|
@@ -25,7 +24,7 @@ export function flattenRect(rect: DOMRect, left: boolean): {
|
|
|
25
24
|
* it ensures that screen readers can properly announce the content within
|
|
26
25
|
* the encapsulated widget.
|
|
27
26
|
*/
|
|
28
|
-
export class
|
|
27
|
+
export class AccessiblePlaceholder extends CM.WidgetType {
|
|
29
28
|
constructor(readonly teaser: UI.Widget.Widget) {
|
|
30
29
|
super();
|
|
31
30
|
}
|
|
@@ -72,25 +71,7 @@ export class AiCodeCompletionTeaserPlaceholder extends CM.WidgetType {
|
|
|
72
71
|
this.teaser?.hideWidget();
|
|
73
72
|
}
|
|
74
73
|
|
|
75
|
-
override eq(other:
|
|
74
|
+
override eq(other: AccessiblePlaceholder): boolean {
|
|
76
75
|
return this.teaser === other.teaser;
|
|
77
76
|
}
|
|
78
77
|
}
|
|
79
|
-
|
|
80
|
-
export function aiCodeCompletionTeaserPlaceholder(teaser: UI.Widget.Widget): CM.Extension {
|
|
81
|
-
const plugin = CM.ViewPlugin.fromClass(class {
|
|
82
|
-
placeholder: CM.DecorationSet;
|
|
83
|
-
|
|
84
|
-
constructor(readonly view: CM.EditorView) {
|
|
85
|
-
this.placeholder = CM.Decoration.set(
|
|
86
|
-
[CM.Decoration.widget({widget: new AiCodeCompletionTeaserPlaceholder(teaser), side: 1}).range(0)]);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
declare update: () => void;
|
|
90
|
-
|
|
91
|
-
get decorations(): CM.DecorationSet {
|
|
92
|
-
return this.view.state.doc.length ? CM.Decoration.none : this.placeholder;
|
|
93
|
-
}
|
|
94
|
-
}, {decorations: v => v.decorations});
|
|
95
|
-
return plugin;
|
|
96
|
-
}
|