blob: 058939f67305a8e26874ebcc48c7e7d0fbfdf574 [file] [log] [blame]
Wolfgang Beyer65a82282022-09-05 08:22:371// 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
5import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
6import * as LitHtml from '../../../ui/lit-html/lit-html.js';
7
8import type * as SDK from '../../../core/sdk/sdk.js';
9import * as i18n from '../../../core/i18n/i18n.js';
10import * as NetworkForward from '../forward/forward.js';
11import * as IconButton from '../../../ui/components/icon_button/icon_button.js';
12import * as Platform from '../../../core/platform/platform.js';
13import {type HeaderDescriptor, HeaderSectionRow, type HeaderSectionRowData} from './HeaderSectionRow.js';
14
15import requestHeaderSectionStyles from './RequestHeaderSection.css.js';
16
17const {render, html} = LitHtml;
18
19const UIStrings = {
20 /**
21 *@description Text that is usually a hyperlink to more documentation
22 */
23 learnMore: 'Learn more',
24 /**
25 *@description Message to explain lack of raw headers for a particular network request
26 */
27 provisionalHeadersAreShownDisableCache: 'Provisional headers are shown. Disable cache to see full headers.',
28 /**
29 *@description Tooltip to explain lack of raw headers for a particular network request
30 */
31 onlyProvisionalHeadersAre:
32 'Only provisional headers are available because this request was not sent over the network and instead was served from a local cache, which doesn’t store the original request headers. Disable cache to see full request headers.',
33 /**
34 *@description Message to explain lack of raw headers for a particular network request
35 */
36 provisionalHeadersAreShown: 'Provisional headers are shown.',
37};
38
39const str_ = i18n.i18n.registerUIStrings('panels/network/components/RequestHeaderSection.ts', UIStrings);
40const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
41
42export interface RequestHeaderSectionData {
43 request: SDK.NetworkRequest.NetworkRequest;
44 toReveal?: {section: NetworkForward.UIRequestLocation.UIHeaderSection, header?: string};
45}
46
47export class RequestHeaderSection extends HTMLElement {
48 static readonly litTagName = LitHtml.literal`devtools-request-header-section`;
49 readonly #shadow = this.attachShadow({mode: 'open'});
50 #request?: Readonly<SDK.NetworkRequest.NetworkRequest>;
51 #headers: HeaderDescriptor[] = [];
52
53 connectedCallback(): void {
54 this.#shadow.adoptedStyleSheets = [requestHeaderSectionStyles];
55 }
56
57 set data(data: RequestHeaderSectionData) {
58 this.#request = data.request;
59
60 this.#headers = this.#request.requestHeaders().map(header => ({...header, headerNotSet: false}));
61 this.#headers.sort(function(a, b) {
62 return Platform.StringUtilities.compare(a.name.toLowerCase(), b.name.toLowerCase());
63 });
64
65 if (data.toReveal?.section === NetworkForward.UIRequestLocation.UIHeaderSection.Request) {
66 this.#headers.filter(header => header.name.toUpperCase() === data.toReveal?.header?.toUpperCase())
67 .forEach(header => {
68 header.highlight = true;
69 });
70 }
71
72 this.#render();
73 }
74
75 #render(): void {
76 if (!this.#request) {
77 return;
78 }
79
80 // Disabled until https://crbug.com/1079231 is fixed.
81 // clang-format off
82 render(html`
83 ${this.#maybeRenderProvisionalHeadersWarning()}
84 ${this.#headers.map(header => html`
85 <${HeaderSectionRow.litTagName} .data=${{
86 header: header,
87 } as HeaderSectionRowData}></${HeaderSectionRow.litTagName}>
88 `)}
89 `, this.#shadow, {host: this});
90 // clang-format on
91 }
92
93 #maybeRenderProvisionalHeadersWarning(): LitHtml.LitTemplate {
94 if (!this.#request || this.#request.requestHeadersText() !== undefined) {
95 return LitHtml.nothing;
96 }
97
98 let cautionText;
99 let cautionTitle = '';
100 if (this.#request.cachedInMemory() || this.#request.cached()) {
101 cautionText = i18nString(UIStrings.provisionalHeadersAreShownDisableCache);
102 cautionTitle = i18nString(UIStrings.onlyProvisionalHeadersAre);
103 } else {
104 cautionText = i18nString(UIStrings.provisionalHeadersAreShown);
105 }
106 // Disabled until https://crbug.com/1079231 is fixed.
107 // clang-format off
108 return html`
109 <div class="call-to-action">
110 <div class="call-to-action-body">
111 <div class="explanation" title=${cautionTitle}>
112 <${IconButton.Icon.Icon.litTagName} class="inline-icon" .data=${{
113 iconName: 'clear-warning_icon',
114 width: '12px',
115 height: '12px',
116 } as IconButton.Icon.IconData}>
117 </${IconButton.Icon.Icon.litTagName}>
118 ${cautionText} <x-link href="https://developer.chrome.com/docs/devtools/network/reference/#provisional-headers" class="link">${i18nString(UIStrings.learnMore)}</x-link>
119 </div>
120 </div>
121 </div>
122 `;
123 // clang-format on
124 }
125}
126
127ComponentHelpers.CustomElements.defineComponent('devtools-request-header-section', RequestHeaderSection);
128
129declare global {
130 interface HTMLElementTagNameMap {
131 'devtools-request-header-section': RequestHeaderSection;
132 }
133}