Skip to content
Merged
29 changes: 20 additions & 9 deletions lighthouse-core/audits/deprecations.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,20 @@
*/

const Audit = require('./audit.js');
const Util = require('../report/html/renderer/util.js');
const i18n = require('../lib/i18n/i18n.js');

const UIStrings = {
title: 'Avoids deprecated APIs',
failureTitle: 'Uses deprecated APIs',
description: 'Deprecated APIs will eventually be removed from the browser. ' +
'[Learn more](https://www.chromestatus.com/features#deprecated).',
displayValue: `{itemCount, plural,
=1 {1 warning found}
other {# warnings found}
}`,
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

class Deprecations extends Audit {
/**
Expand All @@ -21,10 +34,9 @@ class Deprecations extends Audit {
static get meta() {
return {
id: 'deprecations',
title: 'Avoids deprecated APIs',
failureTitle: 'Uses deprecated APIs',
description: 'Deprecated APIs will eventually be removed from the browser. ' +
'[Learn more](https://www.chromestatus.com/features#deprecated).',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['ConsoleMessages'],
};
}
Expand Down Expand Up @@ -54,10 +66,8 @@ class Deprecations extends Audit {
const details = Audit.makeTableDetails(headings, deprecations);

let displayValue = '';
if (deprecations.length > 1) {
displayValue = `${Util.formatNumber(deprecations.length)} warnings found`;
} else if (deprecations.length === 1) {
displayValue = `${deprecations.length} warning found`;
if (deprecations.length > 0) {
displayValue = str_(UIStrings.displayValue, {itemCount: deprecations.length});
}

return {
Expand All @@ -72,3 +82,4 @@ class Deprecations extends Audit {
}

module.exports = Deprecations;
module.exports.UIStrings = UIStrings;
22 changes: 17 additions & 5 deletions lighthouse-core/audits/dobetterweb/appcache-manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@
'use strict';

const Audit = require('../audit.js');
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
title: 'Avoids Application Cache',
failureTitle: 'Uses Application Cache',
description: 'Application Cache is deprecated. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/appcache).',
displayValue: 'Found "{AppCacheManifest}"',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

class AppCacheManifestAttr extends Audit {
/**
Expand All @@ -19,10 +30,9 @@ class AppCacheManifestAttr extends Audit {
static get meta() {
return {
id: 'appcache-manifest',
title: 'Avoids Application Cache',
failureTitle: 'Uses Application Cache',
description: 'Application Cache is deprecated. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/appcache).',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['AppCacheManifest'],
};
}
Expand All @@ -33,7 +43,8 @@ class AppCacheManifestAttr extends Audit {
*/
static audit(artifacts) {
const usingAppcache = artifacts.AppCacheManifest !== null;
const displayValue = usingAppcache ? `Found "${artifacts.AppCacheManifest}"` : '';
const displayValue = usingAppcache ?
str_(UIStrings.displayValue, {AppCacheManifest: artifacts.AppCacheManifest}) : '';

return {
score: usingAppcache ? 0 : 1,
Expand All @@ -43,3 +54,4 @@ class AppCacheManifestAttr extends Audit {
}

module.exports = AppCacheManifestAttr;
module.exports.UIStrings = UIStrings;
32 changes: 23 additions & 9 deletions lighthouse-core/audits/dobetterweb/doctype.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@
'use strict';

const Audit = require('../audit.js');
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
title: 'Page has the HTML doctype',
failureTitle: 'Page is missing the HTML doctype',
description: 'Specifying a doctype prevents the browser ' +
'from switching to quirks-mode. Read more on the ' +
'[MDN Web Docs page](https://developer.mozilla.org/en-US/docs/Glossary/Doctype)',
explanationNoDoctype: 'Document must contain a doctype',
explanationPublicId: 'Expected publicId to be an empty string',
explanationSystemId: 'Expected systemId to be an empty string',
explanationBadDoctype: 'Doctype name must be the lowercase string `html`',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

class Doctype extends Audit {
/**
Expand All @@ -14,11 +29,9 @@ class Doctype extends Audit {
static get meta() {
return {
id: 'doctype',
title: 'Page has the HTML doctype',
failureTitle: 'Page is missing the HTML doctype',
description: 'Specifying a doctype prevents the browser from switching to quirks-mode.' +
'Read more on the ' +
'[MDN Web Docs page](https://developer.mozilla.org/en-US/docs/Glossary/Doctype)',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['Doctype'],
};
}
Expand All @@ -31,7 +44,7 @@ class Doctype extends Audit {
if (!artifacts.Doctype) {
return {
score: 0,
explanation: 'Document must contain a doctype',
explanation: str_(UIStrings.explanationNoDoctype),
};
}

Expand All @@ -43,14 +56,14 @@ class Doctype extends Audit {
if (doctypePublicId !== '') {
return {
score: 0,
explanation: 'Expected publicId to be an empty string',
explanation: str_(UIStrings.explanationPublicId),
};
}

if (doctypeSystemId !== '') {
return {
score: 0,
explanation: 'Expected systemId to be an empty string',
explanation: str_(UIStrings.explanationSystemId),
};
}

Expand All @@ -64,10 +77,11 @@ class Doctype extends Audit {
} else {
return {
score: 0,
explanation: 'Doctype name must be the lowercase string `html`',
explanation: str_(UIStrings.explanationBadDoctype),
};
}
}
}

module.exports = Doctype;
module.exports.UIStrings = UIStrings;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@

const URL = require('../../lib/url-shim.js');
const Audit = require('../audit.js');
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
title: 'Links to cross-origin destinations are safe',
failureTitle: 'Links to cross-origin destinations are unsafe',
description: 'Add `rel="noopener"` or `rel="noreferrer"` to any external links to improve ' +
'performance and prevent security vulnerabilities. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/noopener).',
warning: 'Unable to determine the destination for anchor ({anchorHTML}). ' +
'If not used as a hyperlink, consider removing target=_blank.',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

class ExternalAnchorsUseRelNoopenerAudit extends Audit {
/**
Expand All @@ -15,11 +28,9 @@ class ExternalAnchorsUseRelNoopenerAudit extends Audit {
static get meta() {
return {
id: 'external-anchors-use-rel-noopener',
title: 'Links to cross-origin destinations are safe',
failureTitle: 'Links to cross-origin destinations are unsafe',
description: 'Add `rel="noopener"` or `rel="noreferrer"` to any external links to improve ' +
'performance and prevent security vulnerabilities. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/noopener).',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['URL', 'AnchorElements'],
};
}
Expand All @@ -40,8 +51,7 @@ class ExternalAnchorsUseRelNoopenerAudit extends Audit {
try {
return new URL(anchor.href).host !== pageHost;
} catch (err) {
warnings.push(`Unable to determine the destination for anchor (${anchor.outerHTML}). ` +
'If not used as a hyperlink, consider removing target=_blank.');
warnings.push(str_(UIStrings.warning, {anchorHTML: anchor.outerHTML}));
return true;
}
})
Expand Down Expand Up @@ -78,3 +88,4 @@ class ExternalAnchorsUseRelNoopenerAudit extends Audit {
}

module.exports = ExternalAnchorsUseRelNoopenerAudit;
module.exports.UIStrings = UIStrings;
20 changes: 15 additions & 5 deletions lighthouse-core/audits/dobetterweb/geolocation-on-start.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@
'use strict';

const ViolationAudit = require('../violation-audit.js');
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
title: 'Avoids requesting the geolocation permission on page load',
failureTitle: 'Requests the geolocation permission on page load',
description: 'Users are mistrustful of or confused by sites that request their ' +
'location without context. Consider tying the request to user gestures instead. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/geolocation-on-load).',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

class GeolocationOnStart extends ViolationAudit {
/**
Expand All @@ -20,11 +31,9 @@ class GeolocationOnStart extends ViolationAudit {
static get meta() {
return {
id: 'geolocation-on-start',
title: 'Avoids requesting the geolocation permission on page load',
failureTitle: 'Requests the geolocation permission on page load',
description: 'Users are mistrustful of or confused by sites that request their ' +
'location without context. Consider tying the request to user gestures instead. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/geolocation-on-load).',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['ConsoleMessages'],
};
}
Expand Down Expand Up @@ -57,3 +66,4 @@ class GeolocationOnStart extends ViolationAudit {
}

module.exports = GeolocationOnStart;
module.exports.UIStrings = UIStrings;
13 changes: 11 additions & 2 deletions lighthouse-core/audits/dobetterweb/js-libraries.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@
'use strict';

const Audit = require('../audit.js');
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
title: 'Detected JavaScript libraries',
description: 'All front-end JavaScript libraries detected on the page.',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

class JsLibrariesAudit extends Audit {
/**
Expand All @@ -19,8 +27,8 @@ class JsLibrariesAudit extends Audit {
static get meta() {
return {
id: 'js-libraries',
title: 'Detected JavaScript libraries',
description: 'All front-end JavaScript libraries detected on the page.',
title: str_(UIStrings.title),
description: str_(UIStrings.description),
requiredArtifacts: ['Stacks'],
};
}
Expand Down Expand Up @@ -53,3 +61,4 @@ class JsLibrariesAudit extends Audit {
}

module.exports = JsLibrariesAudit;
module.exports.UIStrings = UIStrings;
20 changes: 15 additions & 5 deletions lighthouse-core/audits/dobetterweb/no-document-write.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@
'use strict';

const ViolationAudit = require('../violation-audit.js');
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
title: 'Avoids `document.write()`',
failureTitle: 'Uses `document.write()`',
description: 'For users on slow connections, external scripts dynamically injected via ' +
'`document.write()` can delay page load by tens of seconds. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/document-write).',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

class NoDocWriteAudit extends ViolationAudit {
/**
Expand All @@ -19,11 +30,9 @@ class NoDocWriteAudit extends ViolationAudit {
static get meta() {
return {
id: 'no-document-write',
title: 'Avoids `document.write()`',
failureTitle: 'Uses `document.write()`',
description: 'For users on slow connections, external scripts dynamically injected via ' +
'`document.write()` can delay page load by tens of seconds. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/document-write).',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['ConsoleMessages'],
};
}
Expand Down Expand Up @@ -54,3 +63,4 @@ class NoDocWriteAudit extends ViolationAudit {
}

module.exports = NoDocWriteAudit;
module.exports.UIStrings = UIStrings;
34 changes: 23 additions & 11 deletions lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,23 @@ const Audit = require('../audit.js');
const Sentry = require('../../lib/sentry.js');
const semver = require('semver');
const snykDatabase = require('../../../third-party/snyk/snapshot.json');
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
title: 'Avoids front-end JavaScript libraries' +
' with known security vulnerabilities',
failureTitle: 'Includes front-end JavaScript libraries' +
' with known security vulnerabilities',
description: 'Some third-party scripts may contain known security vulnerabilities ' +
'that are easily identified and exploited by attackers. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/vulnerabilities).',
displayValue: `{itemCount, plural,
=1 {1 vulnerability detected}
other {# vulnerabilities detected}
}`,
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

const SEMVER_REGEX = /^(\d+\.\d+\.\d+)[^-0-9]+/;

Expand All @@ -29,13 +46,9 @@ class NoVulnerableLibrariesAudit extends Audit {
static get meta() {
return {
id: 'no-vulnerable-libraries',
title: 'Avoids front-end JavaScript libraries'
+ ' with known security vulnerabilities',
failureTitle: 'Includes front-end JavaScript libraries'
+ ' with known security vulnerabilities',
description: 'Some third-party scripts may contain known security vulnerabilities ' +
'that are easily identified and exploited by attackers. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/vulnerabilities).',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['Stacks'],
};
}
Expand Down Expand Up @@ -179,10 +192,8 @@ class NoVulnerableLibrariesAudit extends Audit {
});

let displayValue = '';
if (totalVulns > 1) {
displayValue = `${totalVulns} vulnerabilities detected`;
} else if (totalVulns === 1) {
displayValue = `${totalVulns} vulnerability detected`;
if (totalVulns > 0) {
displayValue = str_(UIStrings.displayValue, {itemCount: totalVulns});
}

/** @type {LH.Audit.Details.Table['headings']} */
Expand All @@ -206,3 +217,4 @@ class NoVulnerableLibrariesAudit extends Audit {
}

module.exports = NoVulnerableLibrariesAudit;
module.exports.UIStrings = UIStrings;
Loading