chrome-devtools-frontend 1.0.1004171 → 1.0.1004641

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.
@@ -1112,6 +1112,8 @@ grd_files_debug_sources = [
1112
1112
  "front_end/panels/network/SignedExchangeInfoView.js",
1113
1113
  "front_end/panels/network/binaryResourceView.css.js",
1114
1114
  "front_end/panels/network/blockedURLsPane.css.js",
1115
+ "front_end/panels/network/components/RequestHeadersView.css.js",
1116
+ "front_end/panels/network/components/RequestHeadersView.js",
1115
1117
  "front_end/panels/network/components/RequestTrustTokensView.css.js",
1116
1118
  "front_end/panels/network/components/RequestTrustTokensView.js",
1117
1119
  "front_end/panels/network/components/WebBundleInfoView.css.js",
@@ -264,9 +264,9 @@ export class ParsedURL {
264
264
  return devToolsPaths.join(separator) as DevToolsPathType;
265
265
  }
266
266
 
267
- static split<DevToolsPathType extends BrandedPathString>(devToolsPath: DevToolsPathType, separator: string|RegExp):
268
- DevToolsPathType[] {
269
- return devToolsPath.split(separator) as DevToolsPathType[];
267
+ static split<DevToolsPathType extends BrandedPathString>(
268
+ devToolsPath: DevToolsPathType, separator: string|RegExp, limit?: number): DevToolsPathType[] {
269
+ return devToolsPath.split(separator, limit) as DevToolsPathType[];
270
270
  }
271
271
 
272
272
  static toLowerCase<DevToolsPathType extends BrandedPathString>(devToolsPath: DevToolsPathType): DevToolsPathType {
@@ -6599,6 +6599,42 @@
6599
6599
  "panels/network/BlockedURLsPane.ts | textPatternToBlockMatching": {
6600
6600
  "message": "Text pattern to block matching requests; use * for wildcard"
6601
6601
  },
6602
+ "panels/network/components/RequestHeadersView.ts | fromDiskCache": {
6603
+ "message": "(from disk cache)"
6604
+ },
6605
+ "panels/network/components/RequestHeadersView.ts | fromMemoryCache": {
6606
+ "message": "(from memory cache)"
6607
+ },
6608
+ "panels/network/components/RequestHeadersView.ts | fromPrefetchCache": {
6609
+ "message": "(from prefetch cache)"
6610
+ },
6611
+ "panels/network/components/RequestHeadersView.ts | fromServiceWorker": {
6612
+ "message": "(from service worker)"
6613
+ },
6614
+ "panels/network/components/RequestHeadersView.ts | fromSignedexchange": {
6615
+ "message": "(from signed-exchange)"
6616
+ },
6617
+ "panels/network/components/RequestHeadersView.ts | fromWebBundle": {
6618
+ "message": "(from Web Bundle)"
6619
+ },
6620
+ "panels/network/components/RequestHeadersView.ts | general": {
6621
+ "message": "General"
6622
+ },
6623
+ "panels/network/components/RequestHeadersView.ts | referrerPolicy": {
6624
+ "message": "Referrer Policy"
6625
+ },
6626
+ "panels/network/components/RequestHeadersView.ts | remoteAddress": {
6627
+ "message": "Remote Address"
6628
+ },
6629
+ "panels/network/components/RequestHeadersView.ts | requestMethod": {
6630
+ "message": "Request Method"
6631
+ },
6632
+ "panels/network/components/RequestHeadersView.ts | requestUrl": {
6633
+ "message": "Request URL"
6634
+ },
6635
+ "panels/network/components/RequestHeadersView.ts | statusCode": {
6636
+ "message": "Status Code"
6637
+ },
6602
6638
  "panels/network/components/RequestTrustTokensView.ts | aClientprovidedArgumentWas": {
6603
6639
  "message": "A client-provided argument was malformed or otherwise invalid."
6604
6640
  },
@@ -9461,6 +9497,9 @@
9461
9497
  "panels/sources/CallStackSidebarPane.ts | removeFromIgnoreList": {
9462
9498
  "message": "Remove from ignore list"
9463
9499
  },
9500
+ "panels/sources/CallStackSidebarPane.ts | restartFrame": {
9501
+ "message": "Restart frame"
9502
+ },
9464
9503
  "panels/sources/CallStackSidebarPane.ts | showIgnorelistedFrames": {
9465
9504
  "message": "Show ignore-listed frames"
9466
9505
  },
@@ -6599,6 +6599,42 @@
6599
6599
  "panels/network/BlockedURLsPane.ts | textPatternToBlockMatching": {
6600
6600
  "message": "T̂éx̂t́ p̂át̂t́êŕn̂ t́ô b́l̂óĉḱ m̂át̂ćĥín̂ǵ r̂éq̂úêśt̂ś; ûśê * f́ôŕ ŵíl̂d́ĉár̂d́"
6601
6601
  },
6602
+ "panels/network/components/RequestHeadersView.ts | fromDiskCache": {
6603
+ "message": "(f̂ŕôḿ d̂íŝḱ ĉáĉh́ê)"
6604
+ },
6605
+ "panels/network/components/RequestHeadersView.ts | fromMemoryCache": {
6606
+ "message": "(f̂ŕôḿ m̂ém̂ór̂ý ĉáĉh́ê)"
6607
+ },
6608
+ "panels/network/components/RequestHeadersView.ts | fromPrefetchCache": {
6609
+ "message": "(f̂ŕôḿ p̂ŕêf́êt́ĉh́ ĉáĉh́ê)"
6610
+ },
6611
+ "panels/network/components/RequestHeadersView.ts | fromServiceWorker": {
6612
+ "message": "(f̂ŕôḿ service worker)"
6613
+ },
6614
+ "panels/network/components/RequestHeadersView.ts | fromSignedexchange": {
6615
+ "message": "(f̂ŕôḿ ŝíĝńêd́-êx́ĉh́âńĝé)"
6616
+ },
6617
+ "panels/network/components/RequestHeadersView.ts | fromWebBundle": {
6618
+ "message": "(f̂ŕôḿ Ŵéb̂ B́ûńd̂ĺê)"
6619
+ },
6620
+ "panels/network/components/RequestHeadersView.ts | general": {
6621
+ "message": "Ĝén̂ér̂ál̂"
6622
+ },
6623
+ "panels/network/components/RequestHeadersView.ts | referrerPolicy": {
6624
+ "message": "R̂éf̂ér̂ŕêŕ P̂ól̂íĉý"
6625
+ },
6626
+ "panels/network/components/RequestHeadersView.ts | remoteAddress": {
6627
+ "message": "R̂ém̂ót̂é Âd́d̂ŕêśŝ"
6628
+ },
6629
+ "panels/network/components/RequestHeadersView.ts | requestMethod": {
6630
+ "message": "R̂éq̂úêśt̂ Ḿêt́ĥód̂"
6631
+ },
6632
+ "panels/network/components/RequestHeadersView.ts | requestUrl": {
6633
+ "message": "R̂éq̂úêśt̂ ÚR̂Ĺ"
6634
+ },
6635
+ "panels/network/components/RequestHeadersView.ts | statusCode": {
6636
+ "message": "Ŝt́ât́ûś Ĉód̂é"
6637
+ },
6602
6638
  "panels/network/components/RequestTrustTokensView.ts | aClientprovidedArgumentWas": {
6603
6639
  "message": "Â ćl̂íêńt̂-ṕr̂óv̂íd̂éd̂ ár̂ǵûḿêńt̂ ẃâś m̂ál̂f́ôŕm̂éd̂ ór̂ ót̂h́êŕŵíŝé îńv̂ál̂íd̂."
6604
6640
  },
@@ -9461,6 +9497,9 @@
9461
9497
  "panels/sources/CallStackSidebarPane.ts | removeFromIgnoreList": {
9462
9498
  "message": "R̂ém̂óv̂é f̂ŕôḿ îǵn̂ór̂é l̂íŝt́"
9463
9499
  },
9500
+ "panels/sources/CallStackSidebarPane.ts | restartFrame": {
9501
+ "message": "R̂éŝt́âŕt̂ f́r̂ám̂é"
9502
+ },
9464
9503
  "panels/sources/CallStackSidebarPane.ts | showIgnorelistedFrames": {
9465
9504
  "message": "Ŝh́ôẃ îǵn̂ór̂é-l̂íŝt́êd́ f̂ŕâḿêś"
9466
9505
  },
@@ -1248,6 +1248,8 @@ export class CallFrame {
1248
1248
  #returnValueInternal: RemoteObject|null;
1249
1249
  readonly warnings: string[] = [];
1250
1250
 
1251
+ readonly canBeRestarted: boolean;
1252
+
1251
1253
  constructor(
1252
1254
  debuggerModel: DebuggerModel, script: Script, payload: Protocol.Debugger.CallFrame, inlineFrameIndex?: number,
1253
1255
  functionName?: string) {
@@ -1259,6 +1261,7 @@ export class CallFrame {
1259
1261
  this.#localScopeInternal = null;
1260
1262
  this.#inlineFrameIndexInternal = inlineFrameIndex || 0;
1261
1263
  this.#functionNameInternal = functionName || payload.functionName;
1264
+ this.canBeRestarted = Boolean(payload.canBeRestarted);
1262
1265
  for (let i = 0; i < payload.scopeChain.length; ++i) {
1263
1266
  const scope = new Scope(this, i);
1264
1267
  this.#scopeChainInternal.push(scope);
@@ -1390,6 +1393,15 @@ export class CallFrame {
1390
1393
  return {object: runtimeModel.createRemoteObject(response.result), exceptionDetails: response.exceptionDetails};
1391
1394
  }
1392
1395
 
1396
+ async restart(): Promise<void> {
1397
+ console.assert(this.canBeRestarted, 'This frame can not be restarted.');
1398
+ // Note that even if `canBeRestarted` is true, the restart frame call can still fail.
1399
+ // The user can evaluate arbitrary code between pausing and restarting the frame that
1400
+ // could mess with the call stack.
1401
+ await this.debuggerModel.agent.invoke_restartFrame(
1402
+ {callFrameId: this.id, mode: Protocol.Debugger.RestartFrameRequestMode.StepInto});
1403
+ }
1404
+
1393
1405
  getPayload(): Protocol.Debugger.CallFrame {
1394
1406
  return this.payload;
1395
1407
  }
@@ -36,6 +36,7 @@ import * as Common from '../common/common.js';
36
36
  import * as Host from '../host/host.js';
37
37
  import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
38
38
  import type * as Protocol from '../../generated/protocol.js';
39
+ import type * as Platform from '../platform/platform.js';
39
40
 
40
41
  import type {FunctionDetails} from './DebuggerModel.js';
41
42
  import {DebuggerModel} from './DebuggerModel.js';
@@ -121,7 +122,8 @@ export class RuntimeModel extends SDKModel<EventTypes> {
121
122
  executionContextCreated(context: Protocol.Runtime.ExecutionContextDescription): void {
122
123
  const data = context.auxData || {isDefault: true};
123
124
  const executionContext = new ExecutionContext(
124
- this, context.id, context.uniqueId, context.name, context.origin, data['isDefault'], data['frameId']);
125
+ this, context.id, context.uniqueId, context.name, context.origin as Platform.DevToolsPath.UrlString,
126
+ data['isDefault'], data['frameId']);
125
127
  this.#executionContextById.set(executionContext.id, executionContext);
126
128
  this.dispatchEventToListeners(Events.ExecutionContextCreated, executionContext);
127
129
  }
@@ -561,14 +563,14 @@ export class ExecutionContext {
561
563
  uniqueId: string;
562
564
  name: string;
563
565
  #labelInternal: string|null;
564
- origin: string;
566
+ origin: Platform.DevToolsPath.UrlString;
565
567
  isDefault: boolean;
566
568
  runtimeModel: RuntimeModel;
567
569
  debuggerModel: DebuggerModel;
568
570
  frameId: Protocol.Page.FrameId|undefined;
569
571
  constructor(
570
572
  runtimeModel: RuntimeModel, id: Protocol.Runtime.ExecutionContextId, uniqueId: string, name: string,
571
- origin: string, isDefault: boolean, frameId?: Protocol.Page.FrameId) {
573
+ origin: Platform.DevToolsPath.UrlString, isDefault: boolean, frameId?: Protocol.Page.FrameId) {
572
574
  this.id = id;
573
575
  this.uniqueId = uniqueId;
574
576
  this.name = name;
@@ -157,7 +157,7 @@ export class ExtensionSidebarPane extends UI.View.SimpleView {
157
157
  expression, true, false, evaluateOptions, securityOrigin, this.onEvaluate.bind(this, title, callback));
158
158
  }
159
159
 
160
- setPage(url: string): void {
160
+ setPage(url: Platform.DevToolsPath.UrlString): void {
161
161
  if (this.objectPropertiesView) {
162
162
  this.objectPropertiesView.detach();
163
163
  delete this.objectPropertiesView;
@@ -54,7 +54,7 @@ import {ExtensionTraceProvider} from './ExtensionTraceProvider.js';
54
54
  import {LanguageExtensionEndpoint} from './LanguageExtensionEndpoint.js';
55
55
  import {PrivateAPI} from './ExtensionAPI.js';
56
56
 
57
- const extensionOrigins: WeakMap<MessagePort, string> = new WeakMap();
57
+ const extensionOrigins: WeakMap<MessagePort, Platform.DevToolsPath.UrlString> = new WeakMap();
58
58
 
59
59
  declare global {
60
60
  interface Window {
@@ -342,7 +342,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
342
342
  return undefined;
343
343
  }
344
344
 
345
- private getExtensionOrigin(port: MessagePort): string {
345
+ private getExtensionOrigin(port: MessagePort): Platform.DevToolsPath.UrlString {
346
346
  const origin = extensionOrigins.get(port);
347
347
  if (!origin) {
348
348
  throw new Error('Received a message from an unregistered extension');
@@ -837,7 +837,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
837
837
  this.postNotification(PrivateAPI.Events.PanelObjectSelected + 'elements');
838
838
  }
839
839
 
840
- sourceSelectionChanged(url: string, range: TextUtils.TextRange.TextRange): void {
840
+ sourceSelectionChanged(url: Platform.DevToolsPath.UrlString, range: TextUtils.TextRange.TextRange): void {
841
841
  this.postNotification(PrivateAPI.Events.PanelObjectSelected + 'sources', {
842
842
  startLine: range.startLine,
843
843
  startColumn: range.startColumn,
@@ -893,7 +893,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
893
893
  return true;
894
894
  }
895
895
 
896
- private registerExtension(origin: string, port: MessagePort): void {
896
+ private registerExtension(origin: Platform.DevToolsPath.UrlString, port: MessagePort): void {
897
897
  if (!this.registeredExtensions.has(origin)) {
898
898
  if (origin !== window.location.origin) { // Just ignore inspector frames.
899
899
  console.error('Ignoring unauthorized client request from ' + origin);
@@ -907,7 +907,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
907
907
 
908
908
  private onWindowMessage(event: MessageEvent): void {
909
909
  if (event.data === 'registerExtension') {
910
- this.registerExtension(event.origin, event.ports[0]);
910
+ this.registerExtension(event.origin as Platform.DevToolsPath.UrlString, event.ports[0]);
911
911
  }
912
912
  }
913
913
 
@@ -981,8 +981,9 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
981
981
  removeLastEventListener.bind(this));
982
982
  }
983
983
 
984
- private expandResourcePath(extensionPath: string, resourcePath: string): string {
985
- return extensionPath + '/' + Common.ParsedURL.normalizePath(resourcePath);
984
+ private expandResourcePath(extensionPath: Platform.DevToolsPath.UrlString, resourcePath: string):
985
+ Platform.DevToolsPath.UrlString {
986
+ return extensionPath + '/' + Common.ParsedURL.normalizePath(resourcePath) as Platform.DevToolsPath.UrlString;
986
987
  }
987
988
 
988
989
  evaluate(
@@ -992,7 +993,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
992
993
  |undefined {
993
994
  let context;
994
995
 
995
- function resolveURLToFrame(url: string): SDK.ResourceTreeModel.ResourceTreeFrame|null {
996
+ function resolveURLToFrame(url: Platform.DevToolsPath.UrlString): SDK.ResourceTreeModel.ResourceTreeFrame|null {
996
997
  let found = null;
997
998
  function hasMatchingURL(frame: SDK.ResourceTreeModel.ResourceTreeFrame): SDK.ResourceTreeModel.ResourceTreeFrame|
998
999
  null {
@@ -1006,7 +1007,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
1006
1007
  options = options || {};
1007
1008
  let frame;
1008
1009
  if (options.frameURL) {
1009
- frame = resolveURLToFrame(options.frameURL);
1010
+ frame = resolveURLToFrame(options.frameURL as Platform.DevToolsPath.UrlString);
1010
1011
  } else {
1011
1012
  const target = SDK.TargetManager.TargetManager.instance().mainTarget();
1012
1013
  const resourceTreeModel = target && target.model(SDK.ResourceTreeModel.ResourceTreeModel);
@@ -1085,7 +1086,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
1085
1086
  return undefined;
1086
1087
  }
1087
1088
 
1088
- private canInspectURL(url: string): boolean {
1089
+ private canInspectURL(url: Platform.DevToolsPath.UrlString): boolean {
1089
1090
  let parsedURL;
1090
1091
  // This is only to work around invalid URLs we're occasionally getting from some tests.
1091
1092
  // TODO(caseq): make sure tests supply valid URLs or we specifically handle invalid ones.
@@ -35,6 +35,7 @@
35
35
  // See https://bugs.webkit.org/show_bug.cgi?id=58127 for details.
36
36
 
37
37
  import * as Common from '../../core/common/common.js';
38
+ import type * as Platform from '../../core/platform/platform.js';
38
39
  import * as SDK from '../../core/sdk/sdk.js';
39
40
  import type * as Protocol from '../../generated/protocol.js';
40
41
 
@@ -346,8 +347,8 @@ export class Entry {
346
347
  return parameters.slice();
347
348
  }
348
349
 
349
- private buildRequestURL(url: string): string {
350
- return url.split('#', 2)[0];
350
+ private buildRequestURL(url: Platform.DevToolsPath.UrlString): Platform.DevToolsPath.UrlString {
351
+ return Common.ParsedURL.ParsedURL.split(url, '#', 2)[0];
351
352
  }
352
353
 
353
354
  private buildCookies(cookies: SDK.Cookie.Cookie[]): CookieDTO[] {
@@ -438,7 +439,7 @@ export interface Content {
438
439
 
439
440
  export interface Request {
440
441
  method: string;
441
- url: string;
442
+ url: Platform.DevToolsPath.UrlString;
442
443
  httpVersion: string;
443
444
  headers: Object;
444
445
  queryString: Parameter[];
@@ -30,12 +30,14 @@
30
30
 
31
31
  import * as Common from '../../core/common/common.js';
32
32
  import * as i18n from '../../core/i18n/i18n.js';
33
+ import * as Root from '../../core/root/root.js';
33
34
  import * as SDK from '../../core/sdk/sdk.js';
34
35
  import * as NetworkForward from '../../panels/network/forward/forward.js';
35
36
  import * as UI from '../../ui/legacy/legacy.js';
36
- import * as NetworkComponents from './components/components.js';
37
37
 
38
+ import * as NetworkComponents from './components/components.js';
38
39
  import {EventSourceMessagesView} from './EventSourceMessagesView.js';
40
+
39
41
  import type {NetworkTimeCalculator} from './NetworkTimeCalculator.js';
40
42
  import {RequestCookiesView} from './RequestCookiesView.js';
41
43
  import {RequestHeadersView} from './RequestHeadersView.js';
@@ -130,6 +132,7 @@ export class NetworkItemView extends UI.TabbedPane.TabbedPane {
130
132
  private requestInternal: SDK.NetworkRequest.NetworkRequest;
131
133
  private readonly resourceViewTabSetting: Common.Settings.Setting<NetworkForward.UIRequestLocation.UIRequestTabs>;
132
134
  private readonly headersView: RequestHeadersView;
135
+ private readonly headersViewComponent: NetworkComponents.RequestHeadersView.RequestHeadersView;
133
136
  private payloadView: RequestPayloadView|null;
134
137
  private readonly responseView: RequestResponseView|undefined;
135
138
  private cookiesView: RequestCookiesView|null;
@@ -149,6 +152,12 @@ export class NetworkItemView extends UI.TabbedPane.TabbedPane {
149
152
  this.appendTab(
150
153
  NetworkForward.UIRequestLocation.UIRequestTabs.Headers, i18nString(UIStrings.headers), this.headersView,
151
154
  i18nString(UIStrings.headers));
155
+ this.headersViewComponent = new NetworkComponents.RequestHeadersView.RequestHeadersView(request);
156
+ if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.HEADER_OVERRIDES)) {
157
+ this.appendTab(
158
+ NetworkForward.UIRequestLocation.UIRequestTabs.HeadersComponent, i18nString(UIStrings.headers),
159
+ this.headersViewComponent, i18nString(UIStrings.headers));
160
+ }
152
161
 
153
162
  this.payloadView = null;
154
163
  void this.maybeAppendPayloadPanel();
@@ -451,7 +451,7 @@ export class RequestHeadersView extends UI.Widget.VBox {
451
451
  if (headersText) {
452
452
  const toggleButton = this.createHeadersToggleButton(this.showRequestHeadersText);
453
453
  toggleButton.addEventListener('click', this.toggleRequestHeadersText.bind(this), false);
454
- treeElement.listItemElement.appendChild(toggleButton);
454
+ treeElement.listItemElement.querySelector('.headers-title-left')?.appendChild(toggleButton);
455
455
  }
456
456
  }
457
457
 
@@ -0,0 +1,78 @@
1
+ /*
2
+ * Copyright 2022 The Chromium Authors. All rights reserved.
3
+ * Use of this source code is governed by a BSD-style license that can be
4
+ * found in the LICENSE file.
5
+ */
6
+
7
+ .header {
8
+ background-color: var(--color-background-elevation-1);
9
+ border-bottom: var(--legacy-divider-border);
10
+ border-top: var(--legacy-divider-border);
11
+ line-height: 25px;
12
+ padding: 0 5px;
13
+ }
14
+
15
+ .header::marker {
16
+ color: rgb(110 110 110); /* stylelint-disable-line plugin/use_theme_colors */
17
+ /* See: crbug.com/1152736 for color variable migration. */
18
+ font-size: 11px;
19
+ line-height: 1;
20
+ }
21
+
22
+ .header:focus {
23
+ background-color: var(--legacy-focus-bg-color);
24
+ }
25
+
26
+ .row {
27
+ display: flex;
28
+ line-height: 20px;
29
+ padding-left: 25px;
30
+ }
31
+
32
+ .row:first-of-type {
33
+ margin-top: 2px;
34
+ }
35
+
36
+ .row:last-child {
37
+ margin-bottom: 10px;
38
+ }
39
+
40
+ .header-name {
41
+ color: var(--color-primary);
42
+ font-weight: bold;
43
+ width: 160px;
44
+ flex-shrink: 0;
45
+ }
46
+
47
+ .header-value {
48
+ word-break: break-all;
49
+ user-select: text;
50
+ }
51
+
52
+ .green-circle::before,
53
+ .red-circle::before,
54
+ .yellow-circle::before {
55
+ content: "";
56
+ display: inline-block;
57
+ width: 12px;
58
+ height: 12px;
59
+ border-radius: 6px;
60
+ vertical-align: text-top;
61
+ margin-right: 2px;
62
+ }
63
+
64
+ .green-circle::before {
65
+ background-color: var(--color-accent-green);
66
+ }
67
+
68
+ .red-circle::before {
69
+ background-color: var(--color-accent-red);
70
+ }
71
+
72
+ .yellow-circle::before {
73
+ background-color: var(--issue-color-yellow);
74
+ }
75
+
76
+ .status-with-comment {
77
+ color: var(--color-text-secondary);
78
+ }
@@ -0,0 +1,262 @@
1
+ // Copyright 2022 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as Common from '../../../core/common/common.js';
6
+ import * as i18n from '../../../core/i18n/i18n.js';
7
+ import {assertNotNullOrUndefined} from '../../../core/platform/platform.js';
8
+ import * as SDK from '../../../core/sdk/sdk.js';
9
+ import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
10
+ import * as UI from '../../../ui/legacy/legacy.js';
11
+ import * as LitHtml from '../../../ui/lit-html/lit-html.js';
12
+
13
+ import requestHeadersViewStyles from './RequestHeadersView.css.js';
14
+
15
+ const {render, html} = LitHtml;
16
+
17
+ const UIStrings = {
18
+ /**
19
+ *@description Text in Request Headers View of the Network panel
20
+ */
21
+ fromMemoryCache: '(from memory cache)',
22
+ /**
23
+ *@description Text in Request Headers View of the Network panel
24
+ */
25
+ fromServiceWorker: '(from `service worker`)',
26
+ /**
27
+ *@description Text in Request Headers View of the Network panel
28
+ */
29
+ fromSignedexchange: '(from signed-exchange)',
30
+ /**
31
+ *@description Text in Request Headers View of the Network panel
32
+ */
33
+ fromPrefetchCache: '(from prefetch cache)',
34
+ /**
35
+ *@description Text in Request Headers View of the Network panel
36
+ */
37
+ fromDiskCache: '(from disk cache)',
38
+ /**
39
+ *@description Text in Request Headers View of the Network panel
40
+ */
41
+ fromWebBundle: '(from Web Bundle)',
42
+ /**
43
+ *@description Section header for a list of the main aspects of a http request
44
+ */
45
+ general: 'General',
46
+ /**
47
+ *@description The URL of a request
48
+ */
49
+ requestUrl: 'Request URL',
50
+ /**
51
+ *@description The HTTP method of a request
52
+ */
53
+ requestMethod: 'Request Method',
54
+ /**
55
+ *@description HTTP response code
56
+ */
57
+ statusCode: 'Status Code',
58
+ /**
59
+ *@description Text in Network Log View Columns of the Network panel
60
+ */
61
+ remoteAddress: 'Remote Address',
62
+ /**
63
+ *@description Text in Request Headers View of the Network panel
64
+ */
65
+ referrerPolicy: 'Referrer Policy',
66
+ };
67
+ const str_ = i18n.i18n.registerUIStrings('panels/network/components/RequestHeadersView.ts', UIStrings);
68
+ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
69
+
70
+ export class RequestHeadersView extends UI.Widget.VBox {
71
+ readonly #headersView = new RequestHeadersComponent();
72
+ readonly #request: SDK.NetworkRequest.NetworkRequest;
73
+
74
+ constructor(request: SDK.NetworkRequest.NetworkRequest) {
75
+ super();
76
+ this.#request = request;
77
+ this.contentElement.appendChild(this.#headersView);
78
+ }
79
+
80
+ wasShown(): void {
81
+ this.#request.addEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this.#refreshHeadersView, this);
82
+ this.#request.addEventListener(SDK.NetworkRequest.Events.FinishedLoading, this.#refreshHeadersView, this);
83
+ this.#refreshHeadersView();
84
+ }
85
+
86
+ willHide(): void {
87
+ this.#request.removeEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this.#refreshHeadersView, this);
88
+ this.#request.removeEventListener(SDK.NetworkRequest.Events.FinishedLoading, this.#refreshHeadersView, this);
89
+ }
90
+
91
+ #refreshHeadersView(): void {
92
+ this.#headersView.data = {
93
+ request: this.#request,
94
+ };
95
+ }
96
+ }
97
+
98
+ export interface RequestHeadersComponentData {
99
+ request: SDK.NetworkRequest.NetworkRequest;
100
+ }
101
+
102
+ export class RequestHeadersComponent extends HTMLElement {
103
+ static readonly litTagName = LitHtml.literal`devtools-request-headers`;
104
+ readonly #shadow = this.attachShadow({mode: 'open'});
105
+ #request?: Readonly<SDK.NetworkRequest.NetworkRequest>;
106
+
107
+ set data(data: RequestHeadersComponentData) {
108
+ this.#request = data.request;
109
+ this.#render();
110
+ }
111
+
112
+ connectedCallback(): void {
113
+ this.#shadow.adoptedStyleSheets = [requestHeadersViewStyles];
114
+ }
115
+
116
+ #render(): void {
117
+ assertNotNullOrUndefined(this.#request);
118
+
119
+ // Disabled until https://crbug.com/1079231 is fixed.
120
+ // clang-format off
121
+ render(html`
122
+ ${this.#renderGeneralSection()}
123
+ `, this.#shadow, {host: this});
124
+ // clang-format on
125
+ }
126
+
127
+ #renderGeneralSection(): LitHtml.TemplateResult {
128
+ assertNotNullOrUndefined(this.#request);
129
+
130
+ let coloredCircleClassName = 'red-circle';
131
+ if (this.#request.statusCode < 300 || this.#request.statusCode === 304) {
132
+ coloredCircleClassName = 'green-circle';
133
+ } else if (this.#request.statusCode < 400) {
134
+ coloredCircleClassName = 'yellow-circle';
135
+ }
136
+
137
+ let statusText = this.#request.statusCode + ' ' + this.#request.statusText;
138
+ let statusTextHasComment = false;
139
+ if (this.#request.cachedInMemory()) {
140
+ statusText += ' ' + i18nString(UIStrings.fromMemoryCache);
141
+ statusTextHasComment = true;
142
+ } else if (this.#request.fetchedViaServiceWorker) {
143
+ statusText += ' ' + i18nString(UIStrings.fromServiceWorker);
144
+ statusTextHasComment = true;
145
+ } else if (this.#request.redirectSourceSignedExchangeInfoHasNoErrors()) {
146
+ statusText += ' ' + i18nString(UIStrings.fromSignedexchange);
147
+ statusTextHasComment = true;
148
+ } else if (this.#request.webBundleInnerRequestInfo()) {
149
+ statusText += ' ' + i18nString(UIStrings.fromWebBundle);
150
+ statusTextHasComment = true;
151
+ } else if (this.#request.fromPrefetchCache()) {
152
+ statusText += ' ' + i18nString(UIStrings.fromPrefetchCache);
153
+ statusTextHasComment = true;
154
+ } else if (this.#request.cached()) {
155
+ statusText += ' ' + i18nString(UIStrings.fromDiskCache);
156
+ statusTextHasComment = true;
157
+ }
158
+
159
+ // Disabled until https://crbug.com/1079231 is fixed.
160
+ // clang-format off
161
+ return html`
162
+ <${Category.litTagName} .data=${{name: 'general', title: i18nString(UIStrings.general)} as CategoryData}>
163
+ <div class="row">
164
+ <div class="header-name">${i18nString(UIStrings.requestUrl)}:</div>
165
+ <div class="header-value">${this.#request.url()}</div>
166
+ </div>
167
+ ${this.#request.statusCode? html`
168
+ <div class="row">
169
+ <div class="header-name">${i18nString(UIStrings.requestMethod)}:</div>
170
+ <div class="header-value">${this.#request.requestMethod}</div>
171
+ </div>
172
+ <div class="row">
173
+ <div class="header-name">${i18nString(UIStrings.statusCode)}:</div>
174
+ <div class="header-value ${coloredCircleClassName} ${statusTextHasComment ? 'status-with-comment' : ''}">${statusText}</div>
175
+ </div>
176
+ ` : ''}
177
+ ${this.#request.remoteAddress()? html`
178
+ <div class="row">
179
+ <div class="header-name">${i18nString(UIStrings.remoteAddress)}:</div>
180
+ <div class="header-value">${this.#request.remoteAddress()}</div>
181
+ </div>
182
+ ` : ''}
183
+ ${this.#request.referrerPolicy()? html`
184
+ <div class="row">
185
+ <div class="header-name">${i18nString(UIStrings.referrerPolicy)}:</div>
186
+ <div class="header-value">${this.#request.referrerPolicy()}</div>
187
+ </div>
188
+ ` : ''}
189
+ </${Category.litTagName}>
190
+ `;
191
+ // clang-format on
192
+ }
193
+ }
194
+
195
+ export interface CategoryData {
196
+ name: string;
197
+ title: Common.UIString.LocalizedString;
198
+ }
199
+
200
+ export class Category extends HTMLElement {
201
+ static readonly litTagName = LitHtml.literal`devtools-request-headers-category`;
202
+ readonly #shadow = this.attachShadow({mode: 'open'});
203
+ #expandedSetting?: Common.Settings.Setting<boolean>;
204
+ #title: Common.UIString.LocalizedString = Common.UIString.LocalizedEmptyString;
205
+
206
+ connectedCallback(): void {
207
+ this.#shadow.adoptedStyleSheets = [requestHeadersViewStyles];
208
+ }
209
+
210
+ set data(data: CategoryData) {
211
+ this.#title = data.title;
212
+ this.#expandedSetting =
213
+ Common.Settings.Settings.instance().createSetting('request-info-' + data.name + '-category-expanded', true);
214
+ this.#render();
215
+ }
216
+
217
+ #render(): void {
218
+ // Disabled until https://crbug.com/1079231 is fixed.
219
+ // clang-format off
220
+ render(html`
221
+ <details ?open=${this.#expandedSetting ? this.#expandedSetting.get() : true} @toggle=${this.#onToggle}>
222
+ <summary class="header" @keydown=${this.#onSummaryKeyDown}>${this.#title}</summary>
223
+ <slot></slot>
224
+ </details>
225
+ `, this.#shadow, {host: this});
226
+ // clang-format on
227
+ }
228
+
229
+ #onSummaryKeyDown(event: KeyboardEvent): void {
230
+ if (!event.target) {
231
+ return;
232
+ }
233
+ const summaryElement = event.target as HTMLElement;
234
+ const detailsElement = summaryElement.parentElement as HTMLDetailsElement;
235
+ if (!detailsElement) {
236
+ throw new Error('<details> element is not found for a <summary> element');
237
+ }
238
+ switch (event.key) {
239
+ case 'ArrowLeft':
240
+ detailsElement.open = false;
241
+ break;
242
+ case 'ArrowRight':
243
+ detailsElement.open = true;
244
+ break;
245
+ }
246
+ }
247
+
248
+ #onToggle(event: Event): void {
249
+ this.#expandedSetting?.set((event.target as HTMLDetailsElement).open);
250
+ }
251
+ }
252
+
253
+ ComponentHelpers.CustomElements.defineComponent('devtools-request-headers', RequestHeadersComponent);
254
+ ComponentHelpers.CustomElements.defineComponent('devtools-request-headers-category', Category);
255
+
256
+ declare global {
257
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
258
+ interface HTMLElementTagNameMap {
259
+ 'devtools-request-headers': RequestHeadersComponent;
260
+ 'devtools-request-headers-category': Category;
261
+ }
262
+ }
@@ -2,8 +2,10 @@
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 * as RequestHeadersView from './RequestHeadersView.js';
5
6
  import * as RequestTrustTokensView from './RequestTrustTokensView.js';
6
7
 
7
8
  export {
9
+ RequestHeadersView,
8
10
  RequestTrustTokensView,
9
11
  };
@@ -24,6 +24,7 @@ export enum UIRequestTabs {
24
24
  Cookies = 'cookies',
25
25
  EventSource = 'eventSource',
26
26
  Headers = 'headers',
27
+ HeadersComponent = 'headersComponent',
27
28
  Payload = 'payload',
28
29
  Initiator = 'initiator',
29
30
  Preview = 'preview',
@@ -70,7 +70,7 @@
70
70
  flex: none;
71
71
  }
72
72
 
73
- .network-log-grid.data-grid table.data {
73
+ .network-log-grid.data-grid tbody {
74
74
  background: transparent;
75
75
  }
76
76
 
@@ -397,8 +397,8 @@
397
397
  /* This is part of the large color block declared above, but should not be
398
398
  extracted out. */
399
399
  /* stylelint-disable no-descending-specificity */
400
- .network-log-grid.data-grid table.data tr.revealed.selected,
401
- .network-log-grid.data-grid:focus table.data tr.revealed.selected,
400
+ .network-log-grid.data-grid tbody tr.revealed.selected,
401
+ .network-log-grid.data-grid:focus tbody tr.revealed.selected,
402
402
  .network-log-grid.data-grid:focus tr.selected .network-dim-cell,
403
403
  .network-log-grid.data-grid tr.selected .network-dim-cell,
404
404
  .network-log-grid.data-grid:focus tr.selected .initiator-column .devtools-link,
@@ -59,6 +59,12 @@
59
59
  display: none;
60
60
  }
61
61
 
62
+ .tree-outline li .headers-title-left {
63
+ min-width: 50%;
64
+ display: flex;
65
+ justify-content: space-between;
66
+ }
67
+
62
68
  .tree-outline li .header-toggle {
63
69
  display: none;
64
70
  }
@@ -86,6 +86,12 @@ const UIStrings = {
86
86
  *@description Text in Call Stack Sidebar Pane of the Sources panel when some call frames have warnings
87
87
  */
88
88
  callFrameWarnings: 'Some call frames have warnings',
89
+ /**
90
+ * @description A contex menu item in the Call Stack Sidebar Pane. "Restart" is a verb and
91
+ * "frame" is a noun. "Frame" refers to an individual item in the call stack, i.e. a call frame.
92
+ * The user opens this context menu by selecting a specific call frame in the call stack sidebar pane.
93
+ */
94
+ restartFrame: 'Restart frame',
89
95
  };
90
96
  const str_ = i18n.i18n.registerUIStrings('panels/sources/CallStackSidebarPane.ts', UIStrings);
91
97
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -384,6 +390,13 @@ export class CallStackSidebarPane extends UI.View.SimpleView implements UI.Conte
384
390
  return;
385
391
  }
386
392
  const contextMenu = new UI.ContextMenu.ContextMenu(event);
393
+ const debuggerCallFrame = itemToCallFrame.get(item);
394
+ if (debuggerCallFrame) {
395
+ contextMenu.defaultSection().appendItem(i18nString(UIStrings.restartFrame), () => {
396
+ Host.userMetrics.actionTaken(Host.UserMetrics.Action.StackFrameRestarted);
397
+ void debuggerCallFrame.restart();
398
+ }, !debuggerCallFrame.canBeRestarted);
399
+ }
387
400
  contextMenu.defaultSection().appendItem(i18nString(UIStrings.copyStackTrace), this.copyStackTrace.bind(this));
388
401
  if (item.uiLocation) {
389
402
  this.appendIgnoreListURLContextMenuItems(contextMenu, item.uiLocation.uiSourceCode);
@@ -311,13 +311,14 @@ export class OpenLinearMemoryInspector extends UI.Widget.VBox implements UI.Cont
311
311
  }
312
312
 
313
313
  private isMemoryObjectProperty(obj: SDK.RemoteObject.RemoteObject): boolean {
314
- const isWasmMemory = obj.type === 'object' && obj.subtype &&
314
+ const isWasmOrBuffer = obj.type === 'object' && obj.subtype &&
315
315
  LinearMemoryInspector.LinearMemoryInspectorController.ACCEPTED_MEMORY_TYPES.includes(obj.subtype);
316
- if (isWasmMemory) {
316
+ if (isWasmOrBuffer) {
317
317
  return true;
318
318
  }
319
319
 
320
- if (obj instanceof Bindings.DebuggerLanguagePlugins.ValueNode) {
320
+ const isWasmDWARF = obj instanceof Bindings.DebuggerLanguagePlugins.ValueNode;
321
+ if (isWasmDWARF) {
321
322
  return obj.inspectableAddress !== undefined;
322
323
  }
323
324
 
@@ -45,6 +45,10 @@
45
45
  z-index: 0;
46
46
  }
47
47
 
48
+ .sources-toolbar .toolbar {
49
+ cursor: default;
50
+ }
51
+
48
52
  .source-frame-debugger-script {
49
53
  --override-debugger-background-tint: rgb(255 255 194 / 50%);
50
54
 
@@ -130,6 +130,7 @@ export class DataGridImpl<T> extends Common.ObjectWrapper.ObjectWrapper<EventTyp
130
130
  [x: string]: Element,
131
131
  };
132
132
  scrollContainerInternal: Element;
133
+ private dataContainerInternal: Element;
133
134
  private readonly dataTable: Element;
134
135
  protected inline: boolean;
135
136
  private columnsArray: ColumnDescriptor[];
@@ -190,8 +191,9 @@ export class DataGridImpl<T> extends Common.ObjectWrapper.ObjectWrapper<EventTyp
190
191
 
191
192
  this.dataTableHeaders = {};
192
193
 
193
- this.scrollContainerInternal = this.element.createChild('div', 'data-container');
194
- this.dataTable = this.scrollContainerInternal.createChild('table', 'data');
194
+ this.dataContainerInternal = this.element.createChild('div', 'data-container');
195
+ this.dataTable = this.dataContainerInternal.createChild('table', 'data');
196
+ this.scrollContainerInternal = this.dataContainerInternal;
195
197
 
196
198
  // FIXME: Add a createCallback which is different from editCallback and has different
197
199
  // behavior when creating a new node.
@@ -1539,6 +1541,18 @@ export class DataGridImpl<T> extends Common.ObjectWrapper.ObjectWrapper<EventTyp
1539
1541
  return this.topFillerRow;
1540
1542
  }
1541
1543
 
1544
+ // Note on the following methods:
1545
+ // The header row is a child of the scrollable container, and uses position: sticky
1546
+ // so it can visually obscure other elements below it in the grid. We need to manually
1547
+ // subtract the header's height when calculating the actual client area in which
1548
+ // data rows are visible. However, if a caller has set a different scroll container
1549
+ // then we report 0 height and the caller is expected to ensure their chosen scroll
1550
+ // container's height matches the visible scrollable data area as seen by the user.
1551
+
1552
+ protected headerHeightInScroller(): number {
1553
+ return this.scrollContainer === this.dataContainerInternal ? this.headerHeight() : 0;
1554
+ }
1555
+
1542
1556
  protected headerHeight(): number {
1543
1557
  return this.dataTableHeadInternal.offsetHeight;
1544
1558
  }
@@ -172,7 +172,7 @@ export class ViewportDataGrid<T> extends Common.ObjectWrapper.eventMixin<EventTy
172
172
  delete this.updateAnimationFrameId;
173
173
  }
174
174
 
175
- const clientHeight = this.scrollContainer.clientHeight - this.headerHeight();
175
+ const clientHeight = this.scrollContainer.clientHeight - this.headerHeightInScroller();
176
176
  let scrollTop: number = this.scrollContainer.scrollTop;
177
177
  const currentScrollTop = scrollTop;
178
178
  const maxScrollTop = Math.max(0, this.contentHeight() - clientHeight);
@@ -249,7 +249,7 @@ export class ViewportDataGrid<T> extends Common.ObjectWrapper.eventMixin<EventTy
249
249
  }
250
250
  const toY = fromY + node.nodeSelfHeight();
251
251
  let scrollTop: number = this.scrollContainer.scrollTop;
252
- const visibleHeight = this.scrollContainer.offsetHeight - this.headerHeight();
252
+ const visibleHeight = this.scrollContainer.offsetHeight - this.headerHeightInScroller();
253
253
  if (scrollTop > fromY) {
254
254
  scrollTop = fromY;
255
255
  this.stickToBottom = false;
package/package.json CHANGED
@@ -55,5 +55,5 @@
55
55
  "unittest": "scripts/test/run_unittests.py --no-text-coverage",
56
56
  "watch": "vpython third_party/node/node.py --output scripts/watch_build.js"
57
57
  },
58
- "version": "1.0.1004171"
58
+ "version": "1.0.1004641"
59
59
  }