chrome-devtools-frontend 1.0.1559913 → 1.0.1561528
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/InspectorFrontendHostStub.ts +0 -3
- package/front_end/core/platform/ArrayUtilities.ts +13 -0
- package/front_end/core/root/Runtime.ts +0 -5
- package/front_end/core/sdk/DOMModel.ts +8 -0
- package/front_end/core/sdk/NetworkManager.ts +4 -0
- package/front_end/core/sdk/NetworkRequest.ts +9 -0
- package/front_end/core/sdk/OverlayModel.ts +20 -9
- package/front_end/entrypoints/main/MainImpl.ts +2 -1
- package/front_end/generated/InspectorBackendCommands.ts +4 -2
- package/front_end/generated/protocol-mapping.d.ts +7 -0
- package/front_end/generated/protocol-proxy-api.d.ts +5 -0
- package/front_end/generated/protocol.ts +24 -0
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +23 -22
- package/front_end/models/badges/UserBadges.ts +48 -16
- package/front_end/models/greendev/Prototypes.ts +6 -1
- package/front_end/models/trace/extras/TraceTree.ts +1 -1
- package/front_end/models/trace/handlers/PageLoadMetricsHandler.ts +8 -3
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +11 -142
- package/front_end/panels/ai_assistance/PatchWidget.ts +90 -72
- package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
- package/front_end/panels/ai_assistance/components/ChatInput.ts +701 -0
- package/front_end/panels/ai_assistance/components/ChatView.ts +71 -1268
- package/front_end/panels/ai_assistance/components/UserActionRow.ts +514 -31
- package/front_end/panels/ai_assistance/components/chatInput.css +387 -0
- package/front_end/panels/ai_assistance/components/chatView.css +38 -599
- package/front_end/panels/ai_assistance/components/userActionRow.css +230 -0
- package/front_end/panels/autofill/AutofillView.ts +2 -2
- package/front_end/panels/changes/ChangesView.ts +15 -1
- package/front_end/panels/changes/changesView.css +6 -0
- package/front_end/panels/common/BadgeNotification.ts +44 -58
- package/front_end/panels/common/CopyChangesToPrompt.ts +233 -0
- package/front_end/panels/common/common.ts +1 -0
- package/front_end/panels/elements/ElementsTreeElement.ts +183 -359
- package/front_end/panels/elements/ElementsTreeOutline.ts +0 -6
- package/front_end/panels/elements/ShortcutTreeElement.ts +57 -50
- package/front_end/panels/elements/StylePropertiesSection.ts +1 -3
- package/front_end/panels/elements/components/AdornerManager.ts +5 -149
- package/front_end/panels/issues/HiddenIssuesRow.ts +1 -2
- package/front_end/panels/issues/IssueKindView.ts +2 -4
- package/front_end/panels/issues/IssueView.ts +2 -4
- package/front_end/panels/network/NetworkDataGridNode.ts +65 -1
- package/front_end/panels/network/NetworkLogView.ts +2 -4
- package/front_end/panels/network/NetworkLogViewColumns.ts +9 -0
- package/front_end/panels/screencast/ScreencastApp.ts +1 -0
- package/front_end/panels/settings/SettingsScreen.ts +3 -2
- package/front_end/panels/timeline/CompatibilityTracksAppender.ts +14 -1
- package/front_end/panels/timeline/ThirdPartyTreeView.ts +1 -4
- package/front_end/panels/timeline/TimelineController.ts +185 -3
- package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +52 -25
- package/front_end/panels/timeline/TimelineFlameChartView.ts +1 -0
- package/front_end/panels/timeline/TimelinePanel.ts +17 -104
- package/front_end/panels/timeline/TimelineTreeView.ts +1 -0
- package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +2 -2
- package/front_end/panels/timeline/components/insights/Table.ts +3 -3
- package/front_end/panels/whats_new/ReleaseNoteText.ts +15 -9
- package/front_end/panels/whats_new/resources/WNDT.md +6 -6
- 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/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +2 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js +9 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPResponse.d.ts +3 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPResponse.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPResponse.js +9 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPResponse.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Request.d.ts +3 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Request.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Request.js +10 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Request.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +8 -4
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/generated/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/generated/injected.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/generated/injected.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/generated/injected.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +10 -1
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +13 -7
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +2 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js +9 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPResponse.d.ts +3 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPResponse.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPResponse.js +9 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPResponse.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Request.d.ts +3 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Request.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Request.js +10 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Request.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +8 -4
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/generated/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/generated/injected.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/generated/injected.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/generated/injected.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/types.d.ts +10 -1
- package/front_end/third_party/puppeteer/package/package.json +3 -3
- package/front_end/third_party/puppeteer/package/src/api/Page.ts +2 -3
- package/front_end/third_party/puppeteer/package/src/bidi/HTTPRequest.ts +13 -0
- package/front_end/third_party/puppeteer/package/src/bidi/HTTPResponse.ts +10 -0
- package/front_end/third_party/puppeteer/package/src/bidi/core/Request.ts +15 -0
- package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +9 -4
- package/front_end/third_party/puppeteer/package/src/generated/injected.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/ui/components/adorners/Adorner.ts +8 -68
- package/front_end/ui/legacy/TabbedPane.ts +1 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
- package/package.json +2 -1
|
@@ -10,7 +10,6 @@ import * as i18n from '../../core/i18n/i18n.js';
|
|
|
10
10
|
import * as Platform from '../../core/platform/platform.js';
|
|
11
11
|
import * as Root from '../../core/root/root.js';
|
|
12
12
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
13
|
-
import * as Protocol from '../../generated/protocol.js';
|
|
14
13
|
import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
|
|
15
14
|
import * as Annotations from '../../models/annotations/annotations.js';
|
|
16
15
|
import * as Badges from '../../models/badges/badges.js';
|
|
@@ -30,28 +29,30 @@ import * as TimelinePanel from '../timeline/timeline.js';
|
|
|
30
29
|
import aiAssistancePanelStyles from './aiAssistancePanel.css.js';
|
|
31
30
|
import {ArtifactsViewer} from './components/ArtifactsViewer.js';
|
|
32
31
|
import {
|
|
33
|
-
type AnswerPart,
|
|
34
|
-
type ChatMessage,
|
|
35
|
-
ChatMessageEntity,
|
|
36
32
|
ChatView,
|
|
37
|
-
type ImageInputData,
|
|
38
|
-
type ModelChatMessage,
|
|
39
33
|
type Props as ChatViewProps,
|
|
40
|
-
type Step
|
|
41
34
|
} from './components/ChatView.js';
|
|
42
35
|
import {DisabledWidget} from './components/DisabledWidget.js';
|
|
43
36
|
import {ExploreWidget} from './components/ExploreWidget.js';
|
|
44
37
|
import {MarkdownRendererWithCodeBlock} from './components/MarkdownRendererWithCodeBlock.js';
|
|
45
38
|
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
|
+
// FIXME: this export is temporary to avoid rewriting tests.
|
|
49
|
+
export {ChatMessageEntity} from './components/UserActionRow.js';
|
|
50
|
+
export type {AnswerPart, ModelChatMessage, StepPart} from './components/UserActionRow.js';
|
|
51
|
+
|
|
48
52
|
const {html} = Lit;
|
|
49
53
|
|
|
50
54
|
const AI_ASSISTANCE_SEND_FEEDBACK = 'https://crbug.com/364805393' as Platform.DevToolsPath.UrlString;
|
|
51
55
|
const AI_ASSISTANCE_HELP = 'https://developer.chrome.com/docs/devtools/ai-assistance';
|
|
52
|
-
const SCREENSHOT_QUALITY = 100;
|
|
53
|
-
const SHOW_LOADING_STATE_TIMEOUT = 100;
|
|
54
|
-
const JPEG_MIME_TYPE = 'image/jpeg';
|
|
55
56
|
|
|
56
57
|
const UIStrings = {
|
|
57
58
|
/**
|
|
@@ -204,14 +205,6 @@ const UIStringsNotTranslate = {
|
|
|
204
205
|
*/
|
|
205
206
|
inputDisclaimerForPerformanceEnterpriseNoLogging:
|
|
206
207
|
'Chat messages and data from your performance trace are sent to Google. The content you submit and that is generated by this feature will not be used to improve Google’s AI models. This is an experimental AI feature and won’t always get it right.',
|
|
207
|
-
/**
|
|
208
|
-
* @description Message displayed in toast in case of any failures while taking a screenshot of the page.
|
|
209
|
-
*/
|
|
210
|
-
screenshotFailureMessage: 'Failed to take a screenshot. Please try again.',
|
|
211
|
-
/**
|
|
212
|
-
* @description Message displayed in toast in case of any failures while uploading an image file as input.
|
|
213
|
-
*/
|
|
214
|
-
uploadImageFailureMessage: 'Failed to upload image. Please try again.',
|
|
215
208
|
} as const;
|
|
216
209
|
|
|
217
210
|
const str_ = i18n.i18n.registerUIStrings('panels/ai_assistance/AiAssistancePanel.ts', UIStrings);
|
|
@@ -536,9 +529,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
536
529
|
accountImage?: string,
|
|
537
530
|
accountFullName?: string,
|
|
538
531
|
};
|
|
539
|
-
#imageInput?: ImageInputData;
|
|
540
|
-
// Used to disable send button when there is not text input.
|
|
541
|
-
#isTextInputEmpty = true;
|
|
542
532
|
#timelinePanelInstance: TimelinePanel.TimelinePanel.TimelinePanel|null = null;
|
|
543
533
|
#runAbortController = new AbortController();
|
|
544
534
|
#additionalContextItemsFromFloaty: UI.Floaty.FloatyContextSelection[] = [];
|
|
@@ -603,12 +593,10 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
603
593
|
canShowFeedbackForm: this.#serverSideLoggingEnabled,
|
|
604
594
|
multimodalInputEnabled: isAiAssistanceMultimodalInputEnabled() &&
|
|
605
595
|
this.#conversation.type === AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING,
|
|
606
|
-
imageInput: this.#imageInput,
|
|
607
596
|
isTextInputDisabled: this.#isTextInputDisabled(),
|
|
608
597
|
emptyStateSuggestions,
|
|
609
598
|
inputPlaceholder: this.#getChatInputPlaceholder(),
|
|
610
599
|
disclaimerText: this.#getDisclaimerText(),
|
|
611
|
-
isTextInputEmpty: this.#isTextInputEmpty,
|
|
612
600
|
changeManager: this.#changeManager,
|
|
613
601
|
uploadImageInputEnabled: isAiAssistanceMultimodalUploadInputEnabled() &&
|
|
614
602
|
this.#conversation.type === AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING,
|
|
@@ -617,8 +605,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
617
605
|
onTextSubmit: async (
|
|
618
606
|
text: string, imageInput?: Host.AidaClient.Part,
|
|
619
607
|
multimodalInputType?: AiAssistanceModel.AiAgent.MultimodalInputType) => {
|
|
620
|
-
this.#imageInput = undefined;
|
|
621
|
-
this.#isTextInputEmpty = true;
|
|
622
608
|
Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiAssistanceQuerySubmitted);
|
|
623
609
|
await this.#startConversation(text, imageInput, multimodalInputType);
|
|
624
610
|
},
|
|
@@ -627,12 +613,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
627
613
|
onCancelClick: this.#cancel.bind(this),
|
|
628
614
|
onContextClick: this.#handleContextClick.bind(this),
|
|
629
615
|
onNewConversation: this.#handleNewChatRequest.bind(this),
|
|
630
|
-
onTakeScreenshot: isAiAssistanceMultimodalInputEnabled() ? this.#handleTakeScreenshot.bind(this) : undefined,
|
|
631
|
-
onRemoveImageInput: isAiAssistanceMultimodalInputEnabled() ? this.#handleRemoveImageInput.bind(this) :
|
|
632
|
-
undefined,
|
|
633
616
|
onCopyResponseClick: this.#onCopyResponseClick.bind(this),
|
|
634
|
-
onTextInputChange: this.#handleTextInputChange.bind(this),
|
|
635
|
-
onLoadImage: isAiAssistanceMultimodalUploadInputEnabled() ? this.#handleLoadImage.bind(this) : undefined,
|
|
636
617
|
}
|
|
637
618
|
};
|
|
638
619
|
}
|
|
@@ -806,10 +787,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
806
787
|
SDK.TargetManager.TargetManager.instance().addModelListener(
|
|
807
788
|
SDK.DOMModel.DOMModel, SDK.DOMModel.Events.AttrRemoved, this.#handleDOMNodeAttrChange, this);
|
|
808
789
|
|
|
809
|
-
SDK.TargetManager.TargetManager.instance().addModelListener(
|
|
810
|
-
SDK.ResourceTreeModel.ResourceTreeModel, SDK.ResourceTreeModel.Events.PrimaryPageChanged,
|
|
811
|
-
this.#onPrimaryPageChanged, this);
|
|
812
|
-
|
|
813
790
|
// Listen to changes in the Timeline Panel state. We also call the
|
|
814
791
|
// function immediately in case the Performance panel is already shown
|
|
815
792
|
// when AI Assistance is loaded.
|
|
@@ -863,9 +840,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
863
840
|
this.#handleDOMNodeAttrChange,
|
|
864
841
|
this,
|
|
865
842
|
);
|
|
866
|
-
SDK.TargetManager.TargetManager.instance().removeModelListener(
|
|
867
|
-
SDK.ResourceTreeModel.ResourceTreeModel, SDK.ResourceTreeModel.Events.PrimaryPageChanged,
|
|
868
|
-
this.#onPrimaryPageChanged, this);
|
|
869
843
|
|
|
870
844
|
if (this.#timelinePanelInstance) {
|
|
871
845
|
this.#timelinePanelInstance.removeEventListener(
|
|
@@ -944,15 +918,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
944
918
|
this.#updateConversationState(this.#conversation);
|
|
945
919
|
};
|
|
946
920
|
|
|
947
|
-
#onPrimaryPageChanged(): void {
|
|
948
|
-
if (!this.#imageInput) {
|
|
949
|
-
return;
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
this.#imageInput = undefined;
|
|
953
|
-
this.requestUpdate();
|
|
954
|
-
}
|
|
955
|
-
|
|
956
921
|
#getChangeSummary(): string|undefined {
|
|
957
922
|
if (!isAiAssistancePatchingEnabled() || !this.#conversation || this.#conversation?.isReadOnly) {
|
|
958
923
|
return;
|
|
@@ -1224,8 +1189,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1224
1189
|
return;
|
|
1225
1190
|
}
|
|
1226
1191
|
|
|
1227
|
-
this.#imageInput = undefined;
|
|
1228
|
-
this.#isTextInputEmpty = true;
|
|
1229
1192
|
Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiAssistanceQuerySubmitted);
|
|
1230
1193
|
if (this.#conversation && this.#conversation.isBlockedByOrigin) {
|
|
1231
1194
|
this.#handleNewChatRequest();
|
|
@@ -1322,100 +1285,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1322
1285
|
}
|
|
1323
1286
|
}
|
|
1324
1287
|
|
|
1325
|
-
async #handleTakeScreenshot(): Promise<void> {
|
|
1326
|
-
const mainTarget = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
1327
|
-
if (!mainTarget) {
|
|
1328
|
-
throw new Error('Could not find main target');
|
|
1329
|
-
}
|
|
1330
|
-
const model = mainTarget.model(SDK.ScreenCaptureModel.ScreenCaptureModel);
|
|
1331
|
-
if (!model) {
|
|
1332
|
-
throw new Error('Could not find model');
|
|
1333
|
-
}
|
|
1334
|
-
const showLoadingTimeout = setTimeout(() => {
|
|
1335
|
-
this.#imageInput = {isLoading: true};
|
|
1336
|
-
this.requestUpdate();
|
|
1337
|
-
}, SHOW_LOADING_STATE_TIMEOUT);
|
|
1338
|
-
const bytes = await model.captureScreenshot(
|
|
1339
|
-
Protocol.Page.CaptureScreenshotRequestFormat.Jpeg,
|
|
1340
|
-
SCREENSHOT_QUALITY,
|
|
1341
|
-
SDK.ScreenCaptureModel.ScreenshotMode.FROM_VIEWPORT,
|
|
1342
|
-
);
|
|
1343
|
-
clearTimeout(showLoadingTimeout);
|
|
1344
|
-
if (bytes) {
|
|
1345
|
-
this.#imageInput = {
|
|
1346
|
-
isLoading: false,
|
|
1347
|
-
data: bytes,
|
|
1348
|
-
mimeType: JPEG_MIME_TYPE,
|
|
1349
|
-
inputType: AiAssistanceModel.AiAgent.MultimodalInputType.SCREENSHOT
|
|
1350
|
-
};
|
|
1351
|
-
this.requestUpdate();
|
|
1352
|
-
void this.updateComplete.then(() => {
|
|
1353
|
-
this.#viewOutput.chatView?.focusTextInput();
|
|
1354
|
-
});
|
|
1355
|
-
} else {
|
|
1356
|
-
this.#imageInput = undefined;
|
|
1357
|
-
this.requestUpdate();
|
|
1358
|
-
Snackbars.Snackbar.Snackbar.show({
|
|
1359
|
-
message: lockedString(UIStringsNotTranslate.screenshotFailureMessage),
|
|
1360
|
-
});
|
|
1361
|
-
}
|
|
1362
|
-
}
|
|
1363
|
-
|
|
1364
|
-
#handleRemoveImageInput(): void {
|
|
1365
|
-
this.#imageInput = undefined;
|
|
1366
|
-
this.requestUpdate();
|
|
1367
|
-
void this.updateComplete.then(() => {
|
|
1368
|
-
this.#viewOutput.chatView?.focusTextInput();
|
|
1369
|
-
});
|
|
1370
|
-
}
|
|
1371
|
-
|
|
1372
|
-
#handleTextInputChange(value: string): void {
|
|
1373
|
-
const disableSubmit = !value;
|
|
1374
|
-
if (disableSubmit !== this.#isTextInputEmpty) {
|
|
1375
|
-
this.#isTextInputEmpty = disableSubmit;
|
|
1376
|
-
void this.requestUpdate();
|
|
1377
|
-
}
|
|
1378
|
-
}
|
|
1379
|
-
|
|
1380
|
-
async #handleLoadImage(file: File): Promise<void> {
|
|
1381
|
-
const showLoadingTimeout = setTimeout(() => {
|
|
1382
|
-
this.#imageInput = {isLoading: true};
|
|
1383
|
-
this.requestUpdate();
|
|
1384
|
-
}, SHOW_LOADING_STATE_TIMEOUT);
|
|
1385
|
-
try {
|
|
1386
|
-
const reader = new FileReader();
|
|
1387
|
-
const dataUrl = await new Promise<string>((resolve, reject) => {
|
|
1388
|
-
reader.onload = () => {
|
|
1389
|
-
if (typeof reader.result === 'string') {
|
|
1390
|
-
resolve(reader.result);
|
|
1391
|
-
} else {
|
|
1392
|
-
reject(new Error('FileReader result was not a string.'));
|
|
1393
|
-
}
|
|
1394
|
-
};
|
|
1395
|
-
reader.readAsDataURL(file);
|
|
1396
|
-
});
|
|
1397
|
-
const commaIndex = dataUrl.indexOf(',');
|
|
1398
|
-
const bytes = dataUrl.substring(commaIndex + 1);
|
|
1399
|
-
this.#imageInput = {
|
|
1400
|
-
isLoading: false,
|
|
1401
|
-
data: bytes,
|
|
1402
|
-
mimeType: file.type,
|
|
1403
|
-
inputType: AiAssistanceModel.AiAgent.MultimodalInputType.UPLOADED_IMAGE
|
|
1404
|
-
};
|
|
1405
|
-
} catch {
|
|
1406
|
-
this.#imageInput = undefined;
|
|
1407
|
-
Snackbars.Snackbar.Snackbar.show({
|
|
1408
|
-
message: lockedString(UIStringsNotTranslate.uploadImageFailureMessage),
|
|
1409
|
-
});
|
|
1410
|
-
}
|
|
1411
|
-
|
|
1412
|
-
clearTimeout(showLoadingTimeout);
|
|
1413
|
-
this.requestUpdate();
|
|
1414
|
-
void this.updateComplete.then(() => {
|
|
1415
|
-
this.#viewOutput.chatView?.focusTextInput();
|
|
1416
|
-
});
|
|
1417
|
-
}
|
|
1418
|
-
|
|
1419
1288
|
#cancel(): void {
|
|
1420
1289
|
this.#runAbortController.abort();
|
|
1421
1290
|
this.#runAbortController = new AbortController();
|
|
@@ -12,6 +12,7 @@ import * as i18n from '../../core/i18n/i18n.js';
|
|
|
12
12
|
import * as Platform from '../../core/platform/platform.js';
|
|
13
13
|
import * as Root from '../../core/root/root.js';
|
|
14
14
|
import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
|
|
15
|
+
import * as GreenDev from '../../models/greendev/greendev.js';
|
|
15
16
|
import * as Persistence from '../../models/persistence/persistence.js';
|
|
16
17
|
import * as Workspace from '../../models/workspace/workspace.js';
|
|
17
18
|
import * as WorkspaceDiff from '../../models/workspace_diff/workspace_diff.js';
|
|
@@ -186,41 +187,42 @@ export interface ViewOutput {
|
|
|
186
187
|
}
|
|
187
188
|
|
|
188
189
|
type View = (input: ViewInput, output: ViewOutput, target: HTMLElement) => void;
|
|
189
|
-
const DEFAULT_VIEW: View =
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
190
|
+
const DEFAULT_VIEW: View = (input, output, target) => {
|
|
191
|
+
if (!input.changeSummary && input.patchSuggestionState === PatchSuggestionState.INITIAL) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
194
|
|
|
195
|
-
|
|
196
|
-
|
|
195
|
+
output.changeRef = output.changeRef ?? Directives.createRef<HTMLElement>();
|
|
196
|
+
output.summaryRef = output.summaryRef ?? Directives.createRef<HTMLElement>();
|
|
197
197
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
198
|
+
function renderSourcesLink(): LitTemplate {
|
|
199
|
+
if (!input.sources) {
|
|
200
|
+
return nothing;
|
|
201
|
+
}
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
return html`<x-link
|
|
204
204
|
class="link"
|
|
205
205
|
title="${UIStringsNotTranslate.viewUploadedFiles} ${UIStringsNotTranslate.opensInNewTab}"
|
|
206
206
|
href="data:text/plain;charset=utf-8,${encodeURIComponent(input.sources)}"
|
|
207
|
-
jslog=${VisualLogging.link('files-used-in-patching').track({
|
|
207
|
+
jslog=${VisualLogging.link('files-used-in-patching').track({
|
|
208
|
+
click: true
|
|
209
|
+
})}>
|
|
208
210
|
${UIStringsNotTranslate.viewUploadedFiles}
|
|
209
211
|
</x-link>`;
|
|
210
|
-
|
|
212
|
+
}
|
|
211
213
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
214
|
+
function renderHeader(): LitTemplate {
|
|
215
|
+
if (input.savedToDisk) {
|
|
216
|
+
return html`
|
|
215
217
|
<devtools-icon class="green-bright-icon summary-badge" name="check-circle"></devtools-icon>
|
|
216
218
|
<span class="header-text">
|
|
217
219
|
${lockedString(UIStringsNotTranslate.savedToDisk)}
|
|
218
220
|
</span>
|
|
219
221
|
`;
|
|
220
|
-
|
|
222
|
+
}
|
|
221
223
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
+
if (input.patchSuggestionState === PatchSuggestionState.SUCCESS) {
|
|
225
|
+
return html`
|
|
224
226
|
<devtools-icon class="on-tonal-icon summary-badge" name="difference"></devtools-icon>
|
|
225
227
|
<span class="header-text">
|
|
226
228
|
${lockedString(`File changes in ${input.projectName}`)}
|
|
@@ -230,9 +232,9 @@ const DEFAULT_VIEW: View =
|
|
|
230
232
|
name="chevron-down"
|
|
231
233
|
></devtools-icon>
|
|
232
234
|
`;
|
|
233
|
-
|
|
235
|
+
}
|
|
234
236
|
|
|
235
|
-
|
|
237
|
+
return html`
|
|
236
238
|
<devtools-icon class="on-tonal-icon summary-badge" name="pen-spark"></devtools-icon>
|
|
237
239
|
<span class="header-text">
|
|
238
240
|
${lockedString(UIStringsNotTranslate.unsavedChanges)}
|
|
@@ -242,49 +244,63 @@ const DEFAULT_VIEW: View =
|
|
|
242
244
|
name="chevron-down"
|
|
243
245
|
></devtools-icon>
|
|
244
246
|
`;
|
|
245
|
-
|
|
247
|
+
}
|
|
246
248
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
249
|
+
function renderContent(): LitTemplate {
|
|
250
|
+
if ((!input.changeSummary && input.patchSuggestionState === PatchSuggestionState.INITIAL) || input.savedToDisk) {
|
|
251
|
+
return nothing;
|
|
252
|
+
}
|
|
251
253
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
+
if (input.patchSuggestionState === PatchSuggestionState.SUCCESS) {
|
|
255
|
+
return html`<devtools-widget .widgetConfig=${
|
|
256
|
+
UI.Widget.widgetConfig(ChangesPanel.CombinedDiffView.CombinedDiffView, {
|
|
254
257
|
workspaceDiff: input.workspaceDiff,
|
|
255
258
|
// Ignore user creates inspector-stylesheets
|
|
256
259
|
ignoredUrls: ['inspector://']
|
|
257
260
|
})}></devtools-widget>`;
|
|
258
|
-
|
|
261
|
+
}
|
|
259
262
|
|
|
260
|
-
|
|
263
|
+
return html`<devtools-code-block
|
|
261
264
|
.code=${input.changeSummary ?? ''}
|
|
262
265
|
.codeLang=${'css'}
|
|
263
266
|
.displayNotice=${true}
|
|
264
267
|
></devtools-code-block>
|
|
265
|
-
${
|
|
266
|
-
|
|
268
|
+
${
|
|
269
|
+
input.patchSuggestionState === PatchSuggestionState.ERROR ?
|
|
270
|
+
html`<div class="error-container">
|
|
267
271
|
<devtools-icon name="cross-circle-filled"></devtools-icon>${
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}`;
|
|
273
|
-
}
|
|
272
|
+
lockedString(UIStringsNotTranslate.genericErrorMessage)} ${renderSourcesLink()}
|
|
273
|
+
</div>` :
|
|
274
|
+
nothing}`;
|
|
275
|
+
}
|
|
274
276
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
277
|
+
function renderCopyPrompt(changedCode?: string): LitTemplate {
|
|
278
|
+
if (!GreenDev.Prototypes.instance().isEnabled('copyToGemini') || !changedCode) {
|
|
279
|
+
return nothing;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// clang-format off
|
|
283
|
+
return html`<devtools-widget class="copy-to-prompt"
|
|
284
|
+
.widgetConfig=${UI.Widget.widgetConfig(PanelCommon.CopyChangesToPrompt, {
|
|
285
|
+
workspaceDiff: input.workspaceDiff,
|
|
286
|
+
patchAgentCSSChange: changedCode,
|
|
287
|
+
})}></devtools-widget>`;
|
|
288
|
+
// clang-format on
|
|
289
|
+
}
|
|
279
290
|
|
|
280
|
-
|
|
281
|
-
|
|
291
|
+
function renderFooter(): LitTemplate {
|
|
292
|
+
if (input.savedToDisk) {
|
|
293
|
+
return nothing;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (input.patchSuggestionState === PatchSuggestionState.SUCCESS) {
|
|
297
|
+
return html`
|
|
282
298
|
<div class="footer">
|
|
283
299
|
<div class="left-side">
|
|
284
300
|
<x-link class="link disclaimer-link" href="https://support.google.com/legal/answer/13505487" jslog=${
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
301
|
+
VisualLogging.link('code-disclaimer').track({
|
|
302
|
+
click: true,
|
|
303
|
+
})}>
|
|
288
304
|
${lockedString(UIStringsNotTranslate.codeDisclaimer)}
|
|
289
305
|
</x-link>
|
|
290
306
|
${renderSourcesLink()}
|
|
@@ -305,18 +321,20 @@ const DEFAULT_VIEW: View =
|
|
|
305
321
|
</div>
|
|
306
322
|
</div>
|
|
307
323
|
`;
|
|
308
|
-
|
|
324
|
+
}
|
|
309
325
|
|
|
310
|
-
|
|
311
|
-
|
|
326
|
+
const iconName = input.projectType === SelectedProjectType.AUTOMATIC_DISCONNECTED ? 'folder-off' :
|
|
327
|
+
input.projectType === SelectedProjectType.AUTOMATIC_CONNECTED ? 'folder-asterisk' :
|
|
328
|
+
'folder';
|
|
329
|
+
return html`
|
|
312
330
|
<div class="footer">
|
|
313
331
|
${
|
|
314
|
-
|
|
332
|
+
input.projectName ? html`
|
|
315
333
|
<div class="change-workspace" jslog=${VisualLogging.section('patch-widget.workspace')}>
|
|
316
334
|
<devtools-icon .name=${iconName}></devtools-icon>
|
|
317
335
|
<span class="folder-name" title=${input.projectPath}>${input.projectName}</span>
|
|
318
336
|
${
|
|
319
|
-
|
|
337
|
+
input.onChangeWorkspaceClick ? html`
|
|
320
338
|
<devtools-button
|
|
321
339
|
@click=${input.onChangeWorkspaceClick}
|
|
322
340
|
.jslogContext=${'change-workspace'}
|
|
@@ -326,23 +344,24 @@ const DEFAULT_VIEW: View =
|
|
|
326
344
|
${Directives.ref(output.changeRef)}
|
|
327
345
|
>${lockedString(UIStringsNotTranslate.change)}</devtools-button>
|
|
328
346
|
` :
|
|
329
|
-
|
|
347
|
+
nothing}
|
|
330
348
|
</div>
|
|
331
349
|
` :
|
|
332
|
-
|
|
350
|
+
nothing}
|
|
333
351
|
<div class="apply-to-workspace-container" aria-live="polite">
|
|
334
352
|
${
|
|
335
|
-
|
|
336
|
-
|
|
353
|
+
input.patchSuggestionState === PatchSuggestionState.LOADING ?
|
|
354
|
+
html`
|
|
337
355
|
<div class="loading-text-container" jslog=${
|
|
338
|
-
|
|
356
|
+
VisualLogging.section('patch-widget.apply-to-workspace-loading')}>
|
|
339
357
|
<devtools-spinner></devtools-spinner>
|
|
340
358
|
<span>
|
|
341
359
|
${lockedString(UIStringsNotTranslate.applyingToWorkspace)}
|
|
342
360
|
</span>
|
|
343
361
|
</div>
|
|
344
362
|
` :
|
|
345
|
-
|
|
363
|
+
html`
|
|
364
|
+
${renderCopyPrompt(input.changeSummary)}
|
|
346
365
|
<devtools-button
|
|
347
366
|
@click=${input.onApplyToWorkspace}
|
|
348
367
|
.jslogContext=${'patch-widget.apply-to-workspace'}
|
|
@@ -351,13 +370,13 @@ const DEFAULT_VIEW: View =
|
|
|
351
370
|
</devtools-button>
|
|
352
371
|
`}
|
|
353
372
|
${
|
|
354
|
-
|
|
373
|
+
input.patchSuggestionState === PatchSuggestionState.LOADING ? html`<devtools-button
|
|
355
374
|
@click=${input.onCancel}
|
|
356
375
|
.jslogContext=${'cancel'}
|
|
357
376
|
.variant=${Buttons.Button.Variant.OUTLINED}>
|
|
358
377
|
${lockedString(UIStringsNotTranslate.cancel)}
|
|
359
378
|
</devtools-button>` :
|
|
360
|
-
|
|
379
|
+
nothing}
|
|
361
380
|
<devtools-button
|
|
362
381
|
aria-details="info-tooltip"
|
|
363
382
|
.jslogContext=${'patch-widget.info-tooltip-trigger'}
|
|
@@ -374,26 +393,25 @@ const DEFAULT_VIEW: View =
|
|
|
374
393
|
class="link tooltip-link"
|
|
375
394
|
role="link"
|
|
376
395
|
jslog=${VisualLogging.link('open-ai-settings').track({
|
|
377
|
-
|
|
378
|
-
|
|
396
|
+
click: true,
|
|
397
|
+
})}
|
|
379
398
|
@click=${input.onLearnMoreTooltipClick}
|
|
380
399
|
>${lockedString(UIStringsNotTranslate.learnMore)}</button>
|
|
381
400
|
</div>
|
|
382
401
|
</devtools-tooltip>
|
|
383
402
|
</div>
|
|
384
403
|
</div>`;
|
|
385
|
-
|
|
404
|
+
}
|
|
386
405
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
? html`
|
|
406
|
+
// Use a simple div for the "Saved to disk" state as it's not expandable,
|
|
407
|
+
// otherwise use the interactive <details> element.
|
|
408
|
+
const template = input.savedToDisk ? html`
|
|
391
409
|
<div class="change-summary saved-to-disk" role="status" aria-live="polite">
|
|
392
410
|
<div class="header-container">
|
|
393
411
|
${renderHeader()}
|
|
394
412
|
</div>
|
|
395
|
-
</div>`
|
|
396
|
-
|
|
413
|
+
</div>` :
|
|
414
|
+
html`
|
|
397
415
|
<details class="change-summary" jslog=${VisualLogging.section('patch-widget')}>
|
|
398
416
|
<summary class="header-container" ${Directives.ref(output.summaryRef)}>
|
|
399
417
|
${renderHeader()}
|
|
@@ -403,8 +421,8 @@ const DEFAULT_VIEW: View =
|
|
|
403
421
|
</details>
|
|
404
422
|
`;
|
|
405
423
|
|
|
406
|
-
|
|
407
|
-
|
|
424
|
+
render(template, target);
|
|
425
|
+
};
|
|
408
426
|
|
|
409
427
|
export class PatchWidget extends UI.Widget.Widget {
|
|
410
428
|
changeSummary = '';
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
export * from './AiAssistancePanel.js';
|
|
6
6
|
export * from './components/ChatView.js';
|
|
7
|
+
export * as ChatInput from './components/ChatInput.js';
|
|
7
8
|
export * from './components/MarkdownRendererWithCodeBlock.js';
|
|
8
9
|
export * from './components/PerformanceAgentFlameChart.js';
|
|
9
10
|
export * from './SelectWorkspaceDialog.js';
|