UNPKG

chrome-devtools-frontend

Version:
183 lines (168 loc) 9.21 kB
// 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. /* eslint-disable rulesdir/no-imperative-dom-api */ import * as Host from '../../core/host/host.js'; import * as i18n from '../../core/i18n/i18n.js'; import type * as Protocol from '../../generated/protocol.js'; import * as IssuesManager from '../../models/issues_manager/issues_manager.js'; import {AffectedItem, AffectedResourcesView} from './AffectedResourcesView.js'; const UIStrings = { /** * @description Label for number of rows in the issue details table. */ nViolations: '{n, plural, =1 {# violation} other {# violations}}', /** * @description Noun, label for the column showing the associated HTML element in the issue details table. */ element: 'Element', /** * @description Noun, label for the column showing the invalid header value in the issue details table. */ invalidHeaderValue: 'Invalid Header Value', /** * @description Noun, label for the column showing the associated network request in the issue details table. */ request: 'Request', /** * @description Label for the column showing the invalid URL used in an HTML anchor element ("a link"). * A origin is (roughly said) the front part of a URL. */ untrustworthyOrigin: 'Untrustworthy origin', } as const; const str_ = i18n.i18n.registerUIStrings('panels/issues/AttributionReportingIssueDetailsView.ts', UIStrings); const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); export class AttributionReportingIssueDetailsView extends AffectedResourcesView { protected override getResourceNameWithCount(count: number): string { return i18nString(UIStrings.nViolations, {n: count}); } override update(): void { this.clear(); const issues = this.issue.getAttributionReportingIssues(); const issue = issues.values().next(); if (issue.done) { this.updateAffectedResourceCount(0); } else { this.#appendDetails(issue.value.code(), issues); } } #appendDetails( issueCode: IssuesManager.AttributionReportingIssue.IssueCode, issues: Iterable<IssuesManager.AttributionReportingIssue.AttributionReportingIssue>): void { const header = document.createElement('tr'); switch (issueCode) { case IssuesManager.AttributionReportingIssue.IssueCode.INVALID_REGISTER_SOURCE_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.INVALID_REGISTER_TRIGGER_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.INVALID_REGISTER_OS_SOURCE_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.INVALID_REGISTER_OS_TRIGGER_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.OS_SOURCE_IGNORED: case IssuesManager.AttributionReportingIssue.IssueCode.OS_TRIGGER_IGNORED: case IssuesManager.AttributionReportingIssue.IssueCode.SOURCE_IGNORED: case IssuesManager.AttributionReportingIssue.IssueCode.TRIGGER_IGNORED: case IssuesManager.AttributionReportingIssue.IssueCode.INVALID_INFO_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.NAVIGATION_REGISTRATION_UNIQUE_SCOPE_ALREADY_SET: this.appendColumnTitle(header, i18nString(UIStrings.request)); this.appendColumnTitle(header, i18nString(UIStrings.invalidHeaderValue)); break; case IssuesManager.AttributionReportingIssue.IssueCode.INSECURE_CONTEXT: case IssuesManager.AttributionReportingIssue.IssueCode.UNTRUSTWORTHY_REPORTING_ORIGIN: this.appendColumnTitle(header, i18nString(UIStrings.element)); this.appendColumnTitle(header, i18nString(UIStrings.request)); this.appendColumnTitle(header, i18nString(UIStrings.untrustworthyOrigin)); break; case IssuesManager.AttributionReportingIssue.IssueCode.PERMISSION_POLICY_DISABLED: this.appendColumnTitle(header, i18nString(UIStrings.element)); this.appendColumnTitle(header, i18nString(UIStrings.request)); break; case IssuesManager.AttributionReportingIssue.IssueCode.SOURCE_AND_TRIGGER_HEADERS: case IssuesManager.AttributionReportingIssue.IssueCode.WEB_AND_OS_HEADERS: case IssuesManager.AttributionReportingIssue.IssueCode.NO_WEB_OR_OS_SUPPORT: case IssuesManager.AttributionReportingIssue.IssueCode.NO_REGISTER_SOURCE_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.NO_REGISTER_TRIGGER_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.NO_REGISTER_OS_SOURCE_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.NO_REGISTER_OS_TRIGGER_HEADER: this.appendColumnTitle(header, i18nString(UIStrings.request)); break; case IssuesManager.AttributionReportingIssue.IssueCode.NAVIGATION_REGISTRATION_WITHOUT_TRANSIENT_USER_ACTIVATION: this.appendColumnTitle(header, i18nString(UIStrings.element)); break; } this.affectedResources.appendChild(header); let count = 0; for (const issue of issues) { count++; void this.#appendDetail(issueCode, issue); } this.updateAffectedResourceCount(count); } async #appendDetail( issueCode: IssuesManager.AttributionReportingIssue.IssueCode, issue: IssuesManager.AttributionReportingIssue.AttributionReportingIssue): Promise<void> { const element = document.createElement('tr'); element.classList.add('affected-resource-directive'); const details = issue.issueDetails; switch (issueCode) { case IssuesManager.AttributionReportingIssue.IssueCode.INVALID_REGISTER_SOURCE_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.INVALID_REGISTER_TRIGGER_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.INVALID_REGISTER_OS_SOURCE_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.INVALID_REGISTER_OS_TRIGGER_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.OS_SOURCE_IGNORED: case IssuesManager.AttributionReportingIssue.IssueCode.OS_TRIGGER_IGNORED: case IssuesManager.AttributionReportingIssue.IssueCode.SOURCE_IGNORED: case IssuesManager.AttributionReportingIssue.IssueCode.TRIGGER_IGNORED: case IssuesManager.AttributionReportingIssue.IssueCode.INVALID_INFO_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.NAVIGATION_REGISTRATION_UNIQUE_SCOPE_ALREADY_SET: this.#appendRequestOrEmptyCell(element, details.request); this.appendIssueDetailCell(element, details.invalidParameter || ''); break; case IssuesManager.AttributionReportingIssue.IssueCode.INSECURE_CONTEXT: case IssuesManager.AttributionReportingIssue.IssueCode.UNTRUSTWORTHY_REPORTING_ORIGIN: await this.#appendElementOrEmptyCell(element, issue); this.#appendRequestOrEmptyCell(element, details.request); this.appendIssueDetailCell(element, details.invalidParameter || ''); break; case IssuesManager.AttributionReportingIssue.IssueCode.PERMISSION_POLICY_DISABLED: await this.#appendElementOrEmptyCell(element, issue); this.#appendRequestOrEmptyCell(element, details.request); break; case IssuesManager.AttributionReportingIssue.IssueCode.SOURCE_AND_TRIGGER_HEADERS: case IssuesManager.AttributionReportingIssue.IssueCode.WEB_AND_OS_HEADERS: case IssuesManager.AttributionReportingIssue.IssueCode.NO_WEB_OR_OS_SUPPORT: case IssuesManager.AttributionReportingIssue.IssueCode.NO_REGISTER_SOURCE_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.NO_REGISTER_TRIGGER_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.NO_REGISTER_OS_SOURCE_HEADER: case IssuesManager.AttributionReportingIssue.IssueCode.NO_REGISTER_OS_TRIGGER_HEADER: this.#appendRequestOrEmptyCell(element, details.request); break; case IssuesManager.AttributionReportingIssue.IssueCode.NAVIGATION_REGISTRATION_WITHOUT_TRANSIENT_USER_ACTIVATION: await this.#appendElementOrEmptyCell(element, issue); break; } this.affectedResources.appendChild(element); } async #appendElementOrEmptyCell( parent: HTMLElement, issue: IssuesManager.AttributionReportingIssue.AttributionReportingIssue): Promise<void> { const details = issue.issueDetails; if (details.violatingNodeId !== undefined) { const target = issue.model()?.target() || null; parent.appendChild(await this.createElementCell( {backendNodeId: details.violatingNodeId, target, nodeName: 'Attribution source element'}, issue.getCategory())); } else { this.appendIssueDetailCell(parent, ''); } } #appendRequestOrEmptyCell(parent: HTMLElement, request?: Protocol.Audits.AffectedRequest): void { if (!request) { this.appendIssueDetailCell(parent, ''); return; } const opts = { additionalOnClickAction(): void { Host.userMetrics.issuesPanelResourceOpened( IssuesManager.Issue.IssueCategory.ATTRIBUTION_REPORTING, AffectedItem.REQUEST); }, }; parent.appendChild(this.createRequestCell(request, opts)); } }