tests(eslint): add export rule (#13282)
This commit is contained in:
Родитель
00117f48b2
Коммит
b066160e4b
|
@ -19,7 +19,7 @@ function buildStrings() {
|
||||||
const locales = require('../shared/localization/locales.js');
|
const locales = require('../shared/localization/locales.js');
|
||||||
// TODO(esmodules): use dynamic import when build/ is esm.
|
// TODO(esmodules): use dynamic import when build/ is esm.
|
||||||
const utilCode = fs.readFileSync(LH_ROOT + '/treemap/app/src/util.js', 'utf-8');
|
const utilCode = fs.readFileSync(LH_ROOT + '/treemap/app/src/util.js', 'utf-8');
|
||||||
const {UIStrings} = eval(utilCode.replace(/export /g, '') + '\nmodule.exports = TreemapUtil;');
|
const {UIStrings} = eval(utilCode.replace(/export {/g, 'module.exports = {'));
|
||||||
const strings = /** @type {Record<LH.Locale, string>} */ ({});
|
const strings = /** @type {Record<LH.Locale, string>} */ ({});
|
||||||
|
|
||||||
for (const [locale, lhlMessages] of Object.entries(locales)) {
|
for (const [locale, lhlMessages] of Object.entries(locales)) {
|
||||||
|
|
|
@ -27,6 +27,8 @@ module.exports = {
|
||||||
],
|
],
|
||||||
'newlines-between': 'always',
|
'newlines-between': 'always',
|
||||||
}],
|
}],
|
||||||
|
'import/group-exports': 2,
|
||||||
|
'import/exports-last': 2,
|
||||||
'@typescript-eslint/type-annotation-spacing': 2,
|
'@typescript-eslint/type-annotation-spacing': 2,
|
||||||
},
|
},
|
||||||
overrides: [
|
overrides: [
|
||||||
|
|
|
@ -12,11 +12,11 @@ import {getFilmstripFrames, getScreenDimensions, getFullPageScreenshot} from './
|
||||||
|
|
||||||
const ANIMATION_FRAME_DURATION_MS = 500;
|
const ANIMATION_FRAME_DURATION_MS = 500;
|
||||||
|
|
||||||
export const Separator: FunctionComponent = () => {
|
const Separator: FunctionComponent = () => {
|
||||||
return <div className="Separator" role="separator"></div>;
|
return <div className="Separator" role="separator"></div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FlowStepIcon: FunctionComponent<{mode: LH.Result.GatherMode}> = ({mode}) => {
|
const FlowStepIcon: FunctionComponent<{mode: LH.Result.GatherMode}> = ({mode}) => {
|
||||||
return <>
|
return <>
|
||||||
{
|
{
|
||||||
mode === 'navigation' && <NavigationIcon/>
|
mode === 'navigation' && <NavigationIcon/>
|
||||||
|
@ -30,7 +30,7 @@ export const FlowStepIcon: FunctionComponent<{mode: LH.Result.GatherMode}> = ({m
|
||||||
</>;
|
</>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FlowSegment: FunctionComponent<{mode?: LH.Result.GatherMode}> = ({mode}) => {
|
const FlowSegment: FunctionComponent<{mode?: LH.Result.GatherMode}> = ({mode}) => {
|
||||||
return (
|
return (
|
||||||
<div className="FlowSegment">
|
<div className="FlowSegment">
|
||||||
<div className="FlowSegment__top-line"/>
|
<div className="FlowSegment__top-line"/>
|
||||||
|
@ -71,7 +71,7 @@ const FlowStepAnimatedThumbnail: FunctionComponent<{
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FlowStepThumbnail: FunctionComponent<{
|
const FlowStepThumbnail: FunctionComponent<{
|
||||||
lhr: LH.Result,
|
lhr: LH.Result,
|
||||||
width?: number,
|
width?: number,
|
||||||
height?: number,
|
height?: number,
|
||||||
|
@ -114,3 +114,10 @@ export const FlowStepThumbnail: FunctionComponent<{
|
||||||
}
|
}
|
||||||
</>;
|
</>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
Separator,
|
||||||
|
FlowStepIcon,
|
||||||
|
FlowSegment,
|
||||||
|
FlowStepThumbnail,
|
||||||
|
};
|
||||||
|
|
|
@ -31,23 +31,23 @@ function useLhrLocale() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useI18n() {
|
function useI18n() {
|
||||||
return useContext(I18nContext);
|
return useContext(I18nContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useLocalizedStrings() {
|
function useLocalizedStrings() {
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
return i18n.strings;
|
return i18n.strings;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useStringFormatter() {
|
function useStringFormatter() {
|
||||||
const {locale} = useLhrLocale();
|
const {locale} = useLhrLocale();
|
||||||
return (str: string, values?: Record<string, string|number>) => {
|
return (str: string, values?: Record<string, string|number>) => {
|
||||||
return formatMessage(str, values, locale);
|
return formatMessage(str, values, locale);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const I18nProvider: FunctionComponent = ({children}) => {
|
const I18nProvider: FunctionComponent = ({children}) => {
|
||||||
const {locale, lhrStrings} = useLhrLocale();
|
const {locale, lhrStrings} = useLhrLocale();
|
||||||
|
|
||||||
const i18n = useMemo(() => {
|
const i18n = useMemo(() => {
|
||||||
|
@ -65,7 +65,6 @@ export const I18nProvider: FunctionComponent = ({children}) => {
|
||||||
|
|
||||||
// Initialize renderer util i18n for strings rendered in wrapped components.
|
// Initialize renderer util i18n for strings rendered in wrapped components.
|
||||||
// TODO: Don't attach global i18n to `Util`.
|
// TODO: Don't attach global i18n to `Util`.
|
||||||
// @ts-ignore TS reports as read-only.
|
|
||||||
Util.i18n = i18n;
|
Util.i18n = i18n;
|
||||||
|
|
||||||
return i18n;
|
return i18n;
|
||||||
|
@ -78,4 +77,9 @@ export const I18nProvider: FunctionComponent = ({children}) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
useI18n,
|
||||||
|
useLocalizedStrings,
|
||||||
|
useStringFormatter,
|
||||||
|
I18nProvider,
|
||||||
|
};
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {FunctionComponent} from 'preact';
|
||||||
|
|
||||||
/* eslint-disable max-len */
|
/* eslint-disable max-len */
|
||||||
|
|
||||||
export const SummaryIcon: FunctionComponent = () => {
|
const SummaryIcon: FunctionComponent = () => {
|
||||||
return (
|
return (
|
||||||
<svg width="14" viewBox="0 0 18 16" fill="none" role="img">
|
<svg width="14" viewBox="0 0 18 16" fill="none" role="img">
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 2C0 1.17 0.67 0.5 1.5 0.5C2.33 0.5 3 1.17 3 2C3 2.83 2.33 3.5 1.5 3.5C0.67 3.5 0 2.83 0 2ZM0 8C0 7.17 0.67 6.5 1.5 6.5C2.33 6.5 3 7.17 3 8C3 8.83 2.33 9.5 1.5 9.5C0.67 9.5 0 8.83 0 8ZM1.5 12.5C0.67 12.5 0 13.18 0 14C0 14.82 0.68 15.5 1.5 15.5C2.32 15.5 3 14.82 3 14C3 13.18 2.33 12.5 1.5 12.5ZM18 15H5V13H18V15ZM5 9H18V7H5V9ZM5 3V1H18V3H5Z" fill="currentColor"/>
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 2C0 1.17 0.67 0.5 1.5 0.5C2.33 0.5 3 1.17 3 2C3 2.83 2.33 3.5 1.5 3.5C0.67 3.5 0 2.83 0 2ZM0 8C0 7.17 0.67 6.5 1.5 6.5C2.33 6.5 3 7.17 3 8C3 8.83 2.33 9.5 1.5 9.5C0.67 9.5 0 8.83 0 8ZM1.5 12.5C0.67 12.5 0 13.18 0 14C0 14.82 0.68 15.5 1.5 15.5C2.32 15.5 3 14.82 3 14C3 13.18 2.33 12.5 1.5 12.5ZM18 15H5V13H18V15ZM5 9H18V7H5V9ZM5 3V1H18V3H5Z" fill="currentColor"/>
|
||||||
|
@ -16,7 +16,7 @@ export const SummaryIcon: FunctionComponent = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const NavigationIcon: FunctionComponent = () => {
|
const NavigationIcon: FunctionComponent = () => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
width="16"
|
width="16"
|
||||||
|
@ -36,7 +36,7 @@ export const NavigationIcon: FunctionComponent = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TimespanIcon: FunctionComponent = () => {
|
const TimespanIcon: FunctionComponent = () => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
width="16"
|
width="16"
|
||||||
|
@ -60,7 +60,7 @@ export const TimespanIcon: FunctionComponent = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SnapshotIcon: FunctionComponent = () => {
|
const SnapshotIcon: FunctionComponent = () => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
@ -79,7 +79,7 @@ export const SnapshotIcon: FunctionComponent = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CloseIcon: FunctionComponent = () => {
|
const CloseIcon: FunctionComponent = () => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
@ -96,7 +96,7 @@ export const CloseIcon: FunctionComponent = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EnvIcon: FunctionComponent = () => {
|
const EnvIcon: FunctionComponent = () => {
|
||||||
return (
|
return (
|
||||||
<svg width="15" height="12" viewBox="0 0 15 12" fill="none" role="img">
|
<svg width="15" height="12" viewBox="0 0 15 12" fill="none" role="img">
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.33317 2.00008H13.9998V0.666748H3.33317C2.59984 0.666748 1.99984 1.26675 1.99984 2.00008V9.33341H0.666504V11.3334H7.99984V9.33341H3.33317V2.00008ZM13.9998 3.33341H9.99984C9.63317 3.33341 9.33317 3.63341 9.33317 4.00008V10.6667C9.33317 11.0334 9.63317 11.3334 9.99984 11.3334H13.9998C14.3665 11.3334 14.6665 11.0334 14.6665 10.6667V4.00008C14.6665 3.63341 14.3665 3.33341 13.9998 3.33341ZM10.6665 9.33341H13.3332V4.66675H10.6665V9.33341Z" fill="currentColor"/>
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.33317 2.00008H13.9998V0.666748H3.33317C2.59984 0.666748 1.99984 1.26675 1.99984 2.00008V9.33341H0.666504V11.3334H7.99984V9.33341H3.33317V2.00008ZM13.9998 3.33341H9.99984C9.63317 3.33341 9.33317 3.63341 9.33317 4.00008V10.6667C9.33317 11.0334 9.63317 11.3334 9.99984 11.3334H13.9998C14.3665 11.3334 14.6665 11.0334 14.6665 10.6667V4.00008C14.6665 3.63341 14.3665 3.33341 13.9998 3.33341ZM10.6665 9.33341H13.3332V4.66675H10.6665V9.33341Z" fill="currentColor"/>
|
||||||
|
@ -104,7 +104,7 @@ export const EnvIcon: FunctionComponent = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CpuIcon: FunctionComponent = () => {
|
const CpuIcon: FunctionComponent = () => {
|
||||||
return (
|
return (
|
||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" role="img">
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" role="img">
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.5 7.16667V5.5H13.8333V3.83333C13.8333 2.91667 13.0833 2.16667 12.1667 2.16667H10.5V0.5H8.83333V2.16667H7.16667V0.5H5.5V2.16667H3.83333C2.91667 2.16667 2.16667 2.91667 2.16667 3.83333V5.5H0.5V7.16667H2.16667V8.83333H0.5V10.5H2.16667V12.1667C2.16667 13.0833 2.91667 13.8333 3.83333 13.8333H5.5V15.5H7.16667V13.8333H8.83333V15.5H10.5V13.8333H12.1667C13.0833 13.8333 13.8333 13.0833 13.8333 12.1667V10.5H15.5V8.83333H13.8333V7.16667H15.5ZM10.5 5.5H5.5V10.5H10.5V5.5ZM3.83333 12.1667H12.1667V3.83333H3.83333V12.1667Z" fill="currentColor"/>
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.5 7.16667V5.5H13.8333V3.83333C13.8333 2.91667 13.0833 2.16667 12.1667 2.16667H10.5V0.5H8.83333V2.16667H7.16667V0.5H5.5V2.16667H3.83333C2.91667 2.16667 2.16667 2.91667 2.16667 3.83333V5.5H0.5V7.16667H2.16667V8.83333H0.5V10.5H2.16667V12.1667C2.16667 13.0833 2.91667 13.8333 3.83333 13.8333H5.5V15.5H7.16667V13.8333H8.83333V15.5H10.5V13.8333H12.1667C13.0833 13.8333 13.8333 13.0833 13.8333 12.1667V10.5H15.5V8.83333H13.8333V7.16667H15.5ZM10.5 5.5H5.5V10.5H10.5V5.5ZM3.83333 12.1667H12.1667V3.83333H3.83333V12.1667Z" fill="currentColor"/>
|
||||||
|
@ -112,7 +112,7 @@ export const CpuIcon: FunctionComponent = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const HamburgerIcon: FunctionComponent = () => {
|
const HamburgerIcon: FunctionComponent = () => {
|
||||||
return (
|
return (
|
||||||
<svg viewBox="0 0 18 12" width="18" height="12" role="img">
|
<svg viewBox="0 0 18 12" width="18" height="12" role="img">
|
||||||
<rect width="18" height="2" fill="currentColor"></rect>
|
<rect width="18" height="2" fill="currentColor"></rect>
|
||||||
|
@ -122,10 +122,22 @@ export const HamburgerIcon: FunctionComponent = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const InfoIcon: FunctionComponent = () => {
|
const InfoIcon: FunctionComponent = () => {
|
||||||
return (
|
return (
|
||||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none">
|
<svg width="14" height="14" viewBox="0 0 14 14" fill="none">
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 7C13 10.3137 10.3137 13 7 13C3.68629 13 1 10.3137 1 7C1 3.68629 3.68629 1 7 1C10.3137 1 13 3.68629 13 7ZM14 7C14 10.866 10.866 14 7 14C3.13401 14 0 10.866 0 7C0 3.13401 3.13401 0 7 0C10.866 0 14 3.13401 14 7ZM7.66658 11H6.33325V9.66667H7.66658V11ZM4.33325 5.66667C4.33325 4.19333 5.52659 3 6.99992 3C8.47325 3 9.66658 4.19333 9.66658 5.66667C9.66658 6.52194 9.1399 6.98221 8.62709 7.43036C8.1406 7.85551 7.66658 8.26975 7.66658 9H6.33325C6.33325 7.78582 6.96133 7.30439 7.51355 6.88112C7.94674 6.54907 8.33325 6.25281 8.33325 5.66667C8.33325 4.93333 7.73325 4.33333 6.99992 4.33333C6.26658 4.33333 5.66658 4.93333 5.66658 5.66667H4.33325Z" fill="currentColor"/>
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 7C13 10.3137 10.3137 13 7 13C3.68629 13 1 10.3137 1 7C1 3.68629 3.68629 1 7 1C10.3137 1 13 3.68629 13 7ZM14 7C14 10.866 10.866 14 7 14C3.13401 14 0 10.866 0 7C0 3.13401 3.13401 0 7 0C10.866 0 14 3.13401 14 7ZM7.66658 11H6.33325V9.66667H7.66658V11ZM4.33325 5.66667C4.33325 4.19333 5.52659 3 6.99992 3C8.47325 3 9.66658 4.19333 9.66658 5.66667C9.66658 6.52194 9.1399 6.98221 8.62709 7.43036C8.1406 7.85551 7.66658 8.26975 7.66658 9H6.33325C6.33325 7.78582 6.96133 7.30439 7.51355 6.88112C7.94674 6.54907 8.33325 6.25281 8.33325 5.66667C8.33325 4.93333 7.73325 4.33333 6.99992 4.33333C6.26658 4.33333 5.66658 4.93333 5.66658 5.66667H4.33325Z" fill="currentColor"/>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
SummaryIcon,
|
||||||
|
NavigationIcon,
|
||||||
|
TimespanIcon,
|
||||||
|
SnapshotIcon,
|
||||||
|
CloseIcon,
|
||||||
|
EnvIcon,
|
||||||
|
CpuIcon,
|
||||||
|
HamburgerIcon,
|
||||||
|
InfoIcon,
|
||||||
|
};
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {CpuIcon, EnvIcon, SummaryIcon} from '../icons';
|
||||||
import {classNames, useHashState, useFlowResult} from '../util';
|
import {classNames, useHashState, useFlowResult} from '../util';
|
||||||
import {SidebarFlow} from './flow';
|
import {SidebarFlow} from './flow';
|
||||||
|
|
||||||
export const SidebarSummary: FunctionComponent = () => {
|
const SidebarSummary: FunctionComponent = () => {
|
||||||
const hashState = useHashState();
|
const hashState = useHashState();
|
||||||
const strings = useLocalizedStrings();
|
const strings = useLocalizedStrings();
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ const SidebarRuntimeSettings: FunctionComponent<{settings: LH.ConfigSettings}> =
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SidebarHeader: FunctionComponent<{title: string, date: string}> = ({title, date}) => {
|
const SidebarHeader: FunctionComponent<{title: string, date: string}> = ({title, date}) => {
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
return (
|
return (
|
||||||
<div className="SidebarHeader">
|
<div className="SidebarHeader">
|
||||||
|
@ -69,7 +69,7 @@ export const SidebarHeader: FunctionComponent<{title: string, date: string}> = (
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Sidebar: FunctionComponent = () => {
|
const Sidebar: FunctionComponent = () => {
|
||||||
const flowResult = useFlowResult();
|
const flowResult = useFlowResult();
|
||||||
const firstLhr = flowResult.steps[0].lhr;
|
const firstLhr = flowResult.steps[0].lhr;
|
||||||
return (
|
return (
|
||||||
|
@ -84,3 +84,9 @@ export const Sidebar: FunctionComponent = () => {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
SidebarSummary,
|
||||||
|
SidebarHeader,
|
||||||
|
Sidebar,
|
||||||
|
};
|
||||||
|
|
|
@ -95,7 +95,7 @@ const SummaryTooltipAudits: FunctionComponent<{category: LH.ReportResult.Categor
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SummaryTooltip: FunctionComponent<{
|
const SummaryTooltip: FunctionComponent<{
|
||||||
category: LH.ReportResult.Category,
|
category: LH.ReportResult.Category,
|
||||||
gatherMode: LH.Result.GatherMode,
|
gatherMode: LH.Result.GatherMode,
|
||||||
url: string,
|
url: string,
|
||||||
|
@ -153,7 +153,7 @@ export const SummaryTooltip: FunctionComponent<{
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SummaryCategory: FunctionComponent<{
|
const SummaryCategory: FunctionComponent<{
|
||||||
category: LH.ReportResult.Category|undefined,
|
category: LH.ReportResult.Category|undefined,
|
||||||
href: string,
|
href: string,
|
||||||
gatherMode: LH.Result.GatherMode,
|
gatherMode: LH.Result.GatherMode,
|
||||||
|
@ -176,3 +176,8 @@ export const SummaryCategory: FunctionComponent<{
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
SummaryTooltip,
|
||||||
|
SummaryCategory,
|
||||||
|
};
|
||||||
|
|
|
@ -44,7 +44,7 @@ const SummaryNavigationHeader: FunctionComponent<{lhr: LH.Result}> = ({lhr}) =>
|
||||||
/**
|
/**
|
||||||
* The div should behave like a JSX <>...</>. This still allows us to identify "rows" with CSS selectors.
|
* The div should behave like a JSX <>...</>. This still allows us to identify "rows" with CSS selectors.
|
||||||
*/
|
*/
|
||||||
export const SummaryFlowStep: FunctionComponent<{
|
const SummaryFlowStep: FunctionComponent<{
|
||||||
lhr: LH.Result,
|
lhr: LH.Result,
|
||||||
label: string,
|
label: string,
|
||||||
hashIndex: number,
|
hashIndex: number,
|
||||||
|
@ -106,7 +106,7 @@ const SummaryFlow: FunctionComponent = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SummaryHeader: FunctionComponent = () => {
|
const SummaryHeader: FunctionComponent = () => {
|
||||||
const flowResult = useFlowResult();
|
const flowResult = useFlowResult();
|
||||||
const strings = useLocalizedStrings();
|
const strings = useLocalizedStrings();
|
||||||
const str_ = useStringFormatter();
|
const str_ = useStringFormatter();
|
||||||
|
@ -151,7 +151,7 @@ const SummarySectionHeader: FunctionComponent = ({children}) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Summary: FunctionComponent = () => {
|
const Summary: FunctionComponent = () => {
|
||||||
const strings = useLocalizedStrings();
|
const strings = useLocalizedStrings();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -163,3 +163,9 @@ export const Summary: FunctionComponent = () => {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
SummaryFlowStep,
|
||||||
|
SummaryHeader,
|
||||||
|
Summary,
|
||||||
|
};
|
||||||
|
|
|
@ -9,14 +9,14 @@ import {useContext, useEffect, useMemo, useState} from 'preact/hooks';
|
||||||
|
|
||||||
import type {UIStringsType} from './i18n/ui-strings';
|
import type {UIStringsType} from './i18n/ui-strings';
|
||||||
|
|
||||||
export const FlowResultContext = createContext<LH.FlowResult|undefined>(undefined);
|
const FlowResultContext = createContext<LH.FlowResult|undefined>(undefined);
|
||||||
|
|
||||||
function getHashParam(param: string): string|null {
|
function getHashParam(param: string): string|null {
|
||||||
const params = new URLSearchParams(location.hash.replace('#', '?'));
|
const params = new URLSearchParams(location.hash.replace('#', '?'));
|
||||||
return params.get(param);
|
return params.get(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function classNames(...args: Array<string|undefined|Record<string, boolean>>): string {
|
function classNames(...args: Array<string|undefined|Record<string, boolean>>): string {
|
||||||
const classes = [];
|
const classes = [];
|
||||||
for (const arg of args) {
|
for (const arg of args) {
|
||||||
if (!arg) continue;
|
if (!arg) continue;
|
||||||
|
@ -35,12 +35,12 @@ export function classNames(...args: Array<string|undefined|Record<string, boolea
|
||||||
return classes.join(' ');
|
return classes.join(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getScreenDimensions(reportResult: LH.Result) {
|
function getScreenDimensions(reportResult: LH.Result) {
|
||||||
const {width, height} = reportResult.configSettings.screenEmulation;
|
const {width, height} = reportResult.configSettings.screenEmulation;
|
||||||
return {width, height};
|
return {width, height};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFullPageScreenshot(reportResult: LH.Result) {
|
function getFullPageScreenshot(reportResult: LH.Result) {
|
||||||
const fullPageScreenshotAudit = reportResult.audits['full-page-screenshot'];
|
const fullPageScreenshotAudit = reportResult.audits['full-page-screenshot'];
|
||||||
const fullPageScreenshot =
|
const fullPageScreenshot =
|
||||||
fullPageScreenshotAudit &&
|
fullPageScreenshotAudit &&
|
||||||
|
@ -51,7 +51,7 @@ export function getFullPageScreenshot(reportResult: LH.Result) {
|
||||||
return fullPageScreenshot || null;
|
return fullPageScreenshot || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFilmstripFrames(
|
function getFilmstripFrames(
|
||||||
reportResult: LH.Result
|
reportResult: LH.Result
|
||||||
): Array<{data: string}> | undefined {
|
): Array<{data: string}> | undefined {
|
||||||
const filmstripAudit = reportResult.audits['screenshot-thumbnails'];
|
const filmstripAudit = reportResult.audits['screenshot-thumbnails'];
|
||||||
|
@ -65,7 +65,7 @@ export function getFilmstripFrames(
|
||||||
return frameItems || undefined;
|
return frameItems || undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getModeDescription(mode: LH.Result.GatherMode, strings: UIStringsType) {
|
function getModeDescription(mode: LH.Result.GatherMode, strings: UIStringsType) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case 'navigation': return strings.navigationDescription;
|
case 'navigation': return strings.navigationDescription;
|
||||||
case 'timespan': return strings.timespanDescription;
|
case 'timespan': return strings.timespanDescription;
|
||||||
|
@ -73,13 +73,13 @@ export function getModeDescription(mode: LH.Result.GatherMode, strings: UIString
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useFlowResult(): LH.FlowResult {
|
function useFlowResult(): LH.FlowResult {
|
||||||
const flowResult = useContext(FlowResultContext);
|
const flowResult = useContext(FlowResultContext);
|
||||||
if (!flowResult) throw Error('useFlowResult must be called in the FlowResultContext');
|
if (!flowResult) throw Error('useFlowResult must be called in the FlowResultContext');
|
||||||
return flowResult;
|
return flowResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useHashParams(...params: string[]) {
|
function useHashParams(...params: string[]) {
|
||||||
const [paramValues, setParamValues] = useState(params.map(getHashParam));
|
const [paramValues, setParamValues] = useState(params.map(getHashParam));
|
||||||
|
|
||||||
// Use two-way-binding on the URL hash.
|
// Use two-way-binding on the URL hash.
|
||||||
|
@ -97,7 +97,7 @@ export function useHashParams(...params: string[]) {
|
||||||
return paramValues;
|
return paramValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useHashState(): LH.FlowResult.HashState|null {
|
function useHashState(): LH.FlowResult.HashState|null {
|
||||||
const flowResult = useFlowResult();
|
const flowResult = useFlowResult();
|
||||||
const [indexString, anchor] = useHashParams('index', 'anchor');
|
const [indexString, anchor] = useHashParams('index', 'anchor');
|
||||||
|
|
||||||
|
@ -120,3 +120,15 @@ export function useHashState(): LH.FlowResult.HashState|null {
|
||||||
return {currentLhr: step.lhr, index, anchor};
|
return {currentLhr: step.lhr, index, anchor};
|
||||||
}, [indexString, flowResult, anchor]);
|
}, [indexString, flowResult, anchor]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
FlowResultContext,
|
||||||
|
classNames,
|
||||||
|
getScreenDimensions,
|
||||||
|
getFullPageScreenshot,
|
||||||
|
getFilmstripFrames,
|
||||||
|
getModeDescription,
|
||||||
|
useFlowResult,
|
||||||
|
useHashParams,
|
||||||
|
useHashState,
|
||||||
|
};
|
||||||
|
|
|
@ -19,15 +19,15 @@ interface ReportRendererGlobals {
|
||||||
reportRenderer: ReportRenderer,
|
reportRenderer: ReportRenderer,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ReportRendererContext = createContext<ReportRendererGlobals|undefined>(undefined);
|
const ReportRendererContext = createContext<ReportRendererGlobals|undefined>(undefined);
|
||||||
|
|
||||||
export function useReportRenderer() {
|
function useReportRenderer() {
|
||||||
const globals = useContext(ReportRendererContext);
|
const globals = useContext(ReportRendererContext);
|
||||||
if (!globals) throw Error('Globals not defined');
|
if (!globals) throw Error('Globals not defined');
|
||||||
return globals;
|
return globals;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ReportRendererProvider: FunctionComponent = ({children}) => {
|
const ReportRendererProvider: FunctionComponent = ({children}) => {
|
||||||
const globals = useMemo(() => {
|
const globals = useMemo(() => {
|
||||||
const dom = new DOM(document);
|
const dom = new DOM(document);
|
||||||
const detailsRenderer = new DetailsRenderer(dom);
|
const detailsRenderer = new DetailsRenderer(dom);
|
||||||
|
@ -44,3 +44,9 @@ export const ReportRendererProvider: FunctionComponent = ({children}) => {
|
||||||
<ReportRendererContext.Provider value={globals}>{children}</ReportRendererContext.Provider>
|
<ReportRendererContext.Provider value={globals}>{children}</ReportRendererContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
ReportRendererContext,
|
||||||
|
ReportRendererProvider,
|
||||||
|
useReportRenderer,
|
||||||
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {useReportRenderer} from './report-renderer';
|
||||||
* This function converts any anchor links under the provided element to a flow report link.
|
* This function converts any anchor links under the provided element to a flow report link.
|
||||||
* e.g. <a href="#link"> -> <a href="#index=0&anchor=link">
|
* e.g. <a href="#link"> -> <a href="#index=0&anchor=link">
|
||||||
*/
|
*/
|
||||||
export function convertChildAnchors(element: HTMLElement, index: number) {
|
function convertChildAnchors(element: HTMLElement, index: number) {
|
||||||
const links = element.querySelectorAll('a[href]') as NodeListOf<HTMLAnchorElement>;
|
const links = element.querySelectorAll('a[href]') as NodeListOf<HTMLAnchorElement>;
|
||||||
for (const link of links) {
|
for (const link of links) {
|
||||||
// Check if the link destination is in the report.
|
// Check if the link destination is in the report.
|
||||||
|
@ -38,7 +38,7 @@ export function convertChildAnchors(element: HTMLElement, index: number) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Report: FunctionComponent<{hashState: LH.FlowResult.HashState}> =
|
const Report: FunctionComponent<{hashState: LH.FlowResult.HashState}> =
|
||||||
({hashState}) => {
|
({hashState}) => {
|
||||||
const {dom, reportRenderer} = useReportRenderer();
|
const {dom, reportRenderer} = useReportRenderer();
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
@ -71,3 +71,8 @@ export const Report: FunctionComponent<{hashState: LH.FlowResult.HashState}> =
|
||||||
<div ref={ref} className="lh-root" data-testid="Report"/>
|
<div ref={ref} className="lh-root" data-testid="Report"/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
convertChildAnchors,
|
||||||
|
Report,
|
||||||
|
};
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {JSDOM} from 'jsdom';
|
||||||
/**
|
/**
|
||||||
* The jest environment "jsdom" does not work when preact is combined with the report renderer.
|
* The jest environment "jsdom" does not work when preact is combined with the report renderer.
|
||||||
*/
|
*/
|
||||||
export function setupJsDom() {
|
function setupJsDom() {
|
||||||
const {window} = new JSDOM(undefined, {
|
const {window} = new JSDOM(undefined, {
|
||||||
url: 'file:///Users/example/report.html/',
|
url: 'file:///Users/example/report.html/',
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,5 +23,7 @@ module.exports = {
|
||||||
],
|
],
|
||||||
'newlines-between': 'always',
|
'newlines-between': 'always',
|
||||||
}],
|
}],
|
||||||
|
'import/group-exports': 2,
|
||||||
|
'import/exports-last': 2,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
const {isUnderTest} = require('../lib/lh-env.js');
|
const {isUnderTest} = require('../lib/lh-env.js');
|
||||||
const statistics = require('../lib/statistics.js');
|
const statistics = require('../lib/statistics.js');
|
||||||
const Util = require('../util-commonjs.js');
|
const {Util} = require('../util-commonjs.js');
|
||||||
|
|
||||||
const DEFAULT_PASS = 'defaultPass';
|
const DEFAULT_PASS = 'defaultPass';
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ const NetworkRecords = require('./network-records.js');
|
||||||
const URL = require('../lib/url-shim.js');
|
const URL = require('../lib/url-shim.js');
|
||||||
const NetworkRequest = require('../lib/network-request.js');
|
const NetworkRequest = require('../lib/network-request.js');
|
||||||
const Budget = require('../config/budget.js');
|
const Budget = require('../config/budget.js');
|
||||||
const Util = require('../util-commonjs.js');
|
const {Util} = require('../util-commonjs.js');
|
||||||
|
|
||||||
/** @typedef {{count: number, resourceSize: number, transferSize: number}} ResourceEntry */
|
/** @typedef {{count: number, resourceSize: number, transferSize: number}} ResourceEntry */
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
* URL shim so we keep our code DRY
|
* URL shim so we keep our code DRY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const Util = require('../util-commonjs.js');
|
const {Util} = require('../util-commonjs.js');
|
||||||
|
|
||||||
/** @typedef {import('./network-request.js')} NetworkRequest */
|
/** @typedef {import('./network-request.js')} NetworkRequest */
|
||||||
|
|
||||||
|
|
|
@ -23,5 +23,7 @@ module.exports = {
|
||||||
],
|
],
|
||||||
'newlines-between': 'always',
|
'newlines-between': 'always',
|
||||||
}],
|
}],
|
||||||
|
'import/group-exports': 2,
|
||||||
|
'import/exports-last': 2,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,5 +16,4 @@ OUT_FILE="$LH_ROOT_DIR"/lighthouse-core/util-commonjs.js
|
||||||
echo '// @ts-nocheck' > "$OUT_FILE"
|
echo '// @ts-nocheck' > "$OUT_FILE"
|
||||||
echo '// Auto-generated by lighthouse-core/scripts/copy-util-commonjs.sh' >> "$OUT_FILE"
|
echo '// Auto-generated by lighthouse-core/scripts/copy-util-commonjs.sh' >> "$OUT_FILE"
|
||||||
echo '// Temporary solution until all our code uses esmodules' >> "$OUT_FILE"
|
echo '// Temporary solution until all our code uses esmodules' >> "$OUT_FILE"
|
||||||
sed 's/export class Util/class Util/g; s/export const UIStrings = Util.UIStrings;//g' "$LH_ROOT_DIR"/report/renderer/util.js >> "$OUT_FILE"
|
sed 's/export /module.exports = /' "$LH_ROOT_DIR"/report/renderer/util.js >> "$OUT_FILE"
|
||||||
echo 'module.exports = Util;' >> "$OUT_FILE"
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ import tsc from 'typescript';
|
||||||
import MessageParser from 'intl-messageformat-parser';
|
import MessageParser from 'intl-messageformat-parser';
|
||||||
import esMain from 'es-main';
|
import esMain from 'es-main';
|
||||||
|
|
||||||
import Util from '../../../lighthouse-core/util-commonjs.js';
|
import {Util} from '../../../lighthouse-core/util-commonjs.js';
|
||||||
import {collectAndBakeCtcStrings} from './bake-ctc-to-lhl.js';
|
import {collectAndBakeCtcStrings} from './bake-ctc-to-lhl.js';
|
||||||
import {pruneObsoleteLhlMessages} from './prune-obsolete-lhl-messages.js';
|
import {pruneObsoleteLhlMessages} from './prune-obsolete-lhl-messages.js';
|
||||||
import {countTranslatedMessages} from './count-translated.js';
|
import {countTranslatedMessages} from './count-translated.js';
|
||||||
|
|
|
@ -42,6 +42,10 @@ const listOfTlds = [
|
||||||
];
|
];
|
||||||
|
|
||||||
class Util {
|
class Util {
|
||||||
|
/** @type {I18n<typeof UIStrings>} */
|
||||||
|
// @ts-expect-error: Is set in report renderer.
|
||||||
|
static i18n = null;
|
||||||
|
|
||||||
static get PASS_THRESHOLD() {
|
static get PASS_THRESHOLD() {
|
||||||
return PASS_THRESHOLD;
|
return PASS_THRESHOLD;
|
||||||
}
|
}
|
||||||
|
@ -557,14 +561,10 @@ Util.getUniqueSuffix = (() => {
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/** @type {I18n<typeof Util['UIStrings']>} */
|
|
||||||
// @ts-expect-error: Is set in report renderer.
|
|
||||||
Util.i18n = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report-renderer-specific strings.
|
* Report-renderer-specific strings.
|
||||||
*/
|
*/
|
||||||
Util.UIStrings = {
|
const UIStrings = {
|
||||||
/** Disclaimer shown to users below the metric values (First Contentful Paint, Time to Interactive, etc) to warn them that the numbers they see will likely change slightly the next time they run Lighthouse. */
|
/** Disclaimer shown to users below the metric values (First Contentful Paint, Time to Interactive, etc) to warn them that the numbers they see will likely change slightly the next time they run Lighthouse. */
|
||||||
varianceDisclaimer: 'Values are estimated and may vary. The [performance score is calculated](https://web.dev/performance-scoring/) directly from these metrics.',
|
varianceDisclaimer: 'Values are estimated and may vary. The [performance score is calculated](https://web.dev/performance-scoring/) directly from these metrics.',
|
||||||
/** Text link pointing to an interactive calculator that explains Lighthouse scoring. The link text should be fairly short. */
|
/** Text link pointing to an interactive calculator that explains Lighthouse scoring. The link text should be fairly short. */
|
||||||
|
@ -677,6 +677,9 @@ Util.UIStrings = {
|
||||||
/** Label indicating that Lighthouse throttled the page using custom throttling settings. */
|
/** Label indicating that Lighthouse throttled the page using custom throttling settings. */
|
||||||
runtimeCustom: 'Custom throttling',
|
runtimeCustom: 'Custom throttling',
|
||||||
};
|
};
|
||||||
|
Util.UIStrings = UIStrings;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
module.exports = Util;
|
Util,
|
||||||
|
UIStrings,
|
||||||
|
};
|
||||||
|
|
|
@ -29,5 +29,7 @@ module.exports = {
|
||||||
],
|
],
|
||||||
'newlines-between': 'always',
|
'newlines-between': 'always',
|
||||||
}],
|
}],
|
||||||
|
'import/group-exports': 2,
|
||||||
|
'import/exports-last': 2,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,12 +21,21 @@
|
||||||
* critical request chains network tree.
|
* critical request chains network tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @typedef {import('./dom.js').DOM} DOM */
|
|
||||||
/** @typedef {import('./details-renderer.js').DetailsRenderer} DetailsRenderer */
|
|
||||||
|
|
||||||
import {Util} from './util.js';
|
import {Util} from './util.js';
|
||||||
|
|
||||||
export class CriticalRequestChainRenderer {
|
/** @typedef {import('./dom.js').DOM} DOM */
|
||||||
|
/** @typedef {import('./details-renderer.js').DetailsRenderer} DetailsRenderer */
|
||||||
|
/**
|
||||||
|
* @typedef CRCSegment
|
||||||
|
* @property {LH.Audit.Details.SimpleCriticalRequestNode[string]} node
|
||||||
|
* @property {boolean} isLastChild
|
||||||
|
* @property {boolean} hasChildren
|
||||||
|
* @property {number} startTime
|
||||||
|
* @property {number} transferSize
|
||||||
|
* @property {boolean[]} treeMarkers
|
||||||
|
*/
|
||||||
|
|
||||||
|
class CriticalRequestChainRenderer {
|
||||||
/**
|
/**
|
||||||
* Create render context for critical-request-chain tree display.
|
* Create render context for critical-request-chain tree display.
|
||||||
* @param {LH.Audit.Details.SimpleCriticalRequestNode} tree
|
* @param {LH.Audit.Details.SimpleCriticalRequestNode} tree
|
||||||
|
@ -191,12 +200,6 @@ export class CriticalRequestChainRenderer {
|
||||||
// Alias b/c the name is really long.
|
// Alias b/c the name is really long.
|
||||||
const CRCRenderer = CriticalRequestChainRenderer;
|
const CRCRenderer = CriticalRequestChainRenderer;
|
||||||
|
|
||||||
/** @typedef {{
|
export {
|
||||||
node: LH.Audit.Details.SimpleCriticalRequestNode[string],
|
CriticalRequestChainRenderer,
|
||||||
isLastChild: boolean,
|
};
|
||||||
hasChildren: boolean,
|
|
||||||
startTime: number,
|
|
||||||
transferSize: number,
|
|
||||||
treeMarkers: Array<boolean>
|
|
||||||
}} CRCSegment
|
|
||||||
*/
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ async function openTabWithUrlData(data, url_, windowName) {
|
||||||
* @param {LH.Result} lhr
|
* @param {LH.Result} lhr
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
export async function openViewer(lhr) {
|
async function openViewer(lhr) {
|
||||||
const windowName = 'viewer-' + computeWindowNameSuffix(lhr);
|
const windowName = 'viewer-' + computeWindowNameSuffix(lhr);
|
||||||
const url = getAppsOrigin() + '/viewer/';
|
const url = getAppsOrigin() + '/viewer/';
|
||||||
await openTabWithUrlData({lhr}, url, windowName);
|
await openTabWithUrlData({lhr}, url, windowName);
|
||||||
|
@ -101,7 +101,7 @@ export async function openViewer(lhr) {
|
||||||
* @param {LH.Result} lhr
|
* @param {LH.Result} lhr
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
export async function openViewerAndSendData(lhr) {
|
async function openViewerAndSendData(lhr) {
|
||||||
const windowName = 'viewer-' + computeWindowNameSuffix(lhr);
|
const windowName = 'viewer-' + computeWindowNameSuffix(lhr);
|
||||||
const url = getAppsOrigin() + '/viewer/';
|
const url = getAppsOrigin() + '/viewer/';
|
||||||
openTabAndSendData({lhr}, url, windowName);
|
openTabAndSendData({lhr}, url, windowName);
|
||||||
|
@ -111,7 +111,7 @@ export async function openViewerAndSendData(lhr) {
|
||||||
* Opens a new tab to the treemap app and sends the JSON results using URL.fragment
|
* Opens a new tab to the treemap app and sends the JSON results using URL.fragment
|
||||||
* @param {LH.Result} json
|
* @param {LH.Result} json
|
||||||
*/
|
*/
|
||||||
export function openTreemap(json) {
|
function openTreemap(json) {
|
||||||
const treemapData = json.audits['script-treemap-data'].details;
|
const treemapData = json.audits['script-treemap-data'].details;
|
||||||
if (!treemapData) {
|
if (!treemapData) {
|
||||||
throw new Error('no script treemap data found');
|
throw new Error('no script treemap data found');
|
||||||
|
@ -135,3 +135,9 @@ export function openTreemap(json) {
|
||||||
|
|
||||||
openTabWithUrlData(treemapOptions, url, windowName);
|
openTabWithUrlData(treemapOptions, url, windowName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
openViewer,
|
||||||
|
openViewerAndSendData,
|
||||||
|
openTreemap,
|
||||||
|
};
|
||||||
|
|
|
@ -38,7 +38,11 @@ const listOfTlds = [
|
||||||
'web', 'spb', 'blog', 'jus', 'kiev', 'mil', 'wi', 'qc', 'ca', 'bel', 'on',
|
'web', 'spb', 'blog', 'jus', 'kiev', 'mil', 'wi', 'qc', 'ca', 'bel', 'on',
|
||||||
];
|
];
|
||||||
|
|
||||||
export class Util {
|
class Util {
|
||||||
|
/** @type {I18n<typeof UIStrings>} */
|
||||||
|
// @ts-expect-error: Is set in report renderer.
|
||||||
|
static i18n = null;
|
||||||
|
|
||||||
static get PASS_THRESHOLD() {
|
static get PASS_THRESHOLD() {
|
||||||
return PASS_THRESHOLD;
|
return PASS_THRESHOLD;
|
||||||
}
|
}
|
||||||
|
@ -554,14 +558,10 @@ Util.getUniqueSuffix = (() => {
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/** @type {I18n<typeof Util['UIStrings']>} */
|
|
||||||
// @ts-expect-error: Is set in report renderer.
|
|
||||||
Util.i18n = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report-renderer-specific strings.
|
* Report-renderer-specific strings.
|
||||||
*/
|
*/
|
||||||
Util.UIStrings = {
|
const UIStrings = {
|
||||||
/** Disclaimer shown to users below the metric values (First Contentful Paint, Time to Interactive, etc) to warn them that the numbers they see will likely change slightly the next time they run Lighthouse. */
|
/** Disclaimer shown to users below the metric values (First Contentful Paint, Time to Interactive, etc) to warn them that the numbers they see will likely change slightly the next time they run Lighthouse. */
|
||||||
varianceDisclaimer: 'Values are estimated and may vary. The [performance score is calculated](https://web.dev/performance-scoring/) directly from these metrics.',
|
varianceDisclaimer: 'Values are estimated and may vary. The [performance score is calculated](https://web.dev/performance-scoring/) directly from these metrics.',
|
||||||
/** Text link pointing to an interactive calculator that explains Lighthouse scoring. The link text should be fairly short. */
|
/** Text link pointing to an interactive calculator that explains Lighthouse scoring. The link text should be fairly short. */
|
||||||
|
@ -674,5 +674,9 @@ Util.UIStrings = {
|
||||||
/** Label indicating that Lighthouse throttled the page using custom throttling settings. */
|
/** Label indicating that Lighthouse throttled the page using custom throttling settings. */
|
||||||
runtimeCustom: 'Custom throttling',
|
runtimeCustom: 'Custom throttling',
|
||||||
};
|
};
|
||||||
|
Util.UIStrings = UIStrings;
|
||||||
|
|
||||||
export const UIStrings = Util.UIStrings;
|
export {
|
||||||
|
Util,
|
||||||
|
UIStrings,
|
||||||
|
};
|
||||||
|
|
|
@ -23,5 +23,7 @@ module.exports = {
|
||||||
],
|
],
|
||||||
'newlines-between': 'always',
|
'newlines-between': 'always',
|
||||||
}],
|
}],
|
||||||
|
'import/group-exports': 2,
|
||||||
|
'import/exports-last': 2,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
/** @template {string} T @typedef {import('typed-query-selector/parser').ParseSelector<T, Element>} ParseSelector */
|
/** @template {string} T @typedef {import('typed-query-selector/parser').ParseSelector<T, Element>} ParseSelector */
|
||||||
/** @template T @typedef {import('../../../report/renderer/i18n').I18n<T>} I18n */
|
/** @template T @typedef {import('../../../report/renderer/i18n').I18n<T>} I18n */
|
||||||
|
|
||||||
export const UIStrings = {
|
const UIStrings = {
|
||||||
/** Label for a button that alternates between showing or hiding a table. */
|
/** Label for a button that alternates between showing or hiding a table. */
|
||||||
toggleTableButtonLabel: 'Toggle Table',
|
toggleTableButtonLabel: 'Toggle Table',
|
||||||
/** Text for an option in a dropdown menu. When selected, the app shows information for all scripts that were found in a web page. */
|
/** Text for an option in a dropdown menu. When selected, the app shows information for all scripts that were found in a web page. */
|
||||||
|
@ -30,7 +30,7 @@ export const UIStrings = {
|
||||||
duplicateModulesLabel: 'Duplicate Modules',
|
duplicateModulesLabel: 'Duplicate Modules',
|
||||||
};
|
};
|
||||||
|
|
||||||
export class TreemapUtil {
|
class TreemapUtil {
|
||||||
/** @type {I18n<typeof TreemapUtil['UIStrings']>} */
|
/** @type {I18n<typeof TreemapUtil['UIStrings']>} */
|
||||||
// @ts-expect-error: Is set in main.
|
// @ts-expect-error: Is set in main.
|
||||||
static i18n = null;
|
static i18n = null;
|
||||||
|
@ -216,3 +216,8 @@ TreemapUtil.COLOR_HUES = [
|
||||||
15.9,
|
15.9,
|
||||||
199.5,
|
199.5,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export {
|
||||||
|
TreemapUtil,
|
||||||
|
UIStrings,
|
||||||
|
};
|
||||||
|
|
|
@ -23,5 +23,7 @@ module.exports = {
|
||||||
],
|
],
|
||||||
'newlines-between': 'always',
|
'newlines-between': 'always',
|
||||||
}],
|
}],
|
||||||
|
'import/group-exports': 2,
|
||||||
|
'import/exports-last': 2,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
const PSI_URL = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed';
|
const PSI_URL = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed';
|
||||||
const PSI_KEY = 'AIzaSyAjcDRNN9CX9dCazhqI4lGR7yyQbkd_oYE';
|
const PSI_KEY = 'AIzaSyAjcDRNN9CX9dCazhqI4lGR7yyQbkd_oYE';
|
||||||
export const PSI_DEFAULT_CATEGORIES = [
|
const PSI_DEFAULT_CATEGORIES = [
|
||||||
'performance',
|
'performance',
|
||||||
'accessibility',
|
'accessibility',
|
||||||
'seo',
|
'seo',
|
||||||
|
@ -29,7 +29,7 @@ export const PSI_DEFAULT_CATEGORIES = [
|
||||||
/**
|
/**
|
||||||
* Wrapper around the PSI API for fetching LHR.
|
* Wrapper around the PSI API for fetching LHR.
|
||||||
*/
|
*/
|
||||||
export class PSIApi {
|
class PSIApi {
|
||||||
/**
|
/**
|
||||||
* @param {PSIParams} params
|
* @param {PSIParams} params
|
||||||
* @return {Promise<PSIResponse>}
|
* @return {Promise<PSIResponse>}
|
||||||
|
@ -49,3 +49,8 @@ export class PSIApi {
|
||||||
return fetch(apiUrl.href).then(res => res.json());
|
return fetch(apiUrl.href).then(res => res.json());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
PSI_DEFAULT_CATEGORIES,
|
||||||
|
PSIApi,
|
||||||
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {LH_ROOT} from '../../root.js';
|
||||||
|
|
||||||
const PAGE = fs.readFileSync(path.join(LH_ROOT, 'viewer/app/index.html'), 'utf8');
|
const PAGE = fs.readFileSync(path.join(LH_ROOT, 'viewer/app/index.html'), 'utf8');
|
||||||
|
|
||||||
export function setupJsDomGlobals() {
|
function setupJsDomGlobals() {
|
||||||
const {window} = new jsdom.JSDOM(PAGE);
|
const {window} = new jsdom.JSDOM(PAGE);
|
||||||
global.document = window.document;
|
global.document = window.document;
|
||||||
global.window = window;
|
global.window = window;
|
||||||
|
@ -24,8 +24,13 @@ export function setupJsDomGlobals() {
|
||||||
global.logger.hide = () => {/* noop */};
|
global.logger.hide = () => {/* noop */};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cleanupJsDomGlobals() {
|
function cleanupJsDomGlobals() {
|
||||||
global.document = undefined;
|
global.document = undefined;
|
||||||
global.window = undefined;
|
global.window = undefined;
|
||||||
global.logger = undefined;
|
global.logger = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
setupJsDomGlobals,
|
||||||
|
cleanupJsDomGlobals,
|
||||||
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче