mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-06 12:01:40 +08:00
Bug: 1299790 Change-Id: Ic9534e960c531b1027d8e4baa98364f16255fb63 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3629863 Reviewed-by: Simon Zünd <szuend@chromium.org> Reviewed-by: Eric Leese <leese@chromium.org> Commit-Queue: Kateryna Prokopenko <kprokopenko@chromium.org>
224 lines
6.9 KiB
TypeScript
224 lines
6.9 KiB
TypeScript
// Copyright 2020 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 SDK from '../../core/sdk/sdk.js';
|
|
import type * as Protocol from '../../generated/protocol.js';
|
|
|
|
import type {MarkdownIssueDescription} from './MarkdownIssueDescription.js';
|
|
|
|
const UIStrings = {
|
|
/**
|
|
*@description The kind of an issue (plural) (Issues are categorized into kinds).
|
|
*/
|
|
improvements: 'Improvements',
|
|
/**
|
|
*@description The kind of an issue (plural) (Issues are categorized into kinds).
|
|
*/
|
|
pageErrors: 'Page Errors',
|
|
/**
|
|
*@description The kind of an issue (plural) (Issues are categorized into kinds).
|
|
*/
|
|
breakingChanges: 'Breaking Changes',
|
|
/**
|
|
*@description A description for a kind of issue we display in the issues tab.
|
|
*/
|
|
pageErrorIssue: 'A page error issue: the page is not working correctly',
|
|
/**
|
|
*@description A description for a kind of issue we display in the issues tab.
|
|
*/
|
|
breakingChangeIssue: 'A breaking change issue: the page may stop working in an upcoming version of Chrome',
|
|
/**
|
|
*@description A description for a kind of issue we display in the issues tab.
|
|
*/
|
|
improvementIssue: 'An improvement issue: there is an opportunity to improve the page',
|
|
};
|
|
const str_ = i18n.i18n.registerUIStrings('models/issues_manager/Issue.ts', UIStrings);
|
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
|
|
// eslint-disable-next-line rulesdir/const_enum
|
|
export enum IssueCategory {
|
|
CrossOriginEmbedderPolicy = 'CrossOriginEmbedderPolicy',
|
|
Generic = 'Generic',
|
|
MixedContent = 'MixedContent',
|
|
Cookie = 'Cookie',
|
|
HeavyAd = 'HeavyAd',
|
|
ContentSecurityPolicy = 'ContentSecurityPolicy',
|
|
TrustedWebActivity = 'TrustedWebActivity',
|
|
LowTextContrast = 'LowTextContrast',
|
|
Cors = 'Cors',
|
|
AttributionReporting = 'AttributionReporting',
|
|
QuirksMode = 'QuirksMode',
|
|
Other = 'Other',
|
|
}
|
|
|
|
// eslint-disable-next-line rulesdir/const_enum
|
|
export enum IssueKind {
|
|
/**
|
|
* Something is not working in the page right now. Issues of this kind need
|
|
* usually be fixed right away. They usually indicate that a Web API is being
|
|
* used in a wrong way, or that a network request was misconfigured.
|
|
*/
|
|
PageError = 'PageError',
|
|
/**
|
|
* The page is using a Web API or relying on browser behavior that is going
|
|
* to change in the future. If possible, the message associated with issues
|
|
* of this kind should include a time when the behavior is going to change.
|
|
*/
|
|
BreakingChange = 'BreakingChange',
|
|
/**
|
|
* Anything that can be improved about the page, but isn't urgent and doesn't
|
|
* impair functionality in a major way.
|
|
*/
|
|
Improvement = 'Improvement',
|
|
}
|
|
|
|
export function getIssueKindName(issueKind: IssueKind): Common.UIString.LocalizedString {
|
|
switch (issueKind) {
|
|
case IssueKind.BreakingChange:
|
|
return i18nString(UIStrings.breakingChanges);
|
|
case IssueKind.Improvement:
|
|
return i18nString(UIStrings.improvements);
|
|
case IssueKind.PageError:
|
|
return i18nString(UIStrings.pageErrors);
|
|
}
|
|
}
|
|
|
|
export function getIssueKindDescription(issueKind: IssueKind): Common.UIString.LocalizedString {
|
|
switch (issueKind) {
|
|
case IssueKind.PageError:
|
|
return i18nString(UIStrings.pageErrorIssue);
|
|
case IssueKind.BreakingChange:
|
|
return i18nString(UIStrings.breakingChangeIssue);
|
|
case IssueKind.Improvement:
|
|
return i18nString(UIStrings.improvementIssue);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Union two issue kinds for issue aggregation. The idea is to show the most
|
|
* important kind on aggregated issues that union issues of different kinds.
|
|
*/
|
|
export function unionIssueKind(a: IssueKind, b: IssueKind): IssueKind {
|
|
if (a === IssueKind.PageError || b === IssueKind.PageError) {
|
|
return IssueKind.PageError;
|
|
}
|
|
if (a === IssueKind.BreakingChange || b === IssueKind.BreakingChange) {
|
|
return IssueKind.BreakingChange;
|
|
}
|
|
return IssueKind.Improvement;
|
|
}
|
|
|
|
export function getShowThirdPartyIssuesSetting(): Common.Settings.Setting<boolean> {
|
|
return Common.Settings.Settings.instance().createSetting('showThirdPartyIssues', false);
|
|
}
|
|
|
|
export interface AffectedElement {
|
|
backendNodeId: Protocol.DOM.BackendNodeId;
|
|
nodeName: string;
|
|
target: SDK.Target.Target|null;
|
|
}
|
|
|
|
export abstract class Issue<IssueCode extends string = string> {
|
|
#issueCode: IssueCode;
|
|
#issuesModel: SDK.IssuesModel.IssuesModel|null;
|
|
protected issueId: Protocol.Audits.IssueId|undefined = undefined;
|
|
#hidden: boolean;
|
|
|
|
constructor(
|
|
code: IssueCode|{code: IssueCode, umaCode: string}, issuesModel: SDK.IssuesModel.IssuesModel|null = null,
|
|
issueId?: Protocol.Audits.IssueId) {
|
|
this.#issueCode = typeof code === 'object' ? code.code : code;
|
|
this.#issuesModel = issuesModel;
|
|
this.issueId = issueId;
|
|
Host.userMetrics.issueCreated(typeof code === 'string' ? code : code.umaCode);
|
|
this.#hidden = false;
|
|
}
|
|
|
|
code(): IssueCode {
|
|
return this.#issueCode;
|
|
}
|
|
|
|
abstract primaryKey(): string;
|
|
abstract getDescription(): MarkdownIssueDescription|null;
|
|
abstract getCategory(): IssueCategory;
|
|
abstract getKind(): IssueKind;
|
|
|
|
getBlockedByResponseDetails(): Iterable<Protocol.Audits.BlockedByResponseIssueDetails> {
|
|
return [];
|
|
}
|
|
|
|
cookies(): Iterable<Protocol.Audits.AffectedCookie> {
|
|
return [];
|
|
}
|
|
|
|
rawCookieLines(): Iterable<string> {
|
|
return [];
|
|
}
|
|
|
|
elements(): Iterable<AffectedElement> {
|
|
return [];
|
|
}
|
|
|
|
requests(): Iterable<Protocol.Audits.AffectedRequest> {
|
|
return [];
|
|
}
|
|
|
|
sources(): Iterable<Protocol.Audits.SourceCodeLocation> {
|
|
return [];
|
|
}
|
|
|
|
isAssociatedWithRequestId(requestId: string): boolean {
|
|
for (const request of this.requests()) {
|
|
if (request.requestId === requestId) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* The model might be unavailable or belong to a target that has already been disposed.
|
|
*/
|
|
model(): SDK.IssuesModel.IssuesModel|null {
|
|
return this.#issuesModel;
|
|
}
|
|
|
|
isCausedByThirdParty(): boolean {
|
|
return false;
|
|
}
|
|
|
|
getIssueId(): Protocol.Audits.IssueId|undefined {
|
|
return this.issueId;
|
|
}
|
|
|
|
isHidden(): boolean {
|
|
return this.#hidden;
|
|
}
|
|
|
|
setHidden(hidden: boolean): void {
|
|
this.#hidden = hidden;
|
|
}
|
|
}
|
|
|
|
export function toZeroBasedLocation(location: Protocol.Audits.SourceCodeLocation|undefined): {
|
|
url: Platform.DevToolsPath.UrlString,
|
|
scriptId: Protocol.Runtime.ScriptId|undefined,
|
|
lineNumber: number,
|
|
columnNumber: number|undefined,
|
|
}|undefined {
|
|
if (!location) {
|
|
return undefined;
|
|
}
|
|
return {
|
|
url: location.url as Platform.DevToolsPath.UrlString,
|
|
scriptId: location.scriptId,
|
|
lineNumber: location.lineNumber,
|
|
columnNumber: location.columnNumber === 0 ? undefined : location.columnNumber - 1,
|
|
};
|
|
}
|