chrome-devtools-frontend 1.0.1575635 → 1.0.1576287
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 +21 -0
- package/front_end/core/sdk/NetworkManager.ts +3 -1
- package/front_end/core/sdk/NetworkRequest.ts +7 -0
- package/front_end/core/sdk/SourceMapScopesInfo.ts +2 -1
- package/front_end/generated/SupportedCSSProperties.js +7 -0
- package/front_end/models/ai_assistance/agents/AiAgent.ts +6 -0
- package/front_end/models/ai_code_generation/AiCodeGeneration.ts +6 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +4 -0
- package/front_end/models/source_map_scopes/NamesResolver.ts +5 -8
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +14 -2
- package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +22 -1
- package/front_end/panels/application/DeviceBoundSessionsView.ts +44 -33
- package/front_end/panels/application/deviceBoundSessionsView.css +1 -1
- package/front_end/panels/common/AiCodeGenerationUpgradeDialog.ts +12 -4
- package/front_end/panels/common/GeminiRebrandPromoDialog.ts +5 -5
- package/front_end/panels/network/NetworkItemView.ts +32 -3
- package/front_end/panels/network/RequestDeviceBoundSessionsView.ts +160 -0
- package/front_end/panels/network/RequestPayloadView.ts +72 -97
- package/front_end/panels/network/forward/UIRequestLocation.ts +1 -0
- package/front_end/panels/network/network.ts +3 -0
- package/front_end/panels/network/requestDeviceBoundSessionsView.css +14 -0
- package/front_end/panels/settings/AISettingsTab.ts +2 -2
- package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +7 -0
- package/front_end/panels/whats_new/resources/WNDT.md +1 -1
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/source-map-scopes-codec/README.chromium +2 -2
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts +2 -2
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/scopes.d.ts +9 -1
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/scopes.d.ts.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/deno.json +8 -1
- package/front_end/third_party/source-map-scopes-codec/package/package.json +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js +20 -7
- package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.ts +29 -9
- package/front_end/third_party/source-map-scopes-codec/package/src/mod.js.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/mod.ts +1 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/scopes.js +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/scopes.ts +12 -1
- package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +37 -5
- package/front_end/ui/visual_logging/KnownContextValues.ts +7 -0
- package/package.json +1 -1
|
@@ -656,6 +656,13 @@ export class AidaClient {
|
|
|
656
656
|
}
|
|
657
657
|
|
|
658
658
|
registerClientEvent(clientEvent: AidaRegisterClientEvent): Promise<AidaClientResult> {
|
|
659
|
+
// Disable logging for now.
|
|
660
|
+
// For context, see b/454563259#comment35.
|
|
661
|
+
// We should be able to remove this ~end of April.
|
|
662
|
+
if (Root.Runtime.hostConfig.devToolsGeminiRebranding?.enabled) {
|
|
663
|
+
clientEvent.disable_user_content_logging = true;
|
|
664
|
+
}
|
|
665
|
+
|
|
659
666
|
const {promise, resolve} = Promise.withResolvers<AidaClientResult>();
|
|
660
667
|
InspectorFrontendHostInstance.registerAidaClientEvent(
|
|
661
668
|
JSON.stringify({
|
|
@@ -673,6 +680,14 @@ export class AidaClient {
|
|
|
673
680
|
if (!InspectorFrontendHostInstance.aidaCodeComplete) {
|
|
674
681
|
throw new Error('aidaCodeComplete is not available');
|
|
675
682
|
}
|
|
683
|
+
|
|
684
|
+
// Disable logging for now.
|
|
685
|
+
// For context, see b/454563259#comment35.
|
|
686
|
+
// We should be able to remove this ~end of April.
|
|
687
|
+
if (Root.Runtime.hostConfig.devToolsGeminiRebranding?.enabled) {
|
|
688
|
+
request.metadata.disable_user_content_logging = true;
|
|
689
|
+
}
|
|
690
|
+
|
|
676
691
|
const {promise, resolve} = Promise.withResolvers<AidaCodeCompleteResult>();
|
|
677
692
|
InspectorFrontendHostInstance.aidaCodeComplete(JSON.stringify(request), resolve);
|
|
678
693
|
const completeCodeResult = await promise;
|
|
@@ -718,6 +733,12 @@ export class AidaClient {
|
|
|
718
733
|
|
|
719
734
|
async generateCode(request: GenerateCodeRequest, options?: {signal?: AbortSignal}):
|
|
720
735
|
Promise<GenerateCodeResponse|null> {
|
|
736
|
+
// Disable logging for now.
|
|
737
|
+
// For context, see b/454563259#comment35.
|
|
738
|
+
// We should be able to remove this ~end of April.
|
|
739
|
+
if (Root.Runtime.hostConfig.devToolsGeminiRebranding?.enabled) {
|
|
740
|
+
request.metadata.disable_user_content_logging = true;
|
|
741
|
+
}
|
|
721
742
|
const response = await DispatchHttpRequestClient.makeHttpRequest<GenerateCodeResponse>(
|
|
722
743
|
{
|
|
723
744
|
service: SERVICE_NAME,
|
|
@@ -1022,6 +1022,7 @@ export class NetworkDispatcher implements ProtocolProxyApi.NetworkDispatcher {
|
|
|
1022
1022
|
requestId,
|
|
1023
1023
|
associatedCookies,
|
|
1024
1024
|
headers,
|
|
1025
|
+
deviceBoundSessionUsages,
|
|
1025
1026
|
clientSecurityState,
|
|
1026
1027
|
connectTiming,
|
|
1027
1028
|
siteHasCookieInOtherPartition,
|
|
@@ -1036,10 +1037,11 @@ export class NetworkDispatcher implements ProtocolProxyApi.NetworkDispatcher {
|
|
|
1036
1037
|
blockedRequestCookies.push({blockedReasons, cookie: Cookie.fromProtocolCookie(cookie)});
|
|
1037
1038
|
}
|
|
1038
1039
|
}
|
|
1039
|
-
const extraRequestInfo = {
|
|
1040
|
+
const extraRequestInfo: ExtraRequestInfo = {
|
|
1040
1041
|
blockedRequestCookies,
|
|
1041
1042
|
includedRequestCookies,
|
|
1042
1043
|
requestHeaders: this.headersMapToHeadersArray(headers),
|
|
1044
|
+
deviceBoundSessionUsages,
|
|
1043
1045
|
clientSecurityState,
|
|
1044
1046
|
connectTiming,
|
|
1045
1047
|
siteHasCookieInOtherPartition,
|
|
@@ -258,6 +258,7 @@ export class NetworkRequest extends Common.ObjectWrapper.ObjectWrapper<EventType
|
|
|
258
258
|
#exemptedResponseCookies: ExemptedSetCookieWithReason[] = [];
|
|
259
259
|
#responseCookiesPartitionKey: Protocol.Network.CookiePartitionKey|null = null;
|
|
260
260
|
#responseCookiesPartitionKeyOpaque: boolean|null = null;
|
|
261
|
+
#deviceBoundSessionUsages: Protocol.Network.DeviceBoundSessionWithUsage[] = [];
|
|
261
262
|
#siteHasCookieInOtherPartition = false;
|
|
262
263
|
localizedFailDescription: string|null = null;
|
|
263
264
|
#url!: Platform.DevToolsPath.UrlString;
|
|
@@ -1612,6 +1613,7 @@ export class NetworkRequest extends Common.ObjectWrapper.ObjectWrapper<EventType
|
|
|
1612
1613
|
this.setRequestHeaders(extraRequestInfo.requestHeaders);
|
|
1613
1614
|
this.#hasExtraRequestInfo = true;
|
|
1614
1615
|
this.setRequestHeadersText(''); // Mark request headers as non-provisional
|
|
1616
|
+
this.#deviceBoundSessionUsages = extraRequestInfo.deviceBoundSessionUsages || [];
|
|
1615
1617
|
this.#clientSecurityState = extraRequestInfo.clientSecurityState;
|
|
1616
1618
|
this.#appliedNetworkConditionsId = extraRequestInfo.appliedNetworkConditionsId;
|
|
1617
1619
|
if (extraRequestInfo.connectTiming) {
|
|
@@ -1630,6 +1632,10 @@ export class NetworkRequest extends Common.ObjectWrapper.ObjectWrapper<EventType
|
|
|
1630
1632
|
this.#appliedNetworkConditionsId = appliedNetworkConditionsId;
|
|
1631
1633
|
}
|
|
1632
1634
|
|
|
1635
|
+
getDeviceBoundSessionUsages(): Protocol.Network.DeviceBoundSessionWithUsage[] {
|
|
1636
|
+
return this.#deviceBoundSessionUsages;
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1633
1639
|
hasExtraRequestInfo(): boolean {
|
|
1634
1640
|
return this.#hasExtraRequestInfo;
|
|
1635
1641
|
}
|
|
@@ -2151,6 +2157,7 @@ export interface ExtraRequestInfo {
|
|
|
2151
2157
|
blockedRequestCookies: Array<{blockedReasons: Protocol.Network.CookieBlockedReason[], cookie: Cookie}>;
|
|
2152
2158
|
requestHeaders: NameValue[];
|
|
2153
2159
|
includedRequestCookies: IncludedCookieWithReason[];
|
|
2160
|
+
deviceBoundSessionUsages?: Protocol.Network.DeviceBoundSessionWithUsage[];
|
|
2154
2161
|
clientSecurityState?: Protocol.Network.ClientSecurityState;
|
|
2155
2162
|
connectTiming: Protocol.Network.ConnectTiming;
|
|
2156
2163
|
siteHasCookieInOtherPartition?: boolean;
|
|
@@ -190,7 +190,8 @@ export class SourceMapScopesInfo {
|
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
isEmpty(): boolean {
|
|
193
|
-
|
|
193
|
+
const noScopes = this.#originalScopes.every(scope => scope === null);
|
|
194
|
+
return noScopes && !this.#generatedRanges.length;
|
|
194
195
|
}
|
|
195
196
|
|
|
196
197
|
addOriginalScopesAtIndex(sourceIdx: number, scope: ScopesCodec.OriginalScope): void {
|
|
@@ -3925,6 +3925,13 @@ export const generatedProperties = [
|
|
|
3925
3925
|
],
|
|
3926
3926
|
"name": "rule-style"
|
|
3927
3927
|
},
|
|
3928
|
+
{
|
|
3929
|
+
"longhands": [
|
|
3930
|
+
"column-rule-visibility-items",
|
|
3931
|
+
"row-rule-visibility-items"
|
|
3932
|
+
],
|
|
3933
|
+
"name": "rule-visibility-items"
|
|
3934
|
+
},
|
|
3928
3935
|
{
|
|
3929
3936
|
"longhands": [
|
|
3930
3937
|
"column-rule-width",
|
|
@@ -309,6 +309,12 @@ export abstract class AiAgent<T> {
|
|
|
309
309
|
constructor(opts: AgentOptions) {
|
|
310
310
|
this.#aidaClient = opts.aidaClient;
|
|
311
311
|
this.#serverSideLoggingEnabled = opts.serverSideLoggingEnabled ?? false;
|
|
312
|
+
// Disable logging for now.
|
|
313
|
+
// For context, see b/454563259#comment35.
|
|
314
|
+
// We should be able to remove this ~end of April.
|
|
315
|
+
if (Root.Runtime.hostConfig.devToolsGeminiRebranding?.enabled) {
|
|
316
|
+
this.#serverSideLoggingEnabled = false;
|
|
317
|
+
}
|
|
312
318
|
this.#sessionId = opts.sessionId ?? crypto.randomUUID();
|
|
313
319
|
this.confirmSideEffect = opts.confirmSideEffectForTest ?? (() => Promise.withResolvers());
|
|
314
320
|
}
|
|
@@ -54,6 +54,12 @@ export class AiCodeGeneration {
|
|
|
54
54
|
constructor(opts: Options) {
|
|
55
55
|
this.#aidaClient = opts.aidaClient;
|
|
56
56
|
this.#serverSideLoggingEnabled = opts.serverSideLoggingEnabled ?? false;
|
|
57
|
+
// Disable logging for now.
|
|
58
|
+
// For context, see b/454563259#comment35.
|
|
59
|
+
// We should be able to remove this ~end of April.
|
|
60
|
+
if (Root.Runtime.hostConfig.devToolsGeminiRebranding?.enabled) {
|
|
61
|
+
this.#serverSideLoggingEnabled = false;
|
|
62
|
+
}
|
|
57
63
|
}
|
|
58
64
|
|
|
59
65
|
#buildRequest(
|
|
@@ -7189,6 +7189,10 @@ export const NativeFunctions = [
|
|
|
7189
7189
|
name: "setMenuListOptionsBoundsInAXTree",
|
|
7190
7190
|
signatures: [["options_bounds","children_updated"]]
|
|
7191
7191
|
},
|
|
7192
|
+
{
|
|
7193
|
+
name: "debugLog",
|
|
7194
|
+
signatures: [["message"]]
|
|
7195
|
+
},
|
|
7192
7196
|
{
|
|
7193
7197
|
name: "allowsFeature",
|
|
7194
7198
|
signatures: [["feature","?origin"]]
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
import * as Common from '../../core/common/common.js';
|
|
6
|
-
import * as Root from '../../core/root/root.js';
|
|
7
6
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
8
7
|
import * as Protocol from '../../generated/protocol.js';
|
|
9
8
|
import * as Bindings from '../bindings/bindings.js';
|
|
@@ -366,17 +365,15 @@ const resolveScope = async(script: SDK.Script.Script, scopeChain: Formatter.Form
|
|
|
366
365
|
export const resolveScopeChain =
|
|
367
366
|
async function(callFrame: SDK.DebuggerModel.CallFrame): Promise<SDK.DebuggerModel.ScopeChainEntry[]> {
|
|
368
367
|
const {pluginManager} = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance();
|
|
369
|
-
|
|
368
|
+
const scopeChain: SDK.DebuggerModel.ScopeChainEntry[]|null|undefined =
|
|
369
|
+
await pluginManager.resolveScopeChain(callFrame);
|
|
370
370
|
if (scopeChain) {
|
|
371
371
|
return scopeChain;
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
if (scopeChain) {
|
|
378
|
-
return scopeChain;
|
|
379
|
-
}
|
|
374
|
+
// TODO(crbug.com/465968290): Re-enable creating the scope chain from the source map once:
|
|
375
|
+
// 1) We have a flag indicating whether the source map contained variable/binding information.
|
|
376
|
+
// 2) We have a chrome feature flag.
|
|
380
377
|
|
|
381
378
|
if (callFrame.script.isWasm()) {
|
|
382
379
|
return callFrame.scopeChain();
|
|
@@ -204,7 +204,16 @@ const UIStringsNotTranslate = {
|
|
|
204
204
|
*/
|
|
205
205
|
inputDisclaimerForPerformanceEnterpriseNoLogging:
|
|
206
206
|
'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
|
-
|
|
207
|
+
/**
|
|
208
|
+
* @description Disclaimer text right after the chat input.
|
|
209
|
+
*/
|
|
210
|
+
inputDisclaimerForNoContext:
|
|
211
|
+
'Chat messages, any data the inspected page can see using Web APIs, and the items you select such as files, network requests, and performance traces are sent to Google and may be seen by human reviewers to improve this feature. This is an experimental AI feature and won’t always get it right.',
|
|
212
|
+
/**
|
|
213
|
+
* @description Disclaimer text right after the chat input.
|
|
214
|
+
*/
|
|
215
|
+
inputDisclaimerForNoContextEnterpriseNoLogging:
|
|
216
|
+
'Chat messages, any data the inspected page can see using Web APIs, and the items you select such as files, network requests, and performance traces are sent to Google. This data will not be used to improve Google’s AI models. This is an experimental AI feature and won’t always get it right.',
|
|
208
217
|
} as const;
|
|
209
218
|
|
|
210
219
|
const str_ = i18n.i18n.registerUIStrings('panels/ai_assistance/AiAssistancePanel.ts', UIStrings);
|
|
@@ -1037,7 +1046,10 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1037
1046
|
return lockedString(UIStringsNotTranslate.inputDisclaimerForPerformance);
|
|
1038
1047
|
|
|
1039
1048
|
case AiAssistanceModel.AiHistoryStorage.ConversationType.NONE:
|
|
1040
|
-
|
|
1049
|
+
if (noLogging) {
|
|
1050
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerForNoContextEnterpriseNoLogging);
|
|
1051
|
+
}
|
|
1052
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerForNoContext);
|
|
1041
1053
|
}
|
|
1042
1054
|
}
|
|
1043
1055
|
|
|
@@ -6,6 +6,7 @@ import type * as Common from '../../core/common/common.js';
|
|
|
6
6
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
7
7
|
import type * as Platform from '../../core/platform/platform.js';
|
|
8
8
|
import {createIcon} from '../../ui/kit/kit.js';
|
|
9
|
+
import * as UI from '../../ui/legacy/legacy.js';
|
|
9
10
|
|
|
10
11
|
import {ApplicationPanelTreeElement} from './ApplicationPanelTreeElement.js';
|
|
11
12
|
import {
|
|
@@ -46,6 +47,16 @@ const UIStrings = {
|
|
|
46
47
|
* linked to a session.
|
|
47
48
|
*/
|
|
48
49
|
noSession: 'No session',
|
|
50
|
+
/**
|
|
51
|
+
*@description Tooltip text for a terminated session.
|
|
52
|
+
*@example {session_1} sessionName
|
|
53
|
+
*/
|
|
54
|
+
terminatedSession: '{sessionName}, Session terminated',
|
|
55
|
+
/**
|
|
56
|
+
*@description Tooltip text for a session with errors.
|
|
57
|
+
*@example {session_1} sessionName
|
|
58
|
+
*/
|
|
59
|
+
sessionWithErrors: '{sessionName}, Session has errors',
|
|
49
60
|
} as const;
|
|
50
61
|
|
|
51
62
|
const str_ = i18n.i18n.registerUIStrings('panels/application/DeviceBoundSessionsTreeElement.ts', UIStrings);
|
|
@@ -122,13 +133,23 @@ export class RootTreeElement extends ApplicationPanelTreeElement {
|
|
|
122
133
|
|
|
123
134
|
#updateElementIconAndStyling(
|
|
124
135
|
sessionElement: ApplicationPanelTreeElement, isSessionTerminated: boolean, sessionHasErrors: boolean): void {
|
|
136
|
+
const title = sessionElement.title as string;
|
|
125
137
|
if (isSessionTerminated) {
|
|
126
138
|
sessionElement.listItemElement.classList.add('device-bound-session-terminated');
|
|
127
139
|
sessionElement.setLeadingIcons([createIcon('database-off')]);
|
|
140
|
+
const terminatedTitle = i18nString(UIStrings.terminatedSession, {sessionName: title});
|
|
141
|
+
UI.ARIAUtils.setLabel(sessionElement.listItemElement, terminatedTitle);
|
|
128
142
|
return;
|
|
129
143
|
}
|
|
130
144
|
sessionElement.listItemElement.classList.remove('device-bound-session-terminated');
|
|
131
|
-
|
|
145
|
+
if (sessionHasErrors) {
|
|
146
|
+
sessionElement.setLeadingIcons([createIcon('warning')]);
|
|
147
|
+
const errorTitle = i18nString(UIStrings.sessionWithErrors, {sessionName: title});
|
|
148
|
+
UI.ARIAUtils.setLabel(sessionElement.listItemElement, errorTitle);
|
|
149
|
+
} else {
|
|
150
|
+
sessionElement.setLeadingIcons([createIcon('database')]);
|
|
151
|
+
UI.ARIAUtils.setLabel(sessionElement.listItemElement, title);
|
|
152
|
+
}
|
|
132
153
|
}
|
|
133
154
|
|
|
134
155
|
#updateIconAndStyling(site: string, sessionId: string|undefined): void {
|
|
@@ -125,6 +125,10 @@ const UIStrings = {
|
|
|
125
125
|
*@description Section header for details about an event.
|
|
126
126
|
*/
|
|
127
127
|
eventDetails: 'Event details',
|
|
128
|
+
/**
|
|
129
|
+
*@description Accessible label for the main area containing session details.
|
|
130
|
+
*/
|
|
131
|
+
sessionDetails: 'Session details',
|
|
128
132
|
/**
|
|
129
133
|
*@description Placeholder text when no row is selected in a table of events.
|
|
130
134
|
*/
|
|
@@ -576,7 +580,8 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
|
|
|
576
580
|
const {key, inclusionRules, cookieCravings} = sessionAndEvents.session;
|
|
577
581
|
sessionDetailsHtml = html`
|
|
578
582
|
<devtools-report>
|
|
579
|
-
<devtools-report-section-header>${
|
|
583
|
+
<devtools-report-section-header role="heading" aria-level="2">${
|
|
584
|
+
i18nString(UIStrings.sessionConfig)}</devtools-report-section-header>
|
|
580
585
|
<devtools-report-key>${i18nString(UIStrings.keySite)}</devtools-report-key>
|
|
581
586
|
<devtools-report-value>${key.site}</devtools-report-value>
|
|
582
587
|
<devtools-report-key>${i18nString(UIStrings.keyId)}</devtools-report-key>
|
|
@@ -590,7 +595,8 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
|
|
|
590
595
|
<devtools-report-value>${sessionAndEvents.session.cachedChallenge || ''}</devtools-report-value>
|
|
591
596
|
<devtools-report-key>${i18nString(UIStrings.allowedRefreshInitiators)}</devtools-report-key>
|
|
592
597
|
<devtools-report-value>${sessionAndEvents.session.allowedRefreshInitiators.join(', ')}</devtools-report-value>
|
|
593
|
-
<devtools-report-section-header>${
|
|
598
|
+
<devtools-report-section-header role="heading" aria-level="2">${
|
|
599
|
+
i18nString(UIStrings.scope)}</devtools-report-section-header>
|
|
594
600
|
<devtools-report-key>${i18nString(UIStrings.origin)}</devtools-report-key>
|
|
595
601
|
<devtools-report-value>${inclusionRules.origin}</devtools-report-value>
|
|
596
602
|
<devtools-report-key>${i18nString(UIStrings.includeSite)}</devtools-report-key>
|
|
@@ -599,13 +605,14 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
|
|
|
599
605
|
${
|
|
600
606
|
inclusionRules.urlRules.length > 0 ? html`
|
|
601
607
|
<div class="device-bound-session-grid-wrapper">
|
|
602
|
-
<devtools-data-grid class="device-bound-session-url-rules-grid" striped inline
|
|
608
|
+
<devtools-data-grid class="device-bound-session-url-rules-grid" striped inline name=${
|
|
609
|
+
i18nString(UIStrings.scope)}>
|
|
603
610
|
<table>
|
|
604
611
|
<thead>
|
|
605
612
|
<tr>
|
|
606
|
-
<th id="should-include"
|
|
607
|
-
<th id="host-pattern"
|
|
608
|
-
<th id="path-prefix"
|
|
613
|
+
<th id="should-include" sortable>${i18nString(UIStrings.ruleType)}</th>
|
|
614
|
+
<th id="host-pattern" sortable>${i18nString(UIStrings.ruleHostPattern)}</th>
|
|
615
|
+
<th id="path-prefix" sortable>${i18nString(UIStrings.rulePathPrefix)}</th>
|
|
609
616
|
</tr>
|
|
610
617
|
</thead>
|
|
611
618
|
<tbody>
|
|
@@ -622,22 +629,22 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
|
|
|
622
629
|
</div>
|
|
623
630
|
` :
|
|
624
631
|
nothing}
|
|
625
|
-
<devtools-report-section-header>${
|
|
632
|
+
<devtools-report-section-header role="heading" aria-level="2">${
|
|
633
|
+
i18nString(UIStrings.cookieCravings)}</devtools-report-section-header>
|
|
626
634
|
${
|
|
627
635
|
cookieCravings.length > 0 ? html`
|
|
628
636
|
<div class="device-bound-session-grid-wrapper">
|
|
629
|
-
<devtools-data-grid class="device-bound-session-cookie-cravings-grid" striped inline
|
|
637
|
+
<devtools-data-grid class="device-bound-session-cookie-cravings-grid" striped inline name=${
|
|
638
|
+
i18nString(UIStrings.cookieCravings)}>
|
|
630
639
|
<table>
|
|
631
640
|
<thead>
|
|
632
641
|
<tr>
|
|
633
|
-
<th id="name"
|
|
634
|
-
<th id="domain"
|
|
635
|
-
<th id="path"
|
|
636
|
-
<th id="secure" type="boolean" align="center"
|
|
637
|
-
|
|
638
|
-
<th id="
|
|
639
|
-
i18n.i18n.lockedString('HttpOnly')}</th>
|
|
640
|
-
<th id="same-site" weight="1" sortable>${i18n.i18n.lockedString('SameSite')}</th>
|
|
642
|
+
<th id="name" sortable>${i18nString(UIStrings.name)}</th>
|
|
643
|
+
<th id="domain" sortable>${i18n.i18n.lockedString('Domain')}</th>
|
|
644
|
+
<th id="path" sortable>${i18n.i18n.lockedString('Path')}</th>
|
|
645
|
+
<th id="secure" type="boolean" align="center" sortable>${i18n.i18n.lockedString('Secure')}</th>
|
|
646
|
+
<th id="http-only" type="boolean" align="center" sortable>${i18n.i18n.lockedString('HttpOnly')}</th>
|
|
647
|
+
<th id="same-site" sortable>${i18n.i18n.lockedString('SameSite')}</th>
|
|
641
648
|
</tr>
|
|
642
649
|
</thead>
|
|
643
650
|
<tbody>
|
|
@@ -660,27 +667,28 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
|
|
|
660
667
|
}
|
|
661
668
|
const events = [...sessionAndEvents.eventsById.values()];
|
|
662
669
|
const eventsHtml = html`
|
|
663
|
-
<devtools-report-section-header>${
|
|
670
|
+
<devtools-report-section-header role="heading" aria-level="2">${
|
|
671
|
+
i18nString(UIStrings.events)}</devtools-report-section-header>
|
|
664
672
|
${
|
|
665
673
|
events.length > 0 && onEventRowSelected ?
|
|
666
674
|
html`
|
|
667
675
|
<div class="device-bound-session-grid-wrapper">
|
|
668
|
-
<devtools-data-grid class="device-bound-session-events-grid" striped inline
|
|
669
|
-
Directives.ref((el?: Element) => {
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
676
|
+
<devtools-data-grid class="device-bound-session-events-grid" striped inline name=${
|
|
677
|
+
i18nString(UIStrings.events)} ${Directives.ref((el?: Element) => {
|
|
678
|
+
if (!el || !(el instanceof HTMLElement)) {
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
const grid = el as HTMLElement & {deselectRow(): void};
|
|
682
|
+
if (!selectedEvent) {
|
|
683
|
+
grid.deselectRow();
|
|
684
|
+
}
|
|
685
|
+
})}>
|
|
678
686
|
<table>
|
|
679
687
|
<thead>
|
|
680
688
|
<tr>
|
|
681
|
-
<th id="type"
|
|
682
|
-
<th id="timestamp"
|
|
683
|
-
<th id="details"
|
|
689
|
+
<th id="type" sortable>${i18nString(UIStrings.type)}</th>
|
|
690
|
+
<th id="timestamp" sortable>${i18nString(UIStrings.timestamp)}</th>
|
|
691
|
+
<th id="details" sortable>${i18nString(UIStrings.result)}</th>
|
|
684
692
|
</tr>
|
|
685
693
|
</thead>
|
|
686
694
|
<tbody>${events.map(({event, timestamp}) => html`
|
|
@@ -764,7 +772,8 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
|
|
|
764
772
|
` :
|
|
765
773
|
html`<div class="device-bound-session-no-event-details">${i18nString(UIStrings.selectEventToViewDetails)}</div>`;
|
|
766
774
|
const eventDetailsHtml = html`
|
|
767
|
-
<devtools-report-section-header>${
|
|
775
|
+
<devtools-report-section-header role="heading" aria-level="2">${
|
|
776
|
+
i18nString(UIStrings.eventDetails)}</devtools-report-section-header>
|
|
768
777
|
${eventDetailsContentHtml}
|
|
769
778
|
`;
|
|
770
779
|
|
|
@@ -774,11 +783,13 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
|
|
|
774
783
|
<style>${deviceBoundSessionsViewStyles}</style>
|
|
775
784
|
${toolbarHtml}
|
|
776
785
|
<devtools-split-view sidebar-position="second">
|
|
777
|
-
<div slot="main" class="device-bound-session-view-wrapper"
|
|
786
|
+
<div slot="main" class="device-bound-session-view-wrapper" role="region" aria-label=${
|
|
787
|
+
i18nString(UIStrings.sessionDetails)}>
|
|
778
788
|
${sessionDetailsHtml || nothing}
|
|
779
789
|
${eventsHtml}
|
|
780
790
|
</div>
|
|
781
|
-
<div slot="sidebar" class="device-bound-session-sidebar"
|
|
791
|
+
<div slot="sidebar" class="device-bound-session-sidebar" role="region" aria-label=${
|
|
792
|
+
i18nString(UIStrings.eventDetails)}>
|
|
782
793
|
${eventDetailsHtml}
|
|
783
794
|
</div>
|
|
784
795
|
</devtools-split-view>`,
|
|
@@ -55,9 +55,10 @@ const UIStringsNotTranslate = {
|
|
|
55
55
|
const lockedString = i18n.i18n.lockedString;
|
|
56
56
|
|
|
57
57
|
export class AiCodeGenerationUpgradeDialog {
|
|
58
|
-
static show({noLogging}: {noLogging: boolean}):
|
|
58
|
+
static show({noLogging}: {noLogging: boolean}): Promise<boolean> {
|
|
59
59
|
const dialog = new UI.Dialog.Dialog();
|
|
60
60
|
dialog.setAriaLabel(lockedString(UIStringsNotTranslate.codeCompletionJustGotBetter));
|
|
61
|
+
const result = Promise.withResolvers<boolean>();
|
|
61
62
|
// clang-format off
|
|
62
63
|
Lit.render(html`
|
|
63
64
|
<div class="ai-code-generation-upgrade-dialog">
|
|
@@ -96,7 +97,8 @@ export class AiCodeGenerationUpgradeDialog {
|
|
|
96
97
|
<div class="right-buttons">
|
|
97
98
|
<devtools-button
|
|
98
99
|
@click=${() => {
|
|
99
|
-
|
|
100
|
+
result.resolve(true);
|
|
101
|
+
void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
|
|
100
102
|
}}
|
|
101
103
|
jslogcontext="ai-code-generation-upgrade-dialog.manage-in-settings"
|
|
102
104
|
.variant=${Buttons.Button.Variant.OUTLINED}
|
|
@@ -105,6 +107,7 @@ export class AiCodeGenerationUpgradeDialog {
|
|
|
105
107
|
</devtools-button>
|
|
106
108
|
<devtools-button
|
|
107
109
|
@click=${() => {
|
|
110
|
+
result.resolve(true);
|
|
108
111
|
dialog.hide();
|
|
109
112
|
}}
|
|
110
113
|
jslogcontext="ai-code-generation-upgrade-dialog.continue"
|
|
@@ -117,13 +120,18 @@ export class AiCodeGenerationUpgradeDialog {
|
|
|
117
120
|
// clang-format on
|
|
118
121
|
|
|
119
122
|
dialog.setOutsideClickCallback(ev => {
|
|
120
|
-
ev.consume(true);
|
|
121
|
-
|
|
123
|
+
ev.consume(true);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
dialog.setOnHideCallback(() => {
|
|
127
|
+
result.resolve(false);
|
|
122
128
|
});
|
|
123
129
|
|
|
124
130
|
dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.MEASURE_CONTENT);
|
|
125
131
|
dialog.setDimmed(true);
|
|
126
132
|
dialog.show();
|
|
133
|
+
|
|
134
|
+
return result.promise;
|
|
127
135
|
}
|
|
128
136
|
|
|
129
137
|
private constructor() {
|
|
@@ -81,7 +81,7 @@ export const DEFAULT_VIEW: View = (input, _output, target): void => {
|
|
|
81
81
|
.variant=${Buttons.Button.Variant.ICON}
|
|
82
82
|
.size=${Buttons.Button.Size.REGULAR}
|
|
83
83
|
.title=${i18nString(UIStrings.dismiss)}
|
|
84
|
-
jslog=${VisualLogging.close().track({click: true})}
|
|
84
|
+
jslog=${VisualLogging.close().track({click: true}).context('gemini-promo-dismiss')}
|
|
85
85
|
@click=${() => input.onCancelClick()}
|
|
86
86
|
></devtools-button>
|
|
87
87
|
</div>
|
|
@@ -111,11 +111,11 @@ export const DEFAULT_VIEW: View = (input, _output, target): void => {
|
|
|
111
111
|
<div class="buttons">
|
|
112
112
|
<devtools-button
|
|
113
113
|
.variant=${Buttons.Button.Variant.OUTLINED}
|
|
114
|
-
|
|
114
|
+
jslog=${VisualLogging.close().track({click: true}).context('gemini-promo-dismiss')}
|
|
115
115
|
@click=${input.onCancelClick}>${i18nString(UIStrings.dismiss)}</devtools-button>
|
|
116
116
|
<devtools-button
|
|
117
117
|
.variant=${Buttons.Button.Variant.PRIMARY}
|
|
118
|
-
.jslogContext=${'get-started'}
|
|
118
|
+
.jslogContext=${'gemini-promo-get-started'}
|
|
119
119
|
@click=${input.onGetStartedClick}>${i18nString(UIStrings.getStarted)}</devtools-button>
|
|
120
120
|
</div>
|
|
121
121
|
`,
|
|
@@ -160,7 +160,7 @@ export class GeminiRebrandPromoDialog extends UI.Widget.VBox {
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
static show(): void {
|
|
163
|
-
const dialog = new UI.Dialog.Dialog('gemini-
|
|
163
|
+
const dialog = new UI.Dialog.Dialog('gemini-promo-dialog');
|
|
164
164
|
dialog.setAriaLabel(i18nString(UIStrings.dialogAriaLabel));
|
|
165
165
|
dialog.setMaxContentSize(new Geometry.Size(384, 500));
|
|
166
166
|
dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.SET_EXACT_WIDTH_MAX_HEIGHT);
|
|
@@ -181,7 +181,7 @@ export class GeminiRebrandPromoDialog extends UI.Widget.VBox {
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
const setting = Common.Settings.Settings.instance().createSetting<boolean>(
|
|
184
|
-
'gemini-
|
|
184
|
+
'gemini-promo-dialog-shown', false, Common.Settings.SettingStorageType.SYNCED);
|
|
185
185
|
if (setting.get()) {
|
|
186
186
|
return;
|
|
187
187
|
}
|
|
@@ -21,6 +21,7 @@ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
|
21
21
|
import * as NetworkComponents from './components/components.js';
|
|
22
22
|
import {EventSourceMessagesView} from './EventSourceMessagesView.js';
|
|
23
23
|
import {RequestCookiesView} from './RequestCookiesView.js';
|
|
24
|
+
import {RequestDeviceBoundSessionsView} from './RequestDeviceBoundSessionsView.js';
|
|
24
25
|
import {RequestInitiatorView} from './RequestInitiatorView.js';
|
|
25
26
|
import {RequestPayloadView} from './RequestPayloadView.js';
|
|
26
27
|
import {RequestPreviewView} from './RequestPreviewView.js';
|
|
@@ -114,6 +115,17 @@ const UIStrings = {
|
|
|
114
115
|
* @description Text for web cookies
|
|
115
116
|
*/
|
|
116
117
|
cookies: 'Cookies',
|
|
118
|
+
/**
|
|
119
|
+
* @description Title of the Device Bound Sessions tab in the Network panel. A
|
|
120
|
+
* website may decide to create a session for a user, for example when the user
|
|
121
|
+
* logs in. They can use a protocol to make it a "device bound session". That
|
|
122
|
+
* means that when the session expires, it is only possible for it to be
|
|
123
|
+
* extended on the device it was created on. Thus the session is considered
|
|
124
|
+
* to be bound to that device. For more details on the protocol, see
|
|
125
|
+
* https://github.com/w3c/webappsec-dbsc/blob/main/README.md and
|
|
126
|
+
* https://w3c.github.io/webappsec-dbsc/.
|
|
127
|
+
*/
|
|
128
|
+
deviceBoundSessions: 'Device bound sessions',
|
|
117
129
|
/**
|
|
118
130
|
* @description Text in Network Item View of the Network panel
|
|
119
131
|
*/
|
|
@@ -140,6 +152,7 @@ export class NetworkItemView extends UI.TabbedPane.TabbedPane {
|
|
|
140
152
|
#payloadView: RequestPayloadView|null = null;
|
|
141
153
|
readonly #responseView: RequestResponseView|undefined;
|
|
142
154
|
#cookiesView: RequestCookiesView|null = null;
|
|
155
|
+
#deviceBoundSessionsView: RequestDeviceBoundSessionsView|null = null;
|
|
143
156
|
#initialTab?: NetworkForward.UIRequestLocation.UIRequestTabs;
|
|
144
157
|
readonly #firstTab: NetworkForward.UIRequestLocation.UIRequestTabs;
|
|
145
158
|
|
|
@@ -253,10 +266,10 @@ export class NetworkItemView extends UI.TabbedPane.TabbedPane {
|
|
|
253
266
|
super.wasShown();
|
|
254
267
|
this.#request.addEventListener(SDK.NetworkRequest.Events.REQUEST_HEADERS_CHANGED, this.requestHeadersChanged, this);
|
|
255
268
|
this.#request.addEventListener(
|
|
256
|
-
SDK.NetworkRequest.Events.RESPONSE_HEADERS_CHANGED, this.
|
|
269
|
+
SDK.NetworkRequest.Events.RESPONSE_HEADERS_CHANGED, this.maybeAppendCookieResponsePanels, this);
|
|
257
270
|
this.#request.addEventListener(
|
|
258
271
|
SDK.NetworkRequest.Events.TRUST_TOKEN_RESULT_ADDED, this.maybeShowErrorIconInTrustTokenTabHeader, this);
|
|
259
|
-
this.
|
|
272
|
+
this.maybeAppendCookieResponsePanels();
|
|
260
273
|
this.maybeShowErrorIconInTrustTokenTabHeader();
|
|
261
274
|
|
|
262
275
|
// Only select the initial tab the first time the view is shown after construction.
|
|
@@ -283,7 +296,7 @@ export class NetworkItemView extends UI.TabbedPane.TabbedPane {
|
|
|
283
296
|
this.#request.removeEventListener(
|
|
284
297
|
SDK.NetworkRequest.Events.REQUEST_HEADERS_CHANGED, this.requestHeadersChanged, this);
|
|
285
298
|
this.#request.removeEventListener(
|
|
286
|
-
SDK.NetworkRequest.Events.RESPONSE_HEADERS_CHANGED, this.
|
|
299
|
+
SDK.NetworkRequest.Events.RESPONSE_HEADERS_CHANGED, this.maybeAppendCookieResponsePanels, this);
|
|
287
300
|
this.#request.removeEventListener(
|
|
288
301
|
SDK.NetworkRequest.Events.TRUST_TOKEN_RESULT_ADDED, this.maybeShowErrorIconInTrustTokenTabHeader, this);
|
|
289
302
|
}
|
|
@@ -293,6 +306,11 @@ export class NetworkItemView extends UI.TabbedPane.TabbedPane {
|
|
|
293
306
|
void this.maybeAppendPayloadPanel();
|
|
294
307
|
}
|
|
295
308
|
|
|
309
|
+
private maybeAppendCookieResponsePanels(): void {
|
|
310
|
+
this.maybeAppendCookiesPanel();
|
|
311
|
+
this.maybeAppendDeviceBoundSessionsPanel();
|
|
312
|
+
}
|
|
313
|
+
|
|
296
314
|
private maybeAppendCookiesPanel(): void {
|
|
297
315
|
const cookiesPresent = this.#request.hasRequestCookies() || this.#request.responseCookies.length > 0;
|
|
298
316
|
console.assert(cookiesPresent || !this.#cookiesView, 'Cookies were introduced in headers and then removed!');
|
|
@@ -311,6 +329,17 @@ export class NetworkItemView extends UI.TabbedPane.TabbedPane {
|
|
|
311
329
|
}
|
|
312
330
|
}
|
|
313
331
|
|
|
332
|
+
private maybeAppendDeviceBoundSessionsPanel(): void {
|
|
333
|
+
const deviceBoundSessionsPresent = this.#request.getDeviceBoundSessionUsages().length > 0;
|
|
334
|
+
if (deviceBoundSessionsPresent && !this.#deviceBoundSessionsView) {
|
|
335
|
+
this.#deviceBoundSessionsView = new RequestDeviceBoundSessionsView(this.#request);
|
|
336
|
+
this.appendTab(
|
|
337
|
+
NetworkForward.UIRequestLocation.UIRequestTabs.DEVICE_BOUND_SESSIONS,
|
|
338
|
+
i18nString(UIStrings.deviceBoundSessions), this.#deviceBoundSessionsView,
|
|
339
|
+
i18nString(UIStrings.deviceBoundSessions));
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
314
343
|
private async maybeAppendPayloadPanel(): Promise<void> {
|
|
315
344
|
if (this.hasTab('payload')) {
|
|
316
345
|
return;
|