debug-server-next
Version:
Dev server for hippy-core.
642 lines (641 loc) • 30.9 kB
JavaScript
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { StackTrace } from './StackTrace.js';
import { PermissionsPolicySection, renderIconLink } from './PermissionsPolicySection.js';
import * as Bindings from '../../../models/bindings/bindings.js';
import * as Common from '../../../core/common/common.js';
import * as i18n from '../../../core/i18n/i18n.js';
import * as NetworkForward from '../../../panels/network/forward/forward.js';
import * as Root from '../../../core/root/root.js';
import * as SDK from '../../../core/sdk/sdk.js';
import * as LitHtml from '../../../ui/lit-html/lit-html.js';
import * as ExpandableList from '../../../ui/components/expandable_list/expandable_list.js';
import * as ReportView from '../../../ui/components/report_view/report_view.js';
import * as IconButton from '../../../ui/components/icon_button/icon_button.js';
import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
import * as UI from '../../../ui/legacy/legacy.js';
import * as Workspace from '../../../models/workspace/workspace.js';
import * as Components from '../../../ui/legacy/components/utils/utils.js';
import { OriginTrialTreeView } from './OriginTrialTreeView.js';
import * as Coordinator from '../../../ui/components/render_coordinator/render_coordinator.js';
import frameDetailsReportViewStyles from './frameDetailsReportView.css.js';
const UIStrings = {
/**
*@description Section header in the Frame Details view
*/
additionalInformation: 'Additional Information',
/**
*@description Explanation for why the additional information section is being shown
*/
thisAdditionalDebugging: 'This additional (debugging) information is shown because the \'Protocol Monitor\' experiment is enabled.',
/**
*@description Label for subtitle of frame details view
*/
frameId: 'Frame ID',
/**
*@description Name of a network resource type
*/
document: 'Document',
/**
*@description Text for web URLs
*/
url: 'URL',
/**
*@description Title for a link to the Sources panel
*/
clickToRevealInSourcesPanel: 'Click to reveal in Sources panel',
/**
*@description Title for a link to the Network panel
*/
clickToRevealInNetworkPanel: 'Click to reveal in Network panel',
/**
*@description Title for unreachable URL field
*/
unreachableUrl: 'Unreachable URL',
/**
*@description Title for a link that applies a filter to the network panel
*/
clickToRevealInNetworkPanelMight: 'Click to reveal in Network panel (might require page reload)',
/**
*@description Text for the origin of something
*/
origin: 'Origin',
/**
*@description Related node label in Timeline UIUtils of the Performance panel
*/
ownerElement: 'Owner Element',
/**
*@description Title for a link to the Elements panel
*/
clickToRevealInElementsPanel: 'Click to reveal in Elements panel',
/**
*@description Title for ad frame type field
*/
adStatus: 'Ad Status',
/**
*@description Description for ad frame type
*/
rootDescription: 'This frame has been identified as the root frame of an ad',
/**
*@description Value for ad frame type
*/
root: 'root',
/**
*@description Description for ad frame type
*/
childDescription: 'This frame has been identified as a child frame of an ad',
/**
*@description Value for ad frame type
*/
child: 'child',
/**
*@description Section header in the Frame Details view
*/
securityIsolation: 'Security & Isolation',
/**
*@description Row title for in the Frame Details view
*/
secureContext: 'Secure Context',
/**
*@description Text in Timeline indicating that input has happened recently
*/
yes: 'Yes',
/**
*@description Text in Timeline indicating that input has not happened recently
*/
no: 'No',
/**
*@description Row title for in the Frame Details view
*/
crossoriginIsolated: 'Cross-Origin Isolated',
/**
*@description Explanatory text in the Frame Details view
*/
localhostIsAlwaysASecureContext: 'Localhost is always a secure context',
/**
*@description Explanatory text in the Frame Details view
*/
aFrameAncestorIsAnInsecure: 'A frame ancestor is an insecure context',
/**
*@description Explanatory text in the Frame Details view
*/
theFramesSchemeIsInsecure: 'The frame\'s scheme is insecure',
/**
*@description Row title in the Frame Details view
*/
crossoriginEmbedderPolicy: 'Cross-Origin Embedder Policy',
/**
*@description Row title in the Frame Details view
*/
crossoriginOpenerPolicy: 'Cross-Origin Opener Policy',
/**
*@description This label specifies the server endpoints to which the server is reporting errors
*and warnings through the Report-to API. Following this label will be the URL of the server.
*/
reportingTo: 'reporting to',
/**
*@description Section header in the Frame Details view
*/
apiAvailability: 'API availability',
/**
*@description Explanatory text in the Frame Details view for the API availability section
*/
availabilityOfCertainApisDepends: 'Availability of certain APIs depends on the document being cross-origin isolated.',
/**
*@description Description of the SharedArrayBuffer status
*/
availableTransferable: 'available, transferable',
/**
*@description Description of the SharedArrayBuffer status
*/
availableNotTransferable: 'available, not transferable',
/**
*@description Explanation for the SharedArrayBuffer availability status
*/
unavailable: 'unavailable',
/**
*@description Tooltip for the SharedArrayBuffer availability status
*/
sharedarraybufferConstructorIs: 'SharedArrayBuffer constructor is available and SABs can be transferred via postMessage',
/**
*@description Tooltip for the SharedArrayBuffer availability status
*/
sharedarraybufferConstructorIsAvailable: 'SharedArrayBuffer constructor is available but SABs cannot be transferred via postMessage',
/**
*@description Explanation for the SharedArrayBuffer availability status
*/
willRequireCrossoriginIsolated: '⚠️ will require cross-origin isolated context in the future',
/**
*@description Explanation for the SharedArrayBuffer availability status
*/
requiresCrossoriginIsolated: 'requires cross-origin isolated context',
/**
*@description Explanation for the SharedArrayBuffer availability status in case the transfer of a SAB requires the
* permission policy `cross-origin-isolated` to be enabled (e.g. because the message refers to the situation in an iframe).
*/
transferRequiresCrossoriginIsolatedPermission: '`SharedArrayBuffer` transfer requires enabling the permission policy:',
/**
*@description Explanation for the Measure Memory availability status
*/
available: 'available',
/**
*@description Tooltip for the Measure Memory availability status
*/
thePerformanceAPI: 'The performance.measureUserAgentSpecificMemory() API is available',
/**
*@description Tooltip for the Measure Memory availability status
*/
thePerformancemeasureuseragentspecificmemory: 'The performance.measureUserAgentSpecificMemory() API is not available',
/**
*@description Entry in the API availability section of the frame details view
*/
measureMemory: 'Measure Memory',
/**
*@description Text that is usually a hyperlink to more documentation
*/
learnMore: 'Learn more',
/**
*@description Label for a stack trace. If a frame is created programmatically (i.e. via JavaScript), there is a
* stack trace for the line of code which caused the creation of the iframe. This is the stack trace we are showing here.
*/
creationStackTrace: 'Frame Creation Stack Trace',
/**
*@description Tooltip for 'Frame Creation Stack Trace' explaining that the stack
*trace shows where in the code the frame has been created programmatically
*/
creationStackTraceExplanation: 'This frame was created programmatically. The stack trace shows where this happened.',
/**
*@description Text descripting why a frame has been indentified as an advertisement.
*/
parentIsAdExplanation: 'This frame is considered an ad frame because its parent frame is an ad frame.',
/**
*@description Text descripting why a frame has been indentified as an advertisement.
*/
matchedBlockingRuleExplanation: 'This frame is considered an ad frame because its current (or previous) main document is an ad resource.',
/**
*@description Text descripting why a frame has been indentified as an advertisement.
*/
createdByAdScriptExplanation: 'There was an ad script in the (async) stack when this frame was created. Examining the creation stack trace of this frame might provide more insight.',
/**
*@description Label for a list of origin trials that associated with at least one token.
*/
originTrials: 'Origin Trials',
};
const str_ = i18n.i18n.registerUIStrings('panels/application/components/FrameDetailsView.ts', UIStrings);
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
export class FrameDetailsView extends UI.ThrottledWidget.ThrottledWidget {
reportView = new FrameDetailsReportView();
frame;
constructor(frame) {
super();
this.frame = frame;
this.contentElement.classList.add('overflow-auto');
this.contentElement.appendChild(this.reportView);
this.update();
}
async doUpdate() {
this.reportView.data = { frame: this.frame };
}
}
const coordinator = Coordinator.RenderCoordinator.RenderCoordinator.instance();
export class FrameDetailsReportView extends HTMLElement {
static litTagName = LitHtml.literal `devtools-resources-frame-details-view`;
shadow = this.attachShadow({ mode: 'open' });
frame;
protocolMonitorExperimentEnabled = false;
permissionsPolicies = null;
permissionsPolicySectionData = { policies: [], showDetails: false };
connectedCallback() {
this.protocolMonitorExperimentEnabled = Root.Runtime.experiments.isEnabled('protocolMonitor');
this.shadow.adoptedStyleSheets = [frameDetailsReportViewStyles];
}
set data(data) {
this.frame = data.frame;
if (!this.permissionsPolicies && this.frame) {
this.permissionsPolicies = this.frame.getPermissionsPolicyState();
}
this.render();
}
async render() {
await coordinator.write('FrameDetailsView render', () => {
if (!this.frame) {
return;
}
// Disabled until https://crbug.com/1079231 is fixed.
// clang-format off
LitHtml.render(LitHtml.html `
<${ReportView.ReportView.Report.litTagName} .data=${{ reportTitle: this.frame.displayName() }}>
${this.renderDocumentSection()}
${this.renderIsolationSection()}
${this.renderApiAvailabilitySection()}
${this.renderOriginTrial()}
${LitHtml.Directives.until(this.permissionsPolicies?.then(policies => {
this.permissionsPolicySectionData.policies = policies || [];
return LitHtml.html `
<${PermissionsPolicySection.litTagName}
.data=${this.permissionsPolicySectionData}
>
</${PermissionsPolicySection.litTagName}>
`;
}), LitHtml.nothing)}
${this.protocolMonitorExperimentEnabled ? this.renderAdditionalInfoSection() : LitHtml.nothing}
</${ReportView.ReportView.Report.litTagName}>
`, this.shadow, { host: this });
// clang-format on
});
}
renderOriginTrial() {
const originTrials = this.frame?.getOriginTrials();
if (!originTrials?.length) {
return LitHtml.nothing;
}
return LitHtml.html `
<${ReportView.ReportView.ReportSectionHeader.litTagName}>${i18nString(UIStrings.originTrials)}
</${ReportView.ReportView.ReportSectionHeader.litTagName}>
<${OriginTrialTreeView.litTagName} class="span-cols"
.data=${{ trials: originTrials }}>
</${OriginTrialTreeView.litTagName}>
<${ReportView.ReportView.ReportSectionDivider.litTagName}></${ReportView.ReportView.ReportSectionDivider.litTagName}>
`;
}
renderDocumentSection() {
if (!this.frame) {
return LitHtml.nothing;
}
return LitHtml.html `
<${ReportView.ReportView.ReportSectionHeader.litTagName}>${i18nString(UIStrings.document)}</${ReportView.ReportView.ReportSectionHeader.litTagName}>
<${ReportView.ReportView.ReportKey.litTagName}>${i18nString(UIStrings.url)}</${ReportView.ReportView.ReportKey.litTagName}>
<${ReportView.ReportView.ReportValue.litTagName}>
<div class="inline-items">
${this.maybeRenderSourcesLinkForURL()}
${this.maybeRenderNetworkLinkForURL()}
<div class="text-ellipsis" title=${this.frame.url}>${this.frame.url}</div>
</div>
</${ReportView.ReportView.ReportValue.litTagName}>
${this.maybeRenderUnreachableURL()}
${this.maybeRenderOrigin()}
${LitHtml.Directives.until(this.renderOwnerElement(), LitHtml.nothing)}
${this.maybeRenderCreationStacktrace()}
${this.maybeRenderAdStatus()}
<${ReportView.ReportView.ReportSectionDivider.litTagName}></${ReportView.ReportView.ReportSectionDivider.litTagName}>
`;
}
maybeRenderSourcesLinkForURL() {
if (!this.frame || this.frame.unreachableUrl()) {
return LitHtml.nothing;
}
const sourceCode = this.uiSourceCodeForFrame(this.frame);
return renderIconLink('sources_panel_icon', i18nString(UIStrings.clickToRevealInSourcesPanel), () => Common.Revealer.reveal(sourceCode));
}
maybeRenderNetworkLinkForURL() {
if (this.frame) {
const resource = this.frame.resourceForURL(this.frame.url);
if (resource && resource.request) {
const request = resource.request;
return renderIconLink('network_panel_icon', i18nString(UIStrings.clickToRevealInNetworkPanel), () => {
const requestLocation = NetworkForward.UIRequestLocation.UIRequestLocation.tab(request, NetworkForward.UIRequestLocation.UIRequestTabs.Headers);
return Common.Revealer.reveal(requestLocation);
});
}
}
return LitHtml.nothing;
}
uiSourceCodeForFrame(frame) {
for (const project of Workspace.Workspace.WorkspaceImpl.instance().projects()) {
const projectTarget = Bindings.NetworkProject.NetworkProject.getTargetForProject(project);
if (projectTarget && projectTarget === frame.resourceTreeModel().target()) {
const uiSourceCode = project.uiSourceCodeForURL(frame.url);
if (uiSourceCode) {
return uiSourceCode;
}
}
}
return null;
}
maybeRenderUnreachableURL() {
if (!this.frame || !this.frame.unreachableUrl()) {
return LitHtml.nothing;
}
return LitHtml.html `
<${ReportView.ReportView.ReportKey.litTagName}>${i18nString(UIStrings.unreachableUrl)}</${ReportView.ReportView.ReportKey.litTagName}>
<${ReportView.ReportView.ReportValue.litTagName}>
<div class="inline-items">
${this.renderNetworkLinkForUnreachableURL()}
<div class="text-ellipsis" title=${this.frame.unreachableUrl()}>${this.frame.unreachableUrl()}</div>
</div>
</${ReportView.ReportView.ReportValue.litTagName}>
`;
}
renderNetworkLinkForUnreachableURL() {
if (this.frame) {
const unreachableUrl = Common.ParsedURL.ParsedURL.fromString(this.frame.unreachableUrl());
if (unreachableUrl) {
return renderIconLink('network_panel_icon', i18nString(UIStrings.clickToRevealInNetworkPanelMight), () => {
Common.Revealer.reveal(NetworkForward.UIFilter.UIRequestFilter.filters([
{
filterType: NetworkForward.UIFilter.FilterType.Domain,
filterValue: unreachableUrl.domain(),
},
{
filterType: null,
filterValue: unreachableUrl.path,
},
]));
});
}
}
return LitHtml.nothing;
}
maybeRenderOrigin() {
if (this.frame && this.frame.securityOrigin && this.frame.securityOrigin !== '://') {
return LitHtml.html `
<${ReportView.ReportView.ReportKey.litTagName}>${i18nString(UIStrings.origin)}</${ReportView.ReportView.ReportKey.litTagName}>
<${ReportView.ReportView.ReportValue.litTagName}>
<div class="text-ellipsis" title=${this.frame.securityOrigin}>${this.frame.securityOrigin}</div>
</${ReportView.ReportView.ReportValue.litTagName}>
`;
}
return LitHtml.nothing;
}
async renderOwnerElement() {
if (this.frame) {
const linkTargetDOMNode = await this.frame.getOwnerDOMNodeOrDocument();
if (linkTargetDOMNode) {
// Disabled until https://crbug.com/1079231 is fixed.
// clang-format off
return LitHtml.html `
<${ReportView.ReportView.ReportKey.litTagName}>${i18nString(UIStrings.ownerElement)}</${ReportView.ReportView.ReportKey.litTagName}>
<${ReportView.ReportView.ReportValue.litTagName} class="without-min-width">
<button class="link" role="link" tabindex=0 title=${i18nString(UIStrings.clickToRevealInElementsPanel)}
=${() => this.frame?.highlight()}
=${() => SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight()}
=${() => Common.Revealer.reveal(linkTargetDOMNode)}
>
<${IconButton.Icon.Icon.litTagName} class="button-icon-with-text" .data=${{
iconName: 'elements_panel_icon',
color: 'var(--color-primary)',
width: '16px',
height: '16px',
}}></${IconButton.Icon.Icon.litTagName}>
<${linkTargetDOMNode.nodeName().toLocaleLowerCase()}>
</button>
</${ReportView.ReportView.ReportValue.litTagName}>
`;
// clang-format on
}
}
return LitHtml.nothing;
}
maybeRenderCreationStacktrace() {
const creationStackTraceData = this.frame?.getCreationStackTraceData();
if (creationStackTraceData && creationStackTraceData.creationStackTrace) {
// Disabled until https://crbug.com/1079231 is fixed.
// clang-format off
return LitHtml.html `
<${ReportView.ReportView.ReportKey.litTagName} title=${i18nString(UIStrings.creationStackTraceExplanation)}>${i18nString(UIStrings.creationStackTrace)}</${ReportView.ReportView.ReportKey.litTagName}>
<${ReportView.ReportView.ReportValue.litTagName}>
<${StackTrace.litTagName} .data=${{
frame: this.frame,
buildStackTraceRows: Components.JSPresentationUtils.buildStackTraceRows,
}}>
</${StackTrace.litTagName}>
</${ReportView.ReportView.ReportValue.litTagName}>
`;
// clang-format on
}
return LitHtml.nothing;
}
getAdFrameTypeStrings(type) {
switch (type) {
case "child" /* Child */:
return { value: i18nString(UIStrings.child), description: i18nString(UIStrings.childDescription) };
case "root" /* Root */:
return { value: i18nString(UIStrings.root), description: i18nString(UIStrings.rootDescription) };
}
}
getAdFrameExplanationString(explanation) {
switch (explanation) {
case "CreatedByAdScript" /* CreatedByAdScript */:
return i18nString(UIStrings.createdByAdScriptExplanation);
case "MatchedBlockingRule" /* MatchedBlockingRule */:
return i18nString(UIStrings.matchedBlockingRuleExplanation);
case "ParentIsAd" /* ParentIsAd */:
return i18nString(UIStrings.parentIsAdExplanation);
}
}
maybeRenderAdStatus() {
if (!this.frame) {
return LitHtml.nothing;
}
const adFrameType = this.frame.adFrameType();
if (adFrameType === "none" /* None */) {
return LitHtml.nothing;
}
const typeStrings = this.getAdFrameTypeStrings(adFrameType);
const rows = [LitHtml.html `<div title="${typeStrings.description}">${typeStrings.value}</div>`];
for (const explanation of this.frame.adFrameStatus()?.explanations || []) {
rows.push(LitHtml.html `<div>${this.getAdFrameExplanationString(explanation)}</div>`);
}
return LitHtml.html `
<${ReportView.ReportView.ReportKey.litTagName}>${i18nString(UIStrings.adStatus)}</${ReportView.ReportView.ReportKey.litTagName}>
<${ReportView.ReportView.ReportValue.litTagName}>
<${ExpandableList.ExpandableList.ExpandableList.litTagName} .data=${{ rows }}></${ExpandableList.ExpandableList.ExpandableList.litTagName}></${ReportView.ReportView.ReportValue.litTagName}>
`;
}
renderIsolationSection() {
if (!this.frame) {
return LitHtml.nothing;
}
return LitHtml.html `
<${ReportView.ReportView.ReportSectionHeader.litTagName}>${i18nString(UIStrings.securityIsolation)}</${ReportView.ReportView.ReportSectionHeader.litTagName}>
<${ReportView.ReportView.ReportKey.litTagName}>${i18nString(UIStrings.secureContext)}</${ReportView.ReportView.ReportKey.litTagName}>
<${ReportView.ReportView.ReportValue.litTagName}>
${this.frame.isSecureContext() ? i18nString(UIStrings.yes) : i18nString(UIStrings.no)}\xA0${this.maybeRenderSecureContextExplanation()}
</${ReportView.ReportView.ReportValue.litTagName}>
<${ReportView.ReportView.ReportKey.litTagName}>${i18nString(UIStrings.crossoriginIsolated)}</${ReportView.ReportView.ReportKey.litTagName}>
<${ReportView.ReportView.ReportValue.litTagName}>
${this.frame.isCrossOriginIsolated() ? i18nString(UIStrings.yes) : i18nString(UIStrings.no)}
</${ReportView.ReportView.ReportValue.litTagName}>
${LitHtml.Directives.until(this.maybeRenderCoopCoepStatus(), LitHtml.nothing)}
<${ReportView.ReportView.ReportSectionDivider.litTagName}></${ReportView.ReportView.ReportSectionDivider.litTagName}>
`;
}
maybeRenderSecureContextExplanation() {
const explanation = this.getSecureContextExplanation();
if (explanation) {
return LitHtml.html `<span class="inline-comment">${explanation}</span>`;
}
return LitHtml.nothing;
}
getSecureContextExplanation() {
switch (this.frame?.getSecureContextType()) {
case "Secure" /* Secure */:
return null;
case "SecureLocalhost" /* SecureLocalhost */:
return i18nString(UIStrings.localhostIsAlwaysASecureContext);
case "InsecureAncestor" /* InsecureAncestor */:
return i18nString(UIStrings.aFrameAncestorIsAnInsecure);
case "InsecureScheme" /* InsecureScheme */:
return i18nString(UIStrings.theFramesSchemeIsInsecure);
}
return null;
}
async maybeRenderCoopCoepStatus() {
if (this.frame) {
const model = this.frame.resourceTreeModel().target().model(SDK.NetworkManager.NetworkManager);
const info = model && await model.getSecurityIsolationStatus(this.frame.id);
if (info) {
return LitHtml.html `
${this.maybeRenderCrossOriginStatus(info.coep, i18nString(UIStrings.crossoriginEmbedderPolicy), "None" /* None */)}
${this.maybeRenderCrossOriginStatus(info.coop, i18nString(UIStrings.crossoriginOpenerPolicy), "UnsafeNone" /* UnsafeNone */)}
`;
}
}
return LitHtml.nothing;
}
maybeRenderCrossOriginStatus(info, policyName, noneValue) {
if (!info) {
return LitHtml.nothing;
}
const isEnabled = info.value !== noneValue;
const isReportOnly = (!isEnabled && info.reportOnlyValue !== noneValue);
const endpoint = isEnabled ? info.reportingEndpoint : info.reportOnlyReportingEndpoint;
return LitHtml.html `
<${ReportView.ReportView.ReportKey.litTagName}>${policyName}</${ReportView.ReportView.ReportKey.litTagName}>
<${ReportView.ReportView.ReportValue.litTagName}>
${isEnabled ? info.value : info.reportOnlyValue}
${isReportOnly ? LitHtml.html `<span class="inline-comment">report-only</span>` : LitHtml.nothing}
${endpoint ? LitHtml.html `<span class="inline-name">${i18nString(UIStrings.reportingTo)}</span>${endpoint}` :
LitHtml.nothing}
</${ReportView.ReportView.ReportValue.litTagName}>
`;
}
renderApiAvailabilitySection() {
if (!this.frame) {
return LitHtml.nothing;
}
return LitHtml.html `
<${ReportView.ReportView.ReportSectionHeader.litTagName}>${i18nString(UIStrings.apiAvailability)}</${ReportView.ReportView.ReportSectionHeader.litTagName}>
<div class="span-cols">
${i18nString(UIStrings.availabilityOfCertainApisDepends)}
<x-link href="https://web.dev/why-coop-coep/" class="link">${i18nString(UIStrings.learnMore)}</x-link>
</div>
${this.renderSharedArrayBufferAvailability()}
${this.renderMeasureMemoryAvailability()}
<${ReportView.ReportView.ReportSectionDivider.litTagName}></${ReportView.ReportView.ReportSectionDivider.litTagName}>
`;
}
renderSharedArrayBufferAvailability() {
if (this.frame) {
const features = this.frame.getGatedAPIFeatures();
if (features) {
const sabAvailable = features.includes("SharedArrayBuffers" /* SharedArrayBuffers */);
const sabTransferAvailable = sabAvailable && features.includes("SharedArrayBuffersTransferAllowed" /* SharedArrayBuffersTransferAllowed */);
const availabilityText = sabTransferAvailable ?
i18nString(UIStrings.availableTransferable) :
(sabAvailable ? i18nString(UIStrings.availableNotTransferable) : i18nString(UIStrings.unavailable));
const tooltipText = sabTransferAvailable ?
i18nString(UIStrings.sharedarraybufferConstructorIs) :
(sabAvailable ? i18nString(UIStrings.sharedarraybufferConstructorIsAvailable) : '');
function renderHint(frame) {
switch (frame.getCrossOriginIsolatedContextType()) {
case "Isolated" /* Isolated */:
return LitHtml.nothing;
case "NotIsolated" /* NotIsolated */:
if (sabAvailable) {
return LitHtml.html `<span class="inline-comment">${i18nString(UIStrings.willRequireCrossoriginIsolated)}</span>`;
}
return LitHtml.html `<span class="inline-comment">${i18nString(UIStrings.requiresCrossoriginIsolated)}</span>`;
case "NotIsolatedFeatureDisabled" /* NotIsolatedFeatureDisabled */:
if (!sabTransferAvailable) {
return LitHtml.html `<span class="inline-comment">${i18nString(UIStrings
.transferRequiresCrossoriginIsolatedPermission)} <code>cross-origin-isolated</code></span>`;
}
break;
}
return LitHtml.nothing;
}
// SharedArrayBuffer is an API name, so we don't translate it.
return LitHtml.html `
<${ReportView.ReportView.ReportKey.litTagName}>SharedArrayBuffers</${ReportView.ReportView.ReportKey.litTagName}>
<${ReportView.ReportView.ReportValue.litTagName} title=${tooltipText}>
${availabilityText}\xA0${renderHint(this.frame)}
</${ReportView.ReportView.ReportValue.litTagName}>
`;
}
}
return LitHtml.nothing;
}
renderMeasureMemoryAvailability() {
if (this.frame) {
const measureMemoryAvailable = this.frame.isCrossOriginIsolated();
const availabilityText = measureMemoryAvailable ? i18nString(UIStrings.available) : i18nString(UIStrings.unavailable);
const tooltipText = measureMemoryAvailable ? i18nString(UIStrings.thePerformanceAPI) :
i18nString(UIStrings.thePerformancemeasureuseragentspecificmemory);
return LitHtml.html `
<${ReportView.ReportView.ReportKey.litTagName}>${i18nString(UIStrings.measureMemory)}</${ReportView.ReportView.ReportKey.litTagName}>
<${ReportView.ReportView.ReportValue.litTagName}>
<span title=${tooltipText}>${availabilityText}</span>\xA0<x-link class="link" href="https://web.dev/monitor-total-page-memory-usage/">${i18nString(UIStrings.learnMore)}</x-link>
</${ReportView.ReportView.ReportValue.litTagName}>
`;
}
return LitHtml.nothing;
}
renderAdditionalInfoSection() {
if (!this.frame) {
return LitHtml.nothing;
}
return LitHtml.html `
<${ReportView.ReportView.ReportSectionHeader.litTagName}
title=${i18nString(UIStrings.thisAdditionalDebugging)}
>${i18nString(UIStrings.additionalInformation)}</${ReportView.ReportView.ReportSectionHeader.litTagName}>
<${ReportView.ReportView.ReportKey.litTagName}>${i18nString(UIStrings.frameId)}</${ReportView.ReportView.ReportKey.litTagName}>
<${ReportView.ReportView.ReportValue.litTagName}>
<div class="text-ellipsis" title=${this.frame.id}>${this.frame.id}</div>
</${ReportView.ReportView.ReportValue.litTagName}>
<${ReportView.ReportView.ReportSectionDivider.litTagName}></${ReportView.ReportView.ReportSectionDivider.litTagName}>
`;
}
}
ComponentHelpers.CustomElements.defineComponent('devtools-resources-frame-details-view', FrameDetailsReportView);