mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-06 20:11:38 +08:00
To suppress the races, we mark these invocations with `void` per the instructions of `no-floating-promises`. This explicitly marks these statements as side-effect promises. Engineers can later analyze these void statements and determine whether the promise races are intentional or accidental. R=jacktfranklin@chromium.org Bug: 1239617 Change-Id: I6b7a24cf21029d6ff73b112b3e8255ebab8c60ec Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3366467 Reviewed-by: Jack Franklin <jacktfranklin@chromium.org> Commit-Queue: Tim Van der Lippe <tvanderlippe@chromium.org> Auto-Submit: Tim Van der Lippe <tvanderlippe@chromium.org>
209 lines
9.4 KiB
TypeScript
209 lines
9.4 KiB
TypeScript
// 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 * as Common from '../../core/common/common.js';
|
|
import * as Host from '../../core/host/host.js';
|
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
import type * as Platform from '../../core/platform/platform.js';
|
|
import type * as Protocol from '../../generated/protocol.js';
|
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
import * as IssuesManager from '../../models/issues_manager/issues_manager.js';
|
|
import * as ElementsComponents from '../elements/components/components.js';
|
|
|
|
import {AffectedItem, AffectedResourcesView} from './AffectedResourcesView.js';
|
|
|
|
const UIStrings = {
|
|
/**
|
|
*@description Singular or plural label for number of affected CSP (content security policy,
|
|
* see https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) directives in issue view.
|
|
*/
|
|
nDirectives: '{n, plural, =1 {# directive} other {# directives}}',
|
|
/**
|
|
*@description Indicates that a CSP error should be treated as a warning
|
|
*/
|
|
reportonly: 'report-only',
|
|
/**
|
|
*@description The kind of resolution for a mixed content issue
|
|
*/
|
|
blocked: 'blocked',
|
|
/**
|
|
*@description Tooltip for button linking to the Elements panel
|
|
*/
|
|
clickToRevealTheViolatingDomNode: 'Click to reveal the violating DOM node in the Elements panel',
|
|
/**
|
|
*@description Header for the section listing affected directives
|
|
*/
|
|
directiveC: 'Directive',
|
|
/**
|
|
*@description Label for the column in the element list in the CSS Overview report
|
|
*/
|
|
element: 'Element',
|
|
/**
|
|
*@description Header for the source location column
|
|
*/
|
|
sourceLocation: 'Source Location',
|
|
/**
|
|
*@description Text for the status of something
|
|
*/
|
|
status: 'Status',
|
|
/**
|
|
*@description Text that refers to the resources of the web page
|
|
*/
|
|
resourceC: 'Resource',
|
|
};
|
|
|
|
const str_ = i18n.i18n.registerUIStrings('panels/issues/AffectedDirectivesView.ts', UIStrings);
|
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
|
|
export class AffectedDirectivesView extends AffectedResourcesView {
|
|
#appendStatus(element: Element, isReportOnly: boolean): void {
|
|
const status = document.createElement('td');
|
|
if (isReportOnly) {
|
|
status.classList.add('affected-resource-report-only-status');
|
|
status.textContent = i18nString(UIStrings.reportonly);
|
|
} else {
|
|
status.classList.add('affected-resource-blocked-status');
|
|
status.textContent = i18nString(UIStrings.blocked);
|
|
}
|
|
element.appendChild(status);
|
|
}
|
|
|
|
protected getResourceNameWithCount(count: number): Platform.UIString.LocalizedString {
|
|
return i18nString(UIStrings.nDirectives, {n: count});
|
|
}
|
|
|
|
#appendViolatedDirective(element: Element, directive: string): void {
|
|
const violatedDirective = document.createElement('td');
|
|
violatedDirective.textContent = directive;
|
|
element.appendChild(violatedDirective);
|
|
}
|
|
|
|
#appendBlockedURL(element: Element, url: string): void {
|
|
const info = document.createElement('td');
|
|
info.classList.add('affected-resource-directive-info');
|
|
info.textContent = url;
|
|
element.appendChild(info);
|
|
}
|
|
|
|
#appendBlockedElement(
|
|
element: Element, nodeId: Protocol.DOM.BackendNodeId|undefined, model: SDK.IssuesModel.IssuesModel): void {
|
|
const elementsPanelLinkComponent = new ElementsComponents.ElementsPanelLink.ElementsPanelLink();
|
|
if (nodeId) {
|
|
const violatingNodeId = nodeId;
|
|
elementsPanelLinkComponent.title = i18nString(UIStrings.clickToRevealTheViolatingDomNode);
|
|
|
|
const onElementRevealIconClick: (arg0?: Event|undefined) => void = (): void => {
|
|
const target = model.getTargetIfNotDisposed();
|
|
if (target) {
|
|
Host.userMetrics.issuesPanelResourceOpened(this.issue.getCategory(), AffectedItem.Element);
|
|
const deferredDOMNode = new SDK.DOMModel.DeferredDOMNode(target, violatingNodeId);
|
|
void Common.Revealer.reveal(deferredDOMNode);
|
|
}
|
|
};
|
|
|
|
const onElementRevealIconMouseEnter: (arg0?: Event|undefined) => void = (): void => {
|
|
const target = model.getTargetIfNotDisposed();
|
|
if (target) {
|
|
const deferredDOMNode = new SDK.DOMModel.DeferredDOMNode(target, violatingNodeId);
|
|
if (deferredDOMNode) {
|
|
deferredDOMNode.highlight();
|
|
}
|
|
}
|
|
};
|
|
|
|
const onElementRevealIconMouseLeave: (arg0?: Event|undefined) => void = (): void => {
|
|
SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight();
|
|
};
|
|
|
|
elementsPanelLinkComponent
|
|
.data = {onElementRevealIconClick, onElementRevealIconMouseEnter, onElementRevealIconMouseLeave};
|
|
}
|
|
|
|
const violatingNode = document.createElement('td');
|
|
violatingNode.classList.add('affected-resource-csp-info-node');
|
|
violatingNode.appendChild(elementsPanelLinkComponent);
|
|
element.appendChild(violatingNode);
|
|
}
|
|
|
|
#appendAffectedContentSecurityPolicyDetails(
|
|
cspIssues: Iterable<IssuesManager.ContentSecurityPolicyIssue.ContentSecurityPolicyIssue>): void {
|
|
const header = document.createElement('tr');
|
|
if (this.issue.code() === IssuesManager.ContentSecurityPolicyIssue.inlineViolationCode) {
|
|
this.appendColumnTitle(header, i18nString(UIStrings.directiveC));
|
|
this.appendColumnTitle(header, i18nString(UIStrings.element));
|
|
this.appendColumnTitle(header, i18nString(UIStrings.sourceLocation));
|
|
this.appendColumnTitle(header, i18nString(UIStrings.status));
|
|
} else if (this.issue.code() === IssuesManager.ContentSecurityPolicyIssue.urlViolationCode) {
|
|
this.appendColumnTitle(header, i18nString(UIStrings.resourceC), 'affected-resource-directive-info-header');
|
|
this.appendColumnTitle(header, i18nString(UIStrings.status));
|
|
this.appendColumnTitle(header, i18nString(UIStrings.directiveC));
|
|
this.appendColumnTitle(header, i18nString(UIStrings.sourceLocation));
|
|
} else if (this.issue.code() === IssuesManager.ContentSecurityPolicyIssue.evalViolationCode) {
|
|
this.appendColumnTitle(header, i18nString(UIStrings.sourceLocation));
|
|
this.appendColumnTitle(header, i18nString(UIStrings.directiveC));
|
|
this.appendColumnTitle(header, i18nString(UIStrings.status));
|
|
} else if (this.issue.code() === IssuesManager.ContentSecurityPolicyIssue.trustedTypesSinkViolationCode) {
|
|
this.appendColumnTitle(header, i18nString(UIStrings.sourceLocation));
|
|
this.appendColumnTitle(header, i18nString(UIStrings.status));
|
|
} else if (this.issue.code() === IssuesManager.ContentSecurityPolicyIssue.trustedTypesPolicyViolationCode) {
|
|
this.appendColumnTitle(header, i18nString(UIStrings.sourceLocation));
|
|
this.appendColumnTitle(header, i18nString(UIStrings.directiveC));
|
|
this.appendColumnTitle(header, i18nString(UIStrings.status));
|
|
} else {
|
|
this.updateAffectedResourceCount(0);
|
|
return;
|
|
}
|
|
this.affectedResources.appendChild(header);
|
|
let count = 0;
|
|
for (const cspIssue of cspIssues) {
|
|
count++;
|
|
this.#appendAffectedContentSecurityPolicyDetail(cspIssue);
|
|
}
|
|
this.updateAffectedResourceCount(count);
|
|
}
|
|
|
|
#appendAffectedContentSecurityPolicyDetail(
|
|
cspIssue: IssuesManager.ContentSecurityPolicyIssue.ContentSecurityPolicyIssue): void {
|
|
const element = document.createElement('tr');
|
|
element.classList.add('affected-resource-directive');
|
|
|
|
const cspIssueDetails = cspIssue.details();
|
|
const location = IssuesManager.Issue.toZeroBasedLocation(cspIssueDetails.sourceCodeLocation);
|
|
const model = cspIssue.model();
|
|
const maybeTarget = cspIssue.model()?.getTargetIfNotDisposed();
|
|
if (this.issue.code() === IssuesManager.ContentSecurityPolicyIssue.inlineViolationCode && model) {
|
|
this.#appendViolatedDirective(element, cspIssueDetails.violatedDirective);
|
|
this.#appendBlockedElement(element, cspIssueDetails.violatingNodeId, model);
|
|
this.appendSourceLocation(element, location, maybeTarget);
|
|
this.#appendStatus(element, cspIssueDetails.isReportOnly);
|
|
} else if (this.issue.code() === IssuesManager.ContentSecurityPolicyIssue.urlViolationCode) {
|
|
const url = cspIssueDetails.blockedURL ? cspIssueDetails.blockedURL : '';
|
|
this.#appendBlockedURL(element, url);
|
|
this.#appendStatus(element, cspIssueDetails.isReportOnly);
|
|
this.#appendViolatedDirective(element, cspIssueDetails.violatedDirective);
|
|
this.appendSourceLocation(element, location, maybeTarget);
|
|
} else if (this.issue.code() === IssuesManager.ContentSecurityPolicyIssue.evalViolationCode) {
|
|
this.appendSourceLocation(element, location, maybeTarget);
|
|
this.#appendViolatedDirective(element, cspIssueDetails.violatedDirective);
|
|
this.#appendStatus(element, cspIssueDetails.isReportOnly);
|
|
} else if (this.issue.code() === IssuesManager.ContentSecurityPolicyIssue.trustedTypesSinkViolationCode) {
|
|
this.appendSourceLocation(element, location, maybeTarget);
|
|
this.#appendStatus(element, cspIssueDetails.isReportOnly);
|
|
} else if (this.issue.code() === IssuesManager.ContentSecurityPolicyIssue.trustedTypesPolicyViolationCode) {
|
|
this.appendSourceLocation(element, location, maybeTarget);
|
|
this.#appendViolatedDirective(element, cspIssueDetails.violatedDirective);
|
|
this.#appendStatus(element, cspIssueDetails.isReportOnly);
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
this.affectedResources.appendChild(element);
|
|
}
|
|
|
|
update(): void {
|
|
this.clear();
|
|
this.#appendAffectedContentSecurityPolicyDetails(this.issue.getCspIssues());
|
|
}
|
|
}
|